[libvirt] [PATCH 1/1] [WIP] implement vol rename

Vasiliy Tolstov v.tolstov at selfip.ru
Fri Jan 26 18:42:01 UTC 2018


Signed-off-by: Vasiliy Tolstov <v.tolstov at 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




More information about the libvir-list mailing list