[libvirt] [PATCH 13/13] qemu: pass iscsi authorization credentials

Paolo Bonzini pbonzini at redhat.com
Mon Feb 25 17:44:32 UTC 2013


A better way to do this would be to use a configuration file like

   [iscsi "target-name"]
   user = name
   password = pwd

and pass it via -readconfig.  This would remove the username and password
from the "ps" output.  For now, however, keep this solution.

Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
 src/qemu/qemu_command.c                            | 80 ++++++++++++++++++----
 ...qemuxml2argv-disk-drive-network-iscsi-auth.args |  1 +
 tests/qemuxml2argvtest.c                           |  2 +
 3 files changed, 70 insertions(+), 13 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 5d52be5..30ddbd3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1888,8 +1888,8 @@ qemuBuildRBDString(virConnectPtr conn,
             VIR_FREE(base64);
         } else {
             virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("rbd username '%s' specified but secret not found"),
-                           disk->auth.username);
+                           _("%s username '%s' specified but secret not found"),
+                           "rbd", disk->auth.username);
             goto error;
         }
     } else {
@@ -2057,6 +2057,7 @@ qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
     char *transp = NULL;
     char *sock = NULL;
     char *volimg = NULL;
+    char *secret = NULL;
 
     if (VIR_ALLOC(def->hosts) < 0)
         goto no_memory;
@@ -2117,6 +2118,16 @@ qemuParseDriveURIString(virDomainDiskDefPtr def, virURIPtr uri,
         def->src = NULL;
     }
 
+    if (uri->user) {
+        secret = strchr(uri->user, ':');
+        if (secret)
+            *secret = '\0';
+
+        def->auth.username = strdup(uri->user);
+        if (!def->auth.username)
+            goto no_memory;
+    }
+
     def->nhosts = 1;
     ret = 0;
 
@@ -2237,14 +2248,20 @@ error:
 }
 
 static int
-qemuBuildDriveURIString(virDomainDiskDefPtr disk, virBufferPtr opt,
-                        const char *scheme)
+qemuBuildDriveURIString(virConnectPtr conn,
+                        virDomainDiskDefPtr disk, virBufferPtr opt,
+                        const char *scheme, virSecretUsageType secretType)
 {
     int ret = -1;
     int port = 0;
+    virSecretPtr sec = NULL;
+    char *secret = NULL;
+    size_t secret_size;
+
     char *tmpscheme = NULL;
     char *volimg = NULL;
     char *sock = NULL;
+    char *user = NULL;
     char *builturi = NULL;
     const char *transp = NULL;
     virURI uri = {
@@ -2280,8 +2297,42 @@ qemuBuildDriveURIString(virDomainDiskDefPtr disk, virBufferPtr opt,
         virAsprintf(&sock, "socket=%s", disk->hosts->socket) < 0)
         goto no_memory;
 
+    if (disk->auth.username && secretType != VIR_SECRET_USAGE_TYPE_NONE) {
+        /* look up secret */
+        switch (disk->auth.secretType) {
+        case VIR_DOMAIN_DISK_SECRET_TYPE_UUID:
+            sec = virSecretLookupByUUID(conn,
+                                        disk->auth.secret.uuid);
+            break;
+        case VIR_DOMAIN_DISK_SECRET_TYPE_USAGE:
+            sec = virSecretLookupByUsage(conn, secretType,
+                                         disk->auth.secret.usage);
+            break;
+        }
+
+        if (sec) {
+            secret = (char *)conn->secretDriver->getValue(sec, &secret_size, 0,
+                                                          VIR_SECRET_GET_VALUE_INTERNAL_CALL);
+            if (secret == NULL) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("could not get the value of the secret for username %s"),
+                               disk->auth.username);
+                ret = -1;
+                goto cleanup;
+            }
+            if (virAsprintf(&user, "%s:%s", disk->auth.username, secret) < 0)
+                goto no_memory;
+        } else {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("%s username '%s' specified but secret not found"),
+                           scheme, disk->auth.username);
+            ret = -1;
+            goto cleanup;
+        }
+    }
     uri.scheme = tmpscheme; /* gluster+<transport> */
     uri.server = disk->hosts->name;
+    uri.user = user;
     uri.port = port;
     uri.path = volimg;
     uri.query = sock;
@@ -2305,16 +2356,18 @@ no_memory:
 }
 
 static int
-qemuBuildGlusterString(virDomainDiskDefPtr disk, virBufferPtr opt)
+qemuBuildGlusterString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
 {
-    return qemuBuildDriveURIString(disk, opt, "gluster");
+    return qemuBuildDriveURIString(conn, disk, opt, "gluster",
+                                   VIR_SECRET_USAGE_TYPE_NONE);
 }
 
 static int
-qemuBuildISCSIString(virDomainDiskDefPtr disk, virBufferPtr opt)
+qemuBuildISCSIString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
 {
     int ret;
-    ret = qemuBuildDriveURIString(disk, opt, "iscsi");
+    ret = qemuBuildDriveURIString(conn, disk, opt, "iscsi",
+                                  VIR_SECRET_USAGE_TYPE_ISCSI);
     if (ret < 0)
         return ret;
 
@@ -2325,7 +2378,7 @@ qemuBuildISCSIString(virDomainDiskDefPtr disk, virBufferPtr opt)
 }
 
 static int
-qemuBuildNBDString(virDomainDiskDefPtr disk, virBufferPtr opt)
+qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
 {
     const char *transp;
 
@@ -2340,7 +2393,8 @@ qemuBuildNBDString(virDomainDiskDefPtr disk, virBufferPtr opt)
             && !disk->hosts->name)
         || (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX
             && disk->hosts->socket && disk->hosts->socket[0] != '/'))
-        return qemuBuildDriveURIString(disk, opt, "nbd");
+        return qemuBuildDriveURIString(conn, disk, opt, "nbd",
+                                       VIR_SECRET_USAGE_TYPE_NONE);
 
     virBufferAddLit(opt, "file=nbd:");
 
@@ -2498,7 +2552,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
         } else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
             switch (disk->protocol) {
             case VIR_DOMAIN_DISK_PROTOCOL_NBD:
-                if (qemuBuildNBDString(disk, &opt) < 0)
+                if (qemuBuildNBDString(conn, disk, &opt) < 0)
                     goto error;
                 virBufferAddChar(&opt, ',');
                 break;
@@ -2509,12 +2563,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
                 virBufferAddChar(&opt, ',');
                 break;
             case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
-                if (qemuBuildGlusterString(disk, &opt) < 0)
+                if (qemuBuildGlusterString(conn, disk, &opt) < 0)
                     goto error;
                 virBufferAddChar(&opt, ',');
                 break;
             case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
-                if (qemuBuildISCSIString(disk, &opt) < 0)
+                if (qemuBuildISCSIString(conn, disk, &opt) < 0)
                     goto error;
                 virBufferAddChar(&opt, ',');
                 break;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args
new file mode 100644
index 0000000..fd2660a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-network-iscsi-auth.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb -drive file=iscsi://myname:AQCVn5hO6HzFAhAAq0NCv8jtJcIcE+HOBlMQ1A@example.org/iqn.1992-01.com.example,if=virtio,format=raw -net none -serial none -parallel none
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index babdd8c..0afecf3 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -495,6 +495,8 @@ mymain(void)
             QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
     DO_TEST("disk-drive-network-iscsi",
             QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
+    DO_TEST("disk-drive-network-iscsi-auth",
+            QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
     DO_TEST("disk-drive-network-gluster",
             QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
     DO_TEST("disk-drive-network-rbd",
-- 
1.8.1.2




More information about the libvir-list mailing list