char *default_vifbackend = NULL;
char *default_remus_netbufscript = NULL;
char *default_colo_proxy_script = NULL;
+libxl_bitmap global_vm_affinity_mask;
+libxl_bitmap global_hvm_affinity_mask;
+libxl_bitmap global_pv_affinity_mask;
enum output_format default_output_format = OUTPUT_FORMAT_JSON;
int claim_mode = 1;
bool progress_use_cr = 0;
xlu_cfg_replace_string (config, "colo.default.proxyscript",
&default_colo_proxy_script, 0);
+ libxl_bitmap_init(&global_vm_affinity_mask);
+ libxl_cpu_bitmap_alloc(ctx, &global_vm_affinity_mask, 0);
+ libxl_bitmap_init(&global_hvm_affinity_mask);
+ libxl_cpu_bitmap_alloc(ctx, &global_hvm_affinity_mask, 0);
+ libxl_bitmap_init(&global_pv_affinity_mask);
+ libxl_cpu_bitmap_alloc(ctx, &global_pv_affinity_mask, 0);
+
+ if (!xlu_cfg_get_string (config, "vm.cpumask", &buf, 0))
+ cpurange_parse(buf, &global_vm_affinity_mask);
+ else
+ libxl_bitmap_set_any(&global_vm_affinity_mask);
+ if (!xlu_cfg_get_string (config, "vm.hvm.cpumask", &buf, 0))
+ cpurange_parse(buf, &global_hvm_affinity_mask);
+ else
+ libxl_bitmap_set_any(&global_hvm_affinity_mask);
+ if (!xlu_cfg_get_string (config, "vm.pv.cpumask", &buf, 0))
+ cpurange_parse(buf, &global_pv_affinity_mask);
+ else
+ libxl_bitmap_set_any(&global_pv_affinity_mask);
+
xlu_cfg_destroy(config);
}
int vncautopass;
int console_autoconnect;
int checkpointed_stream;
+ int ignore_global_affinity_masks;
const char *config_file;
char *extra_config; /* extra config string */
const char *restore_file;
* single cpus or as eintire NUMA nodes) and turns it into the
* corresponding libxl_bitmap (in cpumap).
*/
-static int cpurange_parse(const char *cpu, libxl_bitmap *cpumap)
+int cpurange_parse(const char *cpu, libxl_bitmap *cpumap)
{
char *ptr, *saveptr = NULL, *buf = xstrdup(cpu);
int rc = 0;
parse_config_data(config_source, config_data, config_len, &d_config);
}
+ if (!dom_info->ignore_global_affinity_masks) {
+ libxl_domain_build_info *b_info = &d_config.b_info;
+
+ /* It is possible that no hard affinity is specified in config file.
+ * Generate hard affinity maps now if we care about those.
+ */
+ if (b_info->num_vcpu_hard_affinity == 0 &&
+ (!libxl_bitmap_is_full(&global_vm_affinity_mask) ||
+ (b_info->type == LIBXL_DOMAIN_TYPE_PV &&
+ !libxl_bitmap_is_full(&global_pv_affinity_mask)) ||
+ (b_info->type != LIBXL_DOMAIN_TYPE_PV &&
+ !libxl_bitmap_is_full(&global_hvm_affinity_mask))
+ )) {
+ b_info->num_vcpu_hard_affinity = b_info->max_vcpus;
+ b_info->vcpu_hard_affinity =
+ xmalloc(b_info->max_vcpus * sizeof(libxl_bitmap));
+
+ for (i = 0; i < b_info->num_vcpu_hard_affinity; i++) {
+ libxl_bitmap *m = &b_info->vcpu_hard_affinity[i];
+ libxl_bitmap_init(m);
+ libxl_cpu_bitmap_alloc(ctx, m, 0);
+ libxl_bitmap_set_any(m);
+ }
+ }
+
+ apply_global_affinity_masks(b_info->type,
+ b_info->vcpu_hard_affinity,
+ b_info->num_vcpu_hard_affinity);
+ }
+
if (migrate_fd >= 0) {
if (d_config.c_info.name) {
/* when we receive a domain we get its name from the config
const char *filename = NULL;
struct domain_create dom_info;
int paused = 0, debug = 0, daemonize = 1, console_autoconnect = 0,
- quiet = 0, monitor = 1, vnc = 0, vncautopass = 0;
+ quiet = 0, monitor = 1, vnc = 0, vncautopass = 0, ignore_masks = 0;
int opt, rc;
static struct option opts[] = {
{"dryrun", 0, 0, 'n'},
{"defconfig", 1, 0, 'f'},
{"vncviewer", 0, 0, 'V'},
{"vncviewer-autopass", 0, 0, 'A'},
+ {"ignore-global-affinity-masks", 0, 0, 'i'},
COMMON_LONG_OPTS
};
argc--; argv++;
}
- SWITCH_FOREACH_OPT(opt, "Fnqf:pcdeVA", opts, "create", 0) {
+ SWITCH_FOREACH_OPT(opt, "Fnqf:pcdeVAi", opts, "create", 0) {
case 'f':
filename = optarg;
break;
case 'A':
vnc = vncautopass = 1;
break;
+ case 'i':
+ ignore_masks = 1;
+ break;
}
memset(&dom_info, 0, sizeof(dom_info));
dom_info.vnc = vnc;
dom_info.vncautopass = vncautopass;
dom_info.console_autoconnect = console_autoconnect;
+ dom_info.ignore_global_affinity_masks = ignore_masks;
rc = create_domain(&dom_info);
if (rc < 0) {
libxl_vcpuinfo_list_free(vcpuinfo, nb_vcpu);
}
+void apply_global_affinity_masks(libxl_domain_type type,
+ libxl_bitmap *vcpu_affinity_array,
+ unsigned int size)
+{
+ libxl_bitmap *mask = &global_vm_affinity_mask;
+ libxl_bitmap *type_mask;
+ unsigned int i;
+
+ switch (type) {
+ case LIBXL_DOMAIN_TYPE_HVM:
+ type_mask = &global_hvm_affinity_mask;
+ break;
+ case LIBXL_DOMAIN_TYPE_PV:
+ type_mask = &global_pv_affinity_mask;
+ break;
+ default:
+ fprintf(stderr, "Unknown guest type\n");
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < size; i++) {
+ int rc;
+ libxl_bitmap *t = &vcpu_affinity_array[i];
+ libxl_bitmap b1, b2;
+
+ libxl_bitmap_init(&b1);
+ libxl_bitmap_init(&b2);
+
+ rc = libxl_bitmap_and(ctx, &b1, t, mask);
+ if (rc) {
+ fprintf(stderr, "libxl_bitmap_and errored\n");
+ exit(EXIT_FAILURE);
+ }
+ rc = libxl_bitmap_and(ctx, &b2, &b1, type_mask);
+ if (rc) {
+ fprintf(stderr, "libxl_bitmap_and errored\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (libxl_bitmap_is_empty(&b2)) {
+ fprintf(stderr, "vcpu hard affinity map is empty\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Replace target bitmap with the result */
+ libxl_bitmap_dispose(t);
+ libxl_bitmap_init(t);
+ libxl_bitmap_copy_alloc(ctx, t, &b2);
+
+ libxl_bitmap_dispose(&b1);
+ libxl_bitmap_dispose(&b2);
+ }
+}
+
static void vcpulist(int argc, char **argv)
{
libxl_dominfo *dominfo;
{
static struct option opts[] = {
{"force", 0, 0, 'f'},
+ {"ignore-global-affinity-masks", 0, 0, 'i'},
COMMON_LONG_OPTS
};
libxl_vcpuinfo *vcpuinfo;
const char *vcpu, *hard_str, *soft_str;
char *endptr;
int opt, nb_cpu, nb_vcpu, rc = EXIT_FAILURE;
- bool force = false;
+ bool force = false, ignore_masks = false;
libxl_bitmap_init(&cpumap_hard);
libxl_bitmap_init(&cpumap_soft);
- SWITCH_FOREACH_OPT(opt, "f", opts, "vcpu-pin", 3) {
+ SWITCH_FOREACH_OPT(opt, "fi", opts, "vcpu-pin", 3) {
case 'f':
force = true;
break;
+ case 'i':
+ ignore_masks = true;
+ break;
default:
break;
}
goto out;
}
+ /* Only hard affinity matters here */
+ if (!ignore_masks) {
+ libxl_domain_config d_config;
+
+ libxl_domain_config_init(&d_config);
+ rc = libxl_retrieve_domain_configuration(ctx, domid, &d_config);
+ if (rc) {
+ fprintf(stderr, "Could not retrieve domain configuration\n");
+ libxl_domain_config_dispose(&d_config);
+ goto out;
+ }
+
+ apply_global_affinity_masks(d_config.b_info.type, hard, 1);
+
+ libxl_domain_config_dispose(&d_config);
+ }
+
if (force) {
if (libxl_set_vcpuaffinity_force(ctx, domid, vcpuid, hard, soft)) {
fprintf(stderr, "Could not set affinity for vcpu `%ld'.\n",