[libvirt] [PATCH v5 0/7] Add managed save XML modification APIs (pushed)

This is the version I've pushed. I'm sending it in for a reference of the modifications I've made as part of the review. Kothapally Madhu Pavan (7): lib: Add API to dump xml configuration of managed save state domain lib: Add API to edit domain's managed save state xml configuration qemu: Implement qemuDomainManagedSaveGetXMLDesc qemu: Implement qemuDomainManagedSaveDefineXML virsh: Implement managedsave-define command virsh: Implement managedsave-dumpxml command virsh: Implement managedsave-edit command include/libvirt/libvirt-domain.h | 6 ++ src/driver-hypervisor.h | 11 +++ src/libvirt-domain.c | 106 ++++++++++++++++++++ src/libvirt_public.syms | 2 + src/qemu/qemu_driver.c | 79 +++++++++++++++ src/remote/remote_driver.c | 2 + src/remote/remote_protocol.x | 30 +++++- src/remote_protocol-structs | 14 +++ tools/virsh-domain.c | 204 +++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 39 ++++++++ 10 files changed, 492 insertions(+), 1 deletion(-) -- 2.14.1

From: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> Similar to domainSaveImageGetXMLDesc this commit adds domainManagedSaveGetXMLDesc API which allows to get the xml of managed save state domain. Signed-off-by: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> --- include/libvirt/libvirt-domain.h | 2 ++ src/driver-hypervisor.h | 5 ++++ src/libvirt-domain.c | 49 ++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 17 +++++++++++++- src/remote_protocol-structs | 8 +++++++ 7 files changed, 82 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index fae24ac93..4c5a7f7b5 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1213,6 +1213,8 @@ int virDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags); int virDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags); +char * virDomainManagedSaveGetXMLDesc(virDomainPtr domain, + unsigned int flags); /* * Domain core dump diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index 7b35e9e68..a3f9cbc31 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -750,6 +750,10 @@ typedef int (*virDrvDomainManagedSaveRemove)(virDomainPtr domain, unsigned int flags); +typedef char * +(*virDrvDomainManagedSaveGetXMLDesc)(virDomainPtr domain, + unsigned int flags); + typedef virDomainSnapshotPtr (*virDrvDomainSnapshotCreateXML)(virDomainPtr domain, const char *xmlDesc, @@ -1428,6 +1432,7 @@ struct _virHypervisorDriver { virDrvDomainManagedSave domainManagedSave; virDrvDomainHasManagedSaveImage domainHasManagedSaveImage; virDrvDomainManagedSaveRemove domainManagedSaveRemove; + virDrvDomainManagedSaveGetXMLDesc domainManagedSaveGetXMLDesc; virDrvDomainSnapshotCreateXML domainSnapshotCreateXML; virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc; virDrvDomainSnapshotNum domainSnapshotNum; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 4d0ac30d5..f43ab2478 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -9339,6 +9339,55 @@ virDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags) } +/** + * virDomainManagedSaveGetXMLDesc: + * @domain: a domain object + * @flags: bitwise-OR of subset of virDomainXMLFlags + * + * This method will extract the XML description of the managed save + * state file of a domain. + * + * No security-sensitive data will be included unless @flags contains + * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only + * connections. For this API, @flags should not contain either + * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU. + * + * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of + * error. The caller must free() the returned value. + */ +char * +virDomainManagedSaveGetXMLDesc(virDomainPtr domain, unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "flags=%x", flags); + + virResetLastError(); + + virCheckDomainReturn(domain, NULL); + conn = domain->conn; + + if ((conn->flags & VIR_CONNECT_RO) && (flags & VIR_DOMAIN_XML_SECURE)) { + virReportError(VIR_ERR_OPERATION_DENIED, "%s", + _("virDomainManagedSaveGetXMLDesc with secure flag")); + goto error; + } + + if (conn->driver->domainManagedSaveGetXMLDesc) { + char *ret; + ret = conn->driver->domainManagedSaveGetXMLDesc(domain, flags); + if (!ret) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return NULL; +} + /** * virDomainOpenConsole: diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index b55ca4b55..58b9b4910 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -771,5 +771,6 @@ LIBVIRT_3.4.0 { LIBVIRT_3.7.0 { global: virDomainMigrateGetMaxDowntime; + virDomainManagedSaveGetXMLDesc; } LIBVIRT_3.4.0; # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 027b073ec..c64f5b337 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8411,6 +8411,7 @@ static virHypervisorDriver hypervisor_driver = { .domainManagedSave = remoteDomainManagedSave, /* 0.8.0 */ .domainHasManagedSaveImage = remoteDomainHasManagedSaveImage, /* 0.8.0 */ .domainManagedSaveRemove = remoteDomainManagedSaveRemove, /* 0.8.0 */ + .domainManagedSaveGetXMLDesc = remoteDomainManagedSaveGetXMLDesc, /* 3.7.0 */ .domainSnapshotCreateXML = remoteDomainSnapshotCreateXML, /* 0.8.0 */ .domainSnapshotGetXMLDesc = remoteDomainSnapshotGetXMLDesc, /* 0.8.0 */ .domainSnapshotNum = remoteDomainSnapshotNum, /* 0.8.0 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 2d49ceb3a..76033acc9 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2556,6 +2556,15 @@ struct remote_domain_managed_save_remove_args { unsigned int flags; }; +struct remote_domain_managed_save_get_xml_desc_args { + remote_nonnull_domain dom; + unsigned int flags; +}; + +struct remote_domain_managed_save_get_xml_desc_ret { + remote_nonnull_string xml; +}; + struct remote_domain_snapshot_create_xml_args { remote_nonnull_domain dom; remote_nonnull_string xml_desc; @@ -6079,6 +6088,12 @@ enum remote_procedure { * @generate: both * @acl: domain:migrate */ - REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_DOWNTIME = 387 + REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_DOWNTIME = 387, + /** + * @generate: both + * @acl: domain:read + * @acl: domain:read_secure:VIR_DOMAIN_XML_SECURE + */ + REMOTE_PROC_DOMAIN_MANAGED_SAVE_GET_XML_DESC = 388 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 540553efe..4803a46f2 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1970,6 +1970,13 @@ struct remote_domain_managed_save_remove_args { remote_nonnull_domain dom; u_int flags; }; +struct remote_domain_managed_save_get_xml_desc_args { + remote_nonnull_domain dom; + u_int flags; +}; +struct remote_domain_managed_save_get_xml_desc_ret { + remote_nonnull_string xml; +}; struct remote_domain_snapshot_create_xml_args { remote_nonnull_domain dom; remote_nonnull_string xml_desc; @@ -3241,4 +3248,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_EVENT_BLOCK_THRESHOLD = 385, REMOTE_PROC_DOMAIN_SET_BLOCK_THRESHOLD = 386, REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_DOWNTIME = 387, + REMOTE_PROC_DOMAIN_MANAGED_SAVE_GET_XML_DESC = 388, }; -- 2.14.1

From: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> Similar to domainSaveImageDefineXML this commit adds domainManagedSaveDefineXML API which allows to edit domain's managed save state xml configuration. Signed-off-by: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> --- include/libvirt/libvirt-domain.h | 4 +++ src/driver-hypervisor.h | 6 +++++ src/libvirt-domain.c | 57 ++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 1 + src/remote/remote_driver.c | 1 + src/remote/remote_protocol.x | 15 ++++++++++- src/remote_protocol-structs | 6 +++++ 7 files changed, 89 insertions(+), 1 deletion(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 4c5a7f7b5..030a62c43 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -1215,6 +1215,10 @@ int virDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags); char * virDomainManagedSaveGetXMLDesc(virDomainPtr domain, unsigned int flags); +int virDomainManagedSaveDefineXML(virDomainPtr domain, + const char *dxml, + unsigned int flags); + /* * Domain core dump diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index a3f9cbc31..6c3f7d795 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -754,6 +754,11 @@ typedef char * (*virDrvDomainManagedSaveGetXMLDesc)(virDomainPtr domain, unsigned int flags); +typedef int +(*virDrvDomainManagedSaveDefineXML)(virDomainPtr domain, + const char *dxml, + unsigned int flags); + typedef virDomainSnapshotPtr (*virDrvDomainSnapshotCreateXML)(virDomainPtr domain, const char *xmlDesc, @@ -1433,6 +1438,7 @@ struct _virHypervisorDriver { virDrvDomainHasManagedSaveImage domainHasManagedSaveImage; virDrvDomainManagedSaveRemove domainManagedSaveRemove; virDrvDomainManagedSaveGetXMLDesc domainManagedSaveGetXMLDesc; + virDrvDomainManagedSaveDefineXML domainManagedSaveDefineXML; virDrvDomainSnapshotCreateXML domainSnapshotCreateXML; virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc; virDrvDomainSnapshotNum domainSnapshotNum; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index f43ab2478..ca5a1536a 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -9389,6 +9389,63 @@ virDomainManagedSaveGetXMLDesc(virDomainPtr domain, unsigned int flags) } +/** + * virDomainManagedSaveDefineXML: + * @domain: a domain object + * @dxml: XML config for adjusting guest xml used on restore + * @flags: bitwise-OR of virDomainSaveRestoreFlags + * + * This updates the definition of a domain stored in a saved state + * file. + * + * @dxml can be used to alter host-specific portions of the domain XML + * that will be used on the next start of the domain. For example, it is + * possible to alter the backing filename that is associated with a + * disk device. + * + * Normally, the saved state file will remember whether the domain was + * running or paused, and restore defaults to the same state. + * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in + * @flags will override the default saved into the file; omitting both + * leaves the file's default unchanged. These two flags are mutually + * exclusive. + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virDomainManagedSaveDefineXML(virDomainPtr domain, const char *dxml, + unsigned int flags) +{ + virConnectPtr conn; + + VIR_DOMAIN_DEBUG(domain, "flags=%x", flags); + + virResetLastError(); + + VIR_EXCLUSIVE_FLAGS_GOTO(VIR_DOMAIN_SAVE_RUNNING, + VIR_DOMAIN_SAVE_PAUSED, + error); + + virCheckDomainReturn(domain, -1); + conn = domain->conn; + + if (conn->driver->domainManagedSaveDefineXML) { + int ret; + ret = conn->driver->domainManagedSaveDefineXML(domain, dxml, flags); + + if (ret < 0) + goto error; + return ret; + } + + virReportUnsupportedError(); + + error: + virDispatchError(domain->conn); + return -1; +} + + /** * virDomainOpenConsole: * @dom: a domain object diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 58b9b4910..498601943 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -772,5 +772,6 @@ LIBVIRT_3.7.0 { global: virDomainMigrateGetMaxDowntime; virDomainManagedSaveGetXMLDesc; + virDomainManagedSaveDefineXML; } LIBVIRT_3.4.0; # .... define new API here using predicted next version number .... diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index c64f5b337..7f814cd4f 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -8412,6 +8412,7 @@ static virHypervisorDriver hypervisor_driver = { .domainHasManagedSaveImage = remoteDomainHasManagedSaveImage, /* 0.8.0 */ .domainManagedSaveRemove = remoteDomainManagedSaveRemove, /* 0.8.0 */ .domainManagedSaveGetXMLDesc = remoteDomainManagedSaveGetXMLDesc, /* 3.7.0 */ + .domainManagedSaveDefineXML = remoteDomainManagedSaveDefineXML, /* 3.7.0 */ .domainSnapshotCreateXML = remoteDomainSnapshotCreateXML, /* 0.8.0 */ .domainSnapshotGetXMLDesc = remoteDomainSnapshotGetXMLDesc, /* 0.8.0 */ .domainSnapshotNum = remoteDomainSnapshotNum, /* 0.8.0 */ diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 76033acc9..07463b781 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -2565,6 +2565,12 @@ struct remote_domain_managed_save_get_xml_desc_ret { remote_nonnull_string xml; }; +struct remote_domain_managed_save_define_xml_args { + remote_nonnull_domain dom; + remote_string dxml; + unsigned int flags; +}; + struct remote_domain_snapshot_create_xml_args { remote_nonnull_domain dom; remote_nonnull_string xml_desc; @@ -6095,5 +6101,12 @@ enum remote_procedure { * @acl: domain:read * @acl: domain:read_secure:VIR_DOMAIN_XML_SECURE */ - REMOTE_PROC_DOMAIN_MANAGED_SAVE_GET_XML_DESC = 388 + REMOTE_PROC_DOMAIN_MANAGED_SAVE_GET_XML_DESC = 388, + + /** + * @generate: both + * @acl: domain:write + * @acl: domain:hibernate + */ + REMOTE_PROC_DOMAIN_MANAGED_SAVE_DEFINE_XML = 389 }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 4803a46f2..6038bf138 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -1977,6 +1977,11 @@ struct remote_domain_managed_save_get_xml_desc_args { struct remote_domain_managed_save_get_xml_desc_ret { remote_nonnull_string xml; }; +struct remote_domain_managed_save_define_xml_args { + remote_nonnull_domain dom; + remote_string dxml; + u_int flags; +}; struct remote_domain_snapshot_create_xml_args { remote_nonnull_domain dom; remote_nonnull_string xml_desc; @@ -3249,4 +3254,5 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_SET_BLOCK_THRESHOLD = 386, REMOTE_PROC_DOMAIN_MIGRATE_GET_MAX_DOWNTIME = 387, REMOTE_PROC_DOMAIN_MANAGED_SAVE_GET_XML_DESC = 388, + REMOTE_PROC_DOMAIN_MANAGED_SAVE_DEFINE_XML = 389, }; -- 2.14.1

From: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> This commit adds qemu driver implementation to get xml description for managed save state domain. Signed-off-by: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> --- src/qemu/qemu_driver.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 672d3f8b3..b9e58e562 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6797,6 +6797,50 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const char *path, return ret; } +static char * +qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom, unsigned int flags) +{ + virQEMUDriverPtr driver = dom->conn->privateData; + virDomainObjPtr vm; + char *path = NULL; + char *ret = NULL; + virDomainDefPtr def = NULL; + int fd = -1; + virQEMUSaveDataPtr data = NULL; + + /* We only take subset of virDomainDefFormat flags. */ + virCheckFlags(VIR_DOMAIN_XML_SECURE, NULL); + + if (!(vm = qemuDomObjFromDomain(dom))) + return ret; + + if (virDomainManagedSaveGetXMLDescEnsureACL(dom->conn, vm->def, flags) < 0) + goto cleanup; + + if (!(path = qemuDomainManagedSavePath(driver, vm))) + goto cleanup; + + if (!virFileExists(path)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain does not have managed save image")); + goto cleanup; + } + + if ((fd = qemuDomainSaveImageOpen(driver, path, &def, &data, + false, NULL, false, false)) < 0) + goto cleanup; + + ret = qemuDomainDefFormatXML(driver, def, flags); + + cleanup: + virQEMUSaveDataFree(data); + virDomainDefFree(def); + VIR_FORCE_CLOSE(fd); + virDomainObjEndAPI(&vm); + VIR_FREE(path); + return ret; +} + /* Return 0 on success, 1 if incomplete saved image was silently unlinked, * and -1 on failure with error raised. */ static int @@ -20900,6 +20944,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainManagedSave = qemuDomainManagedSave, /* 0.8.0 */ .domainHasManagedSaveImage = qemuDomainHasManagedSaveImage, /* 0.8.0 */ .domainManagedSaveRemove = qemuDomainManagedSaveRemove, /* 0.8.0 */ + .domainManagedSaveGetXMLDesc = qemuDomainManagedSaveGetXMLDesc, /* 3.7.0 */ .domainSnapshotCreateXML = qemuDomainSnapshotCreateXML, /* 0.8.0 */ .domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */ .domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */ -- 2.14.1

From: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> This commit adds qemu driver implementation to edit xml configuration of managed save state file of a domain. Signed-off-by: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> --- src/qemu/qemu_driver.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b9e58e562..b7824512c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6841,6 +6841,39 @@ qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom, unsigned int flags) return ret; } +static int +qemuDomainManagedSaveDefineXML(virDomainPtr dom, const char *dxml, + unsigned int flags) +{ + virQEMUDriverPtr driver = dom->conn->privateData; + virConnectPtr conn = dom->conn; + virDomainObjPtr vm; + char *path = NULL; + int ret = -1; + + if (!(vm = qemuDomObjFromDomain(dom))) + return -1; + + if (virDomainManagedSaveDefineXMLEnsureACL(conn, vm->def) < 0) + goto cleanup; + + if (!(path = qemuDomainManagedSavePath(driver, vm))) + goto cleanup; + + if (!virFileExists(path)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain does not have managed save image")); + goto cleanup; + } + + ret = qemuDomainSaveImageDefineXML(conn, path, dxml, flags); + + cleanup: + virDomainObjEndAPI(&vm); + VIR_FREE(path); + return ret; +} + /* Return 0 on success, 1 if incomplete saved image was silently unlinked, * and -1 on failure with error raised. */ static int @@ -20945,6 +20978,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainHasManagedSaveImage = qemuDomainHasManagedSaveImage, /* 0.8.0 */ .domainManagedSaveRemove = qemuDomainManagedSaveRemove, /* 0.8.0 */ .domainManagedSaveGetXMLDesc = qemuDomainManagedSaveGetXMLDesc, /* 3.7.0 */ + .domainManagedSaveDefineXML = qemuDomainManagedSaveDefineXML, /* 3.7.0 */ .domainSnapshotCreateXML = qemuDomainSnapshotCreateXML, /* 0.8.0 */ .domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */ .domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */ -- 2.14.1

From: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> Add a simple virsh command handler which makes use of the new API. Signed-off-by: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> --- tools/virsh-domain.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 12 ++++++++ 2 files changed, 90 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index a3410e791..8f048f678 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4704,6 +4704,78 @@ cmdManagedSaveRemove(vshControl *ctl, const vshCmd *cmd) return ret; } +/* + * "managedsave-define" command + */ +static const vshCmdInfo info_managed_save_define[] = { + {.name = "help", + .data = N_("redefine the XML for a domain's managed save state file") + }, + {.name = "desc", + .data = N_("Replace the domain XML associated with a managed save state file") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_managed_save_define[] = { + VIRSH_COMMON_OPT_DOMAIN_FULL, + {.name = "xml", + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_("filename containing updated XML for the target") + }, + {.name = "running", + .type = VSH_OT_BOOL, + .help = N_("set domain to be running on start") + }, + {.name = "paused", + .type = VSH_OT_BOOL, + .help = N_("set domain to be paused on start") + }, + {.name = NULL} +}; + +static bool +cmdManagedSaveDefine(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + virDomainPtr dom = NULL; + const char *xmlfile = NULL; + char *xml = NULL; + unsigned int flags = 0; + + if (vshCommandOptBool(cmd, "running")) + flags |= VIR_DOMAIN_SAVE_RUNNING; + if (vshCommandOptBool(cmd, "paused")) + flags |= VIR_DOMAIN_SAVE_PAUSED; + + VSH_EXCLUSIVE_OPTIONS("running", "paused"); + + if (vshCommandOptStringReq(ctl, cmd, "xml", &xmlfile) < 0) + return false; + + if (virFileReadAll(xmlfile, VSH_MAX_XML_FILE, &xml) < 0) + return false; + + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + goto cleanup; + + if (virDomainManagedSaveDefineXML(dom, xml, flags) < 0) { + vshError(ctl, _("Failed to update %s XML configuration"), + virDomainGetName(dom)); + goto cleanup; + } + + vshPrintExtra(ctl, _("Managed save state file of domain %s updated.\n"), + virDomainGetName(dom)); + ret = true; + + cleanup: + virshDomainFree(dom); + VIR_FREE(xml); + return ret; +} + /* * "schedinfo" command */ @@ -13886,6 +13958,12 @@ const vshCmdDef domManagementCmds[] = { .info = info_managedsaveremove, .flags = 0 }, + {.name = "managedsave-define", + .handler = cmdManagedSaveDefine, + .opts = opts_managed_save_define, + .info = info_managed_save_define, + .flags = 0 + }, {.name = "memtune", .handler = cmdMemtune, .opts = opts_memtune, diff --git a/tools/virsh.pod b/tools/virsh.pod index 15a414399..5c87af302 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1630,6 +1630,18 @@ has any managed save image. Remove the B<managedsave> state file for a domain, if it exists. This ensures the domain will do a full boot the next time it is started. +=item B<managedsave-define> I<domain> I<xml> [{I<--running> | I<--paused>}] + +Update the domain XML that will be used when I<domain> is later +started. The I<xml> argument must be a file name containing +the alternative XML, with changes only in the host-specific portions of +the domain XML. For example, it can be used to change disk file paths. + +The managed save image records whether the domain should be started to a +running or paused state. Normally, this command does not alter the +recorded state; passing either the I<--running> or I<--paused> flag +will allow overriding which state the B<start> should use. + =item B<maxvcpus> [I<type>] Provide the maximum number of virtual CPUs supported for a guest VM on -- 2.14.1

From: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> Add a simple virsh command handler which makes use of the new API. Signed-off-by: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> --- tools/virsh-domain.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 6 ++++++ 2 files changed, 60 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 8f048f678..14960c4a2 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4704,6 +4704,54 @@ cmdManagedSaveRemove(vshControl *ctl, const vshCmd *cmd) return ret; } +/* + * "managedsave-dumpxml" command + */ +static const vshCmdInfo info_managed_save_dumpxml[] = { + {.name = "help", + .data = N_("Domain information of managed save state file in XML") + }, + {.name = "desc", + .data = N_("Dump XML of domain information for a managed save state file to stdout.") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_managed_save_dumpxml[] = { + VIRSH_COMMON_OPT_DOMAIN_FULL, + {.name = "security-info", + .type = VSH_OT_BOOL, + .help = N_("include security sensitive information in XML dump") + }, + {.name = NULL} +}; + +static bool +cmdManagedSaveDumpxml(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + virDomainPtr dom = NULL; + unsigned int flags = 0; + char *xml = NULL; + + if (vshCommandOptBool(cmd, "security-info")) + flags |= VIR_DOMAIN_XML_SECURE; + + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + goto cleanup; + + if (!(xml = virDomainManagedSaveGetXMLDesc(dom, flags))) + goto cleanup; + + vshPrint(ctl, "%s", xml); + ret = true; + + cleanup: + virshDomainFree(dom); + VIR_FREE(xml); + return ret; +} + /* * "managedsave-define" command */ @@ -13958,6 +14006,12 @@ const vshCmdDef domManagementCmds[] = { .info = info_managedsaveremove, .flags = 0 }, + {.name = "managedsave-dumpxml", + .handler = cmdManagedSaveDumpxml, + .opts = opts_managed_save_dumpxml, + .info = info_managed_save_dumpxml, + .flags = 0 + }, {.name = "managedsave-define", .handler = cmdManagedSaveDefine, .opts = opts_managed_save_define, diff --git a/tools/virsh.pod b/tools/virsh.pod index 5c87af302..f7b05f803 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1642,6 +1642,12 @@ running or paused state. Normally, this command does not alter the recorded state; passing either the I<--running> or I<--paused> flag will allow overriding which state the B<start> should use. +=item B<managedsave-dumpxml> I<domain> [I<--security-info>] + +Extract the domain XML that was in effect at the time the saved state +file I<file> was created with the B<managedsave> command. Using +I<--security-info> will also include security sensitive information. + =item B<maxvcpus> [I<type>] Provide the maximum number of virtual CPUs supported for a guest VM on -- 2.14.1

From: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> Add a simple virsh command handler which makes use of the new API. Signed-off-by: Kothapally Madhu Pavan <kmp@linux.vnet.ibm.com> --- tools/virsh-domain.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/virsh.pod | 21 +++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 14960c4a2..f235c66b0 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4704,6 +4704,72 @@ cmdManagedSaveRemove(vshControl *ctl, const vshCmd *cmd) return ret; } +/* + * "managedsave-edit" command + */ +static const vshCmdInfo info_managed_save_edit[] = { + {.name = "help", + .data = N_("edit XML for a domain's managed save state file") + }, + {.name = "desc", + .data = N_("Edit the domain XML associated with the managed save state file") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_managed_save_edit[] = { + VIRSH_COMMON_OPT_DOMAIN_FULL, + {.name = "running", + .type = VSH_OT_BOOL, + .help = N_("set domain to be running on start") + }, + {.name = "paused", + .type = VSH_OT_BOOL, + .help = N_("set domain to be paused on start") + }, + {.name = NULL} +}; + +static bool +cmdManagedSaveEdit(vshControl *ctl, const vshCmd *cmd) +{ + bool ret = false; + virDomainPtr dom = NULL; + unsigned int getxml_flags = VIR_DOMAIN_XML_SECURE; + unsigned int define_flags = 0; + + if (vshCommandOptBool(cmd, "running")) + define_flags |= VIR_DOMAIN_SAVE_RUNNING; + if (vshCommandOptBool(cmd, "paused")) + define_flags |= VIR_DOMAIN_SAVE_PAUSED; + + VSH_EXCLUSIVE_OPTIONS("running", "paused"); + + dom = virshCommandOptDomain(ctl, cmd, NULL); + if (dom == NULL) + goto cleanup; + +#define EDIT_GET_XML virDomainManagedSaveGetXMLDesc(dom, getxml_flags) +#define EDIT_NOT_CHANGED \ + do { \ + vshPrintExtra(ctl, _("Managed save image of domain %s XML configuration " \ + "not changed.\n"), virDomainGetName(dom)); \ + ret = true; \ + goto edit_cleanup; \ + } while (0) +#define EDIT_DEFINE \ + (virDomainManagedSaveDefineXML(dom, doc_edited, define_flags) == 0) +#include "virsh-edit.c" + + vshPrintExtra(ctl, _("Managed save image of Domain %s XML configuration edited.\n"), + virDomainGetName(dom)); + ret = true; + + cleanup: + virshDomainFree(dom); + return ret; +} + /* * "managedsave-dumpxml" command */ @@ -14006,6 +14072,12 @@ const vshCmdDef domManagementCmds[] = { .info = info_managedsaveremove, .flags = 0 }, + {.name = "managedsave-edit", + .handler = cmdManagedSaveEdit, + .opts = opts_managed_save_edit, + .info = info_managed_save_edit, + .flags = 0 + }, {.name = "managedsave-dumpxml", .handler = cmdManagedSaveDumpxml, .opts = opts_managed_save_dumpxml, diff --git a/tools/virsh.pod b/tools/virsh.pod index f7b05f803..c13f96f22 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1648,6 +1648,27 @@ Extract the domain XML that was in effect at the time the saved state file I<file> was created with the B<managedsave> command. Using I<--security-info> will also include security sensitive information. +=item B<managedsave-edit> I<domain> [{I<--running> | I<--paused>}] + +Edit the XML configuration associated with a saved state file of a +I<domain> was created by the B<managedsave> command. + +The managed save image records whether the domain should be started to a +running or paused state. Normally, this command does not alter the +recorded state; passing either the I<--running> or I<--paused> flag +will allow overriding which state the B<restore> should use. + +This is equivalent to: + + virsh managedsave-dumpxml domain-name > state-file.xml + vi state-file.xml (or make changes with your other text editor) + virsh managedsave-define domain-name state-file-xml + +except that it does some error checking. + +The editor used can be supplied by the C<$VISUAL> or C<$EDITOR> environment +variables, and defaults to C<vi>. + =item B<maxvcpus> [I<type>] Provide the maximum number of virtual CPUs supported for a guest VM on -- 2.14.1
participants (1)
-
Peter Krempa