// int rbd_create(rados_ioctx_t io, const char *name, uint64_t size, int *order); // int rbd_create2(rados_ioctx_t io, const char *name, uint64_t size, // uint64_t features, int *order); // int rbd_create3(rados_ioctx_t io, const char *name, uint64_t size, // uint64_t features, int *order, // uint64_t stripe_unit, uint64_t stripe_count); func Create(ioctx *rados.IOContext, name string, size uint64, args ...uint64) (image *Image, err error) { var ret C.int var c_order C.int var c_name *C.char = C.CString(name) defer C.free(unsafe.Pointer(c_name)) switch len(args) { case 2: ret = C.rbd_create3(C.rados_ioctx_t(ioctx.Pointer()), c_name, C.uint64_t(size), C.uint64_t(args[0]), &c_order, C.uint64_t(args[1]), C.uint64_t(args[2])) case 1: ret = C.rbd_create2(C.rados_ioctx_t(ioctx.Pointer()), c_name, C.uint64_t(size), C.uint64_t(args[0]), &c_order) case 0: ret = C.rbd_create(C.rados_ioctx_t(ioctx.Pointer()), c_name, C.uint64_t(size), &c_order) default: return nil, errors.New("Wrong number of argument") } if ret < 0 { return nil, RBDError(int(ret)) } return &Image{ ioctx: ioctx, name: name, }, nil }
// int rbd_open(rados_ioctx_t io, const char *name, rbd_image_t *image, const char *snap_name); // int rbd_open_read_only(rados_ioctx_t io, const char *name, rbd_image_t *image, // const char *snap_name); func (image *Image) Open(args ...interface{}) error { var c_image C.rbd_image_t var c_name *C.char = C.CString(image.name) var c_snap_name *C.char var ret C.int var read_only bool = false defer C.free(unsafe.Pointer(c_name)) for _, arg := range args { switch t := arg.(type) { case string: if t != "" { c_snap_name = C.CString(t) defer C.free(unsafe.Pointer(c_snap_name)) } case bool: read_only = t default: return errors.New("Unexpected argument") } } if read_only { ret = C.rbd_open_read_only(C.rados_ioctx_t(image.ioctx.Pointer()), c_name, &c_image, c_snap_name) } else { ret = C.rbd_open(C.rados_ioctx_t(image.ioctx.Pointer()), c_name, &c_image, c_snap_name) } image.image = c_image return GetError(ret) }
// int rbd_copy(rbd_image_t image, rados_ioctx_t dest_io_ctx, const char *destname); // int rbd_copy2(rbd_image_t src, rbd_image_t dest); // int rbd_copy_with_progress(rbd_image_t image, rados_ioctx_t dest_p, const char *destname, // librbd_progress_fn_t cb, void *cbdata); // int rbd_copy_with_progress2(rbd_image_t src, rbd_image_t dest, // librbd_progress_fn_t cb, void *cbdata); func (image *Image) Copy(args ...interface{}) error { if image.image == nil { return RbdErrorImageNotOpen } switch t := args[0].(type) { case rados.IOContext: switch t2 := args[1].(type) { case string: var c_destname *C.char = C.CString(t2) defer C.free(unsafe.Pointer(c_destname)) return RBDError(C.rbd_copy(image.image, C.rados_ioctx_t(t.Pointer()), c_destname)) default: return errors.New("Must specify destname") } case Image: var dest Image = t if dest.image == nil { return errors.New(fmt.Sprintf("RBD image %s is not open", dest.name)) } return GetError(C.rbd_copy2(image.image, dest.image)) default: return errors.New("Must specify either destination pool " + "or destination image") } }
// int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname, const char *destname); func (image *Image) Rename(destname string) error { var c_srcname *C.char = C.CString(image.name) var c_destname *C.char = C.CString(destname) defer C.free(unsafe.Pointer(c_srcname)) defer C.free(unsafe.Pointer(c_destname)) err := RBDError(C.rbd_rename(C.rados_ioctx_t(image.ioctx.Pointer()), c_srcname, c_destname)) if err == 0 { image.name = destname return nil } return err }
// int rbd_clone(rados_ioctx_t p_ioctx, const char *p_name, // const char *p_snapname, rados_ioctx_t c_ioctx, // const char *c_name, uint64_t features, int *c_order); // int rbd_clone2(rados_ioctx_t p_ioctx, const char *p_name, // const char *p_snapname, rados_ioctx_t c_ioctx, // const char *c_name, uint64_t features, int *c_order, // uint64_t stripe_unit, int stripe_count); func (image *Image) Clone(snapname string, c_ioctx *rados.IOContext, c_name string, features uint64) (*Image, error) { var c_order C.int var c_p_name *C.char = C.CString(image.name) var c_p_snapname *C.char = C.CString(snapname) var c_c_name *C.char = C.CString(c_name) defer C.free(unsafe.Pointer(c_p_name)) defer C.free(unsafe.Pointer(c_p_snapname)) defer C.free(unsafe.Pointer(c_c_name)) ret := C.rbd_clone(C.rados_ioctx_t(image.ioctx.Pointer()), c_p_name, c_p_snapname, C.rados_ioctx_t(c_ioctx.Pointer()), c_c_name, C.uint64_t(features), &c_order) if ret < 0 { return nil, RBDError(int(ret)) } return &Image{ ioctx: c_ioctx, name: c_name, }, nil }
func OpenOrCreate(ioctx *rados.IOContext, name string, stripe_size int, host string, port string) (*Log, error) { c_name := C.CString(name) defer C.free(unsafe.Pointer(c_name)) c_host := C.CString(host) defer C.free(unsafe.Pointer(c_host)) c_port := C.CString(port) defer C.free(unsafe.Pointer(c_port)) log := &Log{} ret := C.zlog_open_or_create(C.rados_ioctx_t(ioctx.Pointer()), c_name, C.int(stripe_size), c_host, c_port, &log.log) if ret == 0 { return log, nil } else { return nil, ZlogError(int(ret)) } }
// GetImageNames returns the list of current RBD images. func GetImageNames(ioctx *rados.IOContext) (names []string, err error) { buf := make([]byte, 4096) for { size := C.size_t(len(buf)) ret := C.rbd_list(C.rados_ioctx_t(ioctx.Pointer()), (*C.char)(unsafe.Pointer(&buf[0])), &size) if ret == -34 { // FIXME buf = make([]byte, size) continue } else if ret < 0 { return nil, RBDError(ret) } tmp := bytes.Split(buf[:size-1], []byte{0}) for _, s := range tmp { if len(s) > 0 { name := C.GoString((*C.char)(unsafe.Pointer(&s[0]))) names = append(names, name) } } return names, nil } }
// int rbd_remove(rados_ioctx_t io, const char *name); // int rbd_remove_with_progress(rados_ioctx_t io, const char *name, // librbd_progress_fn_t cb, void *cbdata); func (image *Image) Remove() error { var c_name *C.char = C.CString(image.name) defer C.free(unsafe.Pointer(c_name)) return GetError(C.rbd_remove(C.rados_ioctx_t(image.ioctx.Pointer()), c_name)) }