diff --git a/libvirt.spec.in b/libvirt.spec.in index e08c9e7aeb..5d8a9d40df 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1592,6 +1592,11 @@ rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.qemu rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/lxc.conf rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.lxc %endif +%if ! %{with_libxl} +rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/libvirt/libxl.conf +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_libxl.aug +rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.aug +%endif %if ! %{with_uml} rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.uml %endif @@ -1997,9 +2002,12 @@ exit 0 %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/uml/ %endif %if %{with_libxl} +%config(noreplace) %{_sysconfdir}/libvirt/libxl.conf %dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/libxl/ %ghost %dir %{_localstatedir}/run/libvirt/libxl/ %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/libxl/ +%{_datadir}/augeas/lenses/libvirtd_libxl.aug +%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.aug %endif %if %{with_xen} %dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/xen/ diff --git a/src/Makefile.am b/src/Makefile.am index 3c9eac6bc4..9a5f16cb9e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1222,7 +1222,15 @@ libvirt_driver_libxl_impl_la_CFLAGS = \ libvirt_driver_libxl_impl_la_LDFLAGS = $(AM_LDFLAGS) libvirt_driver_libxl_impl_la_LIBADD = $(LIBXL_LIBS) libvirt_xenconfig.la libvirt_driver_libxl_impl_la_SOURCES = $(LIBXL_DRIVER_SOURCES) + +conf_DATA += libxl/libxl.conf +augeas_DATA += libxl/libvirtd_libxl.aug +augeastest_DATA += test_libvirtd_libxl.aug +CLEANFILES += test_libvirtd_libxl.aug + endif WITH_LIBXL +EXTRA_DIST += libxl/libxl.conf libxl/libvirtd_libxl.aug \ + libxl/test_libvirtd_libxl.aug.in if WITH_QEMU noinst_LTLIBRARIES += libvirt_driver_qemu_impl.la @@ -1785,10 +1793,11 @@ check-local: check-augeas check-augeas-lxc \ check-augeas-sanlock \ check-augeas-lockd \ + check-augeas-libxl \ $(NULL) check-augeas: check-augeas-qemu check-augeas-lxc check-augeas-sanlock \ - check-augeas-lockd check-augeas-virtlockd + check-augeas-lockd check-augeas-virtlockd check-augeas-libxl AUG_GENTEST = $(PERL) $(top_srcdir)/build-aux/augeas-gentest.pl EXTRA_DIST += $(top_srcdir)/build-aux/augeas-gentest.pl @@ -1858,6 +1867,19 @@ check-augeas-virtlockd: test_virtlockd.aug '$(AUGPARSE)' -I $(srcdir)/locking test_virtlockd.aug; \ fi +if WITH_LIBXL +test_libvirtd_libxl.aug: libxl/test_libvirtd_libxl.aug.in \ + $(srcdir)/libxl/libxl.conf $(AUG_GENTEST) + $(AM_V_GEN)$(AUG_GENTEST) $(srcdir)/libxl/libxl.conf $< $@ + +check-augeas-libxl: test_libvirtd_libxl.aug + $(AM_V_GEN)if test -x '$(AUGPARSE)'; then \ + '$(AUGPARSE)' -I $(srcdir)/libxl test_libvirtd_libxl.aug; \ + fi +else ! WITH_LIBXL +check-augeas-libxl: +endif ! WITH_LIBXL + # # Build our version script. This is composed of three parts: # diff --git a/src/libxl/libvirtd_libxl.aug b/src/libxl/libvirtd_libxl.aug new file mode 100644 index 0000000000..f225954ac4 --- /dev/null +++ b/src/libxl/libvirtd_libxl.aug @@ -0,0 +1,42 @@ +(* /etc/libvirt/libxl.conf *) + +module Libvirtd_libxl = + autoload xfm + + let eol = del /[ \t]*\n/ "\n" + let value_sep = del /[ \t]*=[ \t]*/ " = " + let indent = del /[ \t]*/ "" + + let array_sep = del /,[ \t\n]*/ ", " + let array_start = del /\[[ \t\n]*/ "[ " + let array_end = del /\]/ "]" + + let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\"" + let bool_val = store /0|1/ + let int_val = store /[0-9]+/ + let str_array_element = [ seq "el" . str_val ] . del /[ \t\n]*/ "" + let str_array_val = counter "el" . array_start . ( str_array_element . ( array_sep . str_array_element ) * ) ? . array_end + + let str_entry (kw:string) = [ key kw . value_sep . str_val ] + let bool_entry (kw:string) = [ key kw . value_sep . bool_val ] + let int_entry (kw:string) = [ key kw . value_sep . int_val ] + let str_array_entry (kw:string) = [ key kw . value_sep . str_array_val ] + + + (* Config entry grouped by function - same order as example config *) + let autoballoon_entry = bool_entry "autoballoon" + + (* Each entry in the config is one of the following ... *) + let entry = autoballoon_entry + + let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ] + let empty = [ label "#empty" . eol ] + + let record = indent . entry . eol + + let lns = ( record | comment | empty ) * + + let filter = incl "/etc/libvirt/libxl.conf" + . Util.stdexcl + + let xfm = transform lns filter diff --git a/src/libxl/libxl.conf b/src/libxl/libxl.conf new file mode 100644 index 0000000000..c104d402b3 --- /dev/null +++ b/src/libxl/libxl.conf @@ -0,0 +1,12 @@ +# Master configuration file for the libxl driver. +# All settings described here are optional. If omitted, sensible +# defaults are used. + +# Enable autoballooning of domain0 +# +# By default, autoballooning of domain0 is enabled unless its memory +# is already limited with Xen's "dom0_mem=" parameter, in which case +# autoballooning is disabled. Override the default behavior with the +# autoballoon setting. +# +#autoballoon = 1 diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index a39c977993..1b504faf2d 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -35,6 +35,7 @@ #include "virlog.h" #include "virerror.h" #include "datatypes.h" +#include "virconf.h" #include "virfile.h" #include "virstring.h" #include "viralloc.h" @@ -1348,12 +1349,33 @@ libxlMakeVfbList(virPortAllocatorPtr graphicsports, return -1; } +/* + * Get domain0 autoballoon configuration. Honor user-specified + * setting in libxl.conf first. If not specified, autoballooning + * is disabled when domain0's memory is set with 'dom0_mem'. + * Otherwise autoballooning is enabled. + */ static int -libxlGetAutoballoonConf(libxlDriverConfigPtr cfg, bool *autoballoon) +libxlGetAutoballoonConf(libxlDriverConfigPtr cfg, + virConfPtr conf) { + virConfValuePtr p; regex_t regex; int res; + p = virConfGetValue(conf, "autoballoon"); + if (p) { + if (p->type != VIR_CONF_ULONG) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", + _("Unexpected type for 'autoballoon' setting")); + + return -1; + } + cfg->autoballoon = p->l != 0; + return 0; + } + if ((res = regcomp(®ex, "(^| )dom0_mem=((|min:|max:)[0-9]+[bBkKmMgG]?,?)+($| )", REG_NOSUB | REG_EXTENDED)) != 0) { @@ -1368,7 +1390,7 @@ libxlGetAutoballoonConf(libxlDriverConfigPtr cfg, bool *autoballoon) res = regexec(®ex, cfg->verInfo->commandline, 0, NULL, 0); regfree(®ex); - *autoballoon = res == REG_NOMATCH; + cfg->autoballoon = res == REG_NOMATCH; return 0; } @@ -1386,6 +1408,8 @@ libxlDriverConfigNew(void) if (!(cfg = virObjectNew(libxlDriverConfigClass))) return NULL; + if (VIR_STRDUP(cfg->configBaseDir, LIBXL_CONFIG_BASE_DIR) < 0) + goto error; if (VIR_STRDUP(cfg->configDir, LIBXL_CONFIG_DIR) < 0) goto error; if (VIR_STRDUP(cfg->autostartDir, LIBXL_AUTOSTART_DIR) < 0) @@ -1448,10 +1472,6 @@ libxlDriverConfigNew(void) goto error; } - /* setup autoballoon */ - if (libxlGetAutoballoonConf(cfg, &cfg->autoballoon) < 0) - goto error; - return cfg; error: @@ -1471,6 +1491,35 @@ libxlDriverConfigGet(libxlDriverPrivatePtr driver) return cfg; } +int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg, + const char *filename) +{ + virConfPtr conf = NULL; + int ret = -1; + + /* Check the file is readable before opening it, otherwise + * libvirt emits an error. + */ + if (access(filename, R_OK) == -1) { + VIR_INFO("Could not read libxl config file %s", filename); + return 0; + } + + if (!(conf = virConfReadFile(filename, 0))) + goto cleanup; + + /* setup autoballoon */ + if (libxlGetAutoballoonConf(cfg, conf) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virConfFree(conf); + return ret; + +} + int libxlMakePCI(virDomainHostdevDefPtr hostdev, libxl_device_pci *pcidev) { diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index 59389d1296..5ba1a71ec6 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -46,6 +46,7 @@ # define LIBXL_MIGRATION_PORT_MIN 49152 # define LIBXL_MIGRATION_PORT_MAX 49216 +# define LIBXL_CONFIG_BASE_DIR SYSCONFDIR "/libvirt" # define LIBXL_CONFIG_DIR SYSCONFDIR "/libvirt/libxl" # define LIBXL_AUTOSTART_DIR LIBXL_CONFIG_DIR "/autostart" # define LIBXL_STATE_DIR LOCALSTATEDIR "/run/libvirt/libxl" @@ -100,6 +101,7 @@ struct _libxlDriverConfig { /* Once created, caps are immutable */ virCapsPtr caps; + char *configBaseDir; char *configDir; char *autostartDir; char *logDir; @@ -167,6 +169,9 @@ int libxlDriverNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info); +int libxlDriverConfigLoadFile(libxlDriverConfigPtr cfg, + const char *filename); + virCapsPtr libxlMakeCapabilities(libxl_ctx *ctx); diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 725442889b..6a54c739b8 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -504,6 +504,7 @@ libxlStateInitialize(bool privileged, void *opaque ATTRIBUTE_UNUSED) { libxlDriverConfigPtr cfg; + char *driverConf = NULL; char ebuf[1024]; if (!libxlDriverShouldLoad(privileged)) @@ -543,6 +544,13 @@ libxlStateInitialize(bool privileged, if (!(cfg = libxlDriverConfigNew())) goto error; + if (virAsprintf(&driverConf, "%s/libxl.conf", cfg->configBaseDir) < 0) + goto error; + + if (libxlDriverConfigLoadFile(cfg, driverConf) < 0) + goto error; + VIR_FREE(driverConf); + /* Register the callbacks providing access to libvirt's event loop */ libxl_osevent_register_hooks(cfg->ctx, &libxl_osevent_callbacks, cfg->ctx); @@ -626,6 +634,7 @@ libxlStateInitialize(bool privileged, return 0; error: + VIR_FREE(driverConf); libxlStateCleanup(); return -1; } diff --git a/src/libxl/test_libvirtd_libxl.aug.in b/src/libxl/test_libvirtd_libxl.aug.in new file mode 100644 index 0000000000..23e667c025 --- /dev/null +++ b/src/libxl/test_libvirtd_libxl.aug.in @@ -0,0 +1,5 @@ +module Test_libvirtd_libxl = + ::CONFIG:: + + test Libvirtd_libxl.lns get conf = +{ "autoballoon" = "1" }