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@xxxxxxxxxx> --- 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