The current virtStorageBackendZFSCheckPool checks for the existence of a
path under /dev/zvol/ to determine if the pool is active. ZFS does not
create a path under /dev/zvol/ if no ZFS volumes have been created under
a particular dataset, thus, empty ZFS storage pools are deactivated
whenever checkPool is called on them (as noted in referenced issue).

This commit changes virStorageBackendZFSCheckPool so that the 'zfs list'
command is used to explicitly check for the existence a dataset
specified by the pool's def->source.name.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/221

Signed-off-by: Matt Low <m...@mlow.ca>
---
 src/storage/storage_backend_zfs.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/storage/storage_backend_zfs.c 
b/src/storage/storage_backend_zfs.c
index 2a5d74357d..4e243a738a 100644
--- a/src/storage/storage_backend_zfs.c
+++ b/src/storage/storage_backend_zfs.c
@@ -85,10 +85,24 @@ virStorageBackendZFSCheckPool(virStoragePoolObj *pool 
G_GNUC_UNUSED,
                               bool *isActive)
 {
     virStoragePoolDef *def = virStoragePoolObjGetDef(pool);
-    g_autofree char *devpath = NULL;
+    g_autoptr(virCommand) cmd = NULL;
+    int exit_code = -1;
+
+    /* Check for an existing dataset of type 'filesystem' by the name of our
+     * pool->source.name.  */
+    cmd = virCommandNewArgList(ZFS,
+                               "list", "-H",
+                               "-t", "filesystem",
+                               "-o", "name",
+                               def->source.name,
+                               NULL);
+
+
+    if (virCommandRun(cmd, &exit_code) < 0)
+        return -1;

-    devpath = g_strdup_printf("/dev/zvol/%s", def->source.name);
-    *isActive = virFileIsDir(devpath);
+    /* zfs list exits with 0 if the dataset exists, 1 if it doesn't */
+    *isActive = exit_code == 0;

     return 0;
 }
--
2.39.2

Reply via email to