Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
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;
}