OK, here we go with an updated patch. I think this should go in. Rich. -- Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/ Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 03798903
Index: src/virsh.c =================================================================== RCS file: /data/cvs/libvirt/src/virsh.c,v retrieving revision 1.75 diff -u -r1.75 virsh.c --- src/virsh.c 3 May 2007 16:03:02 -0000 1.75 +++ src/virsh.c 23 May 2007 08:49:43 -0000 @@ -22,6 +22,7 @@ #include <string.h> #include <stdarg.h> #include <unistd.h> +#include <errno.h> #include <getopt.h> #include <sys/types.h> #include <sys/time.h> @@ -673,6 +674,51 @@ {NULL, 0, 0, NULL} }; +/* Read in a whole file and return it as a string. + * If it fails, it logs an error and returns NULL. + * String must be freed by caller. + */ +static char * +readFile (vshControl *ctl, const char *filename) +{ + char *buffer = NULL, *oldbuffer; + int len = 0, fd, r; + char b[1024]; + + fd = open (filename, O_RDONLY); + if (fd == -1) { + file_error: + vshError (ctl, FALSE, "%s: %s", filename, strerror (errno)); + error: + if (buffer) free (buffer); + if (fd >= 0) close (fd); + return NULL; + } + + for (;;) { + r = read (fd, b, sizeof b); + if (r == -1) goto file_error; + if (r == 0) break; /* End of file. */ + oldbuffer = buffer; + buffer = realloc (buffer, len+r); + if (buffer == NULL) { + out_of_memory: + free (oldbuffer); + vshError (ctl, FALSE, "realloc: %s", strerror (errno)); + goto error; + } + memcpy (buffer+len, b, r); + len += r; + } + + oldbuffer = buffer; + buffer = realloc (buffer, len+1); + if (buffer == NULL) goto out_of_memory; + buffer[len] = '\0'; + close (fd); + return buffer; +} + static int cmdCreate(vshControl * ctl, vshCmd * cmd) { @@ -680,8 +726,7 @@ char *from; int found; int ret = TRUE; - char buffer[BUFSIZ]; - int fd, l; + char *buffer; if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) return FALSE; @@ -690,19 +735,12 @@ if (!found) return FALSE; - fd = open(from, O_RDONLY); - if (fd < 0) { - vshError(ctl, FALSE, _("Failed to read description file %s"), from); - return(FALSE); - } - l = read(fd, &buffer[0], sizeof(buffer)); - if ((l <= 0) || (l >= (int) sizeof(buffer))) { - vshError(ctl, FALSE, _("Failed to read description file %s"), from); - close(fd); - return(FALSE); - } - buffer[l] = 0; - dom = virDomainCreateLinux(ctl->conn, &buffer[0], 0); + buffer = readFile (ctl, from); + if (buffer == NULL) return FALSE; + + dom = virDomainCreateLinux(ctl->conn, buffer, 0); + free (buffer); + if (dom != NULL) { vshPrint(ctl, _("Domain %s created from %s\n"), virDomainGetName(dom), from); @@ -735,8 +773,7 @@ char *from; int found; int ret = TRUE; - char buffer[BUFSIZ]; - int fd, l; + char *buffer; if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) return FALSE; @@ -745,19 +782,12 @@ if (!found) return FALSE; - fd = open(from, O_RDONLY); - if (fd < 0) { - vshError(ctl, FALSE, _("Failed to read description file %s"), from); - return(FALSE); - } - l = read(fd, &buffer[0], sizeof(buffer)); - if ((l <= 0) || (l >= (int) sizeof(buffer))) { - vshError(ctl, FALSE, _("Failed to read description file %s"), from); - close(fd); - return(FALSE); - } - buffer[l] = 0; - dom = virDomainDefineXML(ctl->conn, &buffer[0]); + buffer = readFile (ctl, from); + if (buffer == NULL) return FALSE; + + dom = virDomainDefineXML(ctl->conn, buffer); + free (buffer); + if (dom != NULL) { vshPrint(ctl, _("Domain %s defined from %s\n"), virDomainGetName(dom), from); @@ -1800,8 +1830,7 @@ char *from; int found; int ret = TRUE; - char buffer[BUFSIZ]; - int fd, l; + char *buffer; if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) return FALSE; @@ -1810,19 +1839,12 @@ if (!found) return FALSE; - fd = open(from, O_RDONLY); - if (fd < 0) { - vshError(ctl, FALSE, _("Failed to read description file %s"), from); - return(FALSE); - } - l = read(fd, &buffer[0], sizeof(buffer)); - if ((l <= 0) || (l >= (int) sizeof(buffer))) { - vshError(ctl, FALSE, _("Failed to read description file %s"), from); - close(fd); - return(FALSE); - } - buffer[l] = 0; - network = virNetworkCreateXML(ctl->conn, &buffer[0]); + buffer = readFile (ctl, from); + if (buffer == NULL) return FALSE; + + network = virNetworkCreateXML(ctl->conn, buffer); + free (buffer); + if (network != NULL) { vshPrint(ctl, _("Network %s created from %s\n"), virNetworkGetName(network), from); @@ -1856,8 +1878,7 @@ char *from; int found; int ret = TRUE; - char buffer[BUFSIZ]; - int fd, l; + char *buffer; if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) return FALSE; @@ -1866,19 +1887,12 @@ if (!found) return FALSE; - fd = open(from, O_RDONLY); - if (fd < 0) { - vshError(ctl, FALSE, _("Failed to read description file %s"), from); - return(FALSE); - } - l = read(fd, &buffer[0], sizeof(buffer)); - if ((l <= 0) || (l >= (int) sizeof(buffer))) { - vshError(ctl, FALSE, _("Failed to read description file %s"), from); - close(fd); - return(FALSE); - } - buffer[l] = 0; - network = virNetworkDefineXML(ctl->conn, &buffer[0]); + buffer = readFile (ctl, from); + if (buffer == NULL) return FALSE; + + network = virNetworkDefineXML(ctl->conn, buffer); + free (buffer); + if (network != NULL) { vshPrint(ctl, _("Network %s defined from %s\n"), virNetworkGetName(network), from); @@ -2403,6 +2417,113 @@ return ret; } +/* + * "attach-device" command + */ +static vshCmdInfo info_attach_device[] = { + {"syntax", "attach-device <domain> <file> "}, + {"help", gettext_noop("attach device from an XML file")}, + {"desc", gettext_noop("Attach device from an XML <file>.")}, + {NULL, NULL} +}; + +static vshCmdOptDef opts_attach_device[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("XML file")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdAttachDevice(vshControl * ctl, vshCmd * cmd) +{ + virDomainPtr dom; + char *from; + char *buffer; + int ret = TRUE; + int found; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL))) + return FALSE; + + from = vshCommandOptString(cmd, "file", &found); + if (!found) { + virDomainFree(dom); + return FALSE; + } + + buffer = readFile (ctl, from); + if (buffer == NULL) return FALSE; + + ret = virDomainAttachDevice(dom, buffer); + free (buffer); + + if (ret < 0) { + vshError(ctl, FALSE, _("Failed to attach device from %s"), from); + virDomainFree(dom); + return FALSE; + } + + virDomainFree(dom); + return TRUE; +} + + +/* + * "detach-device" command + */ +static vshCmdInfo info_detach_device[] = { + {"syntax", "detach-device <domain> <file> "}, + {"help", gettext_noop("detach device from an XML file")}, + {"desc", gettext_noop("Detach device from an XML <file>")}, + {NULL, NULL} +}; + +static vshCmdOptDef opts_detach_device[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("domain name, id or uuid")}, + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("XML file")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdDetachDevice(vshControl * ctl, vshCmd * cmd) +{ + virDomainPtr dom; + char *from; + char *buffer; + int ret = TRUE; + int found; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL))) + return FALSE; + + from = vshCommandOptString(cmd, "file", &found); + if (!found) { + virDomainFree(dom); + return FALSE; + } + + buffer = readFile (ctl, from); + if (buffer == NULL) return FALSE; + + ret = virDomainDetachDevice(dom, buffer); + free (buffer); + + if (ret < 0) { + vshError(ctl, FALSE, _("Failed to detach device from %s"), from); + virDomainFree(dom); + return FALSE; + } + + virDomainFree(dom); + return TRUE; +} + /* * "quit" command @@ -2467,6 +2588,8 @@ {"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin}, {"version", cmdVersion, NULL, info_version}, {"vncdisplay", cmdVNCDisplay, opts_vncdisplay, info_vncdisplay}, + {"attach-device", cmdAttachDevice, opts_attach_device, info_attach_device}, + {"detach-device", cmdDetachDevice, opts_detach_device, info_detach_device}, {NULL, NULL, NULL, NULL} };
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature