WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[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

<Prev in Thread] Current Thread [Next in Thread>