int hyperxl_domain_start(libxl_ctx* ctx, hyperxl_domain_config* config) { int i, ret = -1; uint32_t domid = 0; libxl_domain_config d_config; libxl_domain_config_init(&d_config); //init create info libxl_domain_create_info* c_info = &d_config.c_info; libxl_domain_create_info_init(c_info); if (config->hvm) c_info->type = LIBXL_DOMAIN_TYPE_HVM; else c_info->type = LIBXL_DOMAIN_TYPE_PV; libxl_uuid_generate(&c_info->uuid); c_info->name = strdup(config->name); libxl_defbool_set(&c_info->run_hotplug_scripts, false); //init_build_info libxl_domain_build_info* b_info = &d_config.b_info; if (config->hvm) libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_HVM); else { // currently only hvm is supported. pv mode will be enabled // whenever we can insert several serial ports and filesystem // into pv domain. goto cleanup; } // currently, we do not change vcpu and memory only, will add this // feature later. b_info->max_vcpus = config->max_vcpus; if (libxl_cpu_bitmap_alloc(ctx, &b_info->avail_vcpus, config->max_vcpus)) goto cleanup; libxl_bitmap_set_none(&b_info->avail_vcpus); for (i = 0; i < config->max_vcpus; i++) libxl_bitmap_set((&b_info->avail_vcpus), i); b_info->sched_params.weight = 1000; b_info->max_memkb = config->max_memory_kb; b_info->target_memkb = config->max_memory_kb; b_info->video_memkb = 0; // currently, we only initialize hvm fields if (config->hvm) { libxl_defbool_set(&b_info->u.hvm.pae, true); libxl_defbool_set(&b_info->u.hvm.apic, false); libxl_defbool_set(&b_info->u.hvm.acpi, true); b_info->u.hvm.boot = strdup("c"); b_info->cmdline = strdup(config->cmdline); b_info->kernel = strdup(config->kernel); b_info->ramdisk = strdup(config->initrd); b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_NONE; libxl_defbool_set(&b_info->u.hvm.nographic, 1); libxl_defbool_set(&b_info->u.hvm.vnc.enable, 0); libxl_defbool_set(&b_info->u.hvm.sdl.enable, 0); b_info->u.hvm.serial = strdup(config->console_sock); libxl_string_list_copy(ctx, &b_info->extra, (libxl_string_list*)config->extra); /* * comments from libvirt and libxenlight: * * The following comment and calculation were taken directly from * libxenlight's internal function libxl_get_required_shadow_memory(): * * 256 pages (1MB) per vcpu, plus 1 page per MiB of RAM for the P2M map, * plus 1 page per MiB of RAM to shadow the resident processes. */ b_info->shadow_memkb = 4 * (256 * libxl_bitmap_count_set(&b_info->avail_vcpus) + 2 * (b_info->max_memkb / 1024)); } if (libxl_domain_create_new(ctx, &d_config, &domid, NULL, NULL)) { goto cleanup; } libxl_evgen_domain_death* e_death = NULL; if (libxl_evenable_domain_death(ctx, domid, 0, &e_death)) { goto cleanup; } libxl_domain_unpause(ctx, domid); config->domid = domid; config->ev = e_death; ret = 0; cleanup: libxl_domain_config_dispose(&d_config); return ret; }
int libxl__domain_build_info_setdefault(libxl__gc *gc, libxl_domain_build_info *b_info) { if (b_info->type != LIBXL_DOMAIN_TYPE_HVM && b_info->type != LIBXL_DOMAIN_TYPE_PV) return ERROR_INVAL; libxl_defbool_setdefault(&b_info->device_model_stubdomain, false); if (!b_info->device_model_version) { if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) b_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL; else { const char *dm; int rc; b_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN; dm = libxl__domain_device_model(gc, b_info); rc = access(dm, X_OK); if (rc < 0) { /* qemu-xen unavailable, use qemu-xen-traditional */ if (errno == ENOENT) { LIBXL__LOG_ERRNO(CTX, XTL_VERBOSE, "qemu-xen is unavailable" ", use qemu-xen-traditional instead"); b_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL; } else { LIBXL__LOG_ERRNO(CTX, XTL_ERROR, "qemu-xen access error"); return ERROR_FAIL; } } } } if (b_info->blkdev_start == NULL) b_info->blkdev_start = libxl__strdup(NOGC, "xvda"); if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) { if (!b_info->u.hvm.bios) switch (b_info->device_model_version) { case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: b_info->u.hvm.bios = LIBXL_BIOS_TYPE_ROMBIOS; break; case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: b_info->u.hvm.bios = LIBXL_BIOS_TYPE_SEABIOS; break; default:return ERROR_INVAL; } /* Enforce BIOS<->Device Model version relationship */ switch (b_info->device_model_version) { case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: if (b_info->u.hvm.bios != LIBXL_BIOS_TYPE_ROMBIOS) return ERROR_INVAL; break; case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: if (b_info->u.hvm.bios == LIBXL_BIOS_TYPE_ROMBIOS) return ERROR_INVAL; break; default:abort(); } } if (b_info->type == LIBXL_DOMAIN_TYPE_HVM && b_info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL && libxl_defbool_val(b_info->device_model_stubdomain)) { LIBXL__LOG(CTX, XTL_ERROR, "device model stubdomains require \"qemu-xen-traditional\""); return ERROR_INVAL; } if (!b_info->max_vcpus) b_info->max_vcpus = 1; if (!b_info->avail_vcpus.size) { if (libxl_cpu_bitmap_alloc(CTX, &b_info->avail_vcpus, 1)) return ERROR_FAIL; libxl_bitmap_set(&b_info->avail_vcpus, 0); } else if (b_info->avail_vcpus.size > HVM_MAX_VCPUS) return ERROR_FAIL; if (!b_info->cpumap.size) { if (libxl_cpu_bitmap_alloc(CTX, &b_info->cpumap, 0)) return ERROR_FAIL; libxl_bitmap_set_any(&b_info->cpumap); } libxl_defbool_setdefault(&b_info->numa_placement, true); if (b_info->max_memkb == LIBXL_MEMKB_DEFAULT) b_info->max_memkb = 32 * 1024; if (b_info->target_memkb == LIBXL_MEMKB_DEFAULT) b_info->target_memkb = b_info->max_memkb; libxl_defbool_setdefault(&b_info->localtime, false); libxl_defbool_setdefault(&b_info->disable_migrate, false); switch (b_info->type) { case LIBXL_DOMAIN_TYPE_HVM: if (b_info->shadow_memkb == LIBXL_MEMKB_DEFAULT) b_info->shadow_memkb = 0; if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT) b_info->video_memkb = 8 * 1024; if (b_info->u.hvm.timer_mode == LIBXL_TIMER_MODE_DEFAULT) b_info->u.hvm.timer_mode = LIBXL_TIMER_MODE_NO_DELAY_FOR_MISSED_TICKS; libxl_defbool_setdefault(&b_info->u.hvm.pae, true); libxl_defbool_setdefault(&b_info->u.hvm.apic, true); libxl_defbool_setdefault(&b_info->u.hvm.acpi, true); libxl_defbool_setdefault(&b_info->u.hvm.acpi_s3, true); libxl_defbool_setdefault(&b_info->u.hvm.acpi_s4, true); libxl_defbool_setdefault(&b_info->u.hvm.nx, true); libxl_defbool_setdefault(&b_info->u.hvm.viridian, false); libxl_defbool_setdefault(&b_info->u.hvm.hpet, true); libxl_defbool_setdefault(&b_info->u.hvm.vpt_align, true); libxl_defbool_setdefault(&b_info->u.hvm.nested_hvm, false); libxl_defbool_setdefault(&b_info->u.hvm.usb, false); libxl_defbool_setdefault(&b_info->u.hvm.xen_platform_pci, true); if (!b_info->u.hvm.boot) { b_info->u.hvm.boot = strdup("cda"); if (!b_info->u.hvm.boot) return ERROR_NOMEM; } if (!b_info->u.hvm.vga.kind) b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_CIRRUS; libxl_defbool_setdefault(&b_info->u.hvm.vnc.enable, true); if (libxl_defbool_val(b_info->u.hvm.vnc.enable)) { libxl_defbool_setdefault(&b_info->u.hvm.vnc.findunused, true); if (!b_info->u.hvm.vnc.listen) { b_info->u.hvm.vnc.listen = strdup("127.0.0.1"); if (!b_info->u.hvm.vnc.listen) return ERROR_NOMEM; } } libxl_defbool_setdefault(&b_info->u.hvm.sdl.enable, false); if (libxl_defbool_val(b_info->u.hvm.sdl.enable)) { libxl_defbool_setdefault(&b_info->u.hvm.sdl.opengl, false); } libxl_defbool_setdefault(&b_info->u.hvm.spice.enable, false); if (libxl_defbool_val(b_info->u.hvm.spice.enable)) { libxl_defbool_setdefault(&b_info->u.hvm.spice.disable_ticketing, false); libxl_defbool_setdefault(&b_info->u.hvm.spice.agent_mouse, true); } libxl_defbool_setdefault(&b_info->u.hvm.nographic, false); libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru, false); break; case LIBXL_DOMAIN_TYPE_PV: libxl_defbool_setdefault(&b_info->u.pv.e820_host, false); if (b_info->shadow_memkb == LIBXL_MEMKB_DEFAULT) b_info->shadow_memkb = 0; if (b_info->u.pv.slack_memkb == LIBXL_MEMKB_DEFAULT) b_info->u.pv.slack_memkb = 0; break; default: LIBXL__LOG(CTX, LIBXL__LOG_ERROR, "invalid domain type %s in create info", libxl_domain_type_to_string(b_info->type)); return ERROR_INVAL; } return 0; }
static int libxlMakeDomBuildInfo(virDomainObjPtr vm, libxl_domain_config *d_config) { virDomainDefPtr def = vm->def; libxlDomainObjPrivatePtr priv = vm->privateData; libxl_domain_build_info *b_info = &d_config->b_info; int hvm = STREQ(def->os.type, "hvm"); size_t i; libxl_domain_build_info_init(b_info); if (hvm) libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_HVM); else libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PV); b_info->max_vcpus = def->maxvcpus; if (libxl_cpu_bitmap_alloc(priv->ctx, &b_info->avail_vcpus, def->maxvcpus)) goto error; libxl_bitmap_set_none(&b_info->avail_vcpus); for (i = 0; i < def->vcpus; i++) libxl_bitmap_set((&b_info->avail_vcpus), i); if (def->clock.ntimers > 0 && def->clock.timers[0]->name == VIR_DOMAIN_TIMER_NAME_TSC) { switch (def->clock.timers[0]->mode) { case VIR_DOMAIN_TIMER_MODE_NATIVE: b_info->tsc_mode = 2; break; case VIR_DOMAIN_TIMER_MODE_PARAVIRT: b_info->tsc_mode = 3; break; default: b_info->tsc_mode = 1; } } b_info->sched_params.weight = 1000; b_info->max_memkb = def->mem.max_balloon; b_info->target_memkb = def->mem.cur_balloon; if (hvm) { char bootorder[VIR_DOMAIN_BOOT_LAST + 1]; libxl_defbool_set(&b_info->u.hvm.pae, def->features[VIR_DOMAIN_FEATURE_PAE] == VIR_DOMAIN_FEATURE_STATE_ON); libxl_defbool_set(&b_info->u.hvm.apic, def->features[VIR_DOMAIN_FEATURE_APIC] == VIR_DOMAIN_FEATURE_STATE_ON); libxl_defbool_set(&b_info->u.hvm.acpi, def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_DOMAIN_FEATURE_STATE_ON); for (i = 0; i < def->clock.ntimers; i++) { if (def->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_HPET && def->clock.timers[i]->present == 1) { libxl_defbool_set(&b_info->u.hvm.hpet, 1); } } for (i = 0; i < def->os.nBootDevs; i++) { switch (def->os.bootDevs[i]) { case VIR_DOMAIN_BOOT_FLOPPY: bootorder[i] = 'a'; break; default: case VIR_DOMAIN_BOOT_DISK: bootorder[i] = 'c'; break; case VIR_DOMAIN_BOOT_CDROM: bootorder[i] = 'd'; break; case VIR_DOMAIN_BOOT_NET: bootorder[i] = 'n'; break; } } if (def->os.nBootDevs == 0) { bootorder[0] = 'c'; bootorder[1] = '\0'; } else { bootorder[def->os.nBootDevs] = '\0'; } if (VIR_STRDUP(b_info->u.hvm.boot, bootorder) < 0) goto error; if (def->nserials) { if (def->nserials > 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Only one serial device is supported by libxl")); goto error; } if (libxlMakeChrdevStr(def->serials[0], &b_info->u.hvm.serial) < 0) goto error; } if (def->nparallels) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Parallel devices are not supported by libxl")); goto error; } /* * The following comment and calculation were taken directly from * libxenlight's internal function libxl_get_required_shadow_memory(): * * 256 pages (1MB) per vcpu, plus 1 page per MiB of RAM for the P2M map, * plus 1 page per MiB of RAM to shadow the resident processes. */ b_info->shadow_memkb = 4 * (256 * libxl_bitmap_count_set(&b_info->avail_vcpus) + 2 * (b_info->max_memkb / 1024)); } else { /* * For compatibility with the legacy xen toolstack, default to pygrub * if bootloader is not specified AND direct kernel boot is not specified. */ if (def->os.bootloader) { if (VIR_STRDUP(b_info->u.pv.bootloader, def->os.bootloader) < 0) goto error; } else if (def->os.kernel == NULL) { if (VIR_STRDUP(b_info->u.pv.bootloader, LIBXL_BOOTLOADER_PATH) < 0) goto error; } if (def->os.bootloaderArgs) { if (!(b_info->u.pv.bootloader_args = virStringSplit(def->os.bootloaderArgs, " \t\n", 0))) goto error; } if (VIR_STRDUP(b_info->u.pv.cmdline, def->os.cmdline) < 0) goto error; if (def->os.kernel) { /* libxl_init_build_info() sets VIR_STRDUP(kernel.path, "hvmloader") */ VIR_FREE(b_info->u.pv.kernel); if (VIR_STRDUP(b_info->u.pv.kernel, def->os.kernel) < 0) goto error; } if (VIR_STRDUP(b_info->u.pv.ramdisk, def->os.initrd) < 0) goto error; } return 0; error: libxl_domain_build_info_dispose(b_info); return -1; }
static int libxl__set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, const libxl_bitmap *cpumap_hard, const libxl_bitmap *cpumap_soft, unsigned flags) { GC_INIT(ctx); libxl_bitmap hard, soft; int rc; libxl_bitmap_init(&hard); libxl_bitmap_init(&soft); if (!cpumap_hard && !cpumap_soft && !flags) { rc = ERROR_INVAL; goto out; } /* * Xen wants writable hard and/or soft cpumaps, to put back in them * the effective hard and/or soft affinity that will be used. */ if (cpumap_hard) { rc = libxl_cpu_bitmap_alloc(ctx, &hard, 0); if (rc) goto out; libxl__bitmap_copy_best_effort(gc, &hard, cpumap_hard); flags |= XEN_VCPUAFFINITY_HARD; } if (cpumap_soft) { rc = libxl_cpu_bitmap_alloc(ctx, &soft, 0); if (rc) goto out; libxl__bitmap_copy_best_effort(gc, &soft, cpumap_soft); flags |= XEN_VCPUAFFINITY_SOFT; } if (xc_vcpu_setaffinity(ctx->xch, domid, vcpuid, cpumap_hard ? hard.map : NULL, cpumap_soft ? soft.map : NULL, flags)) { LOGED(ERROR, domid, "Setting vcpu affinity"); rc = ERROR_FAIL; goto out; } /* * Let's check the results. Hard affinity will never be empty, but it * is possible that Xen will use something different from what we asked * for various reasons. If that's the case, report it. */ if (cpumap_hard && !libxl_bitmap_equal(cpumap_hard, &hard, 0)) LOGD(DEBUG, domid, "New hard affinity for vcpu %d has unreachable cpus", vcpuid); /* * Soft affinity can both be different from what asked and empty. Check * for (and report) both. */ if (cpumap_soft) { if (!libxl_bitmap_equal(cpumap_soft, &soft, 0)) LOGD(DEBUG, domid, "New soft affinity for vcpu %d has unreachable cpus", vcpuid); if (libxl_bitmap_is_empty(&soft)) LOGD(WARN, domid, "All cpus in soft affinity of vcpu %d are unreachable." " Only hard affinity will be considered for scheduling", vcpuid); } rc = 0; out: libxl_bitmap_dispose(&hard); libxl_bitmap_dispose(&soft); GC_FREE; return rc; }