[PATCH v2 5/5] qemuSnapshotUpdateBackingStore: Retry as curent user if qemu-img fails

Peter Krempa via Devel posted 5 patches 6 days, 13 hours ago
[PATCH v2 5/5] qemuSnapshotUpdateBackingStore: Retry as curent user if qemu-img fails
Posted by Peter Krempa via Devel 6 days, 13 hours ago
From: Peter Krempa <pkrempa@redhat.com>

The code calls 'qemu-img rebase' to fix the backing store references.
The 'qemu-img' process here is run as the 'qemu' user or whatever the
defaults and domain XML resolve to. Since this, in certain cases, works
also on images which are not part of the backing chain and in privileged
deployments thus can be owned by 'root:root' the update may fail
(silently).

To preserver root-squash deployments but fix also the above case, retry
the operation on failure as current user.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
---
 src/qemu/qemu_snapshot.c | 53 ++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
index 1628c33865..70e4c37144 100644
--- a/src/qemu/qemu_snapshot.c
+++ b/src/qemu/qemu_snapshot.c
@@ -3710,25 +3710,48 @@ qemuSnapshotUpdateBackingStore(qemuSnapshotDeleteExternalData *data)

     for (cur = data->disksWithBacking; cur; cur = g_slist_next(cur)) {
         struct _qemuSnapshotDisksWithBackingStoreData *backingData = cur->data;
-        g_autoptr(virCommand) cmd = NULL;
+        /* Try to run the command first as the appropriate user based on the
+         * domain definition and config. If error is returned retry as current
+         * (possibly privileged) user for cases where seclabels were reset
+         * to the default */
+        g_autoptr(virCommand) cmd_user_qemu = NULL;
+        g_autoptr(virCommand) cmd_user_curr = NULL;
+
+        if (!(cmd_user_qemu = virCommandNewArgList("qemu-img",
+                                                   "rebase",
+                                                   "-u",
+                                                   "-F",
+                                                   virStorageFileFormatTypeToString(data->parentDiskSrc->format),
+                                                   "-f",
+                                                   virStorageFileFormatTypeToString(backingData->diskSrc->format),
+                                                   "-b",
+                                                   data->parentDiskSrc->path,
+                                                   backingData->diskSrc->path,
+                                                   NULL)))
+            continue;

-        if (!(cmd = virCommandNewArgList("qemu-img",
-                                         "rebase",
-                                         "-u",
-                                         "-F",
-                                         virStorageFileFormatTypeToString(data->parentDiskSrc->format),
-                                         "-f",
-                                         virStorageFileFormatTypeToString(backingData->diskSrc->format),
-                                         "-b",
-                                         data->parentDiskSrc->path,
-                                         backingData->diskSrc->path,
-                                         NULL)))
+        virCommandSetUID(cmd_user_qemu, backingData->uid);
+        virCommandSetGID(cmd_user_qemu, backingData->gid);
+
+        /* done on success */
+        if (virCommandRun(cmd_user_qemu, NULL) == 0)
             continue;

-        virCommandSetUID(cmd, backingData->uid);
-        virCommandSetGID(cmd, backingData->gid);
+        /* retry as current user */
+        if (!(cmd_user_curr = virCommandNewArgList("qemu-img",
+                                                   "rebase",
+                                                   "-u",
+                                                   "-F",
+                                                   virStorageFileFormatTypeToString(data->parentDiskSrc->format),
+                                                   "-f",
+                                                   virStorageFileFormatTypeToString(backingData->diskSrc->format),
+                                                   "-b",
+                                                   data->parentDiskSrc->path,
+                                                   backingData->diskSrc->path,
+                                                   NULL)))
+            continue;

-        ignore_value(virCommandRun(cmd, NULL));
+        ignore_value(virCommandRun(cmd_user_curr, NULL));
     }
 }

-- 
2.52.0