Implement an idea originally requested 22 Mar 2010. * tools/virsh.c (cmdChangeDisk): New command, providing convenience wrapper around update-device. (commands): List it. * tools/virsh.pod (change-disk): Document it. (attach-disk): Update cross-reference. --- tools/virsh.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 13 +++++- 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index fab4b74..ba130bf 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -7646,6 +7646,118 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd) } /* + * "change-disk" command + */ +static const vshCmdInfo info_change_disk[] = { + {"help", N_("change disk device")}, + {"desc", N_("Update attributes of existing disk device.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_change_disk[] = { + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, + {"source", VSH_OT_DATA, VSH_OFLAG_REQ, N_("source of disk device")}, + {"target", VSH_OT_DATA, VSH_OFLAG_REQ, N_("target of disk device")}, + {"driver", VSH_OT_STRING, 0, N_("driver of disk device")}, + {"subdriver", VSH_OT_STRING, 0, N_("subdriver of disk device")}, + {"type", VSH_OT_STRING, 0, N_("target device type")}, + {"mode", VSH_OT_STRING, 0, N_("mode of device reading and writing")}, + {"persistent", VSH_OT_BOOL, 0, N_("persist disk attachment")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdChangeDisk(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom = NULL; + char *source, *target, *driver, *subdriver, *type, *mode; + int isFile = 0, ret = FALSE; + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *xml; + unsigned int flags; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + goto cleanup; + + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) + goto cleanup; + + if (!(source = vshCommandOptString(cmd, "source", NULL))) + goto cleanup; + + if (!(target = vshCommandOptString(cmd, "target", NULL))) + goto cleanup; + + driver = vshCommandOptString(cmd, "driver", NULL); + subdriver = vshCommandOptString(cmd, "subdriver", NULL); + type = vshCommandOptString(cmd, "type", NULL); + mode = vshCommandOptString(cmd, "mode", NULL); + + if (driver) { + if (STREQ(driver, "file") || STREQ(driver, "tap")) { + isFile = 1; + } else if (STRNEQ(driver, "phy")) { + vshError(ctl, _("No support for %s in command 'change-disk'"), + driver); + goto cleanup; + } + } + + if (mode) { + if (STRNEQ(mode, "readonly") && STRNEQ(mode, "shareable")) { + vshError(ctl, _("No support for %s in command 'attach-disk'"), + mode); + goto cleanup; + } + } + + /* Make XML of disk */ + virBufferVSprintf(&buf, " <disk type='%s'", isFile ? "file" : "block"); + if (type) + virBufferVSprintf(&buf, " device='%s'", type); + virBufferVSprintf(&buf, ">\n" + " <driver name='%s'", driver ? driver : "phy"); + if (subdriver) + virBufferVSprintf(&buf, " type='%s'", subdriver); + virBufferVSprintf(&buf, "/>\n" + " <source %s='%s'/>\n", isFile ? "file" : "dev", + source); + virBufferVSprintf(&buf, "<target dev='%s'/>\n", target); + if (mode != NULL) + virBufferVSprintf(&buf, " <%s/>\n", mode); + virBufferAddLit(&buf, " </disk>\n"); + + if ((xml = virBufferContentAndReset(&buf)) == NULL) { + vshPrint(ctl, "%s", _("Failed to allocate XML buffer")); + return FALSE; + } + + if (vshCommandOptBool(cmd, "persistent")) { + flags = VIR_DOMAIN_DEVICE_MODIFY_CONFIG; + if (virDomainIsActive(dom) == 1) + flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; + } else { + flags = VIR_DOMAIN_DEVICE_MODIFY_LIVE; + } + ret = virDomainUpdateDeviceFlags(dom, xml, flags); + VIR_FREE(xml); + + if (ret != 0) { + vshError(ctl, "%s", _("Failed to change disk")); + ret = FALSE; + } else { + vshPrint(ctl, "%s", _("Disk changed successfully\n")); + ret = TRUE; + } + + cleanup: + if (dom) + virDomainFree(dom); + virBufferFreeAndReset(&buf); + return ret; +} + +/* * "detach-disk" command */ static const vshCmdInfo info_detach_disk[] = { @@ -8758,6 +8870,7 @@ static const vshCmdDef commands[] = { #ifndef WIN32 {"cd", cmdCd, opts_cd, info_cd}, #endif + {"change-disk", cmdChangeDisk, opts_change_disk, info_change_disk}, {"connect", cmdConnect, opts_connect, info_connect}, #ifndef WIN32 {"console", cmdConsole, opts_console, info_console}, diff --git a/tools/virsh.pod b/tools/virsh.pod index b195b67..ca6b1c6 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -535,8 +535,8 @@ I<source> and I<target> are paths for the files and devices. I<driver> can be I<file>, I<tap> or I<phy> depending on the kind of access. I<type> can indicate I<cdrom> or I<floppy> as alternative to the disk default, although this use only replaces the media within the existing virtual cdrom or -floppy device; consider using B<update-device> for this usage instead. -I<mode> can specify the two specific mode I<readonly> or I<shareable>. +floppy device; consider using B<change-disk> for this usage instead. +I<mode> can specify the two specific modes I<readonly> or I<shareable>. =item B<attach-interface> I<domain-id> I<type> I<source> optional I<--target target> I<--mac mac> I<--script script> @@ -548,6 +548,15 @@ I<mac> allows to specify the MAC address of the network interface. I<script> allows to specify a path to a script handling a bridge instead of the default one. +=item B<change-disk> I<domain-id> I<source> I<target> optional I<--driver driver> I<--subdriver subdriver> I<--type type> I<--mode mode> + +Change an existing disk device of the domain, such as hot-plugging a disk +or changing the media in a cdrom. +I<source> and I<target> are paths for the files and devices. +I<driver> can be I<file>, I<tap> or I<phy> depending on the kind of access. +I<type> can indicate I<cdrom> or I<floppy> as alternative to the disk default. +I<mode> can specify the two specific modes I<readonly> or I<shareable>. + =item B<detach-device> I<domain-id> I<FILE> Detach a device from the domain, takes the same kind of XML descriptions -- 1.7.0.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list