Class: CephRuby::RadosBlockDevice

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

Constant Summary collapse

FEATURE_LAYERING =
1
FEATURE_STRIPING_V2 =
2
FEATURE_EXCLUSIVE_LOCK =
4
FEATURE_OBJECT_MAP =
8

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pool, name) ⇒ RadosBlockDevice

Returns a new instance of RadosBlockDevice.



12
13
14
15
16
17
18
19
20
21
22
# File 'lib/ceph-ruby/rados_block_device.rb', line 12

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

Instance Attribute Details

#handleObject

Returns the value of attribute handle.



8
9
10
# File 'lib/ceph-ruby/rados_block_device.rb', line 8

def handle
  @handle
end

#nameObject

Returns the value of attribute name.



8
9
10
# File 'lib/ceph-ruby/rados_block_device.rb', line 8

def name
  @name
end

#poolObject

Returns the value of attribute pool.



8
9
10
# File 'lib/ceph-ruby/rados_block_device.rb', line 8

def pool
  @pool
end

Instance Method Details

#clone(snapshot, dst_name, dst_pool = nil, features = 0, order = 0) ⇒ Object

Raises:

  • (SystemCallError)


174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/ceph-ruby/rados_block_device.rb', line 174

def clone(snapshot, dst_name, dst_pool = nil, features = 0, order = 0)
  ensure_open
  case dst_pool
  when String
    dst_pool = cluster.pool(dst_pool)
  when nil
    dst_pool = pool
  end
  dst_pool.ensure_open
  log("clone snapshot #{snapshot} to #{dst_pool.name}/#{dst_name} features #{features} order #{order}")
  order_p = FFI::MemoryPointer.new(:int)
  order_p.put_int(0, order)
  ret = Lib::Rbd.rbd_clone(pool.handle, name, snapshot, dst_pool.handle, dst_name, features, order_p)
  raise SystemCallError.new("clone of '#{name}@#{snapshot}' to '#{dst_pool.name}/#{dst_name}' failed", -ret) if ret < 0
end

#closeObject



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

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)


125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/ceph-ruby/rados_block_device.rb', line 125

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 = 0) ⇒ Object

Raises:

  • (SystemCallError)


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

def create(size, features = 0, order = 0)
  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)


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

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



203
204
205
206
# File 'lib/ceph-ruby/rados_block_device.rb', line 203

def ensure_open
  return if open?
  open
end

#exists?Boolean

Returns:

  • (Boolean)


24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/ceph-ruby/rados_block_device.rb', line 24

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

#featuresObject

Raises:

  • (SystemCallError)


109
110
111
112
113
114
115
116
# File 'lib/ceph-ruby/rados_block_device.rb', line 109

def features
  ensure_open
  log("features")
  features_p = FFI::MemoryPointer.new(:uint64)
  ret = Lib::Rbd.rbd_get_features(handle, features_p)
  raise SystemCallError.new("features of '#{name}' failed", -ret) if ret < 0
  features_p.read_uint64
end

#flattenObject

Raises:

  • (SystemCallError)


190
191
192
193
194
195
# File 'lib/ceph-ruby/rados_block_device.rb', line 190

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

#log(message) ⇒ Object



208
209
210
# File 'lib/ceph-ruby/rados_block_device.rb', line 208

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

#openObject

Raises:

  • (SystemCallError)


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

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)


199
200
201
# File 'lib/ceph-ruby/rados_block_device.rb', line 199

def open?
  !!handle
end

#read(offset, size) ⇒ Object

Raises:

  • (SystemCallError)


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

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)


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

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

Raises:

  • (SystemCallError)


100
101
102
103
104
105
106
107
# File 'lib/ceph-ruby/rados_block_device.rb', line 100

def size
  ensure_open
  log("size")
  size_p = FFI::MemoryPointer.new(:uint64)
  ret = Lib::Rbd.rbd_get_size(handle, size_p)
  raise SystemCallError.new("size of '#{name}' failed", -ret) if ret < 0
  size_p.read_uint64
end

#snapshot_activate(name) ⇒ Object

Raises:

  • (SystemCallError)


167
168
169
170
171
172
# File 'lib/ceph-ruby/rados_block_device.rb', line 167

def snapshot_activate(name)
  log("snapshot_activate #{name}")
  ensure_open
  ret = Lib::Rbd.rbd_snap_set(handle, name)
  raise SystemCallError.new("activate snapshot '#{name}' of '#{self.name}' failed", -ret) if ret < 0
end

#snapshot_create(name) ⇒ Object

Raises:

  • (SystemCallError)


139
140
141
142
143
144
# File 'lib/ceph-ruby/rados_block_device.rb', line 139

def snapshot_create(name)
  log("snapshot_create #{name}")
  ensure_open
  ret = Lib::Rbd.rbd_snap_create(handle, name)
  raise SystemCallError.new("snapshot create '#{name}' of '#{self.name}' failed", -ret) if ret < 0
end

#snapshot_destroy(name) ⇒ Object

Raises:

  • (SystemCallError)


146
147
148
149
150
151
# File 'lib/ceph-ruby/rados_block_device.rb', line 146

def snapshot_destroy(name)
  log("snapshot_destroy #{name}")
  ensure_open
  ret = Lib::Rbd.rbd_snap_remove(handle, name)
  raise SystemCallError.new("snapshot destroy '#{name}' of '#{self.name}' failed", -ret) if ret < 0
end

#snapshot_protect(name) ⇒ Object

Raises:

  • (SystemCallError)


153
154
155
156
157
158
# File 'lib/ceph-ruby/rados_block_device.rb', line 153

def snapshot_protect(name)
  log("snapshot_protect #{name}")
  ensure_open
  ret = Lib::Rbd.rbd_snap_protect(handle, name)
  raise SystemCallError.new("snapshot protect '#{name}' of '#{self.name}' failed", -ret) if ret < 0
end

#snapshot_unprotect(name) ⇒ Object

Raises:

  • (SystemCallError)


160
161
162
163
164
165
# File 'lib/ceph-ruby/rados_block_device.rb', line 160

def snapshot_unprotect(name)
  log("snapshot_unprotect #{name}")
  ensure_open
  ret = Lib::Rbd.rbd_snap_unprotect(handle, name)
  raise SystemCallError.new("snapshot unprotect '#{name}' of '#{self.name}' failed", -ret) if ret < 0
end

#statObject

Raises:

  • (SystemCallError)


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

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)


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

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