Signed-off-by: Ryan Gahagan <rgahagan(a)cs.utexas.edu>
---
tools/virsh-domain.c | 70 ++++++++++++++++++++++++++++++++++----------
1 file changed, 55 insertions(+), 15 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index ae9a2b1101..64c7c454bd 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -578,6 +578,49 @@ static int str2DiskAddress(const char *str, struct DiskAddress
*diskAddr)
return -1;
}
+static void attachDiskHostGen(virBufferPtr buf, const vshCmd *cmd)
+{
+ // Can be multiple hosts so we have to scan
+ // the cmd options to find all the host params
+ // <source tag in XML not yet closed
+ vshCmdOpt *candidate = cmd->opts;
+ char *host_name = NULL, *host_port = NULL;
+ int closeTag = 0;
+
+ while (candidate) {
+ // Iterate candidates to find each host-name
+ if (STREQ(candidate->def->name, "source-host-name")) {
+ // After the first host-name, we need to terminate
+ // the <host ... tag
+ // It's left open so socket and transport can be added later
+ if (closeTag)
+ virBufferAddLit(buf, "/>\n");
+ else
+ closeTag = 1;
+
+ host_name = candidate->data;
+ host_port = strchr(host_name, ':');
+
+ if (!host_port) {
+ // If port isn't provided, only print name
+ virBufferAsprintf(buf, "<host name='%s'",
host_name);
+ } else {
+ // If port is provided, manipulate strings and print both
+ host_name[(int)(host_port - host_name)] = '\0';
+ virBufferAsprintf(buf, "<host name='%s'
port='%s'", host_name, host_port + 1);
+ }
+ } else if (STREQ(candidate->def->name, "source-host-socket")) {
+ virBufferAsprintf(buf, " socket='%s'",
candidate->data);
+ } else if (STREQ(candidate->def->name, "source-host-transport"))
{
+ virBufferAsprintf(buf, " transport='%s'",
candidate->data);
+ }
+
+ candidate = candidate->next;
+ }
+ // Close final <host tag
+ virBufferAddLit(buf, "/>\n");
+}
+
static bool
cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
{
@@ -587,7 +630,7 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
*mode = NULL, *iothread = NULL, *cache = NULL,
*io = NULL, *serial = NULL, *straddr = NULL,
*wwn = NULL, *targetbus = NULL, *alias = NULL,
- *host_transport = NULL, *host_port = NULL, *host_socket = NULL;
+ *host_transport = NULL, *host_name = NULL, *host_socket = NULL;
struct DiskAddress diskAddr;
bool isFile = false, functionReturn = false;
int ret;
@@ -595,7 +638,6 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
const char *stype = NULL;
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
char *xml = NULL;
- char *host_name = NULL;
struct stat st;
bool current = vshCommandOptBool(cmd, "current");
bool config = vshCommandOptBool(cmd, "config");
@@ -698,27 +740,25 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
if (source_name)
virBufferAsprintf(&buf, " name='%s'", source_name);
- if (host_name || host_transport || host_socket) {
+ if (!(host_name || host_transport || host_socket)) {
+ // Close source if no host is provided
+ virBufferAddLit(&buf, "/>\n");
+ } else if (!host_name) {
+ // If no host name is provided but there is a host,
+ // we have a single host with params
virBufferAddLit(&buf, ">\n<host");
- if (host_name) {
- host_port = strchr(host_name, ':');
-
- if (!host_port) {
- virBufferAsprintf(&buf, " name='%s'",
host_name);
- } else {
- host_name[(int)(host_port - host_name)] = '\0';
- virBufferAsprintf(&buf, " name='%s'
port='%s'", host_name, host_port + 1);
- }
- }
if (host_transport)
virBufferAsprintf(&buf, " transport='%s'",
host_transport);
if (host_socket)
virBufferAsprintf(&buf, " socket='%s'",
host_socket);
- virBufferAddLit(&buf, " />\n</source>\n");
+ virBufferAddLit(&buf, "/>\n</source>\n");
} else {
- virBufferAddLit(&buf, " />\n");
+ // May have multiple hosts, use helper method
+ virBufferAddLit(&buf, ">\n");
+ attachDiskHostGen(&buf, cmd);
+ virBufferAddLit(&buf, "</source>\n");
}
}
--
2.29.0