[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.