In the XML warning, we print a virsh command line that can be used to edit that XML. This patch prints UUIDs if the entity name contains special characters (like shell metacharacters, or "--" that would break parsing of the XML comment). If the entity doesn't have a UUID, just print the virsh command that can be used to edit it. --- As opposed to previous versions, this doesn't use virBuffer and it doesn't do any shell escaping at all. The name parameter can be null now. commit 9b704ab8235af010b1fda4886201aab02098b969 xml: omit domain name from comment if it contains double hyphen only checked the 'name' parameter of virXMLEmitWarning. virXMLSaveFile invocation when creating a snapshot put the domain name in 'cmd', which means that snapshot XMLs of a domain with "--" in the name still can't be parsed by libvirt. --- src/conf/domain_conf.c | 6 +++++- src/conf/network_conf.c | 6 +++++- src/conf/nwfilter_conf.c | 12 ++++++++++-- src/conf/storage_conf.c | 6 +++++- src/libvirt_private.syms | 1 + src/parallels/parallels_storage.c | 3 +-- src/qemu/qemu_domain.c | 9 +-------- src/util/xml.c | 18 +++++++++++++----- src/util/xml.h | 1 + 9 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 90ec9aa..7bf0282 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14288,6 +14288,7 @@ int virDomainSaveXML(const char *configDir, virDomainDefPtr def, const char *xml) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; char *configFile = NULL; int ret = -1; @@ -14301,7 +14302,10 @@ int virDomainSaveXML(const char *configDir, goto cleanup; } - ret = virXMLSaveFile(configFile, def->name, "edit", xml); + virUUIDFormat(def->uuid, uuidstr); + ret = virXMLSaveFile(configFile, + virXMLPickShellSafeComment(def->name, uuidstr), "edit", + xml); cleanup: VIR_FREE(configFile); diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 8976f2a..a55339d 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1978,6 +1978,7 @@ int virNetworkSaveXML(const char *configDir, virNetworkDefPtr def, const char *xml) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; char *configFile = NULL; int ret = -1; @@ -1991,7 +1992,10 @@ int virNetworkSaveXML(const char *configDir, goto cleanup; } - ret = virXMLSaveFile(configFile, def->name, "net-edit", xml); + virUUIDFormat(def->uuid, uuidstr); + ret = virXMLSaveFile(configFile, + virXMLPickShellSafeComment(def->name, uuidstr), + "net-edit", xml); cleanup: VIR_FREE(configFile); diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c index 27dbee8..b6d5d40 100644 --- a/src/conf/nwfilter_conf.c +++ b/src/conf/nwfilter_conf.c @@ -2717,6 +2717,7 @@ int virNWFilterSaveXML(const char *configDir, virNWFilterDefPtr def, const char *xml) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; char *configFile = NULL; int ret = -1; @@ -2730,7 +2731,10 @@ int virNWFilterSaveXML(const char *configDir, goto cleanup; } - ret = virXMLSaveFile(configFile, def->name, "nwfilter-edit", xml); + virUUIDFormat(def->uuid, uuidstr); + ret = virXMLSaveFile(configFile, + virXMLPickShellSafeComment(def->name, uuidstr), + "nwfilter-edit", xml); cleanup: VIR_FREE(configFile); @@ -3151,6 +3155,7 @@ virNWFilterObjSaveDef(virNWFilterDriverStatePtr driver, virNWFilterObjPtr nwfilter, virNWFilterDefPtr def) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; char *xml; int ret; @@ -3174,7 +3179,10 @@ virNWFilterObjSaveDef(virNWFilterDriverStatePtr driver, return -1; } - ret = virXMLSaveFile(nwfilter->configFile, def->name, "nwfilter-edit", xml); + virUUIDFormat(def->uuid, uuidstr); + ret = virXMLSaveFile(nwfilter->configFile, + virXMLPickShellSafeComment(def->name, uuidstr), + "nwfilter-edit", xml); VIR_FREE(xml); return ret; diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 5d9e61a..9a765d8 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -1637,6 +1637,7 @@ virStoragePoolObjSaveDef(virStorageDriverStatePtr driver, virStoragePoolObjPtr pool, virStoragePoolDefPtr def) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; char *xml; int ret = -1; @@ -1666,7 +1667,10 @@ virStoragePoolObjSaveDef(virStorageDriverStatePtr driver, return -1; } - ret = virXMLSaveFile(pool->configFile, def->name, "pool-edit", xml); + virUUIDFormat(def->uuid, uuidstr); + ret = virXMLSaveFile(pool->configFile, + virXMLPickShellSafeComment(def->name, uuidstr), + "pool-edit", xml); VIR_FREE(xml); return ret; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8212726..02ca2c7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1819,6 +1819,7 @@ virURIParse; # xml.h virXMLChildElementCount; virXMLParseHelper; +virXMLPickShellSafeComment; virXMLPropString; virXMLSaveFile; virXPathBoolean; diff --git a/src/parallels/parallels_storage.c b/src/parallels/parallels_storage.c index 76d885c..71f3f89 100644 --- a/src/parallels/parallels_storage.c +++ b/src/parallels/parallels_storage.c @@ -973,8 +973,7 @@ parallelsStorageVolumeDefine(virStoragePoolObjPtr pool, if (!xml_path) goto cleanup; - if (virXMLSaveFile(xml_path, privvol->name, - "volume-create", xmldesc)) { + if (virXMLSaveFile(xml_path, NULL, "volume-create", xmldesc)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Can't create file with volume description")); goto cleanup; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4e6a5e9..d01e366 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1599,7 +1599,6 @@ qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm, char *snapDir = NULL; char *snapFile = NULL; char uuidstr[VIR_UUID_STRING_BUFLEN]; - char *tmp; virUUIDFormat(vm->def->uuid, uuidstr); newxml = virDomainSnapshotDefFormat(uuidstr, snapshot->def, @@ -1622,13 +1621,7 @@ qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm, goto cleanup; } - if (virAsprintf(&tmp, "snapshot-edit %s", vm->def->name) < 0) { - virReportOOMError(); - goto cleanup; - } - - ret = virXMLSaveFile(snapFile, snapshot->def->name, tmp, newxml); - VIR_FREE(tmp); + ret = virXMLSaveFile(snapFile, NULL, "snapshot-edit", newxml); cleanup: VIR_FREE(snapFile); diff --git a/src/util/xml.c b/src/util/xml.c index f3dc256..dad9227 100644 --- a/src/util/xml.c +++ b/src/util/xml.c @@ -780,6 +780,16 @@ error: goto cleanup; } +const char *virXMLPickShellSafeComment(const char *str1, const char *str2) +{ + if(str1 && !strpbrk(str1, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") && + !strstr(str1, "--")) + return str1; + if(str2 && !strpbrk(str2, "\r\t\n !\"#$&'()*;<>?[\\]^`{|}~") && + !strstr(str2, "--")) + return str2; + return NULL; +} static int virXMLEmitWarning(int fd, const char *name, @@ -794,7 +804,7 @@ OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:\n\ or other application using the libvirt API.\n\ -->\n\n"; - if (fd < 0 || !name || !cmd) { + if (fd < 0 || !cmd) { errno = EINVAL; return -1; } @@ -807,9 +817,7 @@ or other application using the libvirt API.\n\ if (safewrite(fd, cmd, len) != len) return -1; - /* Omit the domain name if it contains a double hyphen - * because they aren't allowed in XML comments */ - if (!strstr(name, "--")) { + if (name) { if (safewrite(fd, " ", 1) != 1) return -1; @@ -837,7 +845,7 @@ virXMLRewriteFile(int fd, void *opaque) { struct virXMLRewriteFileData *data = opaque; - if (data->warnName && data->warnCommand) { + if (data->warnCommand) { if (virXMLEmitWarning(fd, data->warnName, data->warnCommand) < 0) return -1; } diff --git a/src/util/xml.h b/src/util/xml.h index a3750fa..c3b05df 100644 --- a/src/util/xml.h +++ b/src/util/xml.h @@ -61,6 +61,7 @@ xmlDocPtr virXMLParseHelper(int domcode, const char *url, xmlXPathContextPtr *pctxt); +const char *virXMLPickShellSafeComment(const char *str1, const char *str2); /** * virXMLParse: * @filename: file to parse, or NULL for string parsing -- 1.7.8.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list