]> xenbits.xensource.com Git - libvirt.git/commitdiff
Allow a zfs pool or dataset as source for zfs storage backend
authorGregor Kopka <gregor@kopka.net>
Thu, 7 Nov 2019 04:03:14 +0000 (04:03 +0000)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 15 Nov 2019 14:25:53 +0000 (15:25 +0100)
Enables hosting a pool on an existing zfs pool without affecting
other datasets there.
Specify dataset instead of pool as source to use.
Parent of dataset must exist for pool-build to succeed.
Beware that pool-delete destroys the source dataset and all children.

Solves: https://www.redhat.com/archives/libvirt-users/2017-April/msg00041.html

Signed-off-by: Gregor Kopka <gregor@kopka.net>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/storage/storage_backend_zfs.c

index a3de3e46f2c59612588cdaee2f587350e2d0b4b8..172245c847dd1d31d9863307f7d8a9f2d1246c2e 100644 (file)
@@ -110,10 +110,10 @@ virStorageBackendZFSParseVol(virStoragePoolObjPtr pool,
     if (count != 3)
         goto cleanup;
 
-    if (!(name_tokens = virStringSplit(tokens[0], "/", 2)))
+    if (!(name_tokens = virStringSplitCount(tokens[0], "/", 0, &count)))
         goto cleanup;
 
-    vol_name = name_tokens[1];
+    vol_name = name_tokens[count-1];
 
     if (vol == NULL)
         volume = virStorageVolDefFindByName(pool, vol_name);
@@ -219,6 +219,7 @@ virStorageBackendZFSRefreshPool(virStoragePoolObjPtr pool G_GNUC_UNUSED)
     g_autoptr(virCommand) cmd = NULL;
     VIR_AUTOSTRINGLIST lines = NULL;
     VIR_AUTOSTRINGLIST tokens = NULL;
+    VIR_AUTOSTRINGLIST name_tokens = NULL;
 
     /**
      * $ zpool get -Hp health,size,free,allocated test
@@ -230,10 +231,13 @@ virStorageBackendZFSRefreshPool(virStoragePoolObjPtr pool G_GNUC_UNUSED)
      *
      * Here we just provide a list of properties we want to see
      */
+    if (!(name_tokens = virStringSplit(def->source.name, "/", 0)))
+        goto cleanup;
+
     cmd = virCommandNewArgList(ZPOOL,
                                "get", "-Hp",
                                "health,size,free,allocated",
-                               def->source.name,
+                               name_tokens[0],
                                NULL);
     virCommandSetOutputBuffer(cmd, &zpool_props);
     if (virCommandRun(cmd, NULL) < 0)
@@ -372,20 +376,27 @@ virStorageBackendZFSBuildPool(virStoragePoolObjPtr pool,
     size_t i;
     g_autoptr(virCommand) cmd = NULL;
     int ret = -1;
+    char *tmp;
 
     virCheckFlags(0, -1);
 
-    if (def->source.ndevice == 0) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       "%s", _("missing source devices"));
-        return -1;
-    }
+    tmp = strstr(def->source.name, "/");
+    if (tmp) {
+        cmd = virCommandNewArgList(ZFS, "create", "-o", "mountpoint=none",
+                                   def->source.name, NULL);
+    } else {
+        if (def->source.ndevice == 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           "%s", _("missing source devices"));
+            return -1;
+        }
 
-    cmd = virCommandNewArgList(ZPOOL, "create",
-                               def->source.name, NULL);
+        cmd = virCommandNewArgList(ZPOOL, "create",
+                                   def->source.name, NULL);
 
-    for (i = 0; i < def->source.ndevice; i++)
-        virCommandAddArg(cmd, def->source.devices[i].path);
+        for (i = 0; i < def->source.ndevice; i++)
+            virCommandAddArg(cmd, def->source.devices[i].path);
+    }
 
     virObjectUnlock(pool);
     ret = virCommandRun(cmd, NULL);
@@ -400,11 +411,18 @@ virStorageBackendZFSDeletePool(virStoragePoolObjPtr pool,
 {
     virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
     g_autoptr(virCommand) cmd = NULL;
+    char *tmp;
 
     virCheckFlags(0, -1);
 
-    cmd = virCommandNewArgList(ZPOOL, "destroy",
-                               def->source.name, NULL);
+    tmp = strstr(def->source.name, "/");
+    if (tmp) {
+        cmd = virCommandNewArgList(ZFS, "destroy", "-r",
+                                   def->source.name, NULL);
+    } else {
+        cmd = virCommandNewArgList(ZPOOL, "destroy",
+                                   def->source.name, NULL);
+    }
 
     return virCommandRun(cmd, NULL);
 }