Class: CephRuby::RadosBlockDevice

Inherits:
Object
  • Object
show all
Defined in:
lib/ceph-ruby/rados_block_device.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pool, name) ⇒ RadosBlockDevice

Returns a new instance of RadosBlockDevice.



7
8
9
10
11
12
13
14
# File 'lib/ceph-ruby/rados_block_device.rb', line 7

def initialize(pool, name)
  self.pool = pool
  self.name = name
  if block_given?
    yield(self)
    close
  end
end

Instance Attribute Details

#handleObject

Returns the value of attribute handle.



3
4
5
# File 'lib/ceph-ruby/rados_block_device.rb', line 3

def handle
  @handle
end

#nameObject

Returns the value of attribute name.



3
4
5
# File 'lib/ceph-ruby/rados_block_device.rb', line 3

def name
  @name
end

#poolObject

Returns the value of attribute pool.



3
4
5
# File 'lib/ceph-ruby/rados_block_device.rb', line 3

def pool
  @pool
end

Instance Method Details

#closeObject



49
50
51
52
53
54
# File 'lib/ceph-ruby/rados_block_device.rb', line 49

def close
  return unless open?
  log("close")
  Lib::Rbd.rbd_close(handle)
  self.handle = nil
end

#copy_to(dst_name, dst_pool = nil) ⇒ Object

Raises:

  • (SystemCallError)


103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ceph-ruby/rados_block_device.rb', line 103

def copy_to(dst_name, dst_pool = nil)
  ensure_open
  case dst_pool
  when String
    dst_pool = cluster.pool(dst_pool)
  when nil
    dst_pool = pool
  end
  dst_pool.ensure_open
  log("copy_to #{dst_pool.name}/#{dst_name}")
  ret = Lib::Rbd.rbd_copy(handle, dst_pool.handle, dst_name)
  raise SystemCallError.new("copy of '#{name}' to '#{dst_pool.name}/#{dst_name}' failed", -ret) if ret < 0
end

#create(size, features = 0, order = 26) ⇒ Object

Raises:

  • (SystemCallError)


32
33
34
35
36
37
38
# File 'lib/ceph-ruby/rados_block_device.rb', line 32

def create(size, features = 0, order = 26)
  log("create size #{size}, features #{features}, order #{order}")
  order_p = FFI::MemoryPointer.new(:int)
  order_p.put_int(0, order)
  ret = Lib::Rbd.rbd_create2(pool.handle, name, size, features, order_p)
  raise SystemCallError.new("creation of '#{name}' failed", -ret) if ret < 0
end

#destroyObject

Raises:

  • (SystemCallError)


56
57
58
59
60
61
# File 'lib/ceph-ruby/rados_block_device.rb', line 56

def destroy
  close if open?
  log("destroy")
  ret = Lib::Rbd.rbd_remove(pool.handle, name)
  raise SystemCallError.new("destroy of '#{name}' failed", -ret) if ret < 0
end

#ensure_openObject



123
124
125
126
# File 'lib/ceph-ruby/rados_block_device.rb', line 123

def ensure_open
  return if open?
  open
end

#exists?Boolean

Returns:

  • (Boolean)


16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/ceph-ruby/rados_block_device.rb', line 16

def exists?
  log("exists?")
  handle_p = FFI::MemoryPointer.new(:pointer)
  ret = Lib::Rbd.rbd_open(pool.handle, name, handle_p, nil)
  case ret
  when 0
    handle = handle_p.get_pointer(0)
    Lib::Rbd.rbd_close(handle)
    true
  when -Errno::ENOENT::Errno
    false
  else
    raise SystemCallError.new("open of '#{name}' failed", -ret) if ret < 0
  end
end

#log(message) ⇒ Object



128
129
130
# File 'lib/ceph-ruby/rados_block_device.rb', line 128

def log(message)
  CephRuby.log("rbd image #{pool.name}/#{name} #{message}")
end

#openObject

Raises:

  • (SystemCallError)


40
41
42
43
44
45
46
47
# File 'lib/ceph-ruby/rados_block_device.rb', line 40

def open
  return if open?
  log("open")
  handle_p = FFI::MemoryPointer.new(:pointer)
  ret = Lib::Rbd.rbd_open(pool.handle, name, handle_p, nil)
  raise SystemCallError.new("open of '#{name}' failed", -ret) if ret < 0
  self.handle = handle_p.get_pointer(0)
end

#open?Boolean

helper methods below

Returns:

  • (Boolean)


119
120
121
# File 'lib/ceph-ruby/rados_block_device.rb', line 119

def open?
  !!handle
end

#read(offset, size) ⇒ Object

Raises:

  • (SystemCallError)


72
73
74
75
76
77
78
79
# File 'lib/ceph-ruby/rados_block_device.rb', line 72

def read(offset, size)
  ensure_open
  log("read offset #{offset}, size #{size}")
  data_p = FFI::MemoryPointer.new(:char, size)
  ret = Lib::Rbd.rbd_read(handle, offset, size, data_p)
  raise SystemCallError.new("read of #{size} bytes from '#{name}' at #{offset} failed", -ret) if ret < 0
  data_p.get_bytes(0, ret)
end

#resize(size) ⇒ Object

Raises:

  • (SystemCallError)


92
93
94
95
96
97
# File 'lib/ceph-ruby/rados_block_device.rb', line 92

def resize(size)
  ensure_open
  log("resize size #{size}")
  ret = Lib::Rbd.rbd_resize(handle, size)
  raise SystemCallError.new("resize of '#{name}' to #{size} failed", -ret) if ret < 0
end

#sizeObject



99
100
101
# File 'lib/ceph-ruby/rados_block_device.rb', line 99

def size
  stat[:size]
end

#statObject

Raises:

  • (SystemCallError)


81
82
83
84
85
86
87
88
89
90
# File 'lib/ceph-ruby/rados_block_device.rb', line 81

def stat
  ensure_open
  log("stat")
  stat = Lib::Rbd::StatStruct.new
  ret = Lib::Rbd.rbd_stat(handle, stat, stat.size)
  raise SystemCallError.new("stat of '#{name}' failed", -ret) if ret < 0
  Hash[[:size, :obj_size, :num_objs, :order].map{ |k| [k, stat[k]] }].tap do |hash|
    hash[:block_name_prefix] = stat[:block_name_prefix].to_ptr.read_string
  end
end

#write(offset, data) ⇒ Object

Raises:

  • (SystemCallError)


63
64
65
66
67
68
69
70
# File 'lib/ceph-ruby/rados_block_device.rb', line 63

def write(offset, data)
  ensure_open
  size = data.bytesize
  log("write offset #{offset}, size #{size}")
  ret = Lib::Rbd.rbd_write(handle, offset, size, data)
  raise SystemCallError.new("write of #{size} bytes to '#{name}' at #{offset} failed", -ret) if ret < 0
  raise Errno::EIO.new("wrote only #{ret} of #{size} bytes to '#{name}' at #{offset}") if ret < size
end