int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
libxl_device_model_info *dm_info, uint32_t *need_memkb)
{
+ libxl__gc gc = LIBXL_INIT_GC(ctx);
*need_memkb = b_info->target_memkb;
if (b_info->hvm) {
*need_memkb += b_info->shadow_memkb + LIBXL_HVM_EXTRA_MEMORY;
- if (strstr(dm_info->device_model, "stubdom-dm"))
+ if (dm_info->device_model_stubdomain)
*need_memkb += 32 * 1024;
} else
*need_memkb += b_info->shadow_memkb + LIBXL_PV_EXTRA_MEMORY;
if (*need_memkb % (2 * 1024))
*need_memkb += (2 * 1024) - (*need_memkb % (2 * 1024));
+ libxl__free_all(&gc);
return 0;
}
XENPV,
} libxl_qemu_machine_type;
+typedef enum libxl_device_model_version {
+ /* Historical qemu-xen device model (qemu-dm) */
+ LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL = 1,
+ /* Upstream based qemu-xen device model */
+ LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN = 2,
+} libxl_device_model_version;
+
typedef enum {
LIBXL_CONSTYPE_SERIAL = 1,
LIBXL_CONSTYPE_PV,
libxl_cpumap = Builtin("cpumap", destructor_fn="libxl_cpumap_destroy", passby=PASS_BY_REFERENCE)
libxl_cpuarray = Builtin("cpuarray", destructor_fn="libxl_cpuarray_destroy", passby=PASS_BY_REFERENCE)
libxl_qemu_machine_type = Number("qemu_machine_type", namespace="libxl_")
+libxl_device_model_version = Number("device_model_version", namespace="libxl_")
libxl_console_consback = Number("console_consback", namespace="libxl_")
libxl_console_constype = Number("console_constype", namespace="libxl_")
libxl_disk_format = Number("disk_format", namespace="libxl_")
("domid", integer),
("uuid", libxl_uuid, False, "this is use only with stubdom, and must be different from the domain uuid"),
("dom_name", string),
- ("device_model", string),
+ ("device_model_version", libxl_device_model_version),
+ ("device_model_stubdomain", bool),
+ ("device_model", string, False, "if you set this you must set device_model_version too"),
("saved_state", string),
("type", libxl_qemu_machine_type),
("target_ram", uint32),
libxl_uuid_generate(&dm_info->uuid);
dm_info->dom_name = strdup(c_info->name);
- dm_info->device_model = strdup("qemu-dm");
+ dm_info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL;
+ dm_info->device_model_stubdomain = false;
+ dm_info->device_model = NULL;
dm_info->target_ram = libxl__sizekb_to_mb(b_info->target_memkb);
dm_info->videoram = libxl__sizekb_to_mb(b_info->video_memkb);
dm_info->apic = b_info->u.hvm.apic;
#endif
}
+const char *libxl__domain_device_model(libxl__gc *gc,
+ libxl_device_model_info *info)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ const char *dm;
+
+ if (info->device_model_stubdomain)
+ return NULL;
+
+ if (info->device_model) {
+ dm = libxl__strdup(gc, info->device_model);
+ } else {
+ switch (info->device_model_version) {
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
+ dm = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
+ break;
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
+ dm = libxl__strdup(gc, "/usr/bin/qemu");
+ break;
+ default:
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+ "invalid device model version %d\n",
+ info->device_model_version);
+ dm = NULL;
+ break;
+ }
+ }
+
+ return dm;
+}
+
static char ** libxl__build_device_model_args_old(libxl__gc *gc,
+ const char *dm,
libxl_device_model_info *info,
libxl_device_disk *disks, int num_disks,
libxl_device_nic *vifs, int num_vifs)
if (!dm_args)
return NULL;
- flexarray_vappend(dm_args, "qemu-dm", "-d", libxl__sprintf(gc, "%d", info->domid), NULL);
+ flexarray_vappend(dm_args, dm,
+ "-d", libxl__sprintf(gc, "%d", info->domid), NULL);
if (info->dom_name)
flexarray_vappend(dm_args, "-domain-name", info->dom_name, NULL);
}
static char ** libxl__build_device_model_args_new(libxl__gc *gc,
+ const char *dm,
libxl_device_model_info *info,
libxl_device_disk *disks, int num_disks,
libxl_device_nic *vifs, int num_vifs)
if (!dm_args)
return NULL;
- flexarray_vappend(dm_args, libxl__strdup(gc, info->device_model),
- "-xen-domid", libxl__sprintf(gc, "%d", info->domid), NULL);
+ flexarray_vappend(dm_args, dm,
+ "-xen-domid", libxl__sprintf(gc, "%d", info->domid), NULL);
if (info->type == XENPV) {
flexarray_append(dm_args, "-xen-attach");
}
static char ** libxl__build_device_model_args(libxl__gc *gc,
+ const char *dm,
libxl_device_model_info *info,
libxl_device_disk *disks, int num_disks,
libxl_device_nic *vifs, int num_vifs)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
- int new_qemu;
- new_qemu = libxl_check_device_model_version(ctx, info->device_model);
-
- if (new_qemu == 1) {
- return libxl__build_device_model_args_new(gc, info, disks, num_disks, vifs, num_vifs);
- } else {
- return libxl__build_device_model_args_old(gc, info, disks, num_disks, vifs, num_vifs);
+ switch (info->device_model_version) {
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
+ return libxl__build_device_model_args_old(gc, dm, info,
+ disks, num_disks,
+ vifs, num_vifs);
+ case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
+ return libxl__build_device_model_args_new(gc, dm, info,
+ disks, num_disks,
+ vifs, num_vifs);
+ default:
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "unknown device model version %d",
+ info->device_model_version);
+ return NULL;
}
}
xs_transaction_t t;
libxl__device_model_starting *dm_starting = 0;
- args = libxl__build_device_model_args(gc, info, disks, num_disks,
+ if (info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL) {
+ ret = ERROR_INVAL;
+ goto out;
+ }
+
+ args = libxl__build_device_model_args(gc, "stubdom-dm", info,
+ disks, num_disks,
vifs, num_vifs);
if (!args) {
ret = ERROR_FAIL;
int rc;
char **args;
libxl__device_model_starting buf_starting, *p;
- xs_transaction_t t;
+ xs_transaction_t t;
char *vm_path;
char **pass_stuff;
+ const char *dm;
- if (strstr(info->device_model, "stubdom-dm")) {
+ if (info->device_model_stubdomain) {
libxl_device_vfb vfb;
libxl_device_vkb vkb;
libxl__vfb_and_vkb_from_device_model_info(gc, info, &vfb, &vkb);
- rc = libxl__create_stubdom(gc, info, disks, num_disks, vifs, num_vifs, &vfb, &vkb, starting_r);
+ rc = libxl__create_stubdom(gc, info,
+ disks, num_disks,
+ vifs, num_vifs,
+ &vfb, &vkb, starting_r);
+ goto out;
+ }
+
+ dm = libxl__domain_device_model(gc, info);
+ if (!dm) {
+ rc = ERROR_FAIL;
goto out;
}
- args = libxl__build_device_model_args(gc, info, disks, num_disks,
+ args = libxl__build_device_model_args(gc, dm, info, disks, num_disks,
vifs, num_vifs);
if (!args) {
rc = ERROR_FAIL;
if (!rc) { /* inner child */
setsid();
libxl__exec(null, logfile_w, logfile_w,
- libxl__abs_path(gc, info->device_model, libxl_libexec_path()),
- args);
+ libxl__domain_device_model(gc, info),
+ args);
}
rc = 0;
info->nographic = 1;
info->domid = domid;
info->dom_name = libxl_domid_to_name(ctx, domid);
- info->device_model = libxl__abs_path(gc, "qemu-dm", libxl_libexec_path());
+ info->device_model_version = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL;
+ info->device_model = NULL;
info->type = XENPV;
return 0;
}
_hidden int libxl__domain_build(libxl__gc *gc, libxl_domain_build_info *info, uint32_t domid, /* out */ libxl_domain_build_state *state);
/* for device model creation */
+_hidden const char *libxl__domain_device_model(libxl__gc *gc,
+ libxl_device_model_info *info);
_hidden int libxl__create_device_model(libxl__gc *gc,
libxl_device_model_info *info,
libxl_device_disk *disk, int num_disks,
return rc;
}
-#define QEMU_VERSION_STR "QEMU emulator version "
-
-
-int libxl_check_device_model_version(libxl_ctx *ctx, char *path)
-{
- libxl__gc gc = LIBXL_INIT_GC(ctx);
- pid_t pid = -1;
- int pipefd[2];
- char buf[100];
- ssize_t i, count = 0;
- int status;
- char *abs_path = NULL;
- int rc = -1;
-
- abs_path = libxl__abs_path(&gc, path, libxl_private_bindir_path());
-
- if (pipe(pipefd))
- goto out;
-
- pid = fork();
- if (pid == -1) {
- goto out;
- }
-
- if (!pid) {
- close(pipefd[0]);
- if (dup2(pipefd[1], STDOUT_FILENO) == -1)
- exit(1);
- execlp(abs_path, abs_path, "-h", NULL);
-
- close(pipefd[1]);
- exit(127);
- }
-
- close(pipefd[1]);
-
- /* attempt to get the first line of `qemu -h` */
- while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) {
- if (i + count > 90)
- break;
- for (int j = 0; j < i; j++) {
- if (buf[j + count] == '\n')
- break;
- }
- count += i;
- }
- count += i;
- close(pipefd[0]);
- waitpid(pid, &status, 0);
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
- goto out;
- }
-
- /* Check if we have the forked qemu-xen. */
- /* QEMU-DM emulator version 0.10.2, ... */
- if (strncmp("QEMU-DM ", buf, 7) == 0) {
- rc = 0;
- goto out;
- }
-
- /* Check if the version is above 12.0 */
- /* The first line is : QEMU emulator version 0.12.50, ... */
- if (strncmp(QEMU_VERSION_STR, buf, strlen(QEMU_VERSION_STR)) == 0) {
- int major, minor;
- char *endptr = NULL;
- char *v = buf + strlen(QEMU_VERSION_STR);
-
- major = strtol(v, &endptr, 10);
- if (major == 0 && endptr && *endptr == '.') {
- v = endptr + 1;
- minor = strtol(v, &endptr, 10);
- if (minor >= 12) {
- rc = 1;
- goto out;
- }
- }
- }
- rc = 0;
-out:
- libxl__free_all(&gc);
- return rc;
-}
-
int libxl_cpumap_alloc(libxl_ctx *ctx, libxl_cpumap *cpumap)
{
int max_cpus;
int libxl_devid_to_device_disk(libxl_ctx *ctx, uint32_t domid,
const char *devid, libxl_device_disk *disk);
-/* check the version of qemu
- * return 1 if is the new one
- * return 0 if is the old one
- * return -1 if there are an error */
-int libxl_check_device_model_version(libxl_ctx *ctx, char *path);
-
int libxl_cpumap_alloc(libxl_ctx *ctx, libxl_cpumap *cpumap);
int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu);
void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu);
printf("\t\t\t(timer_mode %d)\n", b_info->u.hvm.timer_mode);
printf("\t\t\t(nestedhvm %d)\n", b_info->u.hvm.nested_hvm);
- printf("\t\t\t(device_model %s)\n", dm_info->device_model);
+ printf("\t\t\t(device_model %s)\n", dm_info->device_model ? : "default");
printf("\t\t\t(videoram %d)\n", dm_info->videoram);
printf("\t\t\t(stdvga %d)\n", dm_info->stdvga);
printf("\t\t\t(vnc %d)\n", dm_info->vnc);
xlu_cfg_replace_string (config, "kernel", &b_info->u.pv.kernel.path);
+ xlu_cfg_replace_string (config, "kernel", &b_info->u.pv.kernel.path);
+
xlu_cfg_get_string (config, "root", &root);
xlu_cfg_get_string (config, "extra", &extra);
libxl_init_dm_info(dm_info, c_info, b_info);
/* then process config related to dm */
- xlu_cfg_replace_string (config, "device_model", &dm_info->device_model);
+ if (!xlu_cfg_get_string (config, "device_model", &buf)) {
+ fprintf(stderr,
+ "WARNING: ignoring device_model directive.\n"
+ "WARNING: Use \"device_model_override\" instead if you really want a non-default device_model\n");
+ if (strstr(buf, "stubdom-dm"))
+ fprintf(stderr, "WARNING: Or use \"device_model_stubdomain_override\" if you want to enable stubdomains\n");
+ }
+
+ xlu_cfg_replace_string (config, "device_model_override",
+ &dm_info->device_model);
+ if (!xlu_cfg_get_string (config, "device_model_version", &buf)) {
+ if (!strcmp(buf, "qemu-xen-traditional")) {
+ dm_info->device_model_version
+ = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL;
+ } else if (!strcmp(buf, "qemu-xen")) {
+ dm_info->device_model_version
+ = LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN;
+ } else {
+ fprintf(stderr,
+ "Unknown device_model_version \"%s\" specified\n", buf);
+ exit(1);
+ }
+ } else if (dm_info->device_model)
+ fprintf(stderr, "WARNING: device model override given without specific DM version\n");
+ if (!xlu_cfg_get_long (config, "device_model_stubdomain_override", &l))
+ dm_info->device_model_stubdomain = l;
if (!xlu_cfg_get_long (config, "stdvga", &l))
dm_info->stdvga = l;
if (!xlu_cfg_get_long (config, "vnc", &l))