"""
utils.RemoveFile("/etc/xen/%s" % instance_name)
+ @classmethod
+ def _CreateConfigCpus(cls, cpu_mask):
+ """Create a CPU config string that's compatible with Xen's
+ configuration file.
+
+ """
+ # Convert the string CPU mask to a list of list of int's
+ cpu_list = utils.ParseMultiCpuMask(cpu_mask)
+
+ if len(cpu_list) == 1:
+ all_cpu_mapping = cpu_list[0]
+ if all_cpu_mapping == constants.CPU_PINNING_OFF:
+ # If CPU pinning has 1 entry that's "all", then remove the
+ # parameter from the config file
+ return None
+ else:
+ # If CPU pinning has one non-all entry, mapping all vCPUS (the entire
+ # VM) to one physical CPU, using format 'cpu = "C"'
+ return "cpu = \"%s\"" % ",".join(map(str, all_cpu_mapping))
+ else:
+ def _GetCPUMap(vcpu):
+ if vcpu[0] == constants.CPU_PINNING_ALL_VAL:
+ cpu_map = constants.CPU_PINNING_ALL_XEN
+ else:
+ cpu_map = ",".join(map(str, vcpu))
+ return "\"%s\"" % cpu_map
+
+ # build the result string in format 'cpus = [ "c", "c", "c" ]',
+ # where each c is a physical CPU number, a range, a list, or any
+ # combination
+ return "cpus = [ %s ]" % ", ".join(map(_GetCPUMap, cpu_list))
+
@staticmethod
def _RunXmList(xmlist_errors):
"""Helper function for L{_GetXMList} to run "xm list".
"""
pass
- def FinalizeMigration(self, instance, info, success):
+ def FinalizeMigrationDst(self, instance, info, success):
"""Finalize an instance migration.
After a successful migration we write the xen config file.
if result.failed:
raise errors.HypervisorError("Failed to migrate instance %s: %s" %
(instance.name, result.output))
- # remove old xen file after migration succeeded
- try:
- self._RemoveConfigFile(instance.name)
- except EnvironmentError:
- logging.exception("Failure while removing instance config file")
+
+ def FinalizeMigrationSource(self, instance, success, live):
+ """Finalize the instance migration on the source node.
+
+ @type instance: L{objects.Instance}
+ @param instance: the instance that was migrated
+ @type success: bool
+ @param success: whether the migration succeeded or not
+ @type live: bool
+ @param live: whether the user requested a live migration or not
+
+ """
+ # pylint: disable=W0613
+ if success:
+ # remove old xen file after migration succeeded
+ try:
+ self._RemoveConfigFile(instance.name)
+ except EnvironmentError:
+ logging.exception("Failure while removing instance config file")
+
+ def GetMigrationStatus(self, instance):
+ """Get the migration status
+
+ As MigrateInstance for Xen is still blocking, if this method is called it
+ means that MigrateInstance has completed successfully. So we can safely
+ assume that the migration was successful and notify this fact to the client.
+
+ @type instance: L{objects.Instance}
+ @param instance: the instance that is being migrated
+ @rtype: L{objects.MigrationStatus}
+ @return: the status of the current migration (one of
+ L{constants.HV_MIGRATION_VALID_STATUSES}), plus any additional
+ progress info that can be retrieved from the hypervisor
+
+ """
+ return objects.MigrationStatus(status=constants.HV_MIGRATION_COMPLETED)
@classmethod
def PowercycleNode(cls):
# 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)
+ hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
+ constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
}
@classmethod
# rest of the settings
config.write("memory = %d\n" % instance.beparams[constants.BE_MEMORY])
config.write("vcpus = %d\n" % instance.beparams[constants.BE_VCPUS])
+ cpu_pinning = cls._CreateConfigCpus(hvp[constants.HV_CPU_MASK])
+ if cpu_pinning:
+ config.write("%s\n" % cpu_pinning)
+
config.write("name = '%s'\n" % instance.name)
vif_data = []
# 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)
+ hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
+ constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
}
@classmethod
config.write("builder = 'hvm'\n")
config.write("memory = %d\n" % instance.beparams[constants.BE_MEMORY])
config.write("vcpus = %d\n" % instance.beparams[constants.BE_VCPUS])
+ cpu_pinning = cls._CreateConfigCpus(hvp[constants.HV_CPU_MASK])
+ if cpu_pinning:
+ config.write("%s\n" % cpu_pinning)
+
config.write("name = '%s'\n" % instance.name)
if hvp[constants.HV_PAE]:
config.write("pae = 1\n")