[libvirt] [PATCH 0/1] WIP: try to implement volume rename

This is incomplete work for implementing volume rename in libvirt I'm try to impelemnt it for some backends. First missing part is remote rpc call, and second - tests. If somebody can/want to help me, i'll very happy. Vasiliy Tolstov (1): [WIP] implement vol rename include/libvirt/libvirt-storage.h | 3 ++ m4/virt-storage-lvm.m4 | 3 ++ src/libvirt-storage.c | 39 +++++++++++++++++++++ src/libvirt_private.syms | 1 + src/libvirt_public.syms | 8 ++++- src/remote/remote_driver.c | 1 + src/storage/storage_backend_fs.c | 3 ++ src/storage/storage_backend_logical.c | 27 +++++++++++++++ src/storage/storage_backend_rbd.c | 28 +++++++++++++++ src/storage/storage_backend_vstorage.c | 1 + src/storage/storage_driver.c | 63 ++++------------------------------ src/storage/storage_util.c | 13 +++++++ src/storage/storage_util.h | 5 +++ src/util/virstoragefile.c | 39 +++++++++++++++++++++ tools/virsh-volume.c | 53 ++++++++++++++++++++++++++++ 15 files changed, 229 insertions(+), 58 deletions(-) -- 2.14.3

Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru> --- include/libvirt/libvirt-storage.h | 3 ++ m4/virt-storage-lvm.m4 | 3 ++ src/libvirt-storage.c | 39 +++++++++++++++++++++ src/libvirt_private.syms | 1 + src/libvirt_public.syms | 8 ++++- src/remote/remote_driver.c | 1 + src/storage/storage_backend_fs.c | 3 ++ src/storage/storage_backend_logical.c | 27 +++++++++++++++ src/storage/storage_backend_rbd.c | 28 +++++++++++++++ src/storage/storage_backend_vstorage.c | 1 + src/storage/storage_driver.c | 63 ++++------------------------------ src/storage/storage_util.c | 13 +++++++ src/storage/storage_util.h | 5 +++ src/util/virstoragefile.c | 39 +++++++++++++++++++++ tools/virsh-volume.c | 53 ++++++++++++++++++++++++++++ 15 files changed, 229 insertions(+), 58 deletions(-) diff --git a/include/libvirt/libvirt-storage.h b/include/libvirt/libvirt-storage.h index 736e2e3b80bd..9c75957879e4 100644 --- a/include/libvirt/libvirt-storage.h +++ b/include/libvirt/libvirt-storage.h @@ -395,6 +395,9 @@ int virStorageVolResize (virStorageVolPtr vol, unsigned long long capacity, unsigned int flags); +int virStorageVolRename (virStorageVolPtr vol, + const char *name); + int virStoragePoolIsActive(virStoragePoolPtr pool); int virStoragePoolIsPersistent(virStoragePoolPtr pool); diff --git a/m4/virt-storage-lvm.m4 b/m4/virt-storage-lvm.m4 index a0ccca7a00ab..74330c8ecb15 100644 --- a/m4/virt-storage-lvm.m4 +++ b/m4/virt-storage-lvm.m4 @@ -30,6 +30,7 @@ AC_DEFUN([LIBVIRT_STORAGE_CHECK_LVM], [ AC_PATH_PROG([VGREMOVE], [vgremove], [], [$LIBVIRT_SBIN_PATH]) AC_PATH_PROG([LVREMOVE], [lvremove], [], [$LIBVIRT_SBIN_PATH]) AC_PATH_PROG([LVCHANGE], [lvchange], [], [$LIBVIRT_SBIN_PATH]) + AC_PATH_PROG([LVRENAME], [lvrename], [], [$LIBVIRT_SBIN_PATH]) AC_PATH_PROG([VGCHANGE], [vgchange], [], [$LIBVIRT_SBIN_PATH]) AC_PATH_PROG([VGSCAN], [vgscan], [], [$LIBVIRT_SBIN_PATH]) AC_PATH_PROG([PVS], [pvs], [], [$LIBVIRT_SBIN_PATH]) @@ -44,6 +45,7 @@ AC_DEFUN([LIBVIRT_STORAGE_CHECK_LVM], [ if test -z "$VGREMOVE" ; then AC_MSG_ERROR([We need vgremove for LVM storage driver]) ; fi if test -z "$LVREMOVE" ; then AC_MSG_ERROR([We need lvremove for LVM storage driver]) ; fi if test -z "$LVCHANGE" ; then AC_MSG_ERROR([We need lvchange for LVM storage driver]) ; fi + if test -z "$LVRENAME" ; then AC_MSG_ERROR([We need lvrename for LVM storage driver]) ; fi if test -z "$VGCHANGE" ; then AC_MSG_ERROR([We need vgchange for LVM storage driver]) ; fi if test -z "$VGSCAN" ; then AC_MSG_ERROR([We need vgscan for LVM storage driver]) ; fi if test -z "$PVS" ; then AC_MSG_ERROR([We need pvs for LVM storage driver]) ; fi @@ -75,6 +77,7 @@ AC_DEFUN([LIBVIRT_STORAGE_CHECK_LVM], [ AC_DEFINE_UNQUOTED([VGREMOVE],["$VGREMOVE"],[Location of vgremove program]) AC_DEFINE_UNQUOTED([LVREMOVE],["$LVREMOVE"],[Location of lvremove program]) AC_DEFINE_UNQUOTED([LVCHANGE],["$LVCHANGE"],[Location of lvchange program]) + AC_DEFINE_UNQUOTED([LVRENAME],["$LVRENAME"],[Location of lvrename program]) AC_DEFINE_UNQUOTED([VGCHANGE],["$VGCHANGE"],[Location of vgchange program]) AC_DEFINE_UNQUOTED([VGSCAN],["$VGSCAN"],[Location of vgscan program]) AC_DEFINE_UNQUOTED([PVS],["$PVS"],[Location of pvs program]) diff --git a/src/libvirt-storage.c b/src/libvirt-storage.c index e4646cb80ff9..754adedcb21e 100644 --- a/src/libvirt-storage.c +++ b/src/libvirt-storage.c @@ -2122,6 +2122,45 @@ virStorageVolResize(virStorageVolPtr vol, } +/** + * virStorageVolRename: + * @vol: pointer to storage volume + * @name: new volume name + * + * Changes the nmae of the storage volume @vol to @name. + * + * Returns 0 on success, or -1 on error. + */ +int +virStorageVolRename(virStorageVolPtr vol, + const char *name) +{ + virConnectPtr conn; + VIR_DEBUG("vol=%p name=%s", vol, name); + + virResetLastError(); + + virCheckStorageVolReturn(vol, -1); + conn = vol->conn; + + virCheckReadOnlyGoto(conn->flags, error); + + if (conn->storageDriver && conn->storageDriver->storageVolRename) { + int ret; + ret = conn->storageDriver->storageVolRename(vol, name); + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(vol->conn); + return -1; +} + + /** * virStoragePoolIsActive: * @pool: pointer to the storage pool object diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f2a2c8650d97..3052b04d5282 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2720,6 +2720,7 @@ virStorageFileParseBackingStoreStr; virStorageFileParseChainIndex; virStorageFileProbeFormat; virStorageFileResize; +virStorageFileRename; virStorageIsFile; virStorageIsRelative; virStorageNetHostDefClear; diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 0efde25a7f76..a828d0a7ce5c 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -777,6 +777,12 @@ LIBVIRT_3.7.0 { LIBVIRT_3.9.0 { global: - virDomainSetLifecycleAction; + virDomainSetLifecycleAction; } LIBVIRT_3.7.0; + +LIBVIRT_4.0.1 { + global: + virStorageVolRename; +} LIBVIRT_3.9.0; + # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index f8fa64af998e..cf6bdf233ed8 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8587,6 +8587,7 @@ static virStorageDriver storage_driver = { .storageVolGetXMLDesc = remoteStorageVolGetXMLDesc, /* 0.4.1 */ .storageVolGetPath = remoteStorageVolGetPath, /* 0.4.1 */ .storageVolResize = remoteStorageVolResize, /* 0.9.10 */ + .storageVolRename = remoteStorageVolRename, /* 3.9.0 */ .storagePoolIsActive = remoteStoragePoolIsActive, /* 0.7.3 */ .storagePoolIsPersistent = remoteStoragePoolIsPersistent, /* 0.7.3 */ }; diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index f54759983ceb..d19e83726bf7 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -664,6 +664,7 @@ virStorageBackend virStorageBackendDirectory = { .refreshVol = virStorageBackendVolRefreshLocal, .deleteVol = virStorageBackendVolDeleteLocal, .resizeVol = virStorageBackendVolResizeLocal, + .renameVol = virStorageBackendVolRenameLocal, .uploadVol = virStorageBackendVolUploadLocal, .downloadVol = virStorageBackendVolDownloadLocal, .wipeVol = virStorageBackendVolWipeLocal, @@ -685,6 +686,7 @@ virStorageBackend virStorageBackendFileSystem = { .refreshVol = virStorageBackendVolRefreshLocal, .deleteVol = virStorageBackendVolDeleteLocal, .resizeVol = virStorageBackendVolResizeLocal, + .renameVol = virStorageBackendVolRenameLocal, .uploadVol = virStorageBackendVolUploadLocal, .downloadVol = virStorageBackendVolDownloadLocal, .wipeVol = virStorageBackendVolWipeLocal, @@ -705,6 +707,7 @@ virStorageBackend virStorageBackendNetFileSystem = { .refreshVol = virStorageBackendVolRefreshLocal, .deleteVol = virStorageBackendVolDeleteLocal, .resizeVol = virStorageBackendVolResizeLocal, + .renameVol = virStorageBackendVolRenameLocal, .uploadVol = virStorageBackendVolUploadLocal, .downloadVol = virStorageBackendVolDownloadLocal, .wipeVol = virStorageBackendVolWipeLocal, diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index 5df30de29d17..015188508123 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -902,6 +902,32 @@ virStorageBackendLogicalDeletePool(virConnectPtr conn ATTRIBUTE_UNUSED, } +static int +virStorageBackendLogicalRenameVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + virStorageVolDefPtr vol, + const char *name) +{ + int ret = -1; + virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool); + virCommandPtr lvrename_cmd = NULL; + + virCheckFlags(0, -1); + + virWaitForDevices(); + + lvrename_cmd = virCommandNewArgList(LVRENAME, "%s", def->target.path, vol->name, name, NULL); + + if (virCommandRun(lvrename_cmd, NULL) < 0) { + goto cleanup; + } + + ret = 0; + cleanup: + virCommandFree(lvrename_cmd); + return ret; +} + static int virStorageBackendLogicalDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, @@ -1107,6 +1133,7 @@ virStorageBackend virStorageBackendLogical = { .buildVolFrom = virStorageBackendLogicalBuildVolFrom, .createVol = virStorageBackendLogicalCreateVol, .deleteVol = virStorageBackendLogicalDeleteVol, + .renameVol = virStorageBackendLogicalRenameVol, .uploadVol = virStorageBackendVolUploadLocal, .downloadVol = virStorageBackendVolDownloadLocal, .wipeVol = virStorageBackendLogicalVolWipe, diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c index 7f9597cabea3..ddc28904c76c 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -1091,6 +1091,34 @@ virStorageBackendRBDRefreshVol(virConnectPtr conn, return ret; } +static int +virStorageBackendRBDRenameVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virStorageVolDefPtr vol, + const char *name) +{ + virStorageBackendRBDStatePtr ptr = NULL; + int ret = -1; + int r = 0; + + virCheckFlags(0, -1); + + if (!(ptr = virStorageBackendRBDNewState(conn, pool))) + goto cleanup; + + if ((r = rbd_rename(ptr->ioctx, vol->name, name)) < 0) { + virReportSystemError(-r, _("failed to rename the RBD image '%s' to '%s'"), + vol->name, name); + goto cleanup; + } + + ret = 0; + + cleanup: + virStorageBackendRBDFreeState(&ptr); + return ret; +} + static int virStorageBackendRBDResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, diff --git a/src/storage/storage_backend_vstorage.c b/src/storage/storage_backend_vstorage.c index 2dc26af38706..3607312ae486 100644 --- a/src/storage/storage_backend_vstorage.c +++ b/src/storage/storage_backend_vstorage.c @@ -182,6 +182,7 @@ virStorageBackend virStorageBackendVstorage = { .refreshVol = virStorageBackendVolRefreshLocal, .deleteVol = virStorageBackendVolDeleteLocal, .resizeVol = virStorageBackendVolResizeLocal, + .renameVol = virStorageBackendVolRenameLocal, .uploadVol = virStorageBackendVolUploadLocal, .downloadVol = virStorageBackendVolDownloadLocal, .wipeVol = virStorageBackendVolWipeLocal, diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 3b66d517191b..e68f158288ca 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -2358,21 +2358,15 @@ storageVolUpload(virStorageVolPtr vol, } static int -storageVolResize(virStorageVolPtr vol, - unsigned long long capacity, - unsigned int flags) +storageVolRename(virStorageVolPtr vol, + const char *name) { virStorageBackendPtr backend; virStoragePoolObjPtr obj = NULL; virStoragePoolDefPtr def; virStorageVolDefPtr voldef = NULL; - unsigned long long abs_capacity, delta = 0; int ret = -1; - virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE | - VIR_STORAGE_VOL_RESIZE_DELTA | - VIR_STORAGE_VOL_RESIZE_SHRINK, -1); - if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend))) return -1; def = virStoragePoolObjGetDef(obj); @@ -2394,61 +2388,16 @@ storageVolResize(virStorageVolPtr vol, goto cleanup; } - if (flags & VIR_STORAGE_VOL_RESIZE_DELTA) { - if (flags & VIR_STORAGE_VOL_RESIZE_SHRINK) - abs_capacity = voldef->target.capacity - MIN(capacity, voldef->target.capacity); - else - abs_capacity = voldef->target.capacity + capacity; - flags &= ~VIR_STORAGE_VOL_RESIZE_DELTA; - } else { - abs_capacity = capacity; - } - - if (abs_capacity < voldef->target.allocation) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("can't shrink capacity below " - "existing allocation")); - goto cleanup; - } - - if (abs_capacity < voldef->target.capacity && - !(flags & VIR_STORAGE_VOL_RESIZE_SHRINK)) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("Can't shrink capacity below current " - "capacity unless shrink flag explicitly specified")); - goto cleanup; - } - - if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) - delta = abs_capacity - voldef->target.allocation; - - if (delta > def->available) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("Not enough space left in storage pool")); - goto cleanup; - } - - if (!backend->resizeVol) { + if (!backend->renameVol) { virReportError(VIR_ERR_NO_SUPPORT, "%s", _("storage pool does not support changing of " - "volume capacity")); + "volume name")); goto cleanup; } - if (backend->resizeVol(vol->conn, obj, voldef, abs_capacity, flags) < 0) + if (backend->renameVol(vol->conn, obj, voldef, name) < 0) goto cleanup; - voldef->target.capacity = abs_capacity; - /* Only update the allocation and pool values if we actually did the - * allocation; otherwise, this is akin to a create operation with a - * capacity value different and potentially much larger than available - */ - if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) { - voldef->target.allocation = abs_capacity; - def->allocation += delta; - def->available -= delta; - } - ret = 0; cleanup: @@ -2732,7 +2681,7 @@ static virStorageDriver storageDriver = { .storageVolGetXMLDesc = storageVolGetXMLDesc, /* 0.4.0 */ .storageVolGetPath = storageVolGetPath, /* 0.4.0 */ .storageVolResize = storageVolResize, /* 0.9.10 */ - + .storageVolRename = storageVolRename, /* 3.9.0 */ .storagePoolIsActive = storagePoolIsActive, /* 0.7.3 */ .storagePoolIsPersistent = storagePoolIsPersistent, /* 0.7.3 */ }; diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 9e1b63a43609..528286b145d5 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -2475,6 +2475,19 @@ virStorageBackendVolResizeLocal(virConnectPtr conn, } +/** + * Rename a volume + */ +int +virStorageBackendVolRenameLocal(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool ATTRIBUTE_UNUSED, + virStorageVolDefPtr vol, + const char *name) +{ + return virStorageFileRename(vol->target.path, name); +} + + /* * Check whether the ploop image has snapshots. * return: -1 - failed to check diff --git a/src/storage/storage_util.h b/src/storage/storage_util.h index dc7e62517b4f..0e90a762df8a 100644 --- a/src/storage/storage_util.h +++ b/src/storage/storage_util.h @@ -69,6 +69,11 @@ int virStorageBackendVolResizeLocal(virConnectPtr conn, unsigned long long capacity, unsigned int flags); +int virStorageBackendVolRenameLocal(virConnectPtr conn, + virStoragePoolObjPtr pool, + virStorageVolDefPtr vol, + const char *name); + int virStorageBackendVolUploadLocal(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 5780180a94ef..c5da169194fd 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -1359,6 +1359,45 @@ virStorageFileResize(const char *path, } +/** + * virStorageFileRename: + * + * Change the name file at 'path'. + */ +int +virStorageFileRename(const char *path, + const char *name) +{ + int ret = -1; + int rc; + char *opath = NULL; + char *npath = NULL; + char *base = NULL; + + VIR_STRDUP(*opath, path) < 0) + goto cleanup; + + base = dirname(npath); + if (virAsprintf(npath, "%s/%s", base, name) < 0) + goto cleanup; + + + if (rename(path, name) < 0) { + virReportSystemError(errno, + _("Failed to rename file '%s' to '%s'"), opath, npath); + goto cleanup; + } + + ret = 0; + + cleanup: + VIR_FREE(opath); + VIR_FREE(npath); + return ret; +} + + + int virStorageFileIsClusterFS(const char *path) { /* These are coherent cluster filesystems known to be safe for diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c index bacbec0d27b7..00a1468feb52 100644 --- a/tools/virsh-volume.c +++ b/tools/virsh-volume.c @@ -1189,6 +1189,59 @@ cmdVolResize(vshControl *ctl, const vshCmd *cmd) return ret; } +/* + * "vol-rename" command + */ +static const vshCmdInfo info_vol_rename[] = { + {.name = "help", + .data = N_("rename a vol") + }, + {.name = "desc", + .data = N_("Renames a storage volume") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_vol_rename[] = { + VIRSH_COMMON_OPT_VOLUME_VOL, + {.name = "name", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("new name for the vol") + }, + {.name = NULL} +}; + + +static bool +cmdVolRename(vshControl *ctl, const vshCmd *cmd) +{ + virStorageVolPtr vol; + const char *name = NULL; + bool ret = false; + + if (!(vol = virshCommandOptVol(ctl, cmd, "vol", "pool", NULL))) + return false; + + if (vshCommandOptStringReq(ctl, cmd, "name", &name) < 0) + goto cleanup; + virSkipSpaces(&name); + + if (virStorageVolRename(vol, name) == 0) { + vshPrintExtra(ctl, _("Name of volume '%s' successfully changed to %s\n"), + virStorageVolGetName(vol), name); + ret = true; + } else { + vshError(ctl, _("Failed to change name of volume '%s' to %s"), + virStorageVolGetName(vol), name); + ret = false; + } + + cleanup: + virStorageVolFree(vol); + return ret; +} + /* * "vol-dumpxml" command */ -- 2.14.3
participants (1)
-
Vasiliy Tolstov