[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Merge
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1281374990 -3600 # Node ID f45026ec8db5a18131acd924a5b99f3b0e480df1 # Parent 2f4a89ad2528ce16711b195dc998def48c0c98c2 # Parent 1644b4efef8a948eec0d257126b70cd37d206f08 Merge --- tools/hotplug/Linux/vif-bridge | 20 ++-- tools/hotplug/Linux/vif-common.sh | 76 +++++++++++---- tools/hotplug/Linux/xen-backend.rules | 5 - tools/libxc/xc_hvm_build.c | 1 tools/libxl/libxl.c | 166 +++++++++++++++++++++++++++++++++- tools/libxl/libxl.h | 2 tools/libxl/libxl_pci.c | 153 ++++++++++++++++++++++++++++--- tools/libxl/libxl_utils.c | 78 +++++++++++++++ tools/libxl/libxl_utils.h | 6 + tools/libxl/xl_cmdimpl.c | 22 +++- tools/libxl/xl_cmdtable.c | 4 11 files changed, 478 insertions(+), 55 deletions(-) diff -r 2f4a89ad2528 -r f45026ec8db5 tools/hotplug/Linux/vif-bridge --- a/tools/hotplug/Linux/vif-bridge Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/hotplug/Linux/vif-bridge Mon Aug 09 18:29:50 2010 +0100 @@ -81,20 +81,26 @@ fi case "$command" in online) - setup_bridge_port "$vif" - add_to_bridge "$bridge" "$vif" + setup_bridge_port "$dev" + add_to_bridge "$bridge" "$dev" ;; offline) - do_without_error brctl delif "$bridge" "$vif" - do_without_error ifconfig "$vif" down + do_without_error brctl delif "$bridge" "$dev" + do_without_error ifconfig "$dev" down + ;; + + add) + add_to_bridge "$bridge" "$dev" ;; esac -handle_iptable +if [ "$type_if" = vif ]; then + handle_iptable +fi -log debug "Successful vif-bridge $command for $vif, bridge $bridge." -if [ "$command" == "online" ] +log debug "Successful vif-bridge $command for $dev, bridge $bridge." +if [ "$type_if" = vif -a "$command" = "online" ] then success fi diff -r 2f4a89ad2528 -r f45026ec8db5 tools/hotplug/Linux/vif-common.sh --- a/tools/hotplug/Linux/vif-common.sh Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/hotplug/Linux/vif-common.sh Mon Aug 09 18:29:50 2010 +0100 @@ -31,12 +31,6 @@ then exit 1 fi -case "$command" in - add | remove) - exit 0 - ;; -esac - # Parameters may be read from the environment, the command line arguments, and # the store, with overriding in that order. The environment is given by the @@ -45,24 +39,62 @@ esac evalVariables "$@" +# Older versions of Xen do not pass in the type as an argument, +# so the default value is vif. +: ${type_if:=vif} + +case "$type_if" in + vif) + dev=$vif + ;; + tap) + dev=$INTERFACE + ;; + *) + log err "unknown interface type $type_if" + exit 1 + ;; +esac + +case "$command" in + online | offline) + test "$type_if" != vif && exit 0 + ;; + add | remove) + test "$type_if" != tap && exit 0 + ;; +esac + + +if [ "$type_if" = vif ]; then + # Check presence of compulsory args. + XENBUS_PATH="${XENBUS_PATH:?}" + vif="${vif:?}" + + vifname=$(xenstore_read_default "$XENBUS_PATH/vifname" "") + if [ "$vifname" ] + then + if [ "$command" == "online" ] && ! ip link show "$vifname" >&/dev/null + then + do_or_die ip link set "$vif" name "$vifname" + fi + vif="$vifname" + fi +elif [ "$type_if" = tap ]; then + # Check presence of compulsory args. + : ${INTERFACE:?} + + # Get xenbus_path from device name. + # The name is built like that: "tap${domid}.${devid}". + dev_=${dev#tap} + domid=${dev_%.*} + devid=${dev_#*.} + + XENBUS_PATH="/local/domain/0/backend/vif/$domid/$devid" +fi + ip=${ip:-} ip=$(xenstore_read_default "$XENBUS_PATH/ip" "$ip") - -# Check presence of compulsory args. -XENBUS_PATH="${XENBUS_PATH:?}" -vif="${vif:?}" - - -vifname=$(xenstore_read_default "$XENBUS_PATH/vifname" "") -if [ "$vifname" ] -then - if [ "$command" == "online" ] && ! ip link show "$vifname" >&/dev/null - then - do_or_die ip link set "$vif" name "$vifname" - fi - vif="$vifname" -fi - frob_iptable() { diff -r 2f4a89ad2528 -r f45026ec8db5 tools/hotplug/Linux/xen-backend.rules --- a/tools/hotplug/Linux/xen-backend.rules Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/hotplug/Linux/xen-backend.rules Mon Aug 09 18:29:50 2010 +0100 @@ -2,10 +2,11 @@ SUBSYSTEM=="xen-backend", KERNEL=="vbd*" SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}" SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}" SUBSYSTEM=="xen-backend", KERNEL=="vif2-*", RUN+="/etc/xen/scripts/vif2 $env{ACTION}" -SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online" -SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", RUN+="/etc/xen/scripts/vif-setup offline" +SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online type_if=vif" +SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", RUN+="/etc/xen/scripts/vif-setup offline type_if=vif" SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi $env{ACTION}" SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/etc/xen/scripts/xen-hotplug-cleanup" KERNEL=="evtchn", NAME="xen/%k" KERNEL=="blktap[0-9]*", NAME="xen/%k" KERNEL=="pci_iomul", NAME="xen/%k" +SUBSYSTEM=="net", KERNEL=="tap*", ACTION=="add", RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap" diff -r 2f4a89ad2528 -r f45026ec8db5 tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/libxc/xc_hvm_build.c Mon Aug 09 18:29:50 2010 +0100 @@ -142,6 +142,7 @@ static int setup_guest(xc_interface *xch if ( memsize > target ) pod_mode = 1; + memset(&elf, 0, sizeof(elf)); if ( elf_init(&elf, image, image_size) != 0 ) goto error_out; elf_parse_binary(&elf); diff -r 2f4a89ad2528 -r f45026ec8db5 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/libxl/libxl.c Mon Aug 09 18:29:50 2010 +0100 @@ -964,7 +964,7 @@ skip_autopass: return 0; } -static char ** libxl_build_device_model_args(libxl_ctx *ctx, +static char ** libxl_build_device_model_args_old(libxl_ctx *ctx, libxl_device_model_info *info, libxl_device_nic *vifs, int num_vifs) @@ -1070,12 +1070,12 @@ static char ** libxl_build_device_model_ vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); if (!vifs[i].ifname) - vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid - 1); + vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid); flexarray_set(dm_args, num++, "-net"); flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", vifs[i].devid, smac, vifs[i].model)); flexarray_set(dm_args, num++, "-net"); - flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s", + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,bridge=%s,script=no", vifs[i].devid, vifs[i].ifname, vifs[i].bridge)); ioemu_vifs++; } @@ -1098,8 +1098,166 @@ static char ** libxl_build_device_model_ else flexarray_set(dm_args, num++, "xenfv"); flexarray_set(dm_args, num++, NULL); - return (char **) flexarray_contents(dm_args); +} + +static char ** libxl_build_device_model_args_new(libxl_ctx *ctx, + libxl_device_model_info *info, + libxl_device_nic *vifs, + int num_vifs) +{ + int num = 0, i; + flexarray_t *dm_args; + int nb; + libxl_device_disk *disks; + + dm_args = flexarray_make(16, 1); + if (!dm_args) + return NULL; + + flexarray_set(dm_args, num++, "qemu-system-xen"); + flexarray_set(dm_args, num++, "-xen-domid"); + + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid)); + + if (info->dom_name) { + flexarray_set(dm_args, num++, "-name"); + flexarray_set(dm_args, num++, info->dom_name); + } + if (info->vnc || info->vncdisplay || info->vnclisten || info->vncunused) { + int display = 0; + const char *listen = "127.0.0.1"; + + flexarray_set(dm_args, num++, "-vnc"); + + if (info->vncdisplay) { + display = info->vncdisplay; + if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) { + listen = info->vnclisten; + } + } else if (info->vnclisten) { + listen = info->vnclisten; + } + + if (strchr(listen, ':') != NULL) + flexarray_set(dm_args, num++, + libxl_sprintf(ctx, "%s%s", listen, + info->vncunused ? ",to=99" : "")); + else + flexarray_set(dm_args, num++, + libxl_sprintf(ctx, "%s:%d%s", listen, display, + info->vncunused ? ",to=99" : "")); + } + if (info->sdl) { + flexarray_set(dm_args, num++, "-sdl"); + } + if (info->keymap) { + flexarray_set(dm_args, num++, "-k"); + flexarray_set(dm_args, num++, info->keymap); + } + if (info->nographic && (!info->sdl && !info->vnc)) { + flexarray_set(dm_args, num++, "-nographic"); + } + if (info->serial) { + flexarray_set(dm_args, num++, "-serial"); + flexarray_set(dm_args, num++, info->serial); + } + if (info->type == XENFV) { + int ioemu_vifs = 0; + + if (info->stdvga) { + flexarray_set(dm_args, num++, "-vga"); + flexarray_set(dm_args, num++, "std"); + } + + if (info->boot) { + flexarray_set(dm_args, num++, "-boot"); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "order=%s", info->boot)); + } + if (info->usb || info->usbdevice) { + flexarray_set(dm_args, num++, "-usb"); + if (info->usbdevice) { + flexarray_set(dm_args, num++, "-usbdevice"); + flexarray_set(dm_args, num++, info->usbdevice); + } + } + if (info->soundhw) { + flexarray_set(dm_args, num++, "-soundhw"); + flexarray_set(dm_args, num++, info->soundhw); + } + if (!info->apic) { + flexarray_set(dm_args, num++, "-no-acpi"); + } + if (info->vcpus > 1) { + flexarray_set(dm_args, num++, "-smp"); + if (info->vcpu_avail) + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d,maxcpus=%d", info->vcpus, info->vcpu_avail)); + else + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->vcpus)); + } + for (i = 0; i < num_vifs; i++) { + if (vifs[i].nictype == NICTYPE_IOEMU) { + char *smac = libxl_sprintf(ctx, "%02x:%02x:%02x:%02x:%02x:%02x", + vifs[i].mac[0], vifs[i].mac[1], vifs[i].mac[2], + vifs[i].mac[3], vifs[i].mac[4], vifs[i].mac[5]); + if (!vifs[i].ifname) + vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", info->domid, vifs[i].devid); + flexarray_set(dm_args, num++, "-net"); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "nic,vlan=%d,macaddr=%s,model=%s", + vifs[i].devid, smac, vifs[i].model)); + flexarray_set(dm_args, num++, "-net"); + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "tap,vlan=%d,ifname=%s,script=no", + vifs[i].devid, vifs[i].ifname)); + ioemu_vifs++; + } + } + /* If we have no emulated nics, tell qemu not to create any */ + if ( ioemu_vifs == 0 ) { + flexarray_set(dm_args, num++, "-net"); + flexarray_set(dm_args, num++, "none"); + } + } + if (info->saved_state) { + flexarray_set(dm_args, num++, "-loadvm"); + flexarray_set(dm_args, num++, info->saved_state); + } + for (i = 0; info->extra && info->extra[i] != NULL; i++) + flexarray_set(dm_args, num++, info->extra[i]); + flexarray_set(dm_args, num++, "-M"); + if (info->type == XENPV) + flexarray_set(dm_args, num++, "xenpv"); + else + flexarray_set(dm_args, num++, "xenfv"); + + disks = libxl_device_disk_list(ctx, info->domid, &nb); + for (; nb > 0; --nb, ++disks) { + if ( disks->is_cdrom ) { + flexarray_set(dm_args, num++, "-cdrom"); + flexarray_set(dm_args, num++, disks->physpath); + }else{ + flexarray_set(dm_args, num++, libxl_sprintf(ctx, "-%s", disks->virtpath)); + flexarray_set(dm_args, num++, disks->physpath); + } + } + + flexarray_set(dm_args, num++, NULL); + return (char **) flexarray_contents(dm_args); +} + +static char ** libxl_build_device_model_args(libxl_ctx *ctx, + libxl_device_model_info *info, + libxl_device_nic *vifs, + int num_vifs) +{ + int new_qemu; + + new_qemu = libxl_check_device_model_version(ctx, info->device_model); + + if (new_qemu == 1) { + return libxl_build_device_model_args_new(ctx, info, vifs, num_vifs); + } else { + return libxl_build_device_model_args_old(ctx, info, vifs, num_vifs); + } } void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild) diff -r 2f4a89ad2528 -r f45026ec8db5 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/libxl/libxl.h Mon Aug 09 18:29:50 2010 +0100 @@ -310,6 +310,8 @@ typedef struct { }; unsigned int domain; unsigned int vdevfn; +#define LIBXL_PCI_FUNC_ALL (~0U) + unsigned int vfunc_mask; bool msitranslate; bool power_mgmt; } libxl_device_pci; diff -r 2f4a89ad2528 -r f45026ec8db5 tools/libxl/libxl_pci.c --- a/tools/libxl/libxl_pci.c Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/libxl/libxl_pci.c Mon Aug 09 18:29:50 2010 +0100 @@ -136,8 +136,13 @@ int libxl_device_pci_parse_bdf(libxl_ctx break; } *ptr = '\0'; - if ( hex_convert(tok, &func, 0x7) ) - goto parse_error; + if ( !strcmp(tok, "*") ) { + pcidev->vfunc_mask = LIBXL_PCI_FUNC_ALL; + }else{ + if ( hex_convert(tok, &func, 0x7) ) + goto parse_error; + pcidev->vfunc_mask = (1 << 0); + } tok = ptr + 1; } break; @@ -187,7 +192,6 @@ int libxl_device_pci_parse_bdf(libxl_ctx return 0; parse_error: - printf("parse error: %s\n", str); return ERROR_INVAL; } @@ -531,6 +535,55 @@ int libxl_device_pci_list_assignable(lib return 0; } +/* + * This function checks that all functions of a device are bound to pciback + * driver. It also initialises a bit-mask of which function numbers are present + * on that device. +*/ +static int pci_multifunction_check(libxl_ctx *ctx, libxl_device_pci *pcidev, unsigned int *func_mask) +{ + struct dirent *de; + DIR *dir; + + *func_mask = 0; + + dir = opendir(SYSFS_PCI_DEV); + if ( NULL == dir ) { + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", SYSFS_PCI_DEV); + return -1; + } + + while( (de = readdir(dir)) ) { + unsigned dom, bus, dev, func; + struct stat st; + char *path; + + if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 ) + continue; + if ( pcidev->domain != dom ) + continue; + if ( pcidev->bus != bus ) + continue; + if ( pcidev->dev != dev ) + continue; + + path = libxl_sprintf(ctx, "%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, bus, dev, func); + if ( lstat(path, &st) ) { + if ( errno == ENOENT ) + XL_LOG(ctx, XL_LOG_ERROR, PCI_BDF " is not assigned to pciback driver", + dom, bus, dev, func); + else + XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't lstat %s", path); + closedir(dir); + return -1; + } + (*func_mask) |= (1 << func); + } + + closedir(dir); + return 0; +} + static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, void *priv) { char *orig_state = priv; @@ -652,8 +705,9 @@ out: int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) { + unsigned int orig_vdev, pfunc_mask; libxl_device_pci *assigned; - int num_assigned, rc; + int num_assigned, rc, i; int stubdomid = 0; rc = get_all_assigned_devices(ctx, &assigned, &num_assigned); @@ -679,10 +733,43 @@ int libxl_device_pci_add(libxl_ctx *ctx, return rc; } - return do_pci_add(ctx, domid, pcidev); -} - -int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) + orig_vdev = pcidev->vdevfn & ~7U; + + if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) { + if ( !(pcidev->vdevfn >> 3) ) { + XL_LOG(ctx, XL_LOG_ERROR, "Must specify a v-slot for multi-function devices"); + return ERROR_INVAL; + } + if ( pci_multifunction_check(ctx, pcidev, &pfunc_mask) ) { + return ERROR_FAIL; + } + pcidev->vfunc_mask &= pfunc_mask; + /* so now vfunc_mask == pfunc_mask */ + }else{ + pfunc_mask = (1 << pcidev->func); + } + + for(i = 7; i >= 0; --i) { + if ( (1 << i) & pfunc_mask ) { + if ( pcidev->vfunc_mask == pfunc_mask ) { + pcidev->func = i; + pcidev->vdevfn = orig_vdev | i; + }else{ + /* if not passing through multiple devices in a block make + * sure that virtual function number 0 is always used otherwise + * guest won't see the device + */ + pcidev->vdevfn = orig_vdev; + } + if ( do_pci_add(ctx, domid, pcidev) ) + rc = ERROR_FAIL; + } + } + + return rc; +} + +static int do_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) { libxl_device_pci *assigned; char *path; @@ -711,10 +798,15 @@ int libxl_device_pci_remove(libxl_ctx *c libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid); - xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem")); - if (libxl_wait_for_device_model(ctx, domid, "pci-removed", NULL, NULL) < 0) { - XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time"); - return ERROR_FAIL; + + /* Remove all functions at once atomically by only signalling + * device-model for function 0 */ + if ( (pcidev->vdevfn & 0x7) == 0 ) { + xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem")); + if (libxl_wait_for_device_model(ctx, domid, "pci-removed", NULL, NULL) < 0) { + XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time"); + return ERROR_FAIL; + } } path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid); xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state)); @@ -769,7 +861,10 @@ skip1: fclose(f); } out: - libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); + /* don't do multiple resets while some functions are still passed through */ + if ( (pcidev->vdevfn & 0x7) == 0 ) { + libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); + } if (!libxl_is_stubdom(ctx, domid, NULL)) { rc = xc_deassign_device(ctx->xch, domid, pcidev->value); @@ -784,6 +879,38 @@ out: } return 0; +} + +int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev) +{ + unsigned int orig_vdev, pfunc_mask; + int i, rc; + + orig_vdev = pcidev->vdevfn & ~7U; + + if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) { + if ( pci_multifunction_check(ctx, pcidev, &pfunc_mask) ) { + return ERROR_FAIL; + } + pcidev->vfunc_mask &= pfunc_mask; + }else{ + pfunc_mask = (1 << pcidev->func); + } + + for(i = 7; i >= 0; --i) { + if ( (1 << i) & pfunc_mask ) { + if ( pcidev->vfunc_mask == pfunc_mask ) { + pcidev->func = i; + pcidev->vdevfn = orig_vdev | i; + }else{ + pcidev->vdevfn = orig_vdev; + } + if ( do_pci_remove(ctx, domid, pcidev) ) + rc = ERROR_FAIL; + } + } + + return rc; } int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, uint32_t domid, int *num) diff -r 2f4a89ad2528 -r f45026ec8db5 tools/libxl/libxl_utils.c --- a/tools/libxl/libxl_utils.c Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/libxl/libxl_utils.c Mon Aug 09 18:29:50 2010 +0100 @@ -538,3 +538,81 @@ int libxl_strtomac(const char *mac_s, ui } return 0; } + +#define QEMU_VERSION_STR "QEMU emulator version " + + +int libxl_check_device_model_version(libxl_ctx *ctx, char *path) +{ + pid_t pid = -1; + int pipefd[2]; + char buf[100]; + ssize_t i, count = 0; + int status; + char *abs_path = NULL; + + abs_path = libxl_abs_path(ctx, path, libxl_private_bindir_path()); + + if (pipe(pipefd)) + return -1; + + pid = fork(); + if (pid == -1) { + return -1; + } + + if (!pid) { + close(pipefd[0]); + if (dup2(pipefd[1], STDOUT_FILENO) == -1) + exit(1); + execlp(abs_path, abs_path, "-h", NULL); + + close(pipefd[1]); + exit(127); + } + + close(pipefd[1]); + if (abs_path != path) + libxl_free(ctx, abs_path); + + /* attempt to get the first line of `qemu -h` */ + while ((i = read(pipefd[0], buf + count, 99 - count)) > 0) { + if (i + count > 90) + break; + for (int j = 0; j < i; j++) { + if (buf[j + count] == '\n') + break; + } + count += i; + } + count += i; + close(pipefd[0]); + waitpid(pid, &status, 0); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + return -1; + } + + /* Check if we have the forked qemu-xen. */ + /* QEMU-DM emulator version 0.10.2, ... */ + if (strncmp("QEMU-DM ", buf, 7) == 0) { + return 0; + } + + /* Check if the version is above 12.0 */ + /* The first line is : QEMU emulator version 0.12.50, ... */ + if (strncmp(QEMU_VERSION_STR, buf, strlen(QEMU_VERSION_STR)) == 0) { + int major, minor; + char *endptr = NULL; + char *v = buf + strlen(QEMU_VERSION_STR); + + major = strtol(v, &endptr, 10); + if (major == 0 && endptr && *endptr == '.') { + v = endptr + 1; + minor = strtol(v, &endptr, 10); + if (minor >= 12) + return 1; + } + } + + return 0; +} diff -r 2f4a89ad2528 -r f45026ec8db5 tools/libxl/libxl_utils.h --- a/tools/libxl/libxl_utils.h Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/libxl/libxl_utils.h Mon Aug 09 18:29:50 2010 +0100 @@ -68,5 +68,11 @@ int libxl_devid_to_device_net2(libxl_ctx int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid, const char *devid, libxl_device_net2 *net2); +/* check the version of qemu + * return 1 if is the new one + * return 0 if is the old one + * return -1 if there are an error */ +int libxl_check_device_model_version(libxl_ctx *ctx, char *path); + #endif diff -r 2f4a89ad2528 -r f45026ec8db5 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Mon Aug 09 18:29:50 2010 +0100 @@ -833,6 +833,11 @@ static void parse_config_data(const char nic->script = strdup(p2 + 1); } else if (!strcmp(p, "vifname")) { nic->ifname = strdup(p2 + 1); + } else if (!strcmp(p, "backend")) { + if(libxl_name_to_domid(&ctx, (p2 + 1), &(nic->backend_domid))) { + fprintf(stderr, "Specified backend domain does not exist, defaulting to Dom0\n"); + nic->backend_domid = 0; + } } else if (!strcmp(p, "rate")) { fprintf(stderr, "the rate parameter for vifs is currently not supported\n"); } else if (!strcmp(p, "accel")) { @@ -1926,7 +1931,7 @@ void pcilist_assignable(void) if ( libxl_device_pci_list_assignable(&ctx, &pcidevs, &num) ) return; for (i = 0; i < num; i++) { - printf("%04x:%02x:%02x:%01x\n", + printf("%04x:%02x:%02x.%01x\n", pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, pcidevs[i].func); } free(pcidevs); @@ -2127,6 +2132,9 @@ void list_domains_details(const libxl_do libxl_device_model_info dm_info; for (i = 0; i < nb_domain; i++) { + /* no detailed info available on dom0 */ + if (info[i].domid == 0) + continue; rc = libxl_userdata_retrieve(&ctx, info[i].domid, "xl", &data, &len); if (rc) continue; @@ -3003,6 +3011,11 @@ int main_list(int argc, char **argv) } else if (optind == argc-1) { find_domain(argv[optind]); rc = libxl_domain_info(&ctx, &info_buf, domid); + if (rc == ERROR_INVAL) { + fprintf(stderr, "Error: Domain \'%s\' does not exist.\n", + argv[optind]); + return -rc; + } if (rc) { fprintf(stderr, "libxl_domain_info failed (code %d).\n", rc); return -rc; @@ -4004,10 +4017,9 @@ int main_networkattach(int argc, char ** } else if (!strncmp("script=", *argv, 6)) { nic.script = (*argv) + 6; } else if (!strncmp("backend=", *argv, 8)) { - val = strtoul((*argv) + 8, &endptr, 10); - if (((*argv) + 8) == endptr) { - fprintf(stderr, "Invalid parameter `backend'.\n"); - return 1; + if(libxl_name_to_domid(&ctx, ((*argv) + 8), &val)) { + fprintf(stderr, "Specified backend domain does not exist, defaulting to Dom0\n"); + val = 0; } nic.backend_domid = val; } else if (!strncmp("vifname=", *argv, 8)) { diff -r 2f4a89ad2528 -r f45026ec8db5 tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c Mon Aug 09 18:28:04 2010 +0100 +++ b/tools/libxl/xl_cmdtable.c Mon Aug 09 18:29:50 2010 +0100 @@ -35,8 +35,8 @@ struct cmd_spec cmd_table[] = { &main_list, "List information about all/some domains", "[options] [Domain]\n", - "-l, --long Output all VM details" - "-v, --verbose Prints out UUIDs", + "-l, --long Output all VM details\n" + "-v, --verbose Prints out UUIDs", }, { "destroy", &main_destroy, _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |