[libvirt PATCH v6 30/36] qemu: implement knownHosts for ssh disks with nbdkit

Jonathon Jongsma jjongsma at redhat.com
Thu Jul 20 22:19:57 UTC 2023


For ssh disks that are served by nbdkit, use the configured value for
knownHosts and pass it to the nbdkit process.

Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
---
 src/conf/domain_conf.c                        |  8 ++++++
 src/conf/storage_source_conf.c                |  1 +
 src/conf/storage_source_conf.h                |  2 ++
 src/qemu/qemu_extdevice.c                     |  4 +--
 src/qemu/qemu_hotplug.c                       |  4 +--
 src/qemu/qemu_nbdkit.c                        | 25 +++++++++++++++----
 src/qemu/qemu_nbdkit.h                        |  6 +++--
 .../disk-network-ssh-password.args.disk0      |  3 ++-
 .../disk-network-ssh.args.disk0               |  3 ++-
 .../disk-network-ssh-password.xml             |  1 +
 tests/qemuxml2argvdata/disk-network-ssh.xml   |  1 +
 11 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5ac5c0b771..6420231e5c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7248,6 +7248,11 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
             return -1;
         }
     }
+    if (src->protocol == VIR_STORAGE_NET_PROTOCOL_SSH &&
+        (tmpnode = virXPathNode("./knownHosts", ctxt))) {
+        if (!(src->ssh_known_hosts_file = virXMLPropStringRequired(tmpnode, "path")))
+            return -1;
+    }
 
     return 0;
 }
@@ -22158,6 +22163,9 @@ virDomainDiskSourceFormatNetwork(virBuffer *attrBuf,
 
     if (src->timeout)
         virBufferAsprintf(childBuf, "<timeout seconds='%llu'/>\n", src->timeout);
+
+    if (src->protocol == VIR_STORAGE_NET_PROTOCOL_SSH && src->ssh_known_hosts_file)
+        virBufferEscapeString(childBuf, "<knownHosts path='%s'/>\n", src->ssh_known_hosts_file);
 }
 
 
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
index dcac3a8ff6..3468deb760 100644
--- a/src/conf/storage_source_conf.c
+++ b/src/conf/storage_source_conf.c
@@ -1170,6 +1170,7 @@ virStorageSourceClear(virStorageSource *def)
     VIR_FREE(def->tlsHostname);
 
     VIR_FREE(def->ssh_user);
+    VIR_FREE(def->ssh_known_hosts_file);
 
     VIR_FREE(def->nfs_user);
     VIR_FREE(def->nfs_group);
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
index f13e7c756a..8a9c7d07e2 100644
--- a/src/conf/storage_source_conf.h
+++ b/src/conf/storage_source_conf.h
@@ -410,6 +410,8 @@ struct _virStorageSource {
     /* these must not be used apart from formatting the output JSON in the qemu driver */
     char *ssh_user;
     bool ssh_host_key_check_disabled;
+    /* additional ssh variables */
+    char *ssh_known_hosts_file;
 
     /* nfs_user and nfs_group store the strings passed in by the user for NFS params.
      * nfs_uid and nfs_gid represent the converted/looked up ID numbers which are used
diff --git a/src/qemu/qemu_extdevice.c b/src/qemu/qemu_extdevice.c
index 42ecdf13d5..3cf3867056 100644
--- a/src/qemu/qemu_extdevice.c
+++ b/src/qemu/qemu_extdevice.c
@@ -297,11 +297,11 @@ qemuExtDevicesStop(virQEMUDriver *driver,
 
     for (i = 0; i < def->ndisks; i++) {
         virDomainDiskDef *disk = def->disks[i];
-        qemuNbdkitStopStorageSource(disk->src);
+        qemuNbdkitStopStorageSource(disk->src, vm);
     }
 
     if (def->os.loader && def->os.loader->nvram)
-        qemuNbdkitStopStorageSource(def->os.loader->nvram);
+        qemuNbdkitStopStorageSource(def->os.loader->nvram, vm);
 }
 
 
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e1725ab627..87dd32a22c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1036,7 +1036,7 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver *driver,
         if (virStorageSourceChainHasManagedPR(disk->src))
             ignore_value(qemuHotplugRemoveManagedPR(vm, VIR_ASYNC_JOB_NONE));
 
-        qemuNbdkitStopStorageSource(disk->src);
+        qemuNbdkitStopStorageSource(disk->src, vm);
     }
     qemuDomainSecretDiskDestroy(disk);
     qemuDomainCleanupStorageSourceFD(disk->src);
@@ -4508,7 +4508,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriver *driver,
         qemuHotplugRemoveManagedPR(vm, VIR_ASYNC_JOB_NONE) < 0)
         goto cleanup;
 
-    qemuNbdkitStopStorageSource(disk->src);
+    qemuNbdkitStopStorageSource(disk->src, vm);
 
     if (disk->transient) {
         VIR_DEBUG("Removing transient overlay '%s' of disk '%s'",
diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 9dbe3af1dd..b4f5b2178c 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -628,7 +628,7 @@ qemuNbdkitProcessRestart(qemuNbdkitProcess *proc,
     virQEMUDriver *driver = vmpriv->driver;
 
     /* clean up resources associated with process */
-    qemuNbdkitProcessStop(proc);
+    qemuNbdkitProcessStop(proc, vm);
 
     if (qemuNbdkitProcessStart(proc, vm, driver) < 0)
         VIR_WARN("Unable to restart nbkdit process");
@@ -899,7 +899,8 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
 
 
 void
-qemuNbdkitStopStorageSource(virStorageSource *src)
+qemuNbdkitStopStorageSource(virStorageSource *src,
+                            virDomainObj *vm)
 {
     virStorageSource *backing;
 
@@ -907,7 +908,7 @@ qemuNbdkitStopStorageSource(virStorageSource *src)
         qemuDomainStorageSourcePrivate *priv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
 
         if (priv && priv->nbdkitProcess &&
-            qemuNbdkitProcessStop(priv->nbdkitProcess) < 0)
+            qemuNbdkitProcessStop(priv->nbdkitProcess, vm) < 0)
             VIR_WARN("Unable to stop nbdkit for storage source '%s'", src->nodestorage);
     }
 }
@@ -1044,6 +1045,9 @@ qemuNbdkitProcessBuildCommandSSH(qemuNbdkitProcess *proc,
     if (proc->source->ssh_host_key_check_disabled)
         virCommandAddArgPair(cmd, "verify-remote-host", "false");
 
+    if (proc->source->ssh_known_hosts_file)
+        virCommandAddArgPair(cmd, "known-hosts", proc->source->ssh_known_hosts_file);
+
     return 0;
 }
 
@@ -1156,6 +1160,10 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
     if (qemuExtDeviceLogCommand(driver, vm, cmd, "nbdkit") < 0)
         goto error;
 
+    if (proc->source->ssh_known_hosts_file &&
+        qemuSecurityDomainSetPathLabel(driver, vm, proc->source->ssh_known_hosts_file, false) < 0)
+        goto error;
+
     if (qemuSecurityCommandRun(driver, vm, cmd, proc->user, proc->group, true, &exitstatus) < 0)
         goto error;
 
@@ -1220,16 +1228,23 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
                    NULLSTR(uristring), NULLSTR(errbuf));
 
  error:
-    qemuNbdkitProcessStop(proc);
+    qemuNbdkitProcessStop(proc, vm);
     return -1;
 }
 
 
 int
-qemuNbdkitProcessStop(qemuNbdkitProcess *proc)
+qemuNbdkitProcessStop(qemuNbdkitProcess *proc,
+                      virDomainObj *vm)
 {
+    qemuDomainObjPrivate *vmpriv = vm->privateData;
+    virQEMUDriver *driver = vmpriv->driver;
+
     qemuNbdkitProcessStopMonitor(proc);
 
+    if (proc->source->ssh_known_hosts_file)
+        qemuSecurityDomainRestorePathLabel(driver, vm, proc->source->ssh_known_hosts_file);
+
     if (proc->pid < 0)
         return 0;
 
diff --git a/src/qemu/qemu_nbdkit.h b/src/qemu/qemu_nbdkit.h
index 326f3d5920..cd5d6ab8db 100644
--- a/src/qemu/qemu_nbdkit.h
+++ b/src/qemu/qemu_nbdkit.h
@@ -66,7 +66,8 @@ qemuNbdkitStartStorageSource(virQEMUDriver *driver,
                              virStorageSource *src);
 
 void
-qemuNbdkitStopStorageSource(virStorageSource *src);
+qemuNbdkitStopStorageSource(virStorageSource *src,
+                            virDomainObj *vm);
 
 void
 qemuNbdkitStorageSourceManageProcess(virStorageSource *src,
@@ -101,7 +102,8 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
                        virQEMUDriver *driver);
 
 int
-qemuNbdkitProcessStop(qemuNbdkitProcess *proc);
+qemuNbdkitProcessStop(qemuNbdkitProcess *proc,
+                      virDomainObj *vm);
 
 void
 qemuNbdkitProcessFree(qemuNbdkitProcess *proc);
diff --git a/tests/qemunbdkitdata/disk-network-ssh-password.args.disk0 b/tests/qemunbdkitdata/disk-network-ssh-password.args.disk0
index 30711f7f07..ee2d7c3343 100644
--- a/tests/qemunbdkitdata/disk-network-ssh-password.args.disk0
+++ b/tests/qemunbdkitdata/disk-network-ssh-password.args.disk0
@@ -5,4 +5,5 @@ host=example.org \
 port=2222 \
 path=test2.img \
 user=testuser \
-password=-777
+password=-777 \
+known-hosts=/path/to/knownhosts
diff --git a/tests/qemunbdkitdata/disk-network-ssh.args.disk0 b/tests/qemunbdkitdata/disk-network-ssh.args.disk0
index c04dc8bb03..481b218936 100644
--- a/tests/qemunbdkitdata/disk-network-ssh.args.disk0
+++ b/tests/qemunbdkitdata/disk-network-ssh.args.disk0
@@ -3,4 +3,5 @@ nbdkit \
 --foreground ssh \
 host=example.org \
 port=2222 \
-path=test.img
+path=test.img \
+known-hosts=/path/to/ssh_known_hosts
diff --git a/tests/qemuxml2argvdata/disk-network-ssh-password.xml b/tests/qemuxml2argvdata/disk-network-ssh-password.xml
index 266acb761f..bdb4cf6e35 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh-password.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh-password.xml
@@ -22,6 +22,7 @@
         <auth username='testuser'>
           <secret type='iscsi' usage='mycluster_myname'/>
         </auth>
+        <knownHosts path='/path/to/knownhosts'/>
       </source>
       <target dev='vda' bus='virtio'/>
     </disk>
diff --git a/tests/qemuxml2argvdata/disk-network-ssh.xml b/tests/qemuxml2argvdata/disk-network-ssh.xml
index 355add4fea..a3aeca0c99 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh.xml
@@ -19,6 +19,7 @@
         <host name='example.org' port='2222'/>
         <timeout seconds='1234'/>
         <readahead size='1024'/>
+        <knownHosts path="/path/to/ssh_known_hosts"/>
       </source>
       <target dev='vda' bus='virtio'/>
     </disk>
-- 
2.41.0



More information about the libvir-list mailing list