[libvirt] [PATCH] Convert libxl driver to Xen 4.2

Based on a patch originally authored by Daniel De Graaf http://lists.xen.org/archives/html/xen-devel/2012-05/msg00565.html This patch converts the Xen libxl driver to support only Xen >= 4.2. Support for Xen 4.1 libxl is dropped since that version of libxl is designated 'technology preview' only and is incompatible with Xen 4.2 libxl. Additionally, the default toolstack in Xen 4.1 is still xend, for which libvirt has a stable, functional driver. --- V2: Remove 128 vcpu limit. Remove split_string_into_string_list() function copied from xen sources since libvirt now has virStringSplit(). configure.ac | 8 +- docs/drvxen.html.in | 8 + libvirt.spec.in | 4 +- src/libxl/libxl_conf.c | 321 +++++++++--------------------- src/libxl/libxl_conf.h | 16 +- src/libxl/libxl_driver.c | 488 +++++++++++++++++++++++++++------------------- 6 files changed, 404 insertions(+), 441 deletions(-) diff --git a/configure.ac b/configure.ac index c888eb8..a695e52 100644 --- a/configure.ac +++ b/configure.ac @@ -718,16 +718,14 @@ if test "$with_libxl" != "no" ; then fi CFLAGS="$CFLAGS $LIBXL_CFLAGS" LIBS="$LIBS $LIBXL_LIBS" - AC_CHECK_LIB([xenlight], [libxl_domain_create_new], [ + AC_CHECK_LIB([xenlight], [libxl_ctx_alloc], [ with_libxl=yes - LIBXL_LIBS="$LIBXL_LIBS -lxenlight -lxenstore -lxenctrl -lxenguest -luuid -lutil -lblktapctl" + LIBXL_LIBS="$LIBXL_LIBS -lxenlight" ],[ if test "$with_libxl" = "yes"; then fail=1 fi with_libxl=no - ],[ - -lxenstore -lxenctrl -lxenguest -luuid -lutil -lblktapctl ]) fi @@ -735,7 +733,7 @@ LIBS="$old_LIBS" CFLAGS="$old_CFLAGS" if test $fail = 1; then - AC_MSG_ERROR([You must install the libxl Library to compile libxenlight driver with -lxl]) + AC_MSG_ERROR([You must install the libxl Library from Xen >= 4.2 to compile libxenlight driver with -lxl]) fi if test "$with_libxl" = "yes"; then diff --git a/docs/drvxen.html.in b/docs/drvxen.html.in index 0bca935..06bd911 100644 --- a/docs/drvxen.html.in +++ b/docs/drvxen.html.in @@ -53,6 +53,14 @@ the <code>/etc/xen</code> directory. It is important not to place any other non-config files in this directory. </li> + <li> + <strong>libxl</strong>: Starting with Xen 4.2, the legacy XenD/xm + toolstack is deprecated in favor of libxl, also commonly called + libxenlight. libvirt supports this new Xen toolstack via the + libxl driver. If XenD is enabled, the legacy xen driver consisting + of the above mentioned channels will be used. If XenD is disabled, + the libxl driver will be used. + </li> </ul> <h2><a name="uri">Connections to Xen driver</a></h2> diff --git a/libvirt.spec.in b/libvirt.spec.in index 5b3f4e4..47cb087 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -189,8 +189,8 @@ %endif %endif -# Fedora doesn't have new enough Xen for libxl until F16 -%if 0%{?fedora} && 0%{?fedora} < 16 +# Fedora doesn't have new enough Xen for libxl until F18 +%if 0%{?fedora} && 0%{?fedora} < 18 %define with_libxl 0 %endif diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index 1c3130b..b8b9ddb 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -36,11 +36,13 @@ #include "virterror_internal.h" #include "datatypes.h" #include "virfile.h" +#include "virstring.h" #include "memory.h" #include "uuid.h" #include "capabilities.h" #include "libxl_driver.h" #include "libxl_conf.h" +#include "libxl_utils.h" #include "storage_file.h" @@ -62,7 +64,6 @@ struct guest_arch { static const char *xen_cap_re = "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64|powerpc64)(p|be)?"; static regex_t xen_cap_rec; - static int libxlNextFreeVncPort(libxlDriverPrivatePtr driver, int startPort) { @@ -360,18 +361,36 @@ libxlMakeCapabilitiesInternal(const char *hostmachine, } static int -libxlMakeDomCreateInfo(virDomainDefPtr def, libxl_domain_create_info *c_info) +libxlMakeDomCreateInfo(libxlDriverPrivatePtr driver, + virDomainDefPtr def, + libxl_domain_create_info *c_info) { char uuidstr[VIR_UUID_STRING_BUFLEN]; - libxl_init_create_info(c_info); + libxl_domain_create_info_init(c_info); + + if (STREQ(def->os.type, "hvm")) + c_info->type = LIBXL_DOMAIN_TYPE_HVM; + else + c_info->type = LIBXL_DOMAIN_TYPE_PV; - c_info->hvm = STREQ(def->os.type, "hvm"); if ((c_info->name = strdup(def->name)) == NULL) { virReportOOMError(); goto error; } + if (def->nseclabels && + def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_STATIC) { + if (libxl_flask_context_to_sid(driver->ctx, + def->seclabels[0]->label, + strlen(def->seclabels[0]->label), + &c_info->ssidref)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("libxenlight failed to resolve security label '%s'"), + def->seclabels[0]->label); + } + } + virUUIDFormat(def->uuid, uuidstr); if (libxl_uuid_from_string(&c_info->uuid, uuidstr)) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -382,7 +401,7 @@ libxlMakeDomCreateInfo(virDomainDefPtr def, libxl_domain_create_info *c_info) return 0; error: - libxl_domain_create_info_destroy(c_info); + libxl_domain_create_info_dispose(c_info); return -1; } @@ -393,26 +412,14 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) int hvm = STREQ(def->os.type, "hvm"); int i; - /* Currently, libxenlight only supports 32 vcpus per domain. - * cur_vcpus member of struct libxl_domain_build_info is defined - * as an int, but its semantic is a bitmap of online vcpus, so - * only 32 can be represented. - */ - if (def->maxvcpus > 32 || def->vcpus > 32) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("This version of libxenlight only supports 32 " - "vcpus per domain")); - return -1; - } + libxl_domain_build_info_init(b_info); - libxl_init_build_info(b_info, &d_config->c_info); - - b_info->hvm = hvm; - b_info->max_vcpus = def->maxvcpus; - if (def->vcpus == 32) - b_info->cur_vcpus = (uint32_t) -1; + if (hvm) + libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_HVM); else - b_info->cur_vcpus = (1 << def->vcpus) - 1; + libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PV); + b_info->max_vcpus = def->maxvcpus; + libxl_bitmap_set((&b_info->avail_vcpus), def->vcpus); if (def->clock.ntimers > 0 && def->clock.timers[0]->name == VIR_DOMAIN_TIMER_NAME_TSC) { switch (def->clock.timers[0]->mode) { @@ -426,16 +433,20 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) 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) { - b_info->u.hvm.pae = def->features & (1 << VIR_DOMAIN_FEATURE_PAE); - b_info->u.hvm.apic = def->features & (1 << VIR_DOMAIN_FEATURE_APIC); - b_info->u.hvm.acpi = def->features & (1 << VIR_DOMAIN_FEATURE_ACPI); + libxl_defbool_set(&b_info->u.hvm.pae, + def->features & (1 << VIR_DOMAIN_FEATURE_PAE)); + libxl_defbool_set(&b_info->u.hvm.apic, + def->features & (1 << VIR_DOMAIN_FEATURE_APIC)); + libxl_defbool_set(&b_info->u.hvm.acpi, + def->features & (1 << VIR_DOMAIN_FEATURE_ACPI)); 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) { - b_info->u.hvm.hpet = 1; + libxl_defbool_set(&b_info->u.hvm.hpet, 1); } } @@ -446,7 +457,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) * 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 * b_info->cur_vcpus + + b_info->shadow_memkb = 4 * (256 * libxl_bitmap_count_set(&b_info->avail_vcpus) + 2 * (b_info->max_memkb / 1024)); } else { if (def->os.bootloader) { @@ -456,10 +467,9 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) } } if (def->os.bootloaderArgs) { - if ((b_info->u.pv.bootloader_args = strdup(def->os.bootloaderArgs)) == NULL) { - virReportOOMError(); + if (!(b_info->u.pv.bootloader_args = + virStringSplit(def->os.bootloaderArgs, " \t\n", 0))) goto error; - } } if (def->os.cmdline) { if ((b_info->u.pv.cmdline = strdup(def->os.cmdline)) == NULL) { @@ -469,14 +479,14 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) } if (def->os.kernel) { /* libxl_init_build_info() sets kernel.path = strdup("hvmloader") */ - VIR_FREE(b_info->kernel.path); - if ((b_info->kernel.path = strdup(def->os.kernel)) == NULL) { + VIR_FREE(b_info->u.pv.kernel); + if ((b_info->u.pv.kernel = strdup(def->os.kernel)) == NULL) { virReportOOMError(); goto error; } } if (def->os.initrd) { - if ((b_info->u.pv.ramdisk.path = strdup(def->os.initrd)) == NULL) { + if ((b_info->u.pv.ramdisk = strdup(def->os.initrd)) == NULL) { virReportOOMError(); goto error; } @@ -486,13 +496,12 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) return 0; error: - libxl_domain_build_info_destroy(b_info); + libxl_domain_build_info_dispose(b_info); return -1; } int -libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, - libxl_device_disk *x_disk) +libxlMakeDisk(virDomainDiskDefPtr l_disk, libxl_device_disk *x_disk) { if (l_disk->src && (x_disk->pdev_path = strdup(l_disk->src)) == NULL) { virReportOOMError(); @@ -509,22 +518,22 @@ libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, STREQ(l_disk->driverName, "tap2")) { switch (l_disk->format) { case VIR_STORAGE_FILE_QCOW: - x_disk->format = DISK_FORMAT_QCOW; - x_disk->backend = DISK_BACKEND_QDISK; + x_disk->format = LIBXL_DISK_FORMAT_QCOW; + x_disk->backend = LIBXL_DISK_BACKEND_QDISK; break; case VIR_STORAGE_FILE_QCOW2: - x_disk->format = DISK_FORMAT_QCOW2; - x_disk->backend = DISK_BACKEND_QDISK; + x_disk->format = LIBXL_DISK_FORMAT_QCOW2; + x_disk->backend = LIBXL_DISK_BACKEND_QDISK; break; case VIR_STORAGE_FILE_VHD: - x_disk->format = DISK_FORMAT_VHD; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_VHD; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; break; case VIR_STORAGE_FILE_NONE: /* No subtype specified, default to raw/tap */ case VIR_STORAGE_FILE_RAW: - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; break; default: virReportError(VIR_ERR_INTERNAL_ERROR, @@ -533,11 +542,11 @@ libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, return -1; } } else if (STREQ(l_disk->driverName, "file")) { - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; } else if (STREQ(l_disk->driverName, "phy")) { - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_PHY; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_PHY; } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight does not support disk driver %s"), @@ -546,12 +555,12 @@ libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, } } else { /* No driverName - default to raw/tap?? */ - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; } - /* How to set unpluggable? */ - x_disk->unpluggable = 1; + /* XXX is this right? */ + x_disk->removable = 1; x_disk->readwrite = !l_disk->readonly; x_disk->is_cdrom = l_disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM ? 1 : 0; if (l_disk->transient) { @@ -560,8 +569,6 @@ libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, return -1; } - x_disk->domid = def->id; - return 0; } @@ -579,7 +586,7 @@ libxlMakeDiskList(virDomainDefPtr def, libxl_domain_config *d_config) } for (i = 0; i < ndisks; i++) { - if (libxlMakeDisk(def, l_disks[i], &x_disks[i]) < 0) + if (libxlMakeDisk(l_disks[i], &x_disks[i]) < 0) goto error; } @@ -590,19 +597,19 @@ libxlMakeDiskList(virDomainDefPtr def, libxl_domain_config *d_config) error: for (i = 0; i < ndisks; i++) - libxl_device_disk_destroy(&x_disks[i]); + libxl_device_disk_dispose(&x_disks[i]); VIR_FREE(x_disks); return -1; } int -libxlMakeNic(virDomainDefPtr def, virDomainNetDefPtr l_nic, - libxl_device_nic *x_nic) +libxlMakeNic(virDomainNetDefPtr l_nic, libxl_device_nic *x_nic) { - // TODO: Where is mtu stored? - //x_nics[i].mtu = 1492; + /* TODO: Where is mtu stored? + * + * x_nics[i].mtu = 1492; + */ - x_nic->domid = def->id; virMacAddrGetRaw(&l_nic->mac, x_nic->mac); if (l_nic->model && !STREQ(l_nic->model, "netfront")) { @@ -610,9 +617,9 @@ libxlMakeNic(virDomainDefPtr def, virDomainNetDefPtr l_nic, virReportOOMError(); return -1; } - x_nic->nictype = NICTYPE_IOEMU; + x_nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU; } else { - x_nic->nictype = NICTYPE_VIF; + x_nic->nictype = LIBXL_NIC_TYPE_VIF; } if (l_nic->ifname && (x_nic->ifname = strdup(l_nic->ifname)) == NULL) { @@ -659,48 +666,49 @@ libxlMakeNicList(virDomainDefPtr def, libxl_domain_config *d_config) for (i = 0; i < nnics; i++) { x_nics[i].devid = i; - if (libxlMakeNic(def, l_nics[i], &x_nics[i])) + if (libxlMakeNic(l_nics[i], &x_nics[i])) goto error; } - d_config->vifs = x_nics; - d_config->num_vifs = nnics; + d_config->nics = x_nics; + d_config->num_nics = nnics; return 0; error: for (i = 0; i < nnics; i++) - libxl_device_nic_destroy(&x_nics[i]); + libxl_device_nic_dispose(&x_nics[i]); VIR_FREE(x_nics); return -1; } int -libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainDefPtr def, - virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb) +libxlMakeVfb(libxlDriverPrivatePtr driver, + virDomainGraphicsDefPtr l_vfb, + libxl_device_vfb *x_vfb) { int port; const char *listenAddr; switch (l_vfb->type) { case VIR_DOMAIN_GRAPHICS_TYPE_SDL: - x_vfb->sdl = 1; + libxl_defbool_set(&x_vfb->sdl.enable, 1); if (l_vfb->data.sdl.display && - (x_vfb->display = strdup(l_vfb->data.sdl.display)) == NULL) { + (x_vfb->sdl.display = strdup(l_vfb->data.sdl.display)) == NULL) { virReportOOMError(); return -1; } if (l_vfb->data.sdl.xauth && - (x_vfb->xauthority = + (x_vfb->sdl.xauthority = strdup(l_vfb->data.sdl.xauth)) == NULL) { virReportOOMError(); return -1; } break; case VIR_DOMAIN_GRAPHICS_TYPE_VNC: - x_vfb->vnc = 1; + libxl_defbool_set(&x_vfb->vnc.enable, 1); /* driver handles selection of free port */ - x_vfb->vncunused = 0; + libxl_defbool_set(&x_vfb->vnc.findunused, 0); if (l_vfb->data.vnc.autoport) { port = libxlNextFreeVncPort(driver, LIBXL_VNC_PORT_MIN); if (port < 0) { @@ -710,13 +718,13 @@ libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainDefPtr def, } l_vfb->data.vnc.port = port; } - x_vfb->vncdisplay = l_vfb->data.vnc.port - LIBXL_VNC_PORT_MIN; + x_vfb->vnc.display = l_vfb->data.vnc.port - LIBXL_VNC_PORT_MIN; listenAddr = virDomainGraphicsListenGetAddress(l_vfb, 0); if (listenAddr) { /* libxl_device_vfb_init() does strdup("127.0.0.1") */ - VIR_FREE(x_vfb->vnclisten); - if ((x_vfb->vnclisten = strdup(listenAddr)) == NULL) { + VIR_FREE(x_vfb->vnc.listen); + if ((x_vfb->vnc.listen = strdup(listenAddr)) == NULL) { virReportOOMError(); return -1; } @@ -729,13 +737,14 @@ libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainDefPtr def, } break; } - x_vfb->domid = def->id; + return 0; } static int libxlMakeVfbList(libxlDriverPrivatePtr driver, - virDomainDefPtr def, libxl_domain_config *d_config) + virDomainDefPtr def, + libxl_domain_config *d_config) { virDomainGraphicsDefPtr *l_vfbs = def->graphics; int nvfbs = def->ngraphics; @@ -757,10 +766,10 @@ libxlMakeVfbList(libxlDriverPrivatePtr driver, } for (i = 0; i < nvfbs; i++) { - libxl_device_vfb_init(&x_vfbs[i], i); - libxl_device_vkb_init(&x_vkbs[i], i); + libxl_device_vfb_init(&x_vfbs[i]); + libxl_device_vkb_init(&x_vkbs[i]); - if (libxlMakeVfb(driver, def, l_vfbs[i], &x_vfbs[i]) < 0) + if (libxlMakeVfb(driver, l_vfbs[i], &x_vfbs[i]) < 0) goto error; } @@ -772,148 +781,14 @@ libxlMakeVfbList(libxlDriverPrivatePtr driver, error: for (i = 0; i < nvfbs; i++) { - libxl_device_vfb_destroy(&x_vfbs[i]); - libxl_device_vkb_destroy(&x_vkbs[i]); + libxl_device_vfb_dispose(&x_vfbs[i]); + libxl_device_vkb_dispose(&x_vkbs[i]); } VIR_FREE(x_vfbs); VIR_FREE(x_vkbs); return -1; } -static int -libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf) -{ - const char *type = virDomainChrTypeToString(def->source.type); - - if (!type) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("unexpected chr device type")); - return -1; - } - - switch (def->source.type) { - case VIR_DOMAIN_CHR_TYPE_NULL: - case VIR_DOMAIN_CHR_TYPE_STDIO: - case VIR_DOMAIN_CHR_TYPE_VC: - case VIR_DOMAIN_CHR_TYPE_PTY: - if (virAsprintf(buf, "%s", type) < 0) { - virReportOOMError(); - return -1; - } - break; - - case VIR_DOMAIN_CHR_TYPE_FILE: - case VIR_DOMAIN_CHR_TYPE_PIPE: - if (virAsprintf(buf, "%s:%s", type, - def->source.data.file.path) < 0) { - virReportOOMError(); - return -1; - } - break; - - case VIR_DOMAIN_CHR_TYPE_DEV: - if (virAsprintf(buf, "%s", def->source.data.file.path) < 0) { - virReportOOMError(); - return -1; - } - break; - } - - return 0; -} - -static int -libxlMakeDeviceModelInfo(virDomainDefPtr def, libxl_domain_config *d_config) -{ - libxl_device_model_info *dm_info = &d_config->dm_info; - int i; - char b_order[VIR_DOMAIN_BOOT_LAST+1]; - - libxl_init_dm_info(dm_info, &d_config->c_info, &d_config->b_info); - - if (d_config->b_info.hvm) { - /* HVM-specific device model info */ - dm_info->type = XENFV; - if (def->os.nBootDevs > 0) { - VIR_FREE(dm_info->boot); - for (i = 0; i < def->os.nBootDevs; i++) { - switch (def->os.bootDevs[i]) { - case VIR_DOMAIN_BOOT_FLOPPY: - b_order[i] = 'a'; - break; - default: - case VIR_DOMAIN_BOOT_DISK: - b_order[i] = 'c'; - break; - case VIR_DOMAIN_BOOT_CDROM: - b_order[i] = 'd'; - break; - case VIR_DOMAIN_BOOT_NET: - b_order[i] = 'n'; - break; - } - } - b_order[def->os.nBootDevs] = '\0'; - if ((dm_info->boot = strdup(b_order)) == NULL) { - virReportOOMError(); - goto error; - } - } - if (def->serials && - (libxlMakeChrdevStr(def->serials[0], &dm_info->serial) < 0)) - goto error; - } else { - /* PV-specific device model info */ - dm_info->type = XENPV; - } - - /* Build qemu graphics options from previously parsed vfb */ - if (d_config->num_vfbs > 0) { - if (d_config->vfbs[0].vnc) { - dm_info->vnc = 1; - /* driver handles selection of free port */ - dm_info->vncunused = 0; - if (d_config->vfbs[0].vnclisten) { - VIR_FREE(dm_info->vnclisten); - if ((dm_info->vnclisten = - strdup(d_config->vfbs[0].vnclisten)) == NULL) { - virReportOOMError(); - goto error; - } - } - if (d_config->vfbs[0].keymap && - (dm_info->keymap = strdup(d_config->vfbs[0].keymap)) == NULL) { - virReportOOMError(); - goto error; - } - dm_info->vncdisplay = d_config->vfbs[0].vncdisplay; - if (d_config->vfbs[0].vncpasswd && - (dm_info->vncpasswd = - strdup(d_config->vfbs[0].vncpasswd)) == NULL) { - virReportOOMError(); - goto error; - } - } else if (d_config->vfbs[0].sdl) { - dm_info->sdl = 1; - dm_info->vnc = 0; - } - } else if (d_config->num_vfbs == 0) { - dm_info->nographic = 1; - dm_info->vnc = 0; - } - - // TODO - //dm_info->usb = ; - //dm_info->usbdevice = ; - //dm_info->soundhw = ; - - return 0; - -error: - libxl_device_model_info_destroy(dm_info); - return -1; -} - virCapsPtr libxlMakeCapabilities(libxl_ctx *ctx) { @@ -947,7 +822,7 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver, virDomainDefPtr def, libxl_domain_config *d_config) { - if (libxlMakeDomCreateInfo(def, &d_config->c_info) < 0) + if (libxlMakeDomCreateInfo(driver, def, &d_config->c_info) < 0) return -1; if (libxlMakeDomBuildInfo(def, d_config) < 0) { @@ -966,10 +841,6 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver, goto error; } - if (libxlMakeDeviceModelInfo(def, d_config) < 0) { - goto error; - } - d_config->on_reboot = def->onReboot; d_config->on_poweroff = def->onPoweroff; d_config->on_crash = def->onCrash; @@ -977,6 +848,6 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver, return 0; error: - libxl_domain_config_destroy(d_config); + libxl_domain_config_dispose(d_config); return -1; } diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index 56bf85c..8b5a9e9 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -58,7 +58,7 @@ struct _libxlDriverPrivate { FILE *logger_file; xentoollog_logger *logger; /* libxl ctx for driver wide ops; getVersion, getNodeInfo, ... */ - libxl_ctx ctx; + libxl_ctx *ctx; virBitmapPtr reservedVNCPorts; virDomainObjList domains; @@ -77,10 +77,8 @@ typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate; typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr; struct _libxlDomainObjPrivate { /* per domain libxl ctx */ - libxl_ctx ctx; - libxl_waiter *dWaiter; - int waiterFD; - int eventHdl; + libxl_ctx *ctx; + libxl_evgen_domain_death *deathW; }; # define LIBXL_SAVE_MAGIC "libvirt-xml\n \0 \r" @@ -100,13 +98,11 @@ virCapsPtr libxlMakeCapabilities(libxl_ctx *ctx); int -libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_dev, - libxl_device_disk *x_dev); +libxlMakeDisk(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev); int -libxlMakeNic(virDomainDefPtr def, virDomainNetDefPtr l_nic, - libxl_device_nic *x_nic); +libxlMakeNic(virDomainNetDefPtr l_nic, libxl_device_nic *x_nic); int -libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainDefPtr def, +libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb); int diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index ae4451a..44d0781 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -40,6 +40,7 @@ #include "memory.h" #include "uuid.h" #include "command.h" +#include "libxl.h" #include "libxl_driver.h" #include "libxl_conf.h" #include "xen_xm.h" @@ -59,6 +60,19 @@ /* Number of Xen scheduler parameters */ #define XEN_SCHED_CREDIT_NPARAM 2 +struct libxlOSEventHookFDInfo { + libxlDomainObjPrivatePtr priv; + void *xl_priv; + int watch; +}; + +struct libxlOSEventHookTimerInfo { + libxlDomainObjPrivatePtr priv; + void *xl_priv; + int id; +}; + + static void libxlDomainManagedSaveLoad(void *payload, const void *n ATTRIBUTE_UNUSED, void *opaque); @@ -84,6 +98,163 @@ libxlDriverUnlock(libxlDriverPrivatePtr driver) virMutexUnlock(&driver->lock); } + +static void libxlFDEventCallback(int watch ATTRIBUTE_UNUSED, + int fd, + int vir_events, + void *fdinfo) +{ + struct libxlOSEventHookFDInfo *info = fdinfo; + int events = 0; + + if (vir_events & VIR_EVENT_HANDLE_READABLE) + events |= POLLIN; + if (vir_events & VIR_EVENT_HANDLE_WRITABLE) + events |= POLLOUT; + if (vir_events & VIR_EVENT_HANDLE_ERROR) + events |= POLLERR; + if (vir_events & VIR_EVENT_HANDLE_HANGUP) + events |= POLLHUP; + + libxl_osevent_occurred_fd(info->priv->ctx, info->xl_priv, fd, 0, events); +} + +static void libxlFreeFDInfo(void *obj) +{ + VIR_FREE(obj); +} + +static int libxlFDRegisterEventHook(void *priv, int fd, void **hndp, + short events, void *xl_priv) +{ + int vir_events = VIR_EVENT_HANDLE_ERROR; + struct libxlOSEventHookFDInfo *fdinfo; + + if (VIR_ALLOC(fdinfo) < 0) { + virReportOOMError(); + return -1; + } + + fdinfo->priv = priv; + fdinfo->xl_priv = xl_priv; + *hndp = fdinfo; + + if (events & POLLIN) + vir_events |= VIR_EVENT_HANDLE_READABLE; + if (events & POLLOUT) + vir_events |= VIR_EVENT_HANDLE_WRITABLE; + fdinfo->watch = virEventAddHandle(fd, vir_events, libxlFDEventCallback, + fdinfo, libxlFreeFDInfo); + if (fdinfo->watch < 0) { + VIR_FREE(fdinfo); + return fdinfo->watch; + } + + return 0; +} + +static int libxlFDModifyEventHook(void *priv ATTRIBUTE_UNUSED, + int fd ATTRIBUTE_UNUSED, + void **hndp, + short events) +{ + struct libxlOSEventHookFDInfo *fdinfo = *hndp; + int vir_events = VIR_EVENT_HANDLE_ERROR; + + if (events & POLLIN) + vir_events |= VIR_EVENT_HANDLE_READABLE; + if (events & POLLOUT) + vir_events |= VIR_EVENT_HANDLE_WRITABLE; + + virEventUpdateHandle(fdinfo->watch, vir_events); + return 0; +} + +static void libxlFDDeregisterEventHook(void *priv ATTRIBUTE_UNUSED, + int fd ATTRIBUTE_UNUSED, + void *hnd) +{ + struct libxlOSEventHookFDInfo *fdinfo = hnd; + + virEventRemoveHandle(fdinfo->watch); +} + + +static void libxlTimerCallback(int timer ATTRIBUTE_UNUSED, void *timer_v) +{ + struct libxlOSEventHookTimerInfo *timer_info = timer_v; + + libxl_osevent_occurred_timeout(timer_info->priv->ctx, timer_info->xl_priv); +} + +static void libxlTimerInfoFree(void* obj) +{ + VIR_FREE(obj); +} + +static int libxlTimeoutRegisterEventHook(void *priv, + void **hndp, + struct timeval abs_t, + void *for_libxl) +{ + struct timeval now; + struct libxlOSEventHookTimerInfo *timer_info; + int timeout, timer_id; + + if (VIR_ALLOC(timer_info) < 0) { + virReportOOMError(); + return -1; + } + + gettimeofday(&now, NULL); + timeout = (abs_t.tv_usec - now.tv_usec) / 1000; + timeout += (abs_t.tv_sec - now.tv_sec) * 1000; + timer_id = virEventAddTimeout(timeout, libxlTimerCallback, + timer_info, libxlTimerInfoFree); + if (timer_id < 0) { + VIR_FREE(timer_info); + return timer_id; + } + + timer_info->priv = priv; + timer_info->xl_priv = for_libxl; + timer_info->id = timer_id; + *hndp = timer_info; + return 0; +} + +static int libxlTimeoutModifyEventHook(void *priv ATTRIBUTE_UNUSED, + void **hndp, + struct timeval abs_t) +{ + struct timeval now; + int timeout; + struct libxlOSEventHookTimerInfo *timer_info = *hndp; + + gettimeofday(&now, NULL); + timeout = (abs_t.tv_usec - now.tv_usec) / 1000; + timeout += (abs_t.tv_sec - now.tv_sec) * 1000; + virEventUpdateTimeout(timer_info->id, timeout); + return 0; +} + +static void libxlTimeoutDeregisterEventHook(void *priv ATTRIBUTE_UNUSED, + void *hnd) +{ + struct libxlOSEventHookTimerInfo *timer_info = hnd; + + virEventRemoveTimeout(timer_info->id); +} + +static const libxl_osevent_hooks libxl_event_callbacks = { + .fd_register = libxlFDRegisterEventHook, + .fd_modify = libxlFDModifyEventHook, + .fd_deregister = libxlFDDeregisterEventHook, + .timeout_register = libxlTimeoutRegisterEventHook, + .timeout_modify = libxlTimeoutModifyEventHook, + .timeout_deregister = libxlTimeoutDeregisterEventHook, +}; + static void * libxlDomainObjPrivateAlloc(void) { @@ -92,9 +263,9 @@ libxlDomainObjPrivateAlloc(void) if (VIR_ALLOC(priv) < 0) return NULL; - libxl_ctx_init(&priv->ctx, LIBXL_VERSION, libxl_driver->logger); - priv->waiterFD = -1; - priv->eventHdl = -1; + libxl_ctx_alloc(&priv->ctx, LIBXL_VERSION, 0, libxl_driver->logger); + priv->deathW = NULL; + libxl_osevent_register_hooks(priv->ctx, &libxl_event_callbacks, priv); return priv; } @@ -104,16 +275,12 @@ libxlDomainObjPrivateFree(void *data) { libxlDomainObjPrivatePtr priv = data; - if (priv->eventHdl >= 0) - virEventRemoveHandle(priv->eventHdl); - - if (priv->dWaiter) { - libxl_stop_waiting(&priv->ctx, priv->dWaiter); - libxl_free_waiter(priv->dWaiter); - VIR_FREE(priv->dWaiter); + if (priv->deathW) { + libxl_evdisable_domain_death(priv->ctx, priv->deathW); + VIR_FREE(priv->deathW); } - libxl_ctx_free(&priv->ctx); + libxl_ctx_free(priv->ctx); VIR_FREE(priv); } @@ -125,17 +292,6 @@ libxlDomainEventQueue(libxlDriverPrivatePtr driver, virDomainEventPtr event) virDomainEventStateQueue(driver->domainEventState, event); } -/* - * Remove reference to domain object. - */ -static void -libxlDomainObjUnref(void *data) -{ - virDomainObjPtr vm = data; - - virObjectUnref(vm); -} - static void libxlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) @@ -166,13 +322,13 @@ libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info) const libxl_version_info* ver_info; struct utsname utsname; - if (libxl_get_physinfo(&driver->ctx, &phy_info)) { + if (libxl_get_physinfo(driver->ctx, &phy_info)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_physinfo_info failed")); return -1; } - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(driver->ctx)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_version_info failed")); return -1; @@ -296,15 +452,9 @@ libxlVmCleanup(libxlDriverPrivatePtr driver, char *file; int i; - if (priv->eventHdl >= 0) { - virEventRemoveHandle(priv->eventHdl); - priv->eventHdl = -1; - } - - if (priv->dWaiter) { - libxl_stop_waiting(&priv->ctx, priv->dWaiter); - libxl_free_waiter(priv->dWaiter); - VIR_FREE(priv->dWaiter); + if (priv->deathW) { + libxl_evdisable_domain_death(priv->ctx, priv->deathW); + priv->deathW = NULL; } if (vm->persistent) { @@ -355,12 +505,11 @@ libxlVmCleanup(libxlDriverPrivatePtr driver, static int libxlVmReap(libxlDriverPrivatePtr driver, virDomainObjPtr vm, - int force, virDomainShutoffReason reason) { libxlDomainObjPrivatePtr priv = vm->privateData; - if (libxl_domain_destroy(&priv->ctx, vm->def->id, force) < 0) { + if (libxl_domain_destroy(priv->ctx, vm->def->id, NULL) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to cleanup domain %d"), vm->def->id); return -1; @@ -373,56 +522,26 @@ libxlVmReap(libxlDriverPrivatePtr driver, /* * Handle previously registered event notification from libxenlight */ -static void libxlEventHandler(int watch, - int fd, - int events, - void *data) +static void libxlEventHandler(void *data, const libxl_event *event) { libxlDriverPrivatePtr driver = libxl_driver; virDomainObjPtr vm = data; - libxlDomainObjPrivatePtr priv; virDomainEventPtr dom_event = NULL; - libxl_event event; - libxl_dominfo info; libxlDriverLock(driver); virDomainObjLock(vm); libxlDriverUnlock(driver); - priv = vm->privateData; - - memset(&event, 0, sizeof(event)); - memset(&info, 0, sizeof(info)); - - if (priv->waiterFD != fd || priv->eventHdl != watch) { - virEventRemoveHandle(watch); - priv->eventHdl = -1; - goto cleanup; - } - - if (!(events & VIR_EVENT_HANDLE_READABLE)) - goto cleanup; - - if (libxl_get_event(&priv->ctx, &event)) - goto cleanup; - - if (event.type == LIBXL_EVENT_DOMAIN_DEATH) { + if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) { virDomainShutoffReason reason; - /* libxl_event_get_domain_death_info returns 1 if death - * event was for this domid */ - if (libxl_event_get_domain_death_info(&priv->ctx, - vm->def->id, - &event, - &info) != 1) + if (event->domid != vm->def->id) goto cleanup; - virEventRemoveHandle(watch); - priv->eventHdl = -1; - switch (info.shutdown_reason) { - case SHUTDOWN_poweroff: - case SHUTDOWN_crash: - if (info.shutdown_reason == SHUTDOWN_crash) { + switch (event->u.domain_shutdown.shutdown_reason) { + case LIBXL_SHUTDOWN_REASON_POWEROFF: + case LIBXL_SHUTDOWN_REASON_CRASH: + if (event->u.domain_shutdown.shutdown_reason == LIBXL_SHUTDOWN_REASON_CRASH) { dom_event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_CRASHED); @@ -430,18 +549,18 @@ static void libxlEventHandler(int watch, } else { reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN; } - libxlVmReap(driver, vm, 0, reason); + libxlVmReap(driver, vm, reason); if (!vm->persistent) { virDomainRemoveInactive(&driver->domains, vm); vm = NULL; } break; - case SHUTDOWN_reboot: - libxlVmReap(driver, vm, 0, VIR_DOMAIN_SHUTOFF_SHUTDOWN); + case LIBXL_SHUTDOWN_REASON_REBOOT: + libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN); libxlVmStart(driver, vm, 0, -1); break; default: - VIR_INFO("Unhandled shutdown_reason %d", info.shutdown_reason); + VIR_INFO("Unhandled shutdown_reason %d", event->u.domain_shutdown.shutdown_reason); break; } } @@ -454,9 +573,14 @@ cleanup: libxlDomainEventQueue(driver, dom_event); libxlDriverUnlock(driver); } - libxl_free_event(&event); } +static const struct libxl_event_hooks ev_hooks = { + .event_occurs_mask = LIBXL_EVENTMASK_ALL, + .event_occurs = libxlEventHandler, + .disaster = NULL, +}; + /* * Register domain events with libxenlight and insert event handles * in libvirt's event loop. @@ -465,40 +589,18 @@ static int libxlCreateDomEvents(virDomainObjPtr vm) { libxlDomainObjPrivatePtr priv = vm->privateData; - int fd; - if (VIR_ALLOC(priv->dWaiter) < 0) { - virReportOOMError(); - return -1; - } - - if (libxl_wait_for_domain_death(&priv->ctx, vm->def->id, priv->dWaiter)) - goto error; - - libxl_get_wait_fd(&priv->ctx, &fd); - if (fd < 0) - goto error; + libxl_event_register_callbacks(priv->ctx, &ev_hooks, vm); - priv->waiterFD = fd; - /* Add a reference to the domain object while it is injected in - * the event loop. - */ - virObjectRef(vm); - if ((priv->eventHdl = virEventAddHandle( - fd, - VIR_EVENT_HANDLE_READABLE | VIR_EVENT_HANDLE_ERROR, - libxlEventHandler, - vm, libxlDomainObjUnref)) < 0) { - virObjectUnref(vm); + if (libxl_evenable_domain_death(priv->ctx, vm->def->id, 0, &priv->deathW)) goto error; - } return 0; error: - libxl_free_waiter(priv->dWaiter); - VIR_FREE(priv->dWaiter); - priv->eventHdl = -1; + if (priv->deathW) + libxl_evdisable_domain_death(priv->ctx, priv->deathW); + VIR_FREE(priv->deathW); return -1; } @@ -507,7 +609,7 @@ libxlDomainSetVcpuAffinites(libxlDriverPrivatePtr driver, virDomainObjPtr vm) { libxlDomainObjPrivatePtr priv = vm->privateData; virDomainDefPtr def = vm->def; - libxl_cpumap map; + libxl_bitmap map; uint8_t *cpumask = NULL; uint8_t *cpumap = NULL; virNodeInfo nodeinfo; @@ -539,7 +641,7 @@ libxlDomainSetVcpuAffinites(libxlDriverPrivatePtr driver, virDomainObjPtr vm) map.size = cpumaplen; map.map = cpumap; - if (libxl_set_vcpuaffinity(&priv->ctx, def->id, vcpu, &map) != 0) { + if (libxl_set_vcpuaffinity(priv->ctx, def->id, vcpu, &map) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to pin vcpu '%d' with libxenlight"), vcpu); goto cleanup; @@ -565,11 +667,10 @@ libxlFreeMem(libxlDomainObjPrivatePtr priv, libxl_domain_config *d_config) int tries = 3; int wait_secs = 10; - if ((ret = libxl_domain_need_memory(&priv->ctx, &d_config->b_info, - &d_config->dm_info, + if ((ret = libxl_domain_need_memory(priv->ctx, &d_config->b_info, &needed_mem)) >= 0) { for (i = 0; i < tries; ++i) { - if ((ret = libxl_get_free_memory(&priv->ctx, &free_mem)) < 0) + if ((ret = libxl_get_free_memory(priv->ctx, &free_mem)) < 0) break; if (free_mem >= needed_mem) { @@ -577,17 +678,17 @@ libxlFreeMem(libxlDomainObjPrivatePtr priv, libxl_domain_config *d_config) break; } - if ((ret = libxl_set_memory_target(&priv->ctx, 0, + if ((ret = libxl_set_memory_target(priv->ctx, 0, free_mem - needed_mem, /* relative */ 1, 0)) < 0) break; - ret = libxl_wait_for_free_memory(&priv->ctx, 0, needed_mem, + ret = libxl_wait_for_free_memory(priv->ctx, 0, needed_mem, wait_secs); if (ret == 0 || ret != ERROR_NOMEM) break; - if ((ret = libxl_wait_for_memory_target(&priv->ctx, 0, 1)) < 0) + if ((ret = libxl_wait_for_memory_target(priv->ctx, 0, 1)) < 0) break; } } @@ -613,7 +714,6 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, char *dom_xml = NULL; char *managed_save_path = NULL; int managed_save_fd = -1; - pid_t child_console_pid = -1; libxlDomainObjPrivatePtr priv = vm->privateData; /* If there is a managed saved state restore it instead of starting @@ -657,7 +757,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, VIR_FREE(managed_save_path); } - memset(&d_config, 0, sizeof(d_config)); + libxl_domain_config_init(&d_config); if (libxlBuildDomainConfig(driver, vm->def, &d_config) < 0) return -1; @@ -669,13 +769,14 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, goto error; } + /* use as synchronous operations => ao_how = NULL and no intermediate reports => ao_progress = NULL */ + if (restore_fd < 0) - ret = libxl_domain_create_new(&priv->ctx, &d_config, - NULL, &child_console_pid, &domid); + ret = libxl_domain_create_new(priv->ctx, &d_config, + &domid, NULL, NULL); else - ret = libxl_domain_create_restore(&priv->ctx, &d_config, NULL, - &child_console_pid, &domid, - restore_fd); + ret = libxl_domain_create_restore(priv->ctx, &d_config, &domid, + restore_fd, NULL, NULL); if (ret) { if (restore_fd < 0) @@ -693,7 +794,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, if ((dom_xml = virDomainDefFormat(vm->def, 0)) == NULL) goto error; - if (libxl_userdata_store(&priv->ctx, domid, "libvirt-xml", + if (libxl_userdata_store(priv->ctx, domid, "libvirt-xml", (uint8_t *)dom_xml, strlen(dom_xml) + 1)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxenlight failed to store userdata")); @@ -707,7 +808,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, goto error; if (!start_paused) { - libxl_domain_unpause(&priv->ctx, domid); + libxl_domain_unpause(priv->ctx, domid); virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED); } else { virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); @@ -723,18 +824,18 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, VIR_DOMAIN_EVENT_STARTED_RESTORED); libxlDomainEventQueue(driver, event); - libxl_domain_config_destroy(&d_config); + libxl_domain_config_dispose(&d_config); VIR_FREE(dom_xml); VIR_FORCE_CLOSE(managed_save_fd); return 0; error: if (domid > 0) { - libxl_domain_destroy(&priv->ctx, domid, 0); + libxl_domain_destroy(priv->ctx, domid, NULL); vm->def->id = -1; virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_FAILED); } - libxl_domain_config_destroy(&d_config); + libxl_domain_config_dispose(&d_config); VIR_FREE(dom_xml); VIR_FREE(managed_save_path); virDomainDefFree(def); @@ -762,7 +863,7 @@ libxlReconnectDomain(void *payload, virDomainObjLock(vm); /* Does domain still exist? */ - rc = libxl_domain_info(&driver->ctx, &d_info, vm->def->id); + rc = libxl_domain_info(driver->ctx, &d_info, vm->def->id); if (rc == ERROR_INVAL) { goto out; } else if (rc != 0) { @@ -772,7 +873,7 @@ libxlReconnectDomain(void *payload, } /* Is this a domain that was under libvirt control? */ - if (libxl_userdata_retrieve(&driver->ctx, vm->def->id, + if (libxl_userdata_retrieve(driver->ctx, vm->def->id, "libvirt-xml", &data, &len)) { VIR_DEBUG("libxl_userdata_retrieve failed, ignoring domain %d", vm->def->id); goto out; @@ -810,7 +911,7 @@ libxlShutdown(void) libxlDriverLock(libxl_driver); virCapabilitiesFree(libxl_driver->caps); virDomainObjListDeinit(&libxl_driver->domains); - libxl_ctx_free(&libxl_driver->ctx); + libxl_ctx_free(libxl_driver->ctx); xtl_logger_destroy(libxl_driver->logger); if (libxl_driver->logger_file) VIR_FORCE_FCLOSE(libxl_driver->logger_file); @@ -943,14 +1044,14 @@ libxlStartup(bool privileged) { goto fail; } - if (libxl_ctx_init(&libxl_driver->ctx, - LIBXL_VERSION, + if (libxl_ctx_alloc(&libxl_driver->ctx, + LIBXL_VERSION, 0, libxl_driver->logger)) { VIR_INFO("cannot initialize libxenlight context, probably not running in a Xen Dom0, disabling driver"); goto fail; } - if ((ver_info = libxl_get_version_info(&libxl_driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(libxl_driver->ctx)) == NULL) { VIR_INFO("cannot version information from libxenlight, disabling driver"); goto fail; } @@ -958,7 +1059,7 @@ libxlStartup(bool privileged) { (ver_info->xen_version_minor * 1000); if ((libxl_driver->caps = - libxlMakeCapabilities(&libxl_driver->ctx)) == NULL) { + libxlMakeCapabilities(libxl_driver->ctx)) == NULL) { VIR_ERROR(_("cannot create capabilities for libxenlight")); goto error; } @@ -1115,7 +1216,7 @@ libxlGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED) int ret; libxlDriverPrivatePtr driver = conn->privateData; - ret = libxl_get_max_cpus(&driver->ctx); + ret = libxl_get_max_cpus(driver->ctx); /* libxl_get_max_cpus() will return 0 if there were any failures, e.g. xc_physinfo() failing */ if (ret == 0) @@ -1320,7 +1421,7 @@ libxlDomainSuspend(virDomainPtr dom) priv = vm->privateData; if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { - if (libxl_domain_pause(&priv->ctx, dom->id) != 0) { + if (libxl_domain_pause(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to suspend domain '%d' with libxenlight"), dom->id); @@ -1379,7 +1480,7 @@ libxlDomainResume(virDomainPtr dom) priv = vm->privateData; if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { - if (libxl_domain_unpause(&priv->ctx, dom->id) != 0) { + if (libxl_domain_unpause(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to resume domain '%d' with libxenlight"), dom->id); @@ -1436,7 +1537,7 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int flags) } priv = vm->privateData; - if (libxl_domain_shutdown(&priv->ctx, dom->id, LIBXL_DOM_REQ_POWEROFF) != 0) { + if (libxl_domain_shutdown(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to shutdown domain '%d' with libxenlight"), dom->id); @@ -1489,7 +1590,7 @@ libxlDomainReboot(virDomainPtr dom, unsigned int flags) } priv = vm->privateData; - if (libxl_domain_shutdown(&priv->ctx, dom->id, LIBXL_DOM_REQ_REBOOT) != 0) { + if (libxl_domain_reboot(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to reboot domain '%d' with libxenlight"), dom->id); @@ -1534,7 +1635,7 @@ libxlDomainDestroyFlags(virDomainPtr dom, event = virDomainEventNewFromObj(vm,VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); - if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_DESTROYED) != 0) { + if (libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), dom->id); goto cleanup; @@ -1672,7 +1773,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, if (flags & VIR_DOMAIN_MEM_LIVE) { priv = vm->privateData; - if (libxl_domain_setmaxmem(&priv->ctx, dom->id, newmem) < 0) { + if (libxl_domain_setmaxmem(priv->ctx, dom->id, newmem) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set maximum memory for domain '%d'" " with libxenlight"), dom->id); @@ -1701,7 +1802,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, if (flags & VIR_DOMAIN_MEM_LIVE) { priv = vm->privateData; - if (libxl_set_memory_target(&priv->ctx, dom->id, newmem, 0, + if (libxl_set_memory_target(priv->ctx, dom->id, newmem, 0, /* force */ 1) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set memory for domain '%d'" @@ -1761,7 +1862,7 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) info->memory = vm->def->mem.cur_balloon; info->maxMem = vm->def->mem.max_balloon; } else { - if (libxl_domain_info(&driver->ctx, &d_info, dom->id) != 0) { + if (libxl_domain_info(driver->ctx, &d_info, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxl_domain_info failed for domain '%d'"), dom->id); goto cleanup; @@ -1861,7 +1962,7 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm, goto cleanup; } - if (libxl_domain_suspend(&priv->ctx, NULL, vm->def->id, fd) != 0) { + if (libxl_domain_suspend(priv->ctx, vm->def->id, fd, 0, NULL) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to save domain '%d' with libxenlight"), vm->def->id); @@ -1871,7 +1972,7 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm, event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SAVED); - if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_SAVED) != 0) { + if (libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SAVED) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), vm->def->id); goto cleanup; @@ -2028,7 +2129,7 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) if (!(flags & VIR_DUMP_LIVE) && virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { - if (libxl_domain_pause(&priv->ctx, dom->id) != 0) { + if (libxl_domain_pause(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Before dumping core, failed to suspend domain '%d'" " with libxenlight"), @@ -2039,7 +2140,7 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) paused = true; } - if (libxl_domain_core_dump(&priv->ctx, dom->id, to) != 0) { + if (libxl_domain_core_dump(priv->ctx, dom->id, to, NULL) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to dump core of domain '%d' with libxenlight"), dom->id); @@ -2048,7 +2149,7 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) libxlDriverLock(driver); if (flags & VIR_DUMP_CRASH) { - if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_CRASHED) != 0) { + if (libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_CRASHED) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), dom->id); goto cleanup_unlock; @@ -2069,7 +2170,7 @@ cleanup_unlock: libxlDriverUnlock(driver); cleanup_unpause: if (virDomainObjIsActive(vm) && paused) { - if (libxl_domain_unpause(&priv->ctx, dom->id) != 0) { + if (libxl_domain_unpause(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("After dumping core, failed to resume domain '%d' with" " libxenlight"), dom->id); @@ -2227,7 +2328,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, libxlDomainObjPrivatePtr priv; virDomainDefPtr def; virDomainObjPtr vm; - libxl_cpumap map; + libxl_bitmap map; uint8_t *bitmask = NULL; unsigned int maplen; unsigned int i, pos; @@ -2322,7 +2423,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, break; case VIR_DOMAIN_VCPU_LIVE: - if (libxl_set_vcpuonline(&priv->ctx, dom->id, &map) != 0) { + if (libxl_set_vcpuonline(priv->ctx, dom->id, &map) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set vcpus for domain '%d'" " with libxenlight"), dom->id); @@ -2331,7 +2432,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, break; case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG: - if (libxl_set_vcpuonline(&priv->ctx, dom->id, &map) != 0) { + if (libxl_set_vcpuonline(priv->ctx, dom->id, &map) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set vcpus for domain '%d'" " with libxenlight"), dom->id); @@ -2427,7 +2528,7 @@ libxlDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap, libxlDomainObjPrivatePtr priv; virDomainObjPtr vm; int ret = -1; - libxl_cpumap map; + libxl_bitmap map; libxlDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -2448,7 +2549,7 @@ libxlDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap, map.size = maplen; map.map = cpumap; - if (libxl_set_vcpuaffinity(&priv->ctx, dom->id, vcpu, &map) != 0) { + if (libxl_set_vcpuaffinity(priv->ctx, dom->id, vcpu, &map) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to pin vcpu '%d' with libxenlight"), vcpu); goto cleanup; @@ -2511,7 +2612,7 @@ libxlDomainGetVcpus(virDomainPtr dom, virVcpuInfoPtr info, int maxinfo, } priv = vm->privateData; - if ((vcpuinfo = libxl_list_vcpu(&priv->ctx, dom->id, &maxcpu, + if ((vcpuinfo = libxl_list_vcpu(priv->ctx, dom->id, &maxcpu, &hostcpus)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to list vcpus for domain '%d' with libxenlight"), @@ -2538,7 +2639,7 @@ libxlDomainGetVcpus(virDomainPtr dom, virVcpuInfoPtr info, int maxinfo, MIN(maplen, vcpuinfo[i].cpumap.size)); } - libxl_vcpuinfo_destroy(&vcpuinfo[i]); + libxl_vcpuinfo_dispose(&vcpuinfo[i]); } VIR_FREE(vcpuinfo); @@ -2596,7 +2697,7 @@ libxlDomainXMLFromNative(virConnectPtr conn, const char * nativeFormat, goto cleanup; } - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(driver->ctx)) == NULL) { VIR_ERROR(_("cannot get version information from libxenlight")); goto cleanup; } @@ -2639,7 +2740,7 @@ libxlDomainXMLToNative(virConnectPtr conn, const char * nativeFormat, goto cleanup; } - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(driver->ctx)) == NULL) { VIR_ERROR(_("cannot get version information from libxenlight")); goto cleanup; } @@ -2899,10 +3000,10 @@ libxlDomainChangeEjectableMedia(libxlDomainObjPrivatePtr priv, return -1; } - if (libxlMakeDisk(vm->def, disk, &x_disk) < 0) + if (libxlMakeDisk(disk, &x_disk) < 0) goto cleanup; - if ((ret = libxl_cdrom_insert(&priv->ctx, vm->def->id, &x_disk)) < 0) { + if ((ret = libxl_cdrom_insert(priv->ctx, vm->def->id, &x_disk, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight failed to change media for disk '%s'"), disk->dst); @@ -2954,11 +3055,11 @@ libxlDomainAttachDeviceDiskLive(libxlDomainObjPrivatePtr priv, goto cleanup; } - if (libxlMakeDisk(vm->def, l_disk, &x_disk) < 0) + if (libxlMakeDisk(l_disk, &x_disk) < 0) goto cleanup; - if ((ret = libxl_device_disk_add(&priv->ctx, vm->def->id, - &x_disk)) < 0) { + if ((ret = libxl_device_disk_add(priv->ctx, vm->def->id, + &x_disk, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight failed to attach disk '%s'"), l_disk->dst); @@ -2991,7 +3092,6 @@ libxlDomainDetachDeviceDiskLive(libxlDomainObjPrivatePtr priv, virDomainDiskDefPtr l_disk = NULL; libxl_device_disk x_disk; int i; - int wait_secs = 2; int ret = -1; switch (dev->data.disk->device) { @@ -3008,11 +3108,11 @@ libxlDomainDetachDeviceDiskLive(libxlDomainObjPrivatePtr priv, l_disk = vm->def->disks[i]; - if (libxlMakeDisk(vm->def, l_disk, &x_disk) < 0) + if (libxlMakeDisk(l_disk, &x_disk) < 0) goto cleanup; - if ((ret = libxl_device_disk_del(&priv->ctx, &x_disk, - wait_secs)) < 0) { + if ((ret = libxl_device_disk_remove(priv->ctx, vm->def->id, + &x_disk, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight failed to detach disk '%s'"), l_disk->dst); @@ -3383,13 +3483,13 @@ libxlNodeGetFreeMemory(virConnectPtr conn) const libxl_version_info* ver_info; libxlDriverPrivatePtr driver = conn->privateData; - if (libxl_get_physinfo(&driver->ctx, &phy_info)) { + if (libxl_get_physinfo(driver->ctx, &phy_info)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_physinfo_info failed")); return 0; } - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(driver->ctx)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_version_info failed")); return 0; @@ -3536,7 +3636,7 @@ libxlDomainGetSchedulerType(virDomainPtr dom, int *nparams) libxlDomainObjPrivatePtr priv; virDomainObjPtr vm; char * ret = NULL; - int sched_id; + libxl_scheduler sched_id; libxlDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -3553,31 +3653,29 @@ libxlDomainGetSchedulerType(virDomainPtr dom, int *nparams) } priv = vm->privateData; - if ((sched_id = libxl_get_sched_id(&priv->ctx)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to get scheduler id for domain '%d'" - " with libxenlight"), dom->id); - goto cleanup; - } + sched_id = libxl_get_scheduler(priv->ctx); if (nparams) *nparams = 0; switch (sched_id) { - case XEN_SCHEDULER_SEDF: + case LIBXL_SCHEDULER_SEDF: ret = strdup("sedf"); break; - case XEN_SCHEDULER_CREDIT: + case LIBXL_SCHEDULER_CREDIT: ret = strdup("credit"); if (nparams) *nparams = XEN_SCHED_CREDIT_NPARAM; break; - case XEN_SCHEDULER_CREDIT2: + case LIBXL_SCHEDULER_CREDIT2: ret = strdup("credit2"); break; - case XEN_SCHEDULER_ARINC653: + case LIBXL_SCHEDULER_ARINC653: ret = strdup("arinc653"); break; default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to get scheduler id for domain '%d'" + " with libxenlight"), dom->id); goto cleanup; } @@ -3599,8 +3697,8 @@ libxlDomainGetSchedulerParametersFlags(virDomainPtr dom, libxlDriverPrivatePtr driver = dom->conn->privateData; libxlDomainObjPrivatePtr priv; virDomainObjPtr vm; - libxl_sched_credit sc_info; - int sched_id; + libxl_domain_sched_params sc_info; + libxl_scheduler sched_id; int ret = -1; virCheckFlags(0, -1); @@ -3610,31 +3708,28 @@ libxlDomainGetSchedulerParametersFlags(virDomainPtr dom, libxlDriverUnlock(driver); if (!vm) { - virReportError(VIR_ERR_NO_DOMAIN, "%s", _("no domain with matching uuid")); + virReportError(VIR_ERR_NO_DOMAIN, "%s", + _("no domain with matching uuid")); goto cleanup; } if (!virDomainObjIsActive(vm)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not running")); + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("Domain is not running")); goto cleanup; } priv = vm->privateData; - if ((sched_id = libxl_get_sched_id(&priv->ctx)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to get scheduler id for domain '%d'" - " with libxenlight"), dom->id); - goto cleanup; - } + sched_id = libxl_get_scheduler(priv->ctx); - if (sched_id != XEN_SCHEDULER_CREDIT) { + if (sched_id != LIBXL_SCHEDULER_CREDIT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only 'credit' scheduler is supported")); goto cleanup; } - if (libxl_sched_credit_domain_get(&priv->ctx, dom->id, &sc_info) != 0) { + if (libxl_domain_sched_params_get(priv->ctx, dom->id, &sc_info) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to get scheduler parameters for domain '%d'" " with libxenlight"), dom->id); @@ -3677,7 +3772,7 @@ libxlDomainSetSchedulerParametersFlags(virDomainPtr dom, libxlDriverPrivatePtr driver = dom->conn->privateData; libxlDomainObjPrivatePtr priv; virDomainObjPtr vm; - libxl_sched_credit sc_info; + libxl_domain_sched_params sc_info; int sched_id; int i; int ret = -1; @@ -3707,20 +3802,15 @@ libxlDomainSetSchedulerParametersFlags(virDomainPtr dom, priv = vm->privateData; - if ((sched_id = libxl_get_sched_id(&priv->ctx)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to get scheduler id for domain '%d'" - " with libxenlight"), dom->id); - goto cleanup; - } + sched_id = libxl_get_scheduler(priv->ctx); - if (sched_id != XEN_SCHEDULER_CREDIT) { + if (sched_id != LIBXL_SCHEDULER_CREDIT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only 'credit' scheduler is supported")); goto cleanup; } - if (libxl_sched_credit_domain_get(&priv->ctx, dom->id, &sc_info) != 0) { + if (libxl_domain_sched_params_get(priv->ctx, dom->id, &sc_info) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to get scheduler parameters for domain '%d'" " with libxenlight"), dom->id); @@ -3737,7 +3827,7 @@ libxlDomainSetSchedulerParametersFlags(virDomainPtr dom, } } - if (libxl_sched_credit_domain_set(&priv->ctx, dom->id, &sc_info) != 0) { + if (libxl_domain_sched_params_set(priv->ctx, dom->id, &sc_info) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set scheduler parameters for domain '%d'" " with libxenlight"), dom->id); -- 1.7.10.4

On 11/30/2012 03:13 PM, Jim Fehlig wrote:
Based on a patch originally authored by Daniel De Graaf
http://lists.xen.org/archives/html/xen-devel/2012-05/msg00565.html
This patch converts the Xen libxl driver to support only Xen >= 4.2. Support for Xen 4.1 libxl is dropped since that version of libxl is designated 'technology preview' only and is incompatible with Xen 4.2 libxl. Additionally, the default toolstack in Xen 4.1 is still xend, for which libvirt has a stable, functional driver. --- V2: Remove 128 vcpu limit. Remove split_string_into_string_list() function copied from xen sources since libvirt now has virStringSplit().
Tested on Fedora 18, with its use of xen 4.2. ACK; let's get this pushed.
@@ -62,7 +64,6 @@ struct guest_arch { static const char *xen_cap_re = "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64|powerpc64)(p|be)?"; static regex_t xen_cap_rec;
- static int libxlNextFreeVncPort(libxlDriverPrivatePtr driver, int startPort) {
This looks like a spurious whitespace change in isolation, but as long as the overall file is consistent on one vs. two blank lines before functions, I don't care if you keep or drop this hunk. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Eric Blake wrote:
On 11/30/2012 03:13 PM, Jim Fehlig wrote:
Based on a patch originally authored by Daniel De Graaf
http://lists.xen.org/archives/html/xen-devel/2012-05/msg00565.html
This patch converts the Xen libxl driver to support only Xen >= 4.2. Support for Xen 4.1 libxl is dropped since that version of libxl is designated 'technology preview' only and is incompatible with Xen 4.2 libxl. Additionally, the default toolstack in Xen 4.1 is still xend, for which libvirt has a stable, functional driver. --- V2: Remove 128 vcpu limit. Remove split_string_into_string_list() function copied from xen sources since libvirt now has virStringSplit().
Tested on Fedora 18, with its use of xen 4.2. ACK; let's get this pushed.
Thanks, pushed.
@@ -62,7 +64,6 @@ struct guest_arch { static const char *xen_cap_re = "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64|powerpc64)(p|be)?"; static regex_t xen_cap_rec;
- static int libxlNextFreeVncPort(libxlDriverPrivatePtr driver, int startPort) {
This looks like a spurious whitespace change in isolation, but as long as the overall file is consistent on one vs. two blank lines before functions, I don't care if you keep or drop this hunk.
That was spurious, and removed before pushing. Regards, Jim

On Thu, 2012-12-06 at 16:20 -0700, Jim Fehlig wrote:
V2: Remove 128 vcpu limit. Remove split_string_into_string_list() function copied from xen sources since libvirt now has virStringSplit().
Tested on Fedora 18, with its use of xen 4.2. ACK; let's get this pushed.
Thanks, pushed.
Cool! (letting virt@lists.fedoraproject.org and xen@lists.fedoraproject.org <xen@lists.fedoraproject.org> know about that!) Dario -- <<This happens because I choose it to happen!>> (Raistlin Majere) ----------------------------------------------------------------- Dario Faggioli, Ph.D, http://retis.sssup.it/people/faggioli Senior Software Engineer, Citrix Systems R&D Ltd., Cambridge (UK)

On 12/07/2012 11:18 AM, Dario Faggioli wrote:
On Thu, 2012-12-06 at 16:20 -0700, Jim Fehlig wrote:
V2: Remove 128 vcpu limit. Remove split_string_into_string_list() function copied from xen sources since libvirt now has virStringSplit().
Tested on Fedora 18, with its use of xen 4.2. ACK; let's get this pushed.
Thanks, pushed.
Cool!
(letting virt@lists.fedoraproject.org and xen@lists.fedoraproject.org <xen@lists.fedoraproject.org> know about that!)
I pushed an F18 build yesterday, but it didn't contain the libxl patch since it wasn't a trivial backport to 0.10.2 and I wanted to get a build out ASAP since it was fixing a CVE. I'll take another stab at the libxl backport later this week. - Cole

On 12/06/2012 03:18 PM, Eric Blake wrote:
On 11/30/2012 03:13 PM, Jim Fehlig wrote:
Based on a patch originally authored by Daniel De Graaf
http://lists.xen.org/archives/html/xen-devel/2012-05/msg00565.html
This patch converts the Xen libxl driver to support only Xen >= 4.2. Support for Xen 4.1 libxl is dropped since that version of libxl is designated 'technology preview' only and is incompatible with Xen 4.2 libxl. Additionally, the default toolstack in Xen 4.1 is still xend, for which libvirt has a stable, functional driver. --- V2: Remove 128 vcpu limit. Remove split_string_into_string_list() function copied from xen sources since libvirt now has virStringSplit().
Tested on Fedora 18, with its use of xen 4.2. ACK; let's get this pushed.
I've also backported this to v0.10.2-maint, since that is the branch used for F18 libvirt. I had some merge conflicts to resolve, so I'll reply to this message with the actual patches that I pushed, if anyone is interested in double-checking them. I went ahead and pushed the backports under the build-breaker rule (as it was interfering with me backporting some other patches to v0.10.2-maint on my F18 box). -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

From: "Daniel P. Berrange" <berrange@redhat.com> This introduces a few new APIs for dealing with strings. One to split a char * into a char **, another to join a char ** into a char *, and finally one to free a char ** There is a simple test suite to validate the edge cases too. No more need to use the horrible strtok_r() API, or hand-written code for splitting strings. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> (cherry picked from commit 76c1fd33c8093d6a7173a85486e1e6f51a832135) Conflicts: tests/Makefile.am - commit eca72d4 not backported --- .gitignore | 1 + src/Makefile.am | 1 + src/libvirt_private.syms | 6 ++ src/util/virstring.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++ src/util/virstring.h | 38 +++++++++++ tests/Makefile.am | 9 ++- tests/virstringtest.c | 161 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 src/util/virstring.c create mode 100644 src/util/virstring.h create mode 100644 tests/virstringtest.c diff --git a/.gitignore b/.gitignore index 004bc76..6db09ef 100644 --- a/.gitignore +++ b/.gitignore @@ -167,6 +167,7 @@ /tests/virkeyfiletest /tests/virnet*test /tests/virshtest +/tests/virstringtest /tests/virtimetest /tests/viruritest /tests/vmx2xmltest diff --git a/src/Makefile.am b/src/Makefile.am index ae3d491..f82c710 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -110,6 +110,7 @@ UTIL_SOURCES = \ util/virnetlink.c util/virnetlink.h \ util/virrandom.h util/virrandom.c \ util/virsocketaddr.h util/virsocketaddr.c \ + util/virstring.h util/virstring.c \ util/virtime.h util/virtime.c \ util/viruri.h util/viruri.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 945894a..45cdace 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1761,6 +1761,12 @@ virSetErrorLogPriorityFunc; virStrerror; +# virstring.h +virStringSplit; +virStringJoin; +virStringFreeList; + + # virtime.h virTimeFieldsNow; virTimeFieldsNowRaw; diff --git a/src/util/virstring.c b/src/util/virstring.c new file mode 100644 index 0000000..1917e9a --- /dev/null +++ b/src/util/virstring.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Authors: + * Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include "virstring.h" +#include "memory.h" +#include "buf.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +/* + * The following virStringSplit & virStringJoin methods + * are derived from g_strsplit / g_strjoin in glib2, + * also available under the LGPLv2+ license terms + */ + +/** + * virStringSplit: + * @string: a string to split + * @delim: a string which specifies the places at which to split + * the string. The delimiter is not included in any of the resulting + * strings, unless @max_tokens is reached. + * @max_tokens: the maximum number of pieces to split @string into. + * If this is 0, the string is split completely. + * + * Splits a string into a maximum of @max_tokens pieces, using the given + * @delim. If @max_tokens is reached, the remainder of @string is + * appended to the last token. + * + * As a special case, the result of splitting the empty string "" is an empty + * vector, not a vector containing a single string. The reason for this + * special case is that being able to represent a empty vector is typically + * more useful than consistent handling of empty elements. If you do need + * to represent empty elements, you'll need to check for the empty string + * before calling virStringSplit(). + * + * Return value: a newly-allocated NULL-terminated array of strings. Use + * virStringFreeList() to free it. + */ +char **virStringSplit(const char *string, + const char *delim, + size_t max_tokens) +{ + char **tokens = NULL; + size_t ntokens = 0; + size_t maxtokens = 0; + const char *remainder = string; + char *tmp; + size_t i; + + if (max_tokens == 0) + max_tokens = INT_MAX; + + tmp = strstr(remainder, delim); + if (tmp) { + size_t delimlen = strlen(delim); + + while (--max_tokens && tmp) { + size_t len = tmp - remainder; + + if (VIR_RESIZE_N(tokens, maxtokens, ntokens, 1) < 0) + goto no_memory; + + if (!(tokens[ntokens] = strndup(remainder, len))) + goto no_memory; + ntokens++; + remainder = tmp + delimlen; + tmp = strstr(remainder, delim); + } + } + if (*string) { + if (VIR_RESIZE_N(tokens, maxtokens, ntokens, 1) < 0) + goto no_memory; + + if (!(tokens[ntokens] = strdup(remainder))) + goto no_memory; + ntokens++; + } + + if (VIR_RESIZE_N(tokens, maxtokens, ntokens, 1) < 0) + goto no_memory; + tokens[ntokens++] = NULL; + + return tokens; + +no_memory: + virReportOOMError(); + for (i = 0 ; i < ntokens ; i++) + VIR_FREE(tokens[i]); + VIR_FREE(tokens); + return NULL; +} + + +/** + * virStringJoin: + * @strings: a NULL-terminated array of strings to join + * @delim: a string to insert between each of the strings + * + * Joins a number of strings together to form one long string, with the + * @delim inserted between each of them. The returned string + * should be freed with VIR_FREE(). + * + * Returns: a newly-allocated string containing all of the strings joined + * together, with @delim between them + */ +char *virStringJoin(const char **strings, + const char *delim) +{ + char *ret; + virBuffer buf = VIR_BUFFER_INITIALIZER; + while (*strings) { + virBufferAdd(&buf, *strings, -1); + if (*(strings+1)) + virBufferAdd(&buf, delim, -1); + strings++; + } + if (virBufferError(&buf)) { + virReportOOMError(); + return NULL; + } + ret = virBufferContentAndReset(&buf); + if (!ret) { + if (!(ret = strdup(""))) { + virReportOOMError(); + return NULL; + } + } + return ret; +} + + +/** + * virStringFreeList: + * @str_array: a NULL-terminated array of strings to free + * + * Frees a NULL-terminated array of strings, and the array itself. + * If called on a NULL value, virStringFreeList() simply returns. + */ +void virStringFreeList(char **strings) +{ + char **tmp = strings; + while (tmp && *tmp) { + VIR_FREE(*tmp); + tmp++; + } + VIR_FREE(strings); +} diff --git a/src/util/virstring.h b/src/util/virstring.h new file mode 100644 index 0000000..a569fe0 --- /dev/null +++ b/src/util/virstring.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2007-2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Authors: + * Daniel P. Berrange <berrange@redhat.com> + */ + +#ifndef __VIR_STRING_H__ +# define __VIR_STRING_H__ + +# include "internal.h" + +char **virStringSplit(const char *string, + const char *delim, + size_t max_tokens) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +char *virStringJoin(const char **strings, + const char *delim) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + +void virStringFreeList(char **strings); + +#endif /* __VIR_STRING_H__ */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 8dbad97..7da0ad5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -93,7 +93,9 @@ test_programs = virshtest sockettest \ utiltest virnettlscontexttest shunloadtest \ virtimetest viruritest virkeyfiletest \ virauthconfigtest \ - virbitmaptest + virbitmaptest \ + virstringtest \ + $(NULL) if WITH_SECDRIVER_SELINUX test_programs += securityselinuxtest @@ -537,6 +539,11 @@ virtimetest_SOURCES = \ virtimetest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS) virtimetest_LDADD = $(LDADDS) +virstringtest_SOURCES = \ + virstringtest.c testutils.h testutils.c +virstringtest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS) +virstringtest_LDADD = $(LDADDS) + viruritest_SOURCES = \ viruritest.c testutils.h testutils.c viruritest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS) diff --git a/tests/virstringtest.c b/tests/virstringtest.c new file mode 100644 index 0000000..7e726c6 --- /dev/null +++ b/tests/virstringtest.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + * Author: Daniel P. Berrange <berrange@redhat.com> + */ + +#include <config.h> + +#include <stdlib.h> + +#include "testutils.h" +#include "util.h" +#include "virterror_internal.h" +#include "memory.h" +#include "logging.h" + +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +struct testSplitData { + const char *string; + const char *delim; + size_t max_tokens; + const char **tokens; +}; + + +struct testJoinData { + const char *string; + const char *delim; + const char **tokens; +}; + +static int testSplit(const void *args) +{ + const struct testSplitData *data = args; + char **got; + char **tmp1; + const char **tmp2; + int ret = -1; + + if (!(got = virStringSplit(data->string, data->delim, data->max_tokens))) { + VIR_DEBUG("Got no tokens at all"); + return -1; + } + + tmp1 = got; + tmp2 = data->tokens; + while (*tmp1 && *tmp2) { + if (STRNEQ(*tmp1, *tmp2)) { + fprintf(stderr, "Mismatch '%s' vs '%s'\n", *tmp1, *tmp2); + goto cleanup; + } + tmp1++; + tmp2++; + } + if (*tmp1) { + fprintf(stderr, "Too many pieces returned\n"); + goto cleanup; + } + if (*tmp2) { + fprintf(stderr, "Too few pieces returned\n"); + goto cleanup; + } + + ret = 0; +cleanup: + virStringFreeList(got); + + return ret; +} + + +static int testJoin(const void *args) +{ + const struct testJoinData *data = args; + char *got; + int ret = -1; + + if (!(got = virStringJoin(data->tokens, data->delim))) { + VIR_DEBUG("Got no result"); + return -1; + } + if (STRNEQ(got, data->string)) { + fprintf(stderr, "Mismatch '%s' vs '%s'\n", got, data->string); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FREE(got); + + return ret; +} + + +static int +mymain(void) +{ + int ret = 0; + +#define TEST_SPLIT(str, del, max, toks) \ + do { \ + struct testSplitData splitData = { \ + .string = str, \ + .delim = del, \ + .max_tokens = max, \ + .tokens = toks, \ + }; \ + struct testJoinData joinData = { \ + .string = str, \ + .delim = del, \ + .tokens = toks, \ + }; \ + if (virtTestRun("Split " #str, 1, testSplit, &splitData) < 0) \ + ret = -1; \ + if (virtTestRun("Join " #str, 1, testJoin, &joinData) < 0) \ + ret = -1; \ + } while (0) + + const char *tokens1[] = { NULL }; + TEST_SPLIT("", " ", 0, tokens1); + + const char *tokens2[] = { "", "", NULL }; + TEST_SPLIT(" ", " ", 0, tokens2); + + const char *tokens3[] = { "", "", "", NULL }; + TEST_SPLIT(" ", " ", 0, tokens3); + + const char *tokens4[] = { "The", "quick", "brown", "fox", NULL }; + TEST_SPLIT("The quick brown fox", " ", 0, tokens4); + + const char *tokens5[] = { "The quick ", " fox", NULL }; + TEST_SPLIT("The quick brown fox", "brown", 0, tokens5); + + const char *tokens6[] = { "", "The", "quick", "brown", "fox", NULL }; + TEST_SPLIT(" The quick brown fox", " ", 0, tokens6); + + const char *tokens7[] = { "The", "quick", "brown", "fox", "", NULL }; + TEST_SPLIT("The quick brown fox ", " ", 0, tokens7); + + + return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN(mymain) -- 1.8.0.2

From: Jim Fehlig <jfehlig@suse.com> Based on a patch originally authored by Daniel De Graaf http://lists.xen.org/archives/html/xen-devel/2012-05/msg00565.html This patch converts the Xen libxl driver to support only Xen >= 4.2. Support for Xen 4.1 libxl is dropped since that version of libxl is designated 'technology preview' only and is incompatible with Xen 4.2 libxl. Additionally, the default toolstack in Xen 4.1 is still xend, for which libvirt has a stable, functional driver. (cherry picked from commit dfa1e1dd5325f3a6bc8865312cde557044bf0b93) Conflicts: src/libxl/libxl_conf.c - commit e5e8d5 not backported src/libxl/libxl_driver.c - commit 1c04f99 not backported --- configure.ac | 8 +- docs/drvxen.html.in | 8 + libvirt.spec.in | 4 +- src/libxl/libxl_conf.c | 325 ++++++++++--------------------- src/libxl/libxl_conf.h | 16 +- src/libxl/libxl_driver.c | 490 ++++++++++++++++++++++++++++------------------- 6 files changed, 407 insertions(+), 444 deletions(-) diff --git a/configure.ac b/configure.ac index e9600ef..c3fa6ed 100644 --- a/configure.ac +++ b/configure.ac @@ -715,16 +715,14 @@ if test "$with_libxl" != "no" ; then fi CFLAGS="$CFLAGS $LIBXL_CFLAGS" LIBS="$LIBS $LIBXL_LIBS" - AC_CHECK_LIB([xenlight], [libxl_domain_create_new], [ + AC_CHECK_LIB([xenlight], [libxl_ctx_alloc], [ with_libxl=yes - LIBXL_LIBS="$LIBXL_LIBS -lxenlight -lxenstore -lxenctrl -lxenguest -luuid -lutil -lblktapctl" + LIBXL_LIBS="$LIBXL_LIBS -lxenlight" ],[ if test "$with_libxl" = "yes"; then fail=1 fi with_libxl=no - ],[ - -lxenstore -lxenctrl -lxenguest -luuid -lutil -lblktapctl ]) fi @@ -732,7 +730,7 @@ LIBS="$old_LIBS" CFLAGS="$old_CFLAGS" if test $fail = 1; then - AC_MSG_ERROR([You must install the libxl Library to compile libxenlight driver with -lxl]) + AC_MSG_ERROR([You must install the libxl Library from Xen >= 4.2 to compile libxenlight driver with -lxl]) fi if test "$with_libxl" = "yes"; then diff --git a/docs/drvxen.html.in b/docs/drvxen.html.in index 0bca935..06bd911 100644 --- a/docs/drvxen.html.in +++ b/docs/drvxen.html.in @@ -53,6 +53,14 @@ the <code>/etc/xen</code> directory. It is important not to place any other non-config files in this directory. </li> + <li> + <strong>libxl</strong>: Starting with Xen 4.2, the legacy XenD/xm + toolstack is deprecated in favor of libxl, also commonly called + libxenlight. libvirt supports this new Xen toolstack via the + libxl driver. If XenD is enabled, the legacy xen driver consisting + of the above mentioned channels will be used. If XenD is disabled, + the libxl driver will be used. + </li> </ul> <h2><a name="uri">Connections to Xen driver</a></h2> diff --git a/libvirt.spec.in b/libvirt.spec.in index 2dbba3a..70922c2 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -188,8 +188,8 @@ %endif %endif -# Fedora doesn't have new enough Xen for libxl until F16 -%if 0%{?fedora} && 0%{?fedora} < 16 +# Fedora doesn't have new enough Xen for libxl until F18 +%if 0%{?fedora} && 0%{?fedora} < 18 %define with_libxl 0 %endif diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index b988fa7..07221fc 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -36,12 +36,13 @@ #include "virterror_internal.h" #include "datatypes.h" #include "virfile.h" +#include "virstring.h" #include "memory.h" #include "uuid.h" #include "capabilities.h" #include "libxl_driver.h" #include "libxl_conf.h" - +#include "libxl_utils.h" #define VIR_FROM_THIS VIR_FROM_LIBXL @@ -358,18 +359,36 @@ libxlMakeCapabilitiesInternal(const char *hostmachine, } static int -libxlMakeDomCreateInfo(virDomainDefPtr def, libxl_domain_create_info *c_info) +libxlMakeDomCreateInfo(libxlDriverPrivatePtr driver, + virDomainDefPtr def, + libxl_domain_create_info *c_info) { char uuidstr[VIR_UUID_STRING_BUFLEN]; - libxl_init_create_info(c_info); + libxl_domain_create_info_init(c_info); + + if (STREQ(def->os.type, "hvm")) + c_info->type = LIBXL_DOMAIN_TYPE_HVM; + else + c_info->type = LIBXL_DOMAIN_TYPE_PV; - c_info->hvm = STREQ(def->os.type, "hvm"); if ((c_info->name = strdup(def->name)) == NULL) { virReportOOMError(); goto error; } + if (def->nseclabels && + def->seclabels[0]->type == VIR_DOMAIN_SECLABEL_STATIC) { + if (libxl_flask_context_to_sid(driver->ctx, + def->seclabels[0]->label, + strlen(def->seclabels[0]->label), + &c_info->ssidref)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("libxenlight failed to resolve security label '%s'"), + def->seclabels[0]->label); + } + } + virUUIDFormat(def->uuid, uuidstr); if (libxl_uuid_from_string(&c_info->uuid, uuidstr) ) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -380,7 +399,7 @@ libxlMakeDomCreateInfo(virDomainDefPtr def, libxl_domain_create_info *c_info) return 0; error: - libxl_domain_create_info_destroy(c_info); + libxl_domain_create_info_dispose(c_info); return -1; } @@ -391,26 +410,14 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) int hvm = STREQ(def->os.type, "hvm"); int i; - /* Currently, libxenlight only supports 32 vcpus per domain. - * cur_vcpus member of struct libxl_domain_build_info is defined - * as an int, but its semantic is a bitmap of online vcpus, so - * only 32 can be represented. - */ - if (def->maxvcpus > 32 || def->vcpus > 32) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("This version of libxenlight only supports 32 " - "vcpus per domain")); - return -1; - } + libxl_domain_build_info_init(b_info); - libxl_init_build_info(b_info, &d_config->c_info); - - b_info->hvm = hvm; - b_info->max_vcpus = def->maxvcpus; - if (def->vcpus == 32) - b_info->cur_vcpus = (uint32_t) -1; + if (hvm) + libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_HVM); else - b_info->cur_vcpus = (1 << def->vcpus) - 1; + libxl_domain_build_info_init_type(b_info, LIBXL_DOMAIN_TYPE_PV); + b_info->max_vcpus = def->maxvcpus; + libxl_bitmap_set((&b_info->avail_vcpus), def->vcpus); if (def->clock.ntimers > 0 && def->clock.timers[0]->name == VIR_DOMAIN_TIMER_NAME_TSC) { switch (def->clock.timers[0]->mode) { @@ -424,16 +431,20 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) 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) { - b_info->u.hvm.pae = def->features & (1 << VIR_DOMAIN_FEATURE_PAE); - b_info->u.hvm.apic = def->features & (1 << VIR_DOMAIN_FEATURE_APIC); - b_info->u.hvm.acpi = def->features & (1 << VIR_DOMAIN_FEATURE_ACPI); + libxl_defbool_set(&b_info->u.hvm.pae, + def->features & (1 << VIR_DOMAIN_FEATURE_PAE)); + libxl_defbool_set(&b_info->u.hvm.apic, + def->features & (1 << VIR_DOMAIN_FEATURE_APIC)); + libxl_defbool_set(&b_info->u.hvm.acpi, + def->features & (1 << VIR_DOMAIN_FEATURE_ACPI)); 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) { - b_info->u.hvm.hpet = 1; + libxl_defbool_set(&b_info->u.hvm.hpet, 1); } } @@ -444,7 +455,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) * 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 * b_info->cur_vcpus + + b_info->shadow_memkb = 4 * (256 * libxl_bitmap_count_set(&b_info->avail_vcpus) + 2 * (b_info->max_memkb / 1024)); } else { if (def->os.bootloader) { @@ -454,10 +465,9 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) } } if (def->os.bootloaderArgs) { - if ((b_info->u.pv.bootloader_args = strdup(def->os.bootloaderArgs)) == NULL) { - virReportOOMError(); + if (!(b_info->u.pv.bootloader_args = + virStringSplit(def->os.bootloaderArgs, " \t\n", 0))) goto error; - } } if (def->os.cmdline) { if ((b_info->u.pv.cmdline = strdup(def->os.cmdline)) == NULL) { @@ -467,14 +477,14 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) } if (def->os.kernel) { /* libxl_init_build_info() sets kernel.path = strdup("hvmloader") */ - VIR_FREE(b_info->kernel.path); - if ((b_info->kernel.path = strdup(def->os.kernel)) == NULL) { + VIR_FREE(b_info->u.pv.kernel); + if ((b_info->u.pv.kernel = strdup(def->os.kernel)) == NULL) { virReportOOMError(); goto error; } } if (def->os.initrd) { - if ((b_info->u.pv.ramdisk.path = strdup(def->os.initrd)) == NULL) { + if ((b_info->u.pv.ramdisk = strdup(def->os.initrd)) == NULL) { virReportOOMError(); goto error; } @@ -484,13 +494,12 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config) return 0; error: - libxl_domain_build_info_destroy(b_info); + libxl_domain_build_info_dispose(b_info); return -1; } int -libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, - libxl_device_disk *x_disk) +libxlMakeDisk(virDomainDiskDefPtr l_disk, libxl_device_disk *x_disk) { if (l_disk->src && (x_disk->pdev_path = strdup(l_disk->src)) == NULL) { virReportOOMError(); @@ -507,30 +516,30 @@ libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, STREQ(l_disk->driverName, "tap2")) { if (l_disk->driverType) { if (STREQ(l_disk->driverType, "qcow")) { - x_disk->format = DISK_FORMAT_QCOW; - x_disk->backend = DISK_BACKEND_QDISK; + x_disk->format = LIBXL_DISK_FORMAT_QCOW; + x_disk->backend = LIBXL_DISK_BACKEND_QDISK; } else if (STREQ(l_disk->driverType, "qcow2")) { - x_disk->format = DISK_FORMAT_QCOW2; - x_disk->backend = DISK_BACKEND_QDISK; + x_disk->format = LIBXL_DISK_FORMAT_QCOW2; + x_disk->backend = LIBXL_DISK_BACKEND_QDISK; } else if (STREQ(l_disk->driverType, "vhd")) { - x_disk->format = DISK_FORMAT_VHD; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_VHD; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; } else if (STREQ(l_disk->driverType, "aio") || STREQ(l_disk->driverType, "raw")) { - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; } } else { /* No subtype specified, default to raw/tap */ - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; } } else if (STREQ(l_disk->driverName, "file")) { - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; } else if (STREQ(l_disk->driverName, "phy")) { - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_PHY; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_PHY; } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight does not support disk driver %s"), @@ -539,12 +548,12 @@ libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, } } else { /* No driverName - default to raw/tap?? */ - x_disk->format = DISK_FORMAT_RAW; - x_disk->backend = DISK_BACKEND_TAP; + x_disk->format = LIBXL_DISK_FORMAT_RAW; + x_disk->backend = LIBXL_DISK_BACKEND_TAP; } - /* How to set unpluggable? */ - x_disk->unpluggable = 1; + /* XXX is this right? */ + x_disk->removable = 1; x_disk->readwrite = !l_disk->readonly; x_disk->is_cdrom = l_disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM ? 1 : 0; if (l_disk->transient) { @@ -553,8 +562,6 @@ libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_disk, return -1; } - x_disk->domid = def->id; - return 0; } @@ -572,7 +579,7 @@ libxlMakeDiskList(virDomainDefPtr def, libxl_domain_config *d_config) } for (i = 0; i < ndisks; i++) { - if (libxlMakeDisk(def, l_disks[i], &x_disks[i]) < 0) + if (libxlMakeDisk(l_disks[i], &x_disks[i]) < 0) goto error; } @@ -583,19 +590,19 @@ libxlMakeDiskList(virDomainDefPtr def, libxl_domain_config *d_config) error: for (i = 0; i < ndisks; i++) - libxl_device_disk_destroy(&x_disks[i]); + libxl_device_disk_dispose(&x_disks[i]); VIR_FREE(x_disks); return -1; } int -libxlMakeNic(virDomainDefPtr def, virDomainNetDefPtr l_nic, - libxl_device_nic *x_nic) +libxlMakeNic(virDomainNetDefPtr l_nic, libxl_device_nic *x_nic) { - // TODO: Where is mtu stored? - //x_nics[i].mtu = 1492; + /* TODO: Where is mtu stored? + * + * x_nics[i].mtu = 1492; + */ - x_nic->domid = def->id; virMacAddrGetRaw(&l_nic->mac, x_nic->mac); if (l_nic->model && !STREQ(l_nic->model, "netfront")) { @@ -603,9 +610,9 @@ libxlMakeNic(virDomainDefPtr def, virDomainNetDefPtr l_nic, virReportOOMError(); return -1; } - x_nic->nictype = NICTYPE_IOEMU; + x_nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU; } else { - x_nic->nictype = NICTYPE_VIF; + x_nic->nictype = LIBXL_NIC_TYPE_VIF; } if (l_nic->ifname && (x_nic->ifname = strdup(l_nic->ifname)) == NULL) { @@ -652,48 +659,49 @@ libxlMakeNicList(virDomainDefPtr def, libxl_domain_config *d_config) for (i = 0; i < nnics; i++) { x_nics[i].devid = i; - if (libxlMakeNic(def, l_nics[i], &x_nics[i])) + if (libxlMakeNic(l_nics[i], &x_nics[i])) goto error; } - d_config->vifs = x_nics; - d_config->num_vifs = nnics; + d_config->nics = x_nics; + d_config->num_nics = nnics; return 0; error: for (i = 0; i < nnics; i++) - libxl_device_nic_destroy(&x_nics[i]); + libxl_device_nic_dispose(&x_nics[i]); VIR_FREE(x_nics); return -1; } int -libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainDefPtr def, - virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb) +libxlMakeVfb(libxlDriverPrivatePtr driver, + virDomainGraphicsDefPtr l_vfb, + libxl_device_vfb *x_vfb) { int port; const char *listenAddr; switch (l_vfb->type) { case VIR_DOMAIN_GRAPHICS_TYPE_SDL: - x_vfb->sdl = 1; + libxl_defbool_set(&x_vfb->sdl.enable, 1); if (l_vfb->data.sdl.display && - (x_vfb->display = strdup(l_vfb->data.sdl.display)) == NULL) { + (x_vfb->sdl.display = strdup(l_vfb->data.sdl.display)) == NULL) { virReportOOMError(); return -1; } if (l_vfb->data.sdl.xauth && - (x_vfb->xauthority = + (x_vfb->sdl.xauthority = strdup(l_vfb->data.sdl.xauth)) == NULL) { virReportOOMError(); return -1; } break; case VIR_DOMAIN_GRAPHICS_TYPE_VNC: - x_vfb->vnc = 1; + libxl_defbool_set(&x_vfb->vnc.enable, 1); /* driver handles selection of free port */ - x_vfb->vncunused = 0; + libxl_defbool_set(&x_vfb->vnc.findunused, 0); if (l_vfb->data.vnc.autoport) { port = libxlNextFreeVncPort(driver, LIBXL_VNC_PORT_MIN); if (port < 0) { @@ -703,13 +711,13 @@ libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainDefPtr def, } l_vfb->data.vnc.port = port; } - x_vfb->vncdisplay = l_vfb->data.vnc.port - LIBXL_VNC_PORT_MIN; + x_vfb->vnc.display = l_vfb->data.vnc.port - LIBXL_VNC_PORT_MIN; listenAddr = virDomainGraphicsListenGetAddress(l_vfb, 0); if (listenAddr) { /* libxl_device_vfb_init() does strdup("127.0.0.1") */ - VIR_FREE(x_vfb->vnclisten); - if ((x_vfb->vnclisten = strdup(listenAddr)) == NULL) { + VIR_FREE(x_vfb->vnc.listen); + if ((x_vfb->vnc.listen = strdup(listenAddr)) == NULL) { virReportOOMError(); return -1; } @@ -722,13 +730,14 @@ libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainDefPtr def, } break; } - x_vfb->domid = def->id; + return 0; } static int libxlMakeVfbList(libxlDriverPrivatePtr driver, - virDomainDefPtr def, libxl_domain_config *d_config) + virDomainDefPtr def, + libxl_domain_config *d_config) { virDomainGraphicsDefPtr *l_vfbs = def->graphics; int nvfbs = def->ngraphics; @@ -750,10 +759,10 @@ libxlMakeVfbList(libxlDriverPrivatePtr driver, } for (i = 0; i < nvfbs; i++) { - libxl_device_vfb_init(&x_vfbs[i], i); - libxl_device_vkb_init(&x_vkbs[i], i); + libxl_device_vfb_init(&x_vfbs[i]); + libxl_device_vkb_init(&x_vkbs[i]); - if (libxlMakeVfb(driver, def, l_vfbs[i], &x_vfbs[i]) < 0) + if (libxlMakeVfb(driver, l_vfbs[i], &x_vfbs[i]) < 0) goto error; } @@ -765,148 +774,14 @@ libxlMakeVfbList(libxlDriverPrivatePtr driver, error: for (i = 0; i < nvfbs; i++) { - libxl_device_vfb_destroy(&x_vfbs[i]); - libxl_device_vkb_destroy(&x_vkbs[i]); + libxl_device_vfb_dispose(&x_vfbs[i]); + libxl_device_vkb_dispose(&x_vkbs[i]); } VIR_FREE(x_vfbs); VIR_FREE(x_vkbs); return -1; } -static int -libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf) -{ - const char *type = virDomainChrTypeToString(def->source.type); - - if (!type) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("unexpected chr device type")); - return -1; - } - - switch (def->source.type) { - case VIR_DOMAIN_CHR_TYPE_NULL: - case VIR_DOMAIN_CHR_TYPE_STDIO: - case VIR_DOMAIN_CHR_TYPE_VC: - case VIR_DOMAIN_CHR_TYPE_PTY: - if (virAsprintf(buf, "%s", type) < 0) { - virReportOOMError(); - return -1; - } - break; - - case VIR_DOMAIN_CHR_TYPE_FILE: - case VIR_DOMAIN_CHR_TYPE_PIPE: - if (virAsprintf(buf, "%s:%s", type, - def->source.data.file.path) < 0) { - virReportOOMError(); - return -1; - } - break; - - case VIR_DOMAIN_CHR_TYPE_DEV: - if (virAsprintf(buf, "%s", def->source.data.file.path) < 0) { - virReportOOMError(); - return -1; - } - break; - } - - return 0; -} - -static int -libxlMakeDeviceModelInfo(virDomainDefPtr def, libxl_domain_config *d_config) -{ - libxl_device_model_info *dm_info = &d_config->dm_info; - int i; - char b_order[VIR_DOMAIN_BOOT_LAST+1]; - - libxl_init_dm_info(dm_info, &d_config->c_info, &d_config->b_info); - - if (d_config->b_info.hvm) { - /* HVM-specific device model info */ - dm_info->type = XENFV; - if (def->os.nBootDevs > 0) { - VIR_FREE(dm_info->boot); - for (i = 0; i < def->os.nBootDevs; i++) { - switch (def->os.bootDevs[i]) { - case VIR_DOMAIN_BOOT_FLOPPY: - b_order[i] = 'a'; - break; - default: - case VIR_DOMAIN_BOOT_DISK: - b_order[i] = 'c'; - break; - case VIR_DOMAIN_BOOT_CDROM: - b_order[i] = 'd'; - break; - case VIR_DOMAIN_BOOT_NET: - b_order[i] = 'n'; - break; - } - } - b_order[def->os.nBootDevs] = '\0'; - if ((dm_info->boot = strdup(b_order)) == NULL) { - virReportOOMError(); - goto error; - } - } - if (def->serials && - (libxlMakeChrdevStr(def->serials[0], &dm_info->serial) < 0)) - goto error; - } else { - /* PV-specific device model info */ - dm_info->type = XENPV; - } - - /* Build qemu graphics options from previously parsed vfb */ - if (d_config->num_vfbs > 0) { - if (d_config->vfbs[0].vnc) { - dm_info->vnc = 1; - /* driver handles selection of free port */ - dm_info->vncunused = 0; - if (d_config->vfbs[0].vnclisten) { - VIR_FREE(dm_info->vnclisten); - if ((dm_info->vnclisten = - strdup(d_config->vfbs[0].vnclisten)) == NULL) { - virReportOOMError(); - goto error; - } - } - if (d_config->vfbs[0].keymap && - (dm_info->keymap = strdup(d_config->vfbs[0].keymap)) == NULL) { - virReportOOMError(); - goto error; - } - dm_info->vncdisplay = d_config->vfbs[0].vncdisplay; - if (d_config->vfbs[0].vncpasswd && - (dm_info->vncpasswd = - strdup(d_config->vfbs[0].vncpasswd)) == NULL) { - virReportOOMError(); - goto error; - } - } else if (d_config->vfbs[0].sdl) { - dm_info->sdl = 1; - dm_info->vnc = 0; - } - } else if (d_config->num_vfbs == 0) { - dm_info->nographic = 1; - dm_info->vnc = 0; - } - - // TODO - //dm_info->usb = ; - //dm_info->usbdevice = ; - //dm_info->soundhw = ; - - return 0; - -error: - libxl_device_model_info_destroy(dm_info); - return -1; -} - virCapsPtr libxlMakeCapabilities(libxl_ctx *ctx) { @@ -940,7 +815,7 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver, virDomainDefPtr def, libxl_domain_config *d_config) { - if (libxlMakeDomCreateInfo(def, &d_config->c_info) < 0) + if (libxlMakeDomCreateInfo(driver, def, &d_config->c_info) < 0) return -1; if (libxlMakeDomBuildInfo(def, d_config) < 0) { @@ -959,10 +834,6 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver, goto error; } - if (libxlMakeDeviceModelInfo(def, d_config) < 0) { - goto error; - } - d_config->on_reboot = def->onReboot; d_config->on_poweroff = def->onPoweroff; d_config->on_crash = def->onCrash; @@ -970,6 +841,6 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver, return 0; error: - libxl_domain_config_destroy(d_config); + libxl_domain_config_dispose(d_config); return -1; } diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index 56bf85c..8b5a9e9 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -58,7 +58,7 @@ struct _libxlDriverPrivate { FILE *logger_file; xentoollog_logger *logger; /* libxl ctx for driver wide ops; getVersion, getNodeInfo, ... */ - libxl_ctx ctx; + libxl_ctx *ctx; virBitmapPtr reservedVNCPorts; virDomainObjList domains; @@ -77,10 +77,8 @@ typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate; typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr; struct _libxlDomainObjPrivate { /* per domain libxl ctx */ - libxl_ctx ctx; - libxl_waiter *dWaiter; - int waiterFD; - int eventHdl; + libxl_ctx *ctx; + libxl_evgen_domain_death *deathW; }; # define LIBXL_SAVE_MAGIC "libvirt-xml\n \0 \r" @@ -100,13 +98,11 @@ virCapsPtr libxlMakeCapabilities(libxl_ctx *ctx); int -libxlMakeDisk(virDomainDefPtr def, virDomainDiskDefPtr l_dev, - libxl_device_disk *x_dev); +libxlMakeDisk(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev); int -libxlMakeNic(virDomainDefPtr def, virDomainNetDefPtr l_nic, - libxl_device_nic *x_nic); +libxlMakeNic(virDomainNetDefPtr l_nic, libxl_device_nic *x_nic); int -libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainDefPtr def, +libxlMakeVfb(libxlDriverPrivatePtr driver, virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb); int diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 6fe284f..fa2f3ff 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -40,6 +40,7 @@ #include "memory.h" #include "uuid.h" #include "command.h" +#include "libxl.h" #include "libxl_driver.h" #include "libxl_conf.h" #include "xen_xm.h" @@ -59,6 +60,19 @@ /* Number of Xen scheduler parameters */ #define XEN_SCHED_CREDIT_NPARAM 2 +struct libxlOSEventHookFDInfo { + libxlDomainObjPrivatePtr priv; + void *xl_priv; + int watch; +}; + +struct libxlOSEventHookTimerInfo { + libxlDomainObjPrivatePtr priv; + void *xl_priv; + int id; +}; + + static void libxlDomainManagedSaveLoad(void *payload, const void *n ATTRIBUTE_UNUSED, void *opaque); @@ -84,6 +98,163 @@ libxlDriverUnlock(libxlDriverPrivatePtr driver) virMutexUnlock(&driver->lock); } + +static void libxlFDEventCallback(int watch ATTRIBUTE_UNUSED, + int fd, + int vir_events, + void *fdinfo) +{ + struct libxlOSEventHookFDInfo *info = fdinfo; + int events = 0; + + if (vir_events & VIR_EVENT_HANDLE_READABLE) + events |= POLLIN; + if (vir_events & VIR_EVENT_HANDLE_WRITABLE) + events |= POLLOUT; + if (vir_events & VIR_EVENT_HANDLE_ERROR) + events |= POLLERR; + if (vir_events & VIR_EVENT_HANDLE_HANGUP) + events |= POLLHUP; + + libxl_osevent_occurred_fd(info->priv->ctx, info->xl_priv, fd, 0, events); +} + +static void libxlFreeFDInfo(void *obj) +{ + VIR_FREE(obj); +} + +static int libxlFDRegisterEventHook(void *priv, int fd, void **hndp, + short events, void *xl_priv) +{ + int vir_events = VIR_EVENT_HANDLE_ERROR; + struct libxlOSEventHookFDInfo *fdinfo; + + if (VIR_ALLOC(fdinfo) < 0) { + virReportOOMError(); + return -1; + } + + fdinfo->priv = priv; + fdinfo->xl_priv = xl_priv; + *hndp = fdinfo; + + if (events & POLLIN) + vir_events |= VIR_EVENT_HANDLE_READABLE; + if (events & POLLOUT) + vir_events |= VIR_EVENT_HANDLE_WRITABLE; + fdinfo->watch = virEventAddHandle(fd, vir_events, libxlFDEventCallback, + fdinfo, libxlFreeFDInfo); + if (fdinfo->watch < 0) { + VIR_FREE(fdinfo); + return fdinfo->watch; + } + + return 0; +} + +static int libxlFDModifyEventHook(void *priv ATTRIBUTE_UNUSED, + int fd ATTRIBUTE_UNUSED, + void **hndp, + short events) +{ + struct libxlOSEventHookFDInfo *fdinfo = *hndp; + int vir_events = VIR_EVENT_HANDLE_ERROR; + + if (events & POLLIN) + vir_events |= VIR_EVENT_HANDLE_READABLE; + if (events & POLLOUT) + vir_events |= VIR_EVENT_HANDLE_WRITABLE; + + virEventUpdateHandle(fdinfo->watch, vir_events); + return 0; +} + +static void libxlFDDeregisterEventHook(void *priv ATTRIBUTE_UNUSED, + int fd ATTRIBUTE_UNUSED, + void *hnd) +{ + struct libxlOSEventHookFDInfo *fdinfo = hnd; + + virEventRemoveHandle(fdinfo->watch); +} + + +static void libxlTimerCallback(int timer ATTRIBUTE_UNUSED, void *timer_v) +{ + struct libxlOSEventHookTimerInfo *timer_info = timer_v; + + libxl_osevent_occurred_timeout(timer_info->priv->ctx, timer_info->xl_priv); +} + +static void libxlTimerInfoFree(void* obj) +{ + VIR_FREE(obj); +} + +static int libxlTimeoutRegisterEventHook(void *priv, + void **hndp, + struct timeval abs_t, + void *for_libxl) +{ + struct timeval now; + struct libxlOSEventHookTimerInfo *timer_info; + int timeout, timer_id; + + if (VIR_ALLOC(timer_info) < 0) { + virReportOOMError(); + return -1; + } + + gettimeofday(&now, NULL); + timeout = (abs_t.tv_usec - now.tv_usec) / 1000; + timeout += (abs_t.tv_sec - now.tv_sec) * 1000; + timer_id = virEventAddTimeout(timeout, libxlTimerCallback, + timer_info, libxlTimerInfoFree); + if (timer_id < 0) { + VIR_FREE(timer_info); + return timer_id; + } + + timer_info->priv = priv; + timer_info->xl_priv = for_libxl; + timer_info->id = timer_id; + *hndp = timer_info; + return 0; +} + +static int libxlTimeoutModifyEventHook(void *priv ATTRIBUTE_UNUSED, + void **hndp, + struct timeval abs_t) +{ + struct timeval now; + int timeout; + struct libxlOSEventHookTimerInfo *timer_info = *hndp; + + gettimeofday(&now, NULL); + timeout = (abs_t.tv_usec - now.tv_usec) / 1000; + timeout += (abs_t.tv_sec - now.tv_sec) * 1000; + virEventUpdateTimeout(timer_info->id, timeout); + return 0; +} + +static void libxlTimeoutDeregisterEventHook(void *priv ATTRIBUTE_UNUSED, + void *hnd) +{ + struct libxlOSEventHookTimerInfo *timer_info = hnd; + + virEventRemoveTimeout(timer_info->id); +} + +static const libxl_osevent_hooks libxl_event_callbacks = { + .fd_register = libxlFDRegisterEventHook, + .fd_modify = libxlFDModifyEventHook, + .fd_deregister = libxlFDDeregisterEventHook, + .timeout_register = libxlTimeoutRegisterEventHook, + .timeout_modify = libxlTimeoutModifyEventHook, + .timeout_deregister = libxlTimeoutDeregisterEventHook, +}; + static void * libxlDomainObjPrivateAlloc(void) { @@ -92,9 +263,9 @@ libxlDomainObjPrivateAlloc(void) if (VIR_ALLOC(priv) < 0) return NULL; - libxl_ctx_init(&priv->ctx, LIBXL_VERSION, libxl_driver->logger); - priv->waiterFD = -1; - priv->eventHdl = -1; + libxl_ctx_alloc(&priv->ctx, LIBXL_VERSION, 0, libxl_driver->logger); + priv->deathW = NULL; + libxl_osevent_register_hooks(priv->ctx, &libxl_event_callbacks, priv); return priv; } @@ -104,16 +275,12 @@ libxlDomainObjPrivateFree(void *data) { libxlDomainObjPrivatePtr priv = data; - if (priv->eventHdl >= 0) - virEventRemoveHandle(priv->eventHdl); - - if (priv->dWaiter) { - libxl_stop_waiting(&priv->ctx, priv->dWaiter); - libxl_free_waiter(priv->dWaiter); - VIR_FREE(priv->dWaiter); + if (priv->deathW) { + libxl_evdisable_domain_death(priv->ctx, priv->deathW); + VIR_FREE(priv->deathW); } - libxl_ctx_free(&priv->ctx); + libxl_ctx_free(priv->ctx); VIR_FREE(priv); } @@ -125,17 +292,6 @@ libxlDomainEventQueue(libxlDriverPrivatePtr driver, virDomainEventPtr event) virDomainEventStateQueue(driver->domainEventState, event); } -/* - * Remove reference to domain object. - */ -static void -libxlDomainObjUnref(void *data) -{ - virDomainObjPtr vm = data; - - virObjectUnref(vm); -} - static void libxlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque) @@ -166,13 +322,13 @@ libxlDoNodeGetInfo(libxlDriverPrivatePtr driver, virNodeInfoPtr info) const libxl_version_info* ver_info; struct utsname utsname; - if (libxl_get_physinfo(&driver->ctx, &phy_info)) { + if (libxl_get_physinfo(driver->ctx, &phy_info)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_physinfo_info failed")); return -1; } - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(driver->ctx)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_version_info failed")); return -1; @@ -296,15 +452,9 @@ libxlVmCleanup(libxlDriverPrivatePtr driver, char *file; int i; - if (priv->eventHdl >= 0) { - virEventRemoveHandle(priv->eventHdl); - priv->eventHdl = -1; - } - - if (priv->dWaiter) { - libxl_stop_waiting(&priv->ctx, priv->dWaiter); - libxl_free_waiter(priv->dWaiter); - VIR_FREE(priv->dWaiter); + if (priv->deathW) { + libxl_evdisable_domain_death(priv->ctx, priv->deathW); + priv->deathW = NULL; } if (vm->persistent) { @@ -355,12 +505,11 @@ libxlVmCleanup(libxlDriverPrivatePtr driver, static int libxlVmReap(libxlDriverPrivatePtr driver, virDomainObjPtr vm, - int force, virDomainShutoffReason reason) { libxlDomainObjPrivatePtr priv = vm->privateData; - if (libxl_domain_destroy(&priv->ctx, vm->def->id, force) < 0) { + if (libxl_domain_destroy(priv->ctx, vm->def->id, NULL) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to cleanup domain %d"), vm->def->id); return -1; @@ -373,56 +522,26 @@ libxlVmReap(libxlDriverPrivatePtr driver, /* * Handle previously registered event notification from libxenlight */ -static void libxlEventHandler(int watch, - int fd, - int events, - void *data) +static void libxlEventHandler(void *data, const libxl_event *event) { libxlDriverPrivatePtr driver = libxl_driver; virDomainObjPtr vm = data; - libxlDomainObjPrivatePtr priv; virDomainEventPtr dom_event = NULL; - libxl_event event; - libxl_dominfo info; libxlDriverLock(driver); virDomainObjLock(vm); libxlDriverUnlock(driver); - priv = vm->privateData; - - memset(&event, 0, sizeof(event)); - memset(&info, 0, sizeof(info)); - - if (priv->waiterFD != fd || priv->eventHdl != watch) { - virEventRemoveHandle(watch); - priv->eventHdl = -1; - goto cleanup; - } - - if (!(events & VIR_EVENT_HANDLE_READABLE)) - goto cleanup; - - if (libxl_get_event(&priv->ctx, &event)) - goto cleanup; - - if (event.type == LIBXL_EVENT_DOMAIN_DEATH) { + if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) { virDomainShutoffReason reason; - /* libxl_event_get_domain_death_info returns 1 if death - * event was for this domid */ - if (libxl_event_get_domain_death_info(&priv->ctx, - vm->def->id, - &event, - &info) != 1) + if (event->domid != vm->def->id) goto cleanup; - virEventRemoveHandle(watch); - priv->eventHdl = -1; - switch (info.shutdown_reason) { - case SHUTDOWN_poweroff: - case SHUTDOWN_crash: - if (info.shutdown_reason == SHUTDOWN_crash) { + switch (event->u.domain_shutdown.shutdown_reason) { + case LIBXL_SHUTDOWN_REASON_POWEROFF: + case LIBXL_SHUTDOWN_REASON_CRASH: + if (event->u.domain_shutdown.shutdown_reason == LIBXL_SHUTDOWN_REASON_CRASH) { dom_event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_CRASHED); @@ -430,18 +549,18 @@ static void libxlEventHandler(int watch, } else { reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN; } - libxlVmReap(driver, vm, 0, reason); + libxlVmReap(driver, vm, reason); if (!vm->persistent) { virDomainRemoveInactive(&driver->domains, vm); vm = NULL; } break; - case SHUTDOWN_reboot: - libxlVmReap(driver, vm, 0, VIR_DOMAIN_SHUTOFF_SHUTDOWN); + case LIBXL_SHUTDOWN_REASON_REBOOT: + libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN); libxlVmStart(driver, vm, 0, -1); break; default: - VIR_INFO("Unhandled shutdown_reason %d", info.shutdown_reason); + VIR_INFO("Unhandled shutdown_reason %d", event->u.domain_shutdown.shutdown_reason); break; } } @@ -454,9 +573,14 @@ cleanup: libxlDomainEventQueue(driver, dom_event); libxlDriverUnlock(driver); } - libxl_free_event(&event); } +static const struct libxl_event_hooks ev_hooks = { + .event_occurs_mask = LIBXL_EVENTMASK_ALL, + .event_occurs = libxlEventHandler, + .disaster = NULL, +}; + /* * Register domain events with libxenlight and insert event handles * in libvirt's event loop. @@ -465,40 +589,18 @@ static int libxlCreateDomEvents(virDomainObjPtr vm) { libxlDomainObjPrivatePtr priv = vm->privateData; - int fd; - if (VIR_ALLOC(priv->dWaiter) < 0) { - virReportOOMError(); - return -1; - } - - if (libxl_wait_for_domain_death(&priv->ctx, vm->def->id, priv->dWaiter)) - goto error; - - libxl_get_wait_fd(&priv->ctx, &fd); - if (fd < 0) - goto error; + libxl_event_register_callbacks(priv->ctx, &ev_hooks, vm); - priv->waiterFD = fd; - /* Add a reference to the domain object while it is injected in - * the event loop. - */ - virObjectRef(vm); - if ((priv->eventHdl = virEventAddHandle( - fd, - VIR_EVENT_HANDLE_READABLE | VIR_EVENT_HANDLE_ERROR, - libxlEventHandler, - vm, libxlDomainObjUnref)) < 0) { - virObjectUnref(vm); + if (libxl_evenable_domain_death(priv->ctx, vm->def->id, 0, &priv->deathW)) goto error; - } return 0; error: - libxl_free_waiter(priv->dWaiter); - VIR_FREE(priv->dWaiter); - priv->eventHdl = -1; + if (priv->deathW) + libxl_evdisable_domain_death(priv->ctx, priv->deathW); + VIR_FREE(priv->deathW); return -1; } @@ -507,7 +609,7 @@ libxlDomainSetVcpuAffinites(libxlDriverPrivatePtr driver, virDomainObjPtr vm) { libxlDomainObjPrivatePtr priv = vm->privateData; virDomainDefPtr def = vm->def; - libxl_cpumap map; + libxl_bitmap map; uint8_t *cpumask = NULL; uint8_t *cpumap = NULL; virNodeInfo nodeinfo; @@ -539,7 +641,7 @@ libxlDomainSetVcpuAffinites(libxlDriverPrivatePtr driver, virDomainObjPtr vm) map.size = cpumaplen; map.map = cpumap; - if (libxl_set_vcpuaffinity(&priv->ctx, def->id, vcpu, &map) != 0) { + if (libxl_set_vcpuaffinity(priv->ctx, def->id, vcpu, &map) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to pin vcpu '%d' with libxenlight"), vcpu); goto cleanup; @@ -565,11 +667,10 @@ libxlFreeMem(libxlDomainObjPrivatePtr priv, libxl_domain_config *d_config) int tries = 3; int wait_secs = 10; - if ((ret = libxl_domain_need_memory(&priv->ctx, &d_config->b_info, - &d_config->dm_info, + if ((ret = libxl_domain_need_memory(priv->ctx, &d_config->b_info, &needed_mem)) >= 0) { for (i = 0; i < tries; ++i) { - if ((ret = libxl_get_free_memory(&priv->ctx, &free_mem)) < 0) + if ((ret = libxl_get_free_memory(priv->ctx, &free_mem)) < 0) break; if (free_mem >= needed_mem) { @@ -577,17 +678,17 @@ libxlFreeMem(libxlDomainObjPrivatePtr priv, libxl_domain_config *d_config) break; } - if ((ret = libxl_set_memory_target(&priv->ctx, 0, + if ((ret = libxl_set_memory_target(priv->ctx, 0, free_mem - needed_mem, /* relative */ 1, 0)) < 0) break; - ret = libxl_wait_for_free_memory(&priv->ctx, 0, needed_mem, + ret = libxl_wait_for_free_memory(priv->ctx, 0, needed_mem, wait_secs); if (ret == 0 || ret != ERROR_NOMEM) break; - if ((ret = libxl_wait_for_memory_target(&priv->ctx, 0, 1)) < 0) + if ((ret = libxl_wait_for_memory_target(priv->ctx, 0, 1)) < 0) break; } } @@ -613,7 +714,6 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, char *dom_xml = NULL; char *managed_save_path = NULL; int managed_save_fd = -1; - pid_t child_console_pid = -1; libxlDomainObjPrivatePtr priv = vm->privateData; /* If there is a managed saved state restore it instead of starting @@ -657,7 +757,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, VIR_FREE(managed_save_path); } - memset(&d_config, 0, sizeof(d_config)); + libxl_domain_config_init(&d_config); if (libxlBuildDomainConfig(driver, vm->def, &d_config) < 0 ) return -1; @@ -669,13 +769,14 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, goto error; } + /* use as synchronous operations => ao_how = NULL and no intermediate reports => ao_progress = NULL */ + if (restore_fd < 0) - ret = libxl_domain_create_new(&priv->ctx, &d_config, - NULL, &child_console_pid, &domid); + ret = libxl_domain_create_new(priv->ctx, &d_config, + &domid, NULL, NULL); else - ret = libxl_domain_create_restore(&priv->ctx, &d_config, NULL, - &child_console_pid, &domid, - restore_fd); + ret = libxl_domain_create_restore(priv->ctx, &d_config, &domid, + restore_fd, NULL, NULL); if (ret) { if (restore_fd < 0) @@ -693,7 +794,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, if ((dom_xml = virDomainDefFormat(vm->def, 0)) == NULL) goto error; - if (libxl_userdata_store(&priv->ctx, domid, "libvirt-xml", + if (libxl_userdata_store(priv->ctx, domid, "libvirt-xml", (uint8_t *)dom_xml, strlen(dom_xml) + 1)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxenlight failed to store userdata")); @@ -707,7 +808,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, goto error; if (!start_paused) { - libxl_domain_unpause(&priv->ctx, domid); + libxl_domain_unpause(priv->ctx, domid); virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED); } else { virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER); @@ -723,18 +824,18 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, VIR_DOMAIN_EVENT_STARTED_RESTORED); libxlDomainEventQueue(driver, event); - libxl_domain_config_destroy(&d_config); + libxl_domain_config_dispose(&d_config); VIR_FREE(dom_xml); VIR_FORCE_CLOSE(managed_save_fd); return 0; error: if (domid > 0) { - libxl_domain_destroy(&priv->ctx, domid, 0); + libxl_domain_destroy(priv->ctx, domid, NULL); vm->def->id = -1; virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_FAILED); } - libxl_domain_config_destroy(&d_config); + libxl_domain_config_dispose(&d_config); VIR_FREE(dom_xml); VIR_FREE(managed_save_path); virDomainDefFree(def); @@ -762,7 +863,7 @@ libxlReconnectDomain(void *payload, virDomainObjLock(vm); /* Does domain still exist? */ - rc = libxl_domain_info(&driver->ctx, &d_info, vm->def->id); + rc = libxl_domain_info(driver->ctx, &d_info, vm->def->id); if (rc == ERROR_INVAL) { goto out; } else if (rc != 0) { @@ -772,7 +873,7 @@ libxlReconnectDomain(void *payload, } /* Is this a domain that was under libvirt control? */ - if (libxl_userdata_retrieve(&driver->ctx, vm->def->id, + if (libxl_userdata_retrieve(driver->ctx, vm->def->id, "libvirt-xml", &data, &len)) { VIR_DEBUG("libxl_userdata_retrieve failed, ignoring domain %d", vm->def->id); goto out; @@ -810,7 +911,7 @@ libxlShutdown(void) libxlDriverLock(libxl_driver); virCapabilitiesFree(libxl_driver->caps); virDomainObjListDeinit(&libxl_driver->domains); - libxl_ctx_free(&libxl_driver->ctx); + libxl_ctx_free(libxl_driver->ctx); xtl_logger_destroy(libxl_driver->logger); if (libxl_driver->logger_file) VIR_FORCE_FCLOSE(libxl_driver->logger_file); @@ -943,14 +1044,14 @@ libxlStartup(int privileged) { goto fail; } - if (libxl_ctx_init(&libxl_driver->ctx, - LIBXL_VERSION, + if (libxl_ctx_alloc(&libxl_driver->ctx, + LIBXL_VERSION, 0, libxl_driver->logger)) { VIR_INFO("cannot initialize libxenlight context, probably not running in a Xen Dom0, disabling driver"); goto fail; } - if ((ver_info = libxl_get_version_info(&libxl_driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(libxl_driver->ctx)) == NULL) { VIR_INFO("cannot version information from libxenlight, disabling driver"); goto fail; } @@ -958,7 +1059,7 @@ libxlStartup(int privileged) { (ver_info->xen_version_minor * 1000); if ((libxl_driver->caps = - libxlMakeCapabilities(&libxl_driver->ctx)) == NULL) { + libxlMakeCapabilities(libxl_driver->ctx)) == NULL) { VIR_ERROR(_("cannot create capabilities for libxenlight")); goto error; } @@ -1115,7 +1216,7 @@ libxlGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED) int ret; libxlDriverPrivatePtr driver = conn->privateData; - ret = libxl_get_max_cpus(&driver->ctx); + ret = libxl_get_max_cpus(driver->ctx); /* libxl_get_max_cpus() will return 0 if there were any failures, e.g. xc_physinfo() failing */ if (ret == 0) @@ -1320,7 +1421,7 @@ libxlDomainSuspend(virDomainPtr dom) priv = vm->privateData; if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { - if (libxl_domain_pause(&priv->ctx, dom->id) != 0) { + if (libxl_domain_pause(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to suspend domain '%d' with libxenlight"), dom->id); @@ -1379,7 +1480,7 @@ libxlDomainResume(virDomainPtr dom) priv = vm->privateData; if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { - if (libxl_domain_unpause(&priv->ctx, dom->id) != 0) { + if (libxl_domain_unpause(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to resume domain '%d' with libxenlight"), dom->id); @@ -1436,7 +1537,7 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int flags) } priv = vm->privateData; - if (libxl_domain_shutdown(&priv->ctx, dom->id, LIBXL_DOM_REQ_POWEROFF) != 0) { + if (libxl_domain_shutdown(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to shutdown domain '%d' with libxenlight"), dom->id); @@ -1489,7 +1590,7 @@ libxlDomainReboot(virDomainPtr dom, unsigned int flags) } priv = vm->privateData; - if (libxl_domain_shutdown(&priv->ctx, dom->id, LIBXL_DOM_REQ_REBOOT) != 0) { + if (libxl_domain_reboot(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to reboot domain '%d' with libxenlight"), dom->id); @@ -1534,7 +1635,7 @@ libxlDomainDestroyFlags(virDomainPtr dom, event = virDomainEventNewFromObj(vm,VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); - if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_DESTROYED) != 0) { + if (libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), dom->id); goto cleanup; @@ -1672,7 +1773,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, if (flags & VIR_DOMAIN_MEM_LIVE) { priv = vm->privateData; - if (libxl_domain_setmaxmem(&priv->ctx, dom->id, newmem) < 0) { + if (libxl_domain_setmaxmem(priv->ctx, dom->id, newmem) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set maximum memory for domain '%d'" " with libxenlight"), dom->id); @@ -1701,7 +1802,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, if (flags & VIR_DOMAIN_MEM_LIVE) { priv = vm->privateData; - if (libxl_set_memory_target(&priv->ctx, dom->id, newmem, 0, + if (libxl_set_memory_target(priv->ctx, dom->id, newmem, 0, /* force */ 1) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set memory for domain '%d'" @@ -1761,7 +1862,7 @@ libxlDomainGetInfo(virDomainPtr dom, virDomainInfoPtr info) info->memory = vm->def->mem.cur_balloon; info->maxMem = vm->def->mem.max_balloon; } else { - if (libxl_domain_info(&driver->ctx, &d_info, dom->id) != 0) { + if (libxl_domain_info(driver->ctx, &d_info, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxl_domain_info failed for domain '%d'"), dom->id); goto cleanup; @@ -1861,7 +1962,7 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm, goto cleanup; } - if (libxl_domain_suspend(&priv->ctx, NULL, vm->def->id, fd) != 0) { + if (libxl_domain_suspend(priv->ctx, vm->def->id, fd, 0, NULL) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to save domain '%d' with libxenlight"), vm->def->id); @@ -1871,7 +1972,7 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm, event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SAVED); - if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_SAVED) != 0) { + if (libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SAVED) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), vm->def->id); goto cleanup; @@ -2028,7 +2129,7 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) if (!(flags & VIR_DUMP_LIVE) && virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { - if (libxl_domain_pause(&priv->ctx, dom->id) != 0) { + if (libxl_domain_pause(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Before dumping core, failed to suspend domain '%d'" " with libxenlight"), @@ -2039,7 +2140,7 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) paused = true; } - if (libxl_domain_core_dump(&priv->ctx, dom->id, to) != 0) { + if (libxl_domain_core_dump(priv->ctx, dom->id, to, NULL) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to dump core of domain '%d' with libxenlight"), dom->id); @@ -2048,7 +2149,7 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) libxlDriverLock(driver); if (flags & VIR_DUMP_CRASH) { - if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_CRASHED) != 0) { + if (libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_CRASHED) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), dom->id); goto cleanup_unlock; @@ -2069,7 +2170,7 @@ cleanup_unlock: libxlDriverUnlock(driver); cleanup_unpause: if (virDomainObjIsActive(vm) && paused) { - if (libxl_domain_unpause(&priv->ctx, dom->id) != 0) { + if (libxl_domain_unpause(priv->ctx, dom->id) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("After dumping core, failed to resume domain '%d' with" " libxenlight"), dom->id); @@ -2227,7 +2328,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, libxlDomainObjPrivatePtr priv; virDomainDefPtr def; virDomainObjPtr vm; - libxl_cpumap map; + libxl_bitmap map; uint8_t *bitmask = NULL; unsigned int maplen; unsigned int i, pos; @@ -2322,7 +2423,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, break; case VIR_DOMAIN_VCPU_LIVE: - if (libxl_set_vcpuonline(&priv->ctx, dom->id, &map) != 0) { + if (libxl_set_vcpuonline(priv->ctx, dom->id, &map) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set vcpus for domain '%d'" " with libxenlight"), dom->id); @@ -2331,7 +2432,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, break; case VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG: - if (libxl_set_vcpuonline(&priv->ctx, dom->id, &map) != 0) { + if (libxl_set_vcpuonline(priv->ctx, dom->id, &map) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set vcpus for domain '%d'" " with libxenlight"), dom->id); @@ -2427,7 +2528,7 @@ libxlDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap, libxlDomainObjPrivatePtr priv; virDomainObjPtr vm; int ret = -1; - libxl_cpumap map; + libxl_bitmap map; libxlDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -2448,7 +2549,7 @@ libxlDomainPinVcpu(virDomainPtr dom, unsigned int vcpu, unsigned char *cpumap, map.size = maplen; map.map = cpumap; - if (libxl_set_vcpuaffinity(&priv->ctx, dom->id, vcpu, &map) != 0) { + if (libxl_set_vcpuaffinity(priv->ctx, dom->id, vcpu, &map) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to pin vcpu '%d' with libxenlight"), vcpu); goto cleanup; @@ -2511,7 +2612,7 @@ libxlDomainGetVcpus(virDomainPtr dom, virVcpuInfoPtr info, int maxinfo, } priv = vm->privateData; - if ((vcpuinfo = libxl_list_vcpu(&priv->ctx, dom->id, &maxcpu, + if ((vcpuinfo = libxl_list_vcpu(priv->ctx, dom->id, &maxcpu, &hostcpus)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to list vcpus for domain '%d' with libxenlight"), @@ -2538,7 +2639,7 @@ libxlDomainGetVcpus(virDomainPtr dom, virVcpuInfoPtr info, int maxinfo, MIN(maplen, vcpuinfo[i].cpumap.size)); } - libxl_vcpuinfo_destroy(&vcpuinfo[i]); + libxl_vcpuinfo_dispose(&vcpuinfo[i]); } VIR_FREE(vcpuinfo); @@ -2596,7 +2697,7 @@ libxlDomainXMLFromNative(virConnectPtr conn, const char * nativeFormat, goto cleanup; } - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(driver->ctx)) == NULL) { VIR_ERROR(_("cannot get version information from libxenlight")); goto cleanup; } @@ -2639,7 +2740,7 @@ libxlDomainXMLToNative(virConnectPtr conn, const char * nativeFormat, goto cleanup; } - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(driver->ctx)) == NULL) { VIR_ERROR(_("cannot get version information from libxenlight")); goto cleanup; } @@ -2899,10 +3000,10 @@ libxlDomainChangeEjectableMedia(libxlDomainObjPrivatePtr priv, return -1; } - if (libxlMakeDisk(vm->def, disk, &x_disk) < 0) + if (libxlMakeDisk(disk, &x_disk) < 0) goto cleanup; - if ((ret = libxl_cdrom_insert(&priv->ctx, vm->def->id, &x_disk)) < 0) { + if ((ret = libxl_cdrom_insert(priv->ctx, vm->def->id, &x_disk, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight failed to change media for disk '%s'"), disk->dst); @@ -2954,11 +3055,11 @@ libxlDomainAttachDeviceDiskLive(libxlDomainObjPrivatePtr priv, goto cleanup; } - if (libxlMakeDisk(vm->def, l_disk, &x_disk) < 0) + if (libxlMakeDisk(l_disk, &x_disk) < 0) goto cleanup; - if ((ret = libxl_device_disk_add(&priv->ctx, vm->def->id, - &x_disk)) < 0) { + if ((ret = libxl_device_disk_add(priv->ctx, vm->def->id, + &x_disk, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight failed to attach disk '%s'"), l_disk->dst); @@ -2991,7 +3092,6 @@ libxlDomainDetachDeviceDiskLive(libxlDomainObjPrivatePtr priv, virDomainDiskDefPtr l_disk = NULL; libxl_device_disk x_disk; int i; - int wait_secs = 2; int ret = -1; switch (dev->data.disk->device) { @@ -3008,11 +3108,11 @@ libxlDomainDetachDeviceDiskLive(libxlDomainObjPrivatePtr priv, l_disk = vm->def->disks[i]; - if (libxlMakeDisk(vm->def, l_disk, &x_disk) < 0) + if (libxlMakeDisk(l_disk, &x_disk) < 0) goto cleanup; - if ((ret = libxl_device_disk_del(&priv->ctx, &x_disk, - wait_secs)) < 0) { + if ((ret = libxl_device_disk_remove(priv->ctx, vm->def->id, + &x_disk, NULL)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight failed to detach disk '%s'"), l_disk->dst); @@ -3387,13 +3487,13 @@ libxlNodeGetFreeMemory(virConnectPtr conn) const libxl_version_info* ver_info; libxlDriverPrivatePtr driver = conn->privateData; - if (libxl_get_physinfo(&driver->ctx, &phy_info)) { + if (libxl_get_physinfo(driver->ctx, &phy_info)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_physinfo_info failed")); return 0; } - if ((ver_info = libxl_get_version_info(&driver->ctx)) == NULL) { + if ((ver_info = libxl_get_version_info(driver->ctx)) == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("libxl_get_version_info failed")); return 0; @@ -3540,7 +3640,7 @@ libxlDomainGetSchedulerType(virDomainPtr dom, int *nparams) libxlDomainObjPrivatePtr priv; virDomainObjPtr vm; char * ret = NULL; - int sched_id; + libxl_scheduler sched_id; libxlDriverLock(driver); vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -3557,31 +3657,29 @@ libxlDomainGetSchedulerType(virDomainPtr dom, int *nparams) } priv = vm->privateData; - if ((sched_id = libxl_get_sched_id(&priv->ctx)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to get scheduler id for domain '%d'" - " with libxenlight"), dom->id); - goto cleanup; - } + sched_id = libxl_get_scheduler(priv->ctx); if (nparams) *nparams = 0; - switch(sched_id) { - case XEN_SCHEDULER_SEDF: + switch (sched_id) { + case LIBXL_SCHEDULER_SEDF: ret = strdup("sedf"); break; - case XEN_SCHEDULER_CREDIT: + case LIBXL_SCHEDULER_CREDIT: ret = strdup("credit"); if (nparams) *nparams = XEN_SCHED_CREDIT_NPARAM; break; - case XEN_SCHEDULER_CREDIT2: + case LIBXL_SCHEDULER_CREDIT2: ret = strdup("credit2"); break; - case XEN_SCHEDULER_ARINC653: + case LIBXL_SCHEDULER_ARINC653: ret = strdup("arinc653"); break; default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to get scheduler id for domain '%d'" + " with libxenlight"), dom->id); goto cleanup; } @@ -3603,8 +3701,8 @@ libxlDomainGetSchedulerParametersFlags(virDomainPtr dom, libxlDriverPrivatePtr driver = dom->conn->privateData; libxlDomainObjPrivatePtr priv; virDomainObjPtr vm; - libxl_sched_credit sc_info; - int sched_id; + libxl_domain_sched_params sc_info; + libxl_scheduler sched_id; int ret = -1; virCheckFlags(0, -1); @@ -3614,31 +3712,28 @@ libxlDomainGetSchedulerParametersFlags(virDomainPtr dom, libxlDriverUnlock(driver); if (!vm) { - virReportError(VIR_ERR_NO_DOMAIN, "%s", _("no domain with matching uuid")); + virReportError(VIR_ERR_NO_DOMAIN, "%s", + _("no domain with matching uuid")); goto cleanup; } if (!virDomainObjIsActive(vm)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not running")); + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("Domain is not running")); goto cleanup; } priv = vm->privateData; - if ((sched_id = libxl_get_sched_id(&priv->ctx)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to get scheduler id for domain '%d'" - " with libxenlight"), dom->id); - goto cleanup; - } + sched_id = libxl_get_scheduler(priv->ctx); - if (sched_id != XEN_SCHEDULER_CREDIT) { + if (sched_id != LIBXL_SCHEDULER_CREDIT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only 'credit' scheduler is supported")); goto cleanup; } - if (libxl_sched_credit_domain_get(&priv->ctx, dom->id, &sc_info) != 0) { + if (libxl_domain_sched_params_get(priv->ctx, dom->id, &sc_info) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to get scheduler parameters for domain '%d'" " with libxenlight"), dom->id); @@ -3681,7 +3776,7 @@ libxlDomainSetSchedulerParametersFlags(virDomainPtr dom, libxlDriverPrivatePtr driver = dom->conn->privateData; libxlDomainObjPrivatePtr priv; virDomainObjPtr vm; - libxl_sched_credit sc_info; + libxl_domain_sched_params sc_info; int sched_id; int i; int ret = -1; @@ -3711,20 +3806,15 @@ libxlDomainSetSchedulerParametersFlags(virDomainPtr dom, priv = vm->privateData; - if ((sched_id = libxl_get_sched_id(&priv->ctx)) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to get scheduler id for domain '%d'" - " with libxenlight"), dom->id); - goto cleanup; - } + sched_id = libxl_get_scheduler(priv->ctx); - if (sched_id != XEN_SCHEDULER_CREDIT) { + if (sched_id != LIBXL_SCHEDULER_CREDIT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Only 'credit' scheduler is supported")); goto cleanup; } - if (libxl_sched_credit_domain_get(&priv->ctx, dom->id, &sc_info) != 0) { + if (libxl_domain_sched_params_get(priv->ctx, dom->id, &sc_info) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to get scheduler parameters for domain '%d'" " with libxenlight"), dom->id); @@ -3741,7 +3831,7 @@ libxlDomainSetSchedulerParametersFlags(virDomainPtr dom, } } - if (libxl_sched_credit_domain_set(&priv->ctx, dom->id, &sc_info) != 0) { + if (libxl_domain_sched_params_set(priv->ctx, dom->id, &sc_info) != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to set scheduler parameters for domain '%d'" " with libxenlight"), dom->id); -- 1.8.0.2

Eric Blake wrote:
From: Jim Fehlig <jfehlig@suse.com>
Based on a patch originally authored by Daniel De Graaf
http://lists.xen.org/archives/html/xen-devel/2012-05/msg00565.html
This patch converts the Xen libxl driver to support only Xen >= 4.2. Support for Xen 4.1 libxl is dropped since that version of libxl is designated 'technology preview' only and is incompatible with Xen 4.2 libxl. Additionally, the default toolstack in Xen 4.1 is still xend, for which libvirt has a stable, functional driver. (cherry picked from commit dfa1e1dd5325f3a6bc8865312cde557044bf0b93)
Conflicts: src/libxl/libxl_conf.c - commit e5e8d5 not backported src/libxl/libxl_driver.c - commit 1c04f99 not backported --- configure.ac | 8 +- docs/drvxen.html.in | 8 + libvirt.spec.in | 4 +- src/libxl/libxl_conf.c | 325 ++++++++++--------------------- src/libxl/libxl_conf.h | 16 +- src/libxl/libxl_driver.c | 490 ++++++++++++++++++++++++++++------------------- 6 files changed, 407 insertions(+), 444 deletions(-)
[...]
static int libxlMakeVfbList(libxlDriverPrivatePtr driver, - virDomainDefPtr def, libxl_domain_config *d_config) + virDomainDefPtr def, + libxl_domain_config *d_config) { virDomainGraphicsDefPtr *l_vfbs = def->graphics; int nvfbs = def->ngraphics; @@ -750,10 +759,10 @@ libxlMakeVfbList(libxlDriverPrivatePtr driver, }
for (i = 0; i < nvfbs; i++) { - libxl_device_vfb_init(&x_vfbs[i], i); - libxl_device_vkb_init(&x_vkbs[i], i); + libxl_device_vfb_init(&x_vfbs[i]); + libxl_device_vkb_init(&x_vkbs[i]);
FYI, the vfb and vkb devid are not initialized here, resulting in hangs of PV guests on xen-unstable. I've submitted a patch to xen-devel to initialize devid for these devices to a sane value in libxl http://lists.xen.org/archives/html/xen-devel/2013-01/msg00137.html Hmm, it might be best to initialize devid in libxlMakeVfbList() anyhow, similar to libxlMakeNicList(). [...]
@@ -84,6 +98,163 @@ libxlDriverUnlock(libxlDriverPrivatePtr driver) virMutexUnlock(&driver->lock); }
+ +static void libxlFDEventCallback(int watch ATTRIBUTE_UNUSED, + int fd, + int vir_events, + void *fdinfo) +{ + struct libxlOSEventHookFDInfo *info = fdinfo; + int events = 0; + + if (vir_events & VIR_EVENT_HANDLE_READABLE) + events |= POLLIN; + if (vir_events & VIR_EVENT_HANDLE_WRITABLE) + events |= POLLOUT; + if (vir_events & VIR_EVENT_HANDLE_ERROR) + events |= POLLERR; + if (vir_events & VIR_EVENT_HANDLE_HANGUP) + events |= POLLHUP; + + libxl_osevent_occurred_fd(info->priv->ctx, info->xl_priv, fd, 0, events); +}
Another FYI, recent testing with xen-unstable has uncovered a race between the fd (and timer) callback and libxl deregistering the fd (or timer). I.e. libxl calls libxlFDDeregisterEventHook(), sometime later the libxl libxlFDEventCallback() is invoked and we call into libxl with stale xl_priv. I've been experimenting with a patch to resolve this issue but not satisfied with it quite yet. [...]
@@ -125,17 +292,6 @@ libxlDomainEventQueue(libxlDriverPrivatePtr driver, virDomainEventPtr event) virDomainEventStateQueue(driver->domainEventState, event); }
-/* - * Remove reference to domain object. - */ -static void -libxlDomainObjUnref(void *data) -{ - virDomainObjPtr vm = data; - - virObjectUnref(vm); -} -
In hindsight, I wonder if this and associated changes are correct. I've also noticed a race where we call virDomainObjUnlock() on a vm that has already been freed. E.g. in libxlDomainSaveFlags(), we call virDomainObjUnlock() on vm, but that vm may have already been reaped (and libxlDomainObjPrivateFree() already called) via libxlEventHandler(). That said, the races I've mentioned exist in the original patch. I've reviewed this backport and it looks good IMO. Regards, Jim
participants (4)
-
Cole Robinson
-
Dario Faggioli
-
Eric Blake
-
Jim Fehlig