| bool_entry "auto_dump_bypass_cache"
| bool_entry "auto_start_bypass_cache"
| int_entry "auto_start_delay"
+ | str_entry "auto_shutdown_try_save"
+ | str_entry "auto_shutdown_try_shutdown"
+ | str_entry "auto_shutdown_poweroff"
let process_entry = str_entry "hugetlbfs_mount"
| str_entry "bridge_helper"
#
#auto_start_delay = 0
+# The settings for auto shutdown actions accept one of
+# four possible options:
+#
+# * "none" - do not try to save any running VMs
+# * "persistent" - only try to save persistent running VMs
+# * "transient" - only try to save transient running VMs
+# * "all" - try to save all running VMs
+
+# Whether to perform managed save of running VMs if a host OS
+# shutdown is requested (system/session daemons), or the desktop
+# session terminates (session daemon only).
+#
+# Defaults to "persistent" for session daemons and "none"
+# for system daemons. The values "all" and "transient" are
+# not permitted for this setting, since managed save is not
+# implemented for transient VMs.
+#
+# If 'libvirt-guests.service' is enabled, then this must be
+# set to 'none' for system daemons to avoid dueling actions
+#auto_shutdown_try_save = "persistent"
+
+# As above, but with a graceful shutdown action instead of
+# managed save. If managed save is enabled, shutdown will
+# be tried only on failure to perform managed save.
+#
+# Defaults to "none"
+#
+# If 'libvirt-guests.service' is enabled, then this must be
+# set to 'none' for system daemons to avoid dueling actions
+#auto_shutdown_try_shutdown = "none"
+
+# As above, but with a forced poweroff instead of managed
+# save. If managed save or graceful shutdown are enabled,
+# forced poweroff will be tried only on failure of the
+# other options.
+#
+# Defaults to "none"
+#
+# If 'libvirt-guests.service' is enabled, then this must be
+# set to 'none' for system daemons to avoid dueling actions
+#auto_shutdown_poweroff = "none"
+
# If provided by the host and a hugetlbfs mount point is configured,
# a guest may request huge page backing. When this mount point is
# unspecified here, determination of a host mount point in /proc/mounts
cfg->dumpGuestCore = true;
#endif
+ if (privileged) {
+ /*
+ * Defer to libvirt-guests.service.
+ *
+ * XXX, or query if libvirt-guests.service is enabled perhaps ?
+ */
+ cfg->autoShutdownTrySave = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE;
+ cfg->autoShutdownTryShutdown = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE;
+ cfg->autoShutdownPoweroff = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE;
+ } else {
+ cfg->autoShutdownTrySave = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT;
+ cfg->autoShutdownTryShutdown = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE;
+ cfg->autoShutdownPoweroff = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE;
+ }
+
return g_steal_pointer(&cfg);
}
g_autofree char *savestr = NULL;
g_autofree char *dumpstr = NULL;
g_autofree char *snapstr = NULL;
+ g_autofree char *autoShutdownTrySave = NULL;
+ g_autofree char *autoShutdownTryShutdown = NULL;
+ g_autofree char *autoShutdownPoweroff = NULL;
+ int autoShutdownVal;
if (virConfGetValueString(conf, "save_image_format", &savestr) < 0)
return -1;
return -1;
if (virConfGetValueUInt(conf, "auto_start_delay", &cfg->autoStartDelayMS) < 0)
return -1;
+ if (virConfGetValueString(conf, "auto_shutdown_try_save", &autoShutdownTrySave) < 0)
+ return -1;
+
+ if (autoShutdownTrySave != NULL) {
+ if ((autoShutdownVal =
+ virDomainDriverAutoShutdownScopeTypeFromString(autoShutdownTrySave)) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("unknown auto_shutdown_try_save '%1$s'"),
+ autoShutdownTrySave);
+ return -1;
+ }
+ cfg->autoShutdownTrySave = autoShutdownVal;
+ }
+
+ if (cfg->autoShutdownTrySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_ALL ||
+ cfg->autoShutdownTrySave == VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_TRANSIENT) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("managed save cannot be requested for transient domains"));
+ return -1;
+ }
+
+ if (virConfGetValueString(conf, "auto_shutdown_try_shutdown", &autoShutdownTryShutdown) < 0)
+ return -1;
+
+ if (autoShutdownTryShutdown != NULL) {
+ if ((autoShutdownVal =
+ virDomainDriverAutoShutdownScopeTypeFromString(autoShutdownTryShutdown)) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("unknown auto_shutdown_try_shutdown '%1$s'"),
+ autoShutdownTryShutdown);
+ return -1;
+ }
+ cfg->autoShutdownTryShutdown = autoShutdownVal;
+ }
+
+ if (virConfGetValueString(conf, "auto_shutdown_poweroff", &autoShutdownPoweroff) < 0)
+ return -1;
+
+ if (autoShutdownPoweroff != NULL) {
+ if ((autoShutdownVal =
+ virDomainDriverAutoShutdownScopeTypeFromString(autoShutdownPoweroff)) < 0) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("unknown auto_shutdown_poweroff '%1$s'"),
+ autoShutdownPoweroff);
+ return -1;
+ }
+ cfg->autoShutdownPoweroff = autoShutdownVal;
+ }
return 0;
}
#include "virfilecache.h"
#include "virfirmware.h"
#include "virinhibitor.h"
+#include "domain_driver.h"
#define QEMU_DRIVER_NAME "QEMU"
bool autoDumpBypassCache;
bool autoStartBypassCache;
unsigned int autoStartDelayMS;
+ virDomainDriverAutoShutdownScope autoShutdownTrySave;
+ virDomainDriverAutoShutdownScope autoShutdownTryShutdown;
+ virDomainDriverAutoShutdownScope autoShutdownPoweroff;
char *lockManagerName;
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(qemu_driver);
virDomainDriverAutoShutdownConfig ascfg = {
.uri = cfg->uri,
- .trySave = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_PERSISTENT,
- .tryShutdown = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE,
- .poweroff = VIR_DOMAIN_DRIVER_AUTO_SHUTDOWN_SCOPE_NONE
+ .trySave = cfg->autoShutdownTrySave,
+ .tryShutdown = cfg->autoShutdownTryShutdown,
+ .poweroff = cfg->autoShutdownPoweroff,
};
- if (!qemu_driver->privileged)
- virDomainDriverAutoShutdown(&ascfg);
+ virDomainDriverAutoShutdown(&ascfg);
return 0;
}
{ "auto_dump_bypass_cache" = "0" }
{ "auto_start_bypass_cache" = "0" }
{ "auto_start_delay" = "0" }
+{ "auto_shutdown_try_save" = "persistent" }
+{ "auto_shutdown_try_shutdown" = "none" }
+{ "auto_shutdown_poweroff" = "none" }
{ "hugetlbfs_mount" = "/dev/hugepages" }
{ "bridge_helper" = "qemu-bridge-helper" }
{ "set_process_name" = "1" }