Introduce a new config option 'xml_validator' into the daemon config
file which will allow users to make libvirt daemons use a custom XML
validator.
The rationale is that validators such as 'jing'[1] provide drastically
better error specification when compared to the native libxml2 validator
we use. A drawback though is that jing is written in Java and thus
unusable by libvirt directly and also not a popular package present in
distros.
For power users and developers it still is worth having this feature to
provide better errors in a native way.
An example showing the quality of the errors:
XML used:
<vcpu placement='static' current='1'>asdf8</vcpu>
native validator:
error: XML document failed to validate against schema: Unable to validate doc against
/home/pipo/libvirt/src/conf/schemas/domain.rng
Extra element vcpu in interleave
Invalid sequence in interleave
Element domain failed to validate content
jing:
error: XML document failed to validate against schema: Unable to validate doc against
/home/pipo/libvirt/src/conf/schemas/domain.rng
/dev/stdin:6:52: error: character content of element "vcpu" invalid; must be
an integer
Example script to make this feature work with jing:
#!/bin/bash
java -jar /home/pipo/git/jing-trang/build/jing.jar $1 /dev/stdin 2>&1 || exit 1
[1]
https://github.com/relaxng/jing-trang
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/remote/libvirtd.aug.in | 1 +
src/remote/libvirtd.conf.in | 21 +++++++++++++++++++++
src/remote/remote_daemon.c | 3 +++
src/remote/remote_daemon_config.c | 4 ++++
src/remote/remote_daemon_config.h | 2 ++
src/remote/test_libvirtd.aug.in | 1 +
6 files changed, 32 insertions(+)
diff --git a/src/remote/libvirtd.aug.in b/src/remote/libvirtd.aug.in
index d744548f41..9a15eb14e5 100644
--- a/src/remote/libvirtd.aug.in
+++ b/src/remote/libvirtd.aug.in
@@ -91,6 +91,7 @@ module @DAEMON_NAME_UC@ =
let misc_entry = str_entry "host_uuid"
| str_entry "host_uuid_source"
| int_entry "ovs_timeout"
+ | str_entry "xml_validator"
(* Each entry in the config is one of the following three ... *)
let entry = sock_acl_entry
diff --git a/src/remote/libvirtd.conf.in b/src/remote/libvirtd.conf.in
index 80a98b1529..5cfe0c0918 100644
--- a/src/remote/libvirtd.conf.in
+++ b/src/remote/libvirtd.conf.in
@@ -541,3 +541,24 @@
# potential infinite waits blocking libvirt.
#
#ovs_timeout = 5
+
+###################################################################
+# Custom XML validator
+#
+# The following option instructs @DAEMON_NAME@ to use a custom
+# XML validator binary or script before invoking the default
+# validator from libxml2.
+#
+# The custom validator is called using following arguments.
+#
+# /path/to/validator /path/to/schema.rng
+#
+# The actual XML file is provided on the standard input of the process.
+# If the validation fails the process is expected to return a non-zero exit
+# code. The standard output and standard error output are used as error message
+# provided back to the user.
+#
+# Note that the XMLs sent for validation may contain security sensitive
+# information.
+#
+#xml_validator = "/path/to/validator"
diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c
index f369d09d35..cbbf81e141 100644
--- a/src/remote/remote_daemon.c
+++ b/src/remote/remote_daemon.c
@@ -936,6 +936,9 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
+ if (config->xml_validator)
+ virXMLParseSetCustomValidator(config->xml_validator);
+
/* Let's try to initialize global variable that holds the host's boot time.
*/
if (virHostBootTimeInit() < 0) {
/* This is acceptable failure. Maybe we won't need the boot time
diff --git a/src/remote/remote_daemon_config.c b/src/remote/remote_daemon_config.c
index 3567e337c4..affafa2a86 100644
--- a/src/remote/remote_daemon_config.c
+++ b/src/remote/remote_daemon_config.c
@@ -219,6 +219,7 @@ daemonConfigFree(struct daemonConfig *data)
g_free(data->host_uuid_source);
g_free(data->log_filters);
g_free(data->log_outputs);
+ g_free(data->xml_validator);
g_free(data);
}
@@ -380,6 +381,9 @@ daemonConfigLoadOptions(struct daemonConfig *data,
if (virConfGetValueUInt(conf, "ovs_timeout", &data->ovs_timeout)
< 0)
return -1;
+ if (virConfGetValueString(conf, "xml_validator",
&data->xml_validator) < 0)
+ return -1;
+
return 0;
}
diff --git a/src/remote/remote_daemon_config.h b/src/remote/remote_daemon_config.h
index 9f9e54e838..4bc8bce90f 100644
--- a/src/remote/remote_daemon_config.h
+++ b/src/remote/remote_daemon_config.h
@@ -96,6 +96,8 @@ struct daemonConfig {
unsigned int admin_keepalive_count;
unsigned int ovs_timeout;
+
+ char *xml_validator;
};
diff --git a/src/remote/test_libvirtd.aug.in b/src/remote/test_libvirtd.aug.in
index c27680e130..eedc3af24d 100644
--- a/src/remote/test_libvirtd.aug.in
+++ b/src/remote/test_libvirtd.aug.in
@@ -67,3 +67,4 @@ module Test_@DAEMON_NAME@ =
{ "admin_keepalive_interval" = "5" }
{ "admin_keepalive_count" = "5" }
{ "ovs_timeout" = "5" }
+ { "xml_validator" = "/path/to/validator" }
--
2.37.1