[libvirt] [PATCH v3] xml: print uuids in the warning

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

On 10/29/12 13:15, Ján Tomko wrote:
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/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;
For now, this second check is not really needed as you always pass the UUID that is safe, but it doesn't hurt to check anyways if somebody would like to use this helper somewhere else.
+ 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";
Hm, I don't like formatting of these strings. I'll send a follow-up to clean this up as it's not caused by you.
- if (fd < 0 || !name || !cmd) { + if (fd < 0 || !cmd) { errno = EINVAL; return -1; }
ACK && pushed. Peter
participants (2)
-
Ján Tomko
-
Peter Krempa