1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
//! Low level bindings for Ceph's RBD interface.
//! Please see [Ceph librbd](http://docs.ceph.com/docs/master/rbd/librbdpy/#module-rbd) for more
//! information. Those are the python docs but the parameters should be the same.
#![allow(non_camel_case_types)]
extern crate libc;
extern crate librados_sys;

use self::libc::{int64_t, size_t, ssize_t, uint8_t, uint64_t};
use self::librados_sys::rados_ioctx_t;

pub type rbd_snap_t = *mut ::std::os::raw::c_void;
pub type rbd_image_t = *mut ::std::os::raw::c_void;
pub type librbd_progress_fn_t =
    ::std::option::Option<unsafe extern "C" fn(offset: uint64_t,
                                               total: uint64_t,
                                               ptr:
                                                   *mut ::std::os::raw::c_void)
                              -> ::std::os::raw::c_int>;
#[repr(C)]
#[derive(Copy)]
pub struct rbd_snap_info_t{
    /// Numeric identifier of the snapshot
    pub id: uint64_t,
    /// Size of the image at the time of snapshot (in bytes)
    pub size: uint64_t,
    /// Name of the snapshot
    pub name: *const ::std::os::raw::c_char,
}
impl ::std::clone::Clone for rbd_snap_info_t {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for rbd_snap_info_t {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}

#[repr(C)]
#[derive(Copy)]
pub struct rbd_image_info_t {
    ///  The size of the image in bytes
    pub size: uint64_t,
    /// The size of each object that comprises the image
    pub obj_size: uint64_t,
    /// The number of objects in the image
    pub num_objs: uint64_t,
    /// log_2(object_size)
    pub order: ::std::os::raw::c_int,
    /// The prefix of the RADOS objects used to store the image
    pub block_name_prefix: [::std::os::raw::c_char; 24usize],
    /// deprecated
    pub parent_pool: int64_t,
    /// deprecated
    pub parent_name: [::std::os::raw::c_char; 96usize],
}
impl ::std::clone::Clone for rbd_image_info_t {
    fn clone(&self) -> Self { *self }
}
impl ::std::default::Default for rbd_image_info_t {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type rbd_completion_t = *mut ::std::os::raw::c_void;
pub type rbd_callback_t =
    ::std::option::Option<unsafe extern "C" fn(cb: rbd_completion_t,
                                               arg:
                                                   *mut ::std::os::raw::c_void)>;
#[link(name = "rbd")]
extern "C" {
    /// Get the version number of the librbd C library.
    pub fn rbd_version(major: *mut ::std::os::raw::c_int,
                       minor: *mut ::std::os::raw::c_int,
                       extra: *mut ::std::os::raw::c_int);
    /// List image names.
    pub fn rbd_list(io: rados_ioctx_t, names: *mut ::std::os::raw::c_char,
                    size: *mut size_t) -> ::std::os::raw::c_int;
    pub fn rbd_create(io: rados_ioctx_t, name: *const ::std::os::raw::c_char,
                      size: uint64_t, order: *mut ::std::os::raw::c_int)
     -> ::std::os::raw::c_int;
    pub fn rbd_create2(io: rados_ioctx_t, name: *const ::std::os::raw::c_char,
                       size: uint64_t, features: uint64_t,
                       order: *mut ::std::os::raw::c_int)
     -> ::std::os::raw::c_int;

    /// create new rbd image
    ///
    /// The stripe_unit must be a factor of the object size (1 << order).
    /// The stripe_count can be one (no intra-object striping) or greater
    /// than one.  The RBD_FEATURE_STRIPINGV2 must be specified if the
    /// stripe_unit != the object size and the stripe_count is != 1.
    ///
    /// # Arguments
    ///  * `io` ioctx
    ///  * `name` image name
    ///  * `size` image size in bytes
    ///  * `features` initial feature bits
    ///  * `order` object/block size, as a power of two (object size == 1 << order)
    ///  * `stripe_unit` stripe unit size, in bytes.
    ///  * `stripe_count` number of objects to stripe over before looping
    /// @return 0 on success, or negative error code
    pub fn rbd_create3(io: rados_ioctx_t, name: *const ::std::os::raw::c_char,
                       size: uint64_t, features: uint64_t,
                       order: *mut ::std::os::raw::c_int,
                       stripe_unit: uint64_t, stripe_count: uint64_t)
     -> ::std::os::raw::c_int;
    /// Clone a parent rbd snapshot into a COW sparse child.
    pub fn rbd_clone(p_ioctx: rados_ioctx_t,
                     p_name: *const ::std::os::raw::c_char,
                     p_snapname: *const ::std::os::raw::c_char,
                     c_ioctx: rados_ioctx_t,
                     c_name: *const ::std::os::raw::c_char,
                     features: uint64_t, c_order: *mut ::std::os::raw::c_int)
     -> ::std::os::raw::c_int;
    /// Clone a parent rbd snapshot into a COW sparse child.
    pub fn rbd_clone2(p_ioctx: rados_ioctx_t,
                      p_name: *const ::std::os::raw::c_char,
                      p_snapname: *const ::std::os::raw::c_char,
                      c_ioctx: rados_ioctx_t,
                      c_name: *const ::std::os::raw::c_char,
                      features: uint64_t, c_order: *mut ::std::os::raw::c_int,
                      stripe_unit: uint64_t,
                      stripe_count: ::std::os::raw::c_int)
     -> ::std::os::raw::c_int;
    /// Delete an RBD image. This may take a long time, since it does not return until every
    /// object that comprises the image has been deleted. Note that all snapshots must be deleted
    /// before the image can be removed.
    pub fn rbd_remove(io: rados_ioctx_t, name: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_remove_with_progress(io: rados_ioctx_t,
                                    name: *const ::std::os::raw::c_char,
                                    cb: librbd_progress_fn_t,
                                    cbdata: *mut ::std::os::raw::c_void)
     -> ::std::os::raw::c_int;
    /// Rename an RBD image.
    pub fn rbd_rename(src_io_ctx: rados_ioctx_t,
                      srcname: *const ::std::os::raw::c_char,
                      destname: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_open(io: rados_ioctx_t, name: *const ::std::os::raw::c_char,
                    image: *mut rbd_image_t,
                    snap_name: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;

    /// Open an image in read-only mode.
    ///
    /// This is intended for use by clients that cannot write to a block
    /// device due to cephx restrictions. There will be no watch
    /// established on the header object, since a watch is a write. This
    /// means the metadata reported about this image (parents, snapshots,
    /// size, etc.) may become stale. This should not be used for
    /// long-running operations, unless you can be sure that one of these
    /// properties changing is safe.
    ///
    /// Attempting to write to a read-only image will return -EROFS.
    ///
    /// # Arguments
    ///  * `io` ioctx to determine the pool the image is in
    ///  * `name` image name
    ///  * `image` where to store newly opened image handle
    ///  * `snap_name` name of snapshot to open at, or NULL for no snapshot
    /// @returns 0 on success, negative error code on failure
    pub fn rbd_open_read_only(io: rados_ioctx_t,
                              name: *const ::std::os::raw::c_char,
                              image: *mut rbd_image_t,
                              snap_name: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_close(image: rbd_image_t) -> ::std::os::raw::c_int;

    /// Change the size of the image.
    pub fn rbd_resize(image: rbd_image_t, size: uint64_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_resize_with_progress(image: rbd_image_t, size: uint64_t,
                                    cb: librbd_progress_fn_t,
                                    cbdata: *mut ::std::os::raw::c_void)
     -> ::std::os::raw::c_int;
    /// Get information about the image. Currently parent pool and parent name are always -1 and ‘’.
    pub fn rbd_stat(image: rbd_image_t, info: *mut rbd_image_info_t,
                    infosize: size_t) -> ::std::os::raw::c_int;
    pub fn rbd_get_old_format(image: rbd_image_t, old: *mut uint8_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_get_size(image: rbd_image_t, size: *mut uint64_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_get_features(image: rbd_image_t, features: *mut uint64_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_get_stripe_unit(image: rbd_image_t, stripe_unit: *mut uint64_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_get_stripe_count(image: rbd_image_t,
                                stripe_count: *mut uint64_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_get_overlap(image: rbd_image_t, overlap: *mut uint64_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_get_parent_info(image: rbd_image_t,
                               parent_poolname: *mut ::std::os::raw::c_char,
                               ppoolnamelen: size_t,
                               parent_name: *mut ::std::os::raw::c_char,
                               pnamelen: size_t,
                               parent_snapname: *mut ::std::os::raw::c_char,
                               psnapnamelen: size_t) -> ::std::os::raw::c_int;
    pub fn rbd_copy(image: rbd_image_t, dest_io_ctx: rados_ioctx_t,
                    destname: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_copy2(src: rbd_image_t, dest: rbd_image_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_copy_with_progress(image: rbd_image_t, dest_p: rados_ioctx_t,
                                  destname: *const ::std::os::raw::c_char,
                                  cb: librbd_progress_fn_t,
                                  cbdata: *mut ::std::os::raw::c_void)
     -> ::std::os::raw::c_int;
    pub fn rbd_copy_with_progress2(src: rbd_image_t, dest: rbd_image_t,
                                   cb: librbd_progress_fn_t,
                                   cbdata: *mut ::std::os::raw::c_void)
     -> ::std::os::raw::c_int;
    pub fn rbd_snap_list(image: rbd_image_t, snaps: *mut rbd_snap_info_t,
                         max_snaps: *mut ::std::os::raw::c_int)
     -> ::std::os::raw::c_int;
    pub fn rbd_snap_list_end(snaps: *mut rbd_snap_info_t);
    pub fn rbd_snap_create(image: rbd_image_t,
                           snapname: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_snap_remove(image: rbd_image_t,
                           snapname: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_snap_rollback(image: rbd_image_t,
                             snapname: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_snap_rollback_with_progress(image: rbd_image_t,
                                           snapname:
                                               *const ::std::os::raw::c_char,
                                           cb: librbd_progress_fn_t,
                                           cbdata:
                                               *mut ::std::os::raw::c_void)
     -> ::std::os::raw::c_int;

    /// Prevent a snapshot from being deleted until it is unprotected.
    pub fn rbd_snap_protect(image: rbd_image_t,
                            snap_name: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;

    /// Allow a snaphshot to be deleted
    pub fn rbd_snap_unprotect(image: rbd_image_t,
                              snap_name: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    /// Determine whether a snapshot is protected.
    pub fn rbd_snap_is_protected(image: rbd_image_t,
                                 snap_name: *const ::std::os::raw::c_char,
                                 is_protected: *mut ::std::os::raw::c_int)
     -> ::std::os::raw::c_int;
    pub fn rbd_snap_set(image: rbd_image_t,
                        snapname: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_flatten(image: rbd_image_t) -> ::std::os::raw::c_int;

    /// List all images that are cloned from the image at the
    /// snapshot that is set via rbd_snap_set().
    ///
    /// This iterates over all pools, so it should be run by a user with
    /// read access to all of them. pools_len and images_len are filled in
    /// with the number of bytes put into the pools and images buffers.
    /// If the provided buffers are too short, the required lengths are
    /// still filled in, but the data is not and -ERANGE is returned.
    /// Otherwise, the buffers are filled with the pool and image names
    /// of the children, with a '\0' after each.
    /// # Arguments
    ///  * `image` which image (and implicitly snapshot) to list clones of
    ///  * `pools` buffer in which to store pool names
    ///  * `pools_len` number of bytes in pools buffer
    ///  * `images` buffer in which to store image names
    ///  * `images_len` number of bytes in images buffer
    /// @returns number of children on success, negative error code on failure
    /// @returns -ERANGE if either buffer is too short
    pub fn rbd_list_children(image: rbd_image_t,
                             pools: *mut ::std::os::raw::c_char,
                             pools_len: *mut size_t,
                             images: *mut ::std::os::raw::c_char,
                             images_len: *mut size_t) -> ssize_t;

    /// List clients that have locked the image and information about the lock.
    ///
    /// The number of bytes required in each buffer is put in the
    /// corresponding size out parameter. If any of the provided buffers
    /// are too short, -ERANGE is returned after these sizes are filled in.
    /// # Arguments
    ///  * `image` which image (and implicitly snapshot) to list lockers of
    ///  * `exclusive` where to store whether the lock is exclusive (1) or shared (0)
    ///  * `tag` where to store the tag associated with the image
    ///  * `tag_len` number of bytes in tag buffer
    ///  * `clients` buffer in which locker clients are stored, separated by '\0'
    ///  * `clients_len` number of bytes in the clients buffer
    ///  * `cookies` buffer in which locker cookies are stored, separated by '\0'
    ///  * `cookies_len` number of bytes in the cookies buffer
    ///  * `addrs` buffer in which locker addresses are stored, separated by '\0'
    ///  * `addrs_len` number of bytes in the clients buffer
    /// @returns number of lockers on success, negative error code on failure
    /// @returns -ERANGE if any of the buffers are too short
    pub fn rbd_list_lockers(image: rbd_image_t,
                            exclusive: *mut ::std::os::raw::c_int,
                            tag: *mut ::std::os::raw::c_char,
                            tag_len: *mut size_t,
                            clients: *mut ::std::os::raw::c_char,
                            clients_len: *mut size_t,
                            cookies: *mut ::std::os::raw::c_char,
                            cookies_len: *mut size_t,
                            addrs: *mut ::std::os::raw::c_char,
                            addrs_len: *mut size_t) -> ssize_t;
    /// Take an exclusive lock on the image.
    /// # Arguments
    ///  * `image` the image to lock
    ///  * `cookie` user-defined identifier for this instance of the lock
    /// @returns 0 on success, negative error code on failure
    /// @returns -EBUSY if the lock is already held by another (client, cookie) pair
    /// @returns -EEXIST if the lock is already held by the same (client, cookie) pair
    pub fn rbd_lock_exclusive(image: rbd_image_t,
                              cookie: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;

    /// Take a shared lock on the image.
    ///
    /// Other clients may also take a shared lock, as lock as they use the
    /// same tag.
    ///
    /// # Arguments
    ///  * `image` the image to lock
    ///  * `cookie` user-defined identifier for this instance of the lock
    ///  * `tag` user-defined identifier for this shared use of the lock
    /// @returns 0 on success, negative error code on failure
    /// @returns -EBUSY if the lock is already held by another (client, cookie) pair
    /// @returns -EEXIST if the lock is already held by the same (client, cookie) pair
    pub fn rbd_lock_shared(image: rbd_image_t,
                           cookie: *const ::std::os::raw::c_char,
                           tag: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;

    /// Release a shared or exclusive lock on the image.
    ///
    /// # Arguments
    ///  * `image` the image to unlock
    ///  * `cookie` user-defined identifier for the instance of the lock
    /// @returns 0 on success, negative error code on failure
    /// @returns -ENOENT if the lock is not held by the specified (client, cookie) pair
    pub fn rbd_unlock(image: rbd_image_t,
                      cookie: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;

    /// Release a shared or exclusive lock that was taken by the specified client.
    ///
    /// # Arguments
    /// * `image` the image to unlock
    /// * `client` the entity holding the lock (as given by rbd_list_lockers())
    /// * `cookie` user-defined identifier for the instance of the lock to break
    ///
    /// @returns 0 on success, negative error code on failure
    /// @returns -ENOENT if the lock is not held by the specified (client, cookie) pair
    pub fn rbd_break_lock(image: rbd_image_t,
                          client: *const ::std::os::raw::c_char,
                          cookie: *const ::std::os::raw::c_char)
     -> ::std::os::raw::c_int;
    pub fn rbd_read(image: rbd_image_t, ofs: uint64_t, len: size_t,
                    buf: *mut ::std::os::raw::c_char) -> ssize_t;

    /// iterate read over an image
    /// Reads each region of the image and calls the callback.  If the
    /// buffer pointer passed to the callback is NULL, the given extent is
    /// defined to be zeros (a hole).  Normally the granularity for the
    /// callback is the image stripe size.
    /// # Arguments
    ///  * `image` image to read
    ///  * `ofs` offset to start from
    ///  * `len` bytes of source image to cover
    ///  * `cb` callback for each region
    /// @returns 0 success, error otherwise
    pub fn rbd_read_iterate2(image: rbd_image_t, ofs: uint64_t, len: uint64_t,
                             cb:
                                 ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                                uint64_t,
                                                                            arg2:
                                                                                size_t,
                                                                            arg3:
                                                                                *const ::std::os::raw::c_char,
                                                                            arg4:
                                                                                *mut ::std::os::raw::c_void)
                                                           ->
                                                               ::std::os::raw::c_int>,
                             arg: *mut ::std::os::raw::c_void)
     -> ::std::os::raw::c_int;

    /// get difference between two versions of an image
    ///
    /// This will return the differences between two versions of an image
    /// via a callback, which gets the offset and length and a flag
    /// indicating whether the extent exists (1), or is known/defined to
    /// be zeros (a hole, 0).  If the source snapshot name is NULL, we
    /// interpret that as the beginning of time and return all allocated
    /// regions of the image.  The end version is whatever is currently
    /// selected for the image handle (either a snapshot or the writeable
    /// head).
    /// # Arguments
    ///  * `fromsnapname` start snapshot name, or NULL
    ///  * `ofs` start offset
    ///  * `len` len in bytes of region to report on
    ///  * `cb` callback to call for each allocated region
    ///  * `arg` argument to pass to the callback
    /// @returns 0 on success, or negative error code on error
    pub fn rbd_diff_iterate(image: rbd_image_t,
                            fromsnapname: *const ::std::os::raw::c_char,
                            ofs: uint64_t, len: uint64_t,
                            cb:
                                ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                               uint64_t,
                                                                           arg2:
                                                                               size_t,
                                                                           arg3:
                                                                               ::std::os::raw::c_int,
                                                                           arg4:
                                                                               *mut ::std::os::raw::c_void)
                                                          ->
                                                              ::std::os::raw::c_int>,
                            arg: *mut ::std::os::raw::c_void)
     -> ::std::os::raw::c_int;
    pub fn rbd_write(image: rbd_image_t, ofs: uint64_t, len: size_t,
                     buf: *const ::std::os::raw::c_char) -> ssize_t;
    /// Trim the range from the image. It will be logically filled with zeroes.
    /// # Arguments
    ///  * `image` the image to trim a range from
    ///  * `ofs` offset to start from
    ///  * `len` bytes of image to trim
    pub fn rbd_discard(image: rbd_image_t, ofs: uint64_t, len: uint64_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_aio_write(image: rbd_image_t, off: uint64_t, len: size_t,
                         buf: *const ::std::os::raw::c_char,
                         c: rbd_completion_t) -> ::std::os::raw::c_int;
    pub fn rbd_aio_read(image: rbd_image_t, off: uint64_t, len: size_t,
                        buf: *mut ::std::os::raw::c_char, c: rbd_completion_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_aio_discard(image: rbd_image_t, off: uint64_t, len: uint64_t,
                           c: rbd_completion_t) -> ::std::os::raw::c_int;
    pub fn rbd_aio_create_completion(cb_arg: *mut ::std::os::raw::c_void,
                                     complete_cb: rbd_callback_t,
                                     c: *mut rbd_completion_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_aio_is_complete(c: rbd_completion_t) -> ::std::os::raw::c_int;
    pub fn rbd_aio_wait_for_complete(c: rbd_completion_t)
     -> ::std::os::raw::c_int;
    pub fn rbd_aio_get_return_value(c: rbd_completion_t) -> ssize_t;
    pub fn rbd_aio_release(c: rbd_completion_t);

    /// Start a flush if caching is enabled. Get a callback when
    /// the currently pending writes are on disk.
    /// # Arguments
    ///  * `image` the image to flush writes to
    ///  * `c` what to call when flushing is complete
    /// @returns 0 on success, negative error code on failure
    pub fn rbd_flush(image: rbd_image_t) -> ::std::os::raw::c_int;
    pub fn rbd_aio_flush(image: rbd_image_t, c: rbd_completion_t)
     -> ::std::os::raw::c_int;

    /// Drop any cached data for an image
    ///
    /// # Arguments
    ///  * `image` the image to invalidate cached data for
    /// @returns 0 on success, negative error code on failure
    pub fn rbd_invalidate_cache(image: rbd_image_t) -> ::std::os::raw::c_int;
}