# 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
|