diff --git a/lib/constants.py b/lib/constants.py index ea8f408fe09e0750e697cbcbd685feb6764f41bc..52e875fcdd3226dee26cee73eb0eccde6dbc3367 100644 --- a/lib/constants.py +++ b/lib/constants.py @@ -590,9 +590,20 @@ INSTANCE_REBOOT_SOFT = "soft" INSTANCE_REBOOT_HARD = "hard" INSTANCE_REBOOT_FULL = "full" -REBOOT_TYPES = frozenset([INSTANCE_REBOOT_SOFT, - INSTANCE_REBOOT_HARD, - INSTANCE_REBOOT_FULL]) +REBOOT_TYPES = frozenset([ + INSTANCE_REBOOT_SOFT, + INSTANCE_REBOOT_HARD, + INSTANCE_REBOOT_FULL + ]) + +# instance reboot behaviors +INSTANCE_REBOOT_ALLOWED = "reboot" +INSTANCE_REBOOT_EXIT = "exit" + +REBOOT_BEHAVIORS = frozenset([ + INSTANCE_REBOOT_ALLOWED, + INSTANCE_REBOOT_EXIT + ]) VTYPE_STRING = "string" VTYPE_MAYBE_STRING = "maybe-string" @@ -648,6 +659,7 @@ HV_KVM_USE_CHROOT = "use_chroot" HV_CPU_MASK = "cpu_mask" HV_MEM_PATH = "mem_path" HV_BLOCKDEV_PREFIX = "blockdev_prefix" +HV_REBOOT_BEHAVIOR = "reboot_behavior" HVS_PARAMETER_TYPES = { HV_BOOT_ORDER: VTYPE_STRING, @@ -690,6 +702,7 @@ HVS_PARAMETER_TYPES = { HV_CPU_MASK: VTYPE_STRING, HV_MEM_PATH: VTYPE_STRING, HV_BLOCKDEV_PREFIX: VTYPE_STRING, + HV_REBOOT_BEHAVIOR: VTYPE_STRING, } HVS_PARAMETERS = frozenset(HVS_PARAMETER_TYPES.keys()) @@ -1178,6 +1191,7 @@ HVC_DEFAULTS = { HV_MIGRATION_PORT: 8002, HV_MIGRATION_MODE: HT_MIGRATION_LIVE, HV_BLOCKDEV_PREFIX: "sd", + HV_REBOOT_BEHAVIOR: INSTANCE_REBOOT_ALLOWED, }, HT_XEN_HVM: { HV_BOOT_ORDER: "cd", @@ -1194,6 +1208,7 @@ HVC_DEFAULTS = { HV_MIGRATION_MODE: HT_MIGRATION_NONLIVE, HV_USE_LOCALTIME: False, HV_BLOCKDEV_PREFIX: "hd", + HV_REBOOT_BEHAVIOR: INSTANCE_REBOOT_ALLOWED, }, HT_KVM: { HV_KERNEL_PATH: "/boot/vmlinuz-2.6-kvmU", @@ -1228,6 +1243,7 @@ HVC_DEFAULTS = { HV_VHOST_NET: False, HV_KVM_USE_CHROOT: False, HV_MEM_PATH: "", + HV_REBOOT_BEHAVIOR: INSTANCE_REBOOT_ALLOWED, }, HT_FAKE: { }, diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py index b11bf4cf59dca54e9b18129721d1680a25fb4577..1b95d6d5baa208ca12779f38787b6971ecabc351 100644 --- a/lib/hypervisor/hv_kvm.py +++ b/lib/hypervisor/hv_kvm.py @@ -194,6 +194,8 @@ class KVMHypervisor(hv_base.BaseHypervisor): constants.HV_VHOST_NET: hv_base.NO_CHECK, constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK, constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK, + constants.HV_REBOOT_BEHAVIOR: + hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS) } _MIGRATION_STATUS_RE = re.compile("Migration\s+status:\s+(\w+)", @@ -535,6 +537,9 @@ class KVMHypervisor(hv_base.BaseHypervisor): kvm_cmd.extend(["-no-acpi"]) if startup_paused: kvm_cmd.extend(["-S"]) + if instance.hvparams[constants.HV_REBOOT_BEHAVIOR] == \ + constants.INSTANCE_REBOOT_EXIT: + kvm_cmd.extend(["-no-reboot"]) hvp = instance.hvparams boot_disk = hvp[constants.HV_BOOT_ORDER] == constants.HT_BO_DISK diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py index 7693bead17b2f89227823d2bf38443e86eb806aa..923c3910d475b50374bf150b08449618ab432a42 100644 --- a/lib/hypervisor/hv_xen.py +++ b/lib/hypervisor/hv_xen.py @@ -470,6 +470,8 @@ class XenPvmHypervisor(XenHypervisor): constants.HV_MIGRATION_MODE: hv_base.MIGRATION_MODE_CHECK, # TODO: Add a check for the blockdev prefix (matching [a-z:] or similar). constants.HV_BLOCKDEV_PREFIX: hv_base.NO_CHECK, + constants.HV_REBOOT_BEHAVIOR: + hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS) } @classmethod @@ -529,7 +531,10 @@ class XenPvmHypervisor(XenHypervisor): if hvp[constants.HV_ROOT_PATH]: config.write("root = '%s'\n" % hvp[constants.HV_ROOT_PATH]) config.write("on_poweroff = 'destroy'\n") - config.write("on_reboot = 'restart'\n") + if hvp[constants.HV_REBOOT_BEHAVIOR] == constants.INSTANCE_REBOOT_ALLOWED: + config.write("on_reboot = 'restart'\n") + else: + config.write("on_reboot = 'destroy'\n") config.write("on_crash = 'restart'\n") config.write("extra = '%s'\n" % hvp[constants.HV_KERNEL_ARGS]) # just in case it exists @@ -574,6 +579,8 @@ class XenHvmHypervisor(XenHypervisor): constants.HV_USE_LOCALTIME: hv_base.NO_CHECK, # TODO: Add a check for the blockdev prefix (matching [a-z:] or similar). constants.HV_BLOCKDEV_PREFIX: hv_base.NO_CHECK, + constants.HV_REBOOT_BEHAVIOR: + hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS) } @classmethod @@ -666,7 +673,10 @@ class XenHvmHypervisor(XenHypervisor): config.write("disk = [%s]\n" % (",".join(disk_data))) config.write("on_poweroff = 'destroy'\n") - config.write("on_reboot = 'restart'\n") + if hvp[constants.HV_REBOOT_BEHAVIOR] == constants.INSTANCE_REBOOT_ALLOWED: + config.write("on_reboot = 'restart'\n") + else: + config.write("on_reboot = 'destroy'\n") config.write("on_crash = 'restart'\n") # just in case it exists utils.RemoveFile("/etc/xen/auto/%s" % instance.name) diff --git a/man/gnt-instance.rst b/man/gnt-instance.rst index f5233dfb8b4dc896f419c0ef9dfb0088aea25da9..afc0ad94acbb9a9805d93e7d8860a200c74cf169 100644 --- a/man/gnt-instance.rst +++ b/man/gnt-instance.rst @@ -439,6 +439,15 @@ keymap This option specifies the keyboard mapping to be used. It is only needed when using the VNC console. For example: "fr" or "en-gb". +reboot\_behavior + Valid for Xen PVM, Xen HVM and KVM hypervisors. + + Normally if an instance reboots, the hypervisor will restart it. If + this option is set to ``exit``, the hypervisor will treat a reboot + as a shutdown instead. + + It is set to ``reboot`` by default. + The ``-O (--os-parameters)`` option allows customisation of the OS parameters. The actual parameter names and values depends on the OS