]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Fixed up various functions for Xen 3.0.5
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 13 Apr 2007 00:43:57 +0000 (00:43 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 13 Apr 2007 00:43:57 +0000 (00:43 +0000)
ChangeLog
src/xen_internal.c
src/xen_unified.c
src/xend_internal.c
src/xml.c
src/xs_internal.c
tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml

index 04570090b2a07814b7ed179f91611748def54310..20755417b46312abca52ec45995f3d24846a1979 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+Thu Apr 12 19:51:00 EST 2007 Daniel Berrange <berrange@redhat.com>
+
+       * src/xen_internal.c: Updated structs to work with new Xen 3.0.5
+       hypercall ABI. Mask out HVM bit when determining domain status.
+       Limit number of iterations when counting active IDs to 65000
+       * src/xen_unified.c: Fix checking of return value for the
+       domainGetVCpus method.
+       * src/xend_internal.c: Added an impl of the DomainGetOSType
+       method which works with inactive domains too. Don't do a
+       redundant ping test against GetVersion, since we now already
+       fetch config file format number which serves as a ping test.
+       Allow the kernel SEXPR field to be missing for domain0, or if
+       using a bootloader. Mark interface as type=bridge, if there
+       is a bridge device listed, but no explicit script to fix inactive
+       domains. Allow multiple boot devices to be provided for HVM
+       * src/xml.c: Allow multiple boot devices to be provided for HVM.
+       Support new style graphics config for HVM in xen 3.0.5
+       * src/xs_internal.c: Don't hardcode domain type of 'linux',
+       since we now have a fallback driver with xend that can make
+       the correct diagnosis for inactive domains.
+
 Thu Apr 12 15:18:00 BST 2007 Richard Jones <rjones@redhat.com>
 
        * src/libvirt.c: set VIR_CONNECT_RO on read-only connections.
index 637a6a1f45fd32ed3e354cc3c2c68c7b668072df..6a90f58956b5b5257cd51a4e1a4e196ac79fc12f 100644 (file)
@@ -93,6 +93,7 @@ static regex_t xen_cap_rec;
  */
 #ifndef DOMFLAGS_DYING
 #define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
+#define DOMFLAGS_HVM       (1<<1) /* Domain is HVM                           */
 #define DOMFLAGS_SHUTDOWN  (1<<2) /* The guest OS has shut down.             */
 #define DOMFLAGS_PAUSED    (1<<3) /* Currently paused by control software.   */
 #define DOMFLAGS_BLOCKED   (1<<4) /* Currently blocked pending an event.     */
@@ -146,87 +147,136 @@ struct xen_v2_getdomaininfo {
 };
 typedef struct xen_v2_getdomaininfo xen_v2_getdomaininfo;
 
+
+/* As of Hypervisor Call v2,  DomCtl v5 we are now 8-byte aligned
+   even on 32-bit archs when dealing with uint64_t */
+#define ALIGN_64 __attribute__((aligned(8)))
+
+struct xen_v2d5_getdomaininfo {
+    domid_t  domain;   /* the domain number */
+    uint32_t flags;    /* falgs, see before */
+    uint64_t tot_pages ALIGN_64;       /* total number of pages used */
+    uint64_t max_pages ALIGN_64;       /* maximum number of pages allowed */
+    uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
+    uint64_t cpu_time ALIGN_64;  /* CPU time used */
+    uint32_t nr_online_vcpus;  /* Number of VCPUs currently online. */
+    uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
+    uint32_t ssidref;
+    xen_domain_handle_t handle;
+};
+typedef struct xen_v2d5_getdomaininfo xen_v2d5_getdomaininfo;
+
 union xen_getdomaininfo {
     struct xen_v0_getdomaininfo v0;
     struct xen_v2_getdomaininfo v2;
+    struct xen_v2d5_getdomaininfo v2d5;
 };
 typedef union xen_getdomaininfo xen_getdomaininfo;
 
 union xen_getdomaininfolist {
     struct xen_v0_getdomaininfo *v0;
     struct xen_v2_getdomaininfo *v2;
+    struct xen_v2d5_getdomaininfo *v2d5;
 };
 typedef union xen_getdomaininfolist xen_getdomaininfolist;
 
 #define XEN_GETDOMAININFOLIST_ALLOC(domlist, size)                      \
     (hypervisor_version < 2 ?                                           \
      ((domlist.v0 = malloc(sizeof(xen_v0_getdomaininfo)*(size))) != NULL) : \
-     ((domlist.v2 = malloc(sizeof(xen_v2_getdomaininfo)*(size))) != NULL))
-
-#define XEN_GETDOMAININFOLIST_FREE(domlist)     \
-    (hypervisor_version < 2 ?                   \
-     free(domlist.v0) :                         \
-     free(domlist.v2))
-
-#define XEN_GETDOMAININFOLIST_CLEAR(domlist, size)                  \
-    (hypervisor_version < 2 ?                                       \
-     memset(domlist.v0, 0, sizeof(xen_v0_getdomaininfo) * size) :   \
-     memset(domlist.v2, 0, sizeof(xen_v2_getdomaininfo) * size))
+     (dom_interface_version < 5 ?                                       \
+      ((domlist.v2 = malloc(sizeof(xen_v2_getdomaininfo)*(size))) != NULL) : \
+      ((domlist.v2d5 = malloc(sizeof(xen_v2d5_getdomaininfo)*(size))) != NULL)))
+
+#define XEN_GETDOMAININFOLIST_FREE(domlist)        \
+    (hypervisor_version < 2 ?                      \
+     free(domlist.v0) :                            \
+     (dom_interface_version < 5 ?                  \
+      free(domlist.v2) :                           \
+      free(domlist.v2d5)))
+
+#define XEN_GETDOMAININFOLIST_CLEAR(domlist, size)                     \
+    (hypervisor_version < 2 ?                                          \
+     memset(domlist.v0, 0, sizeof(xen_v0_getdomaininfo) * size) :      \
+     (dom_interface_version < 5 ?                                      \
+      memset(domlist.v2, 0, sizeof(xen_v2_getdomaininfo) * size) :     \
+      memset(domlist.v2d5, 0, sizeof(xen_v2d5_getdomaininfo) * size)))
 
 #define XEN_GETDOMAININFOLIST_DOMAIN(domlist, n)    \
     (hypervisor_version < 2 ?                       \
      domlist.v0[n].domain :                         \
-     domlist.v2[n].domain)
-
-#define XEN_GETDOMAININFOLIST_DATA(domlist)     \
-    (hypervisor_version < 2 ?                   \
-     (void*)(domlist->v0) :                     \
-     (void*)(domlist->v2))
-
-#define XEN_GETDOMAININFO_SIZE                  \
-    (hypervisor_version < 2 ?                   \
-     sizeof(xen_v0_getdomaininfo) :             \
-     sizeof(xen_v2_getdomaininfo))
-
-#define XEN_GETDOMAININFO_CLEAR(dominfo)                        \
-    (hypervisor_version < 2 ?                                   \
-     memset(&(dominfo.v0), 0, sizeof(xen_v0_getdomaininfo)) :   \
-     memset(&(dominfo.v2), 0, sizeof(xen_v2_getdomaininfo)))
+     (dom_interface_version < 5 ?                   \
+      domlist.v2[n].domain :                        \
+      domlist.v2d5[n].domain))
+
+#define XEN_GETDOMAININFOLIST_DATA(domlist)        \
+    (hypervisor_version < 2 ?                      \
+     (void*)(domlist->v0) :                        \
+     (dom_interface_version < 5 ?                  \
+      (void*)(domlist->v2) :                       \
+      (void*)(domlist->v2d5)))
+
+#define XEN_GETDOMAININFO_SIZE                     \
+    (hypervisor_version < 2 ?                      \
+     sizeof(xen_v0_getdomaininfo) :                \
+     (dom_interface_version < 5 ?                  \
+      sizeof(xen_v2_getdomaininfo) :               \
+      sizeof(xen_v2d5_getdomaininfo)))
+
+#define XEN_GETDOMAININFO_CLEAR(dominfo)                           \
+    (hypervisor_version < 2 ?                                      \
+     memset(&(dominfo.v0), 0, sizeof(xen_v0_getdomaininfo)) :      \
+     (dom_interface_version < 5 ?                                  \
+      memset(&(dominfo.v2), 0, sizeof(xen_v2_getdomaininfo)) :     \
+      memset(&(dominfo.v2d5), 0, sizeof(xen_v2d5_getdomaininfo))))
 
 #define XEN_GETDOMAININFO_DOMAIN(dominfo)       \
     (hypervisor_version < 2 ?                   \
      dominfo.v0.domain :                        \
-     dominfo.v2.domain)
+     (dom_interface_version < 5 ?               \
+      dominfo.v2.domain :                       \
+      dominfo.v2d5.domain))
 
 #define XEN_GETDOMAININFO_CPUTIME(dominfo)      \
     (hypervisor_version < 2 ?                   \
      dominfo.v0.cpu_time :                      \
-     dominfo.v2.cpu_time)
+     (dom_interface_version < 5 ?               \
+      dominfo.v2.cpu_time :                     \
+      dominfo.v2d5.cpu_time))
 
 #define XEN_GETDOMAININFO_CPUCOUNT(dominfo)     \
     (hypervisor_version < 2 ?                   \
      dominfo.v0.nr_online_vcpus :               \
-     dominfo.v2.nr_online_vcpus)
+     (dom_interface_version < 5 ?               \
+      dominfo.v2.nr_online_vcpus :              \
+      dominfo.v2d5.nr_online_vcpus))
 
 #define XEN_GETDOMAININFO_MAXCPUID(dominfo)  \
     (hypervisor_version < 2 ?                   \
      dominfo.v0.max_vcpu_id :                   \
-     dominfo.v2.max_vcpu_id)
+     (dom_interface_version < 5 ?               \
+      dominfo.v2.max_vcpu_id :                  \
+      dominfo.v2d5.max_vcpu_id))
 
 #define XEN_GETDOMAININFO_FLAGS(dominfo)        \
     (hypervisor_version < 2 ?                   \
      dominfo.v0.flags :                         \
-     dominfo.v2.flags)
+     (dom_interface_version < 5 ?               \
+      dominfo.v2.flags :                        \
+      dominfo.v2d5.flags))
 
 #define XEN_GETDOMAININFO_TOT_PAGES(dominfo)    \
     (hypervisor_version < 2 ?                   \
      dominfo.v0.tot_pages :                     \
-     dominfo.v2.tot_pages)
+     (dom_interface_version < 5 ?               \
+      dominfo.v2.tot_pages :                    \
+      dominfo.v2d5.tot_pages))
 
 #define XEN_GETDOMAININFO_MAX_PAGES(dominfo)    \
     (hypervisor_version < 2 ?                   \
      dominfo.v0.max_pages :                     \
-     dominfo.v2.max_pages)
+     (dom_interface_version < 5 ?               \
+      dominfo.v2.max_pages :                    \
+      dominfo.v2d5.max_pages))
 
 
 
@@ -247,6 +297,18 @@ struct xen_v2_getdomaininfolistop {
 };
 typedef struct xen_v2_getdomaininfolistop xen_v2_getdomaininfolistop;
 
+/* As of HV version 2, sysctl version 3 the *buffer pointer is 64-bit aligned */
+struct xen_v2s3_getdomaininfolistop {
+    domid_t   first_domain;
+    uint32_t  max_domains;
+    union {
+        struct xen_v2d5_getdomaininfo *v;
+        uint64_t pad ALIGN_64;
+    } buffer;
+    uint32_t  num_domains;
+};
+typedef struct xen_v2s3_getdomaininfolistop xen_v2s3_getdomaininfolistop;
+
 
 
 struct xen_v0_domainop {
@@ -294,6 +356,11 @@ struct xen_v2_setmaxmem {
 };
 typedef struct xen_v2_setmaxmem xen_v2_setmaxmem;
 
+struct xen_v2d5_setmaxmem {
+    uint64_t   maxmem ALIGN_64;
+};
+typedef struct xen_v2d5_setmaxmem xen_v2d5_setmaxmem;
+
 /*
  * The informations for an setmaxvcpu system hypercall
  */
@@ -340,6 +407,20 @@ struct xen_v2_setvcpumap {
 };
 typedef struct xen_v2_setvcpumap xen_v2_setvcpumap;
 
+/* HV version 2, Dom version 5 requires 64-bit alignment */
+struct xen_v2d5_cpumap {
+    union {
+        uint8_t    *v;
+        uint64_t   pad ALIGN_64;
+    } bitmap;
+    uint32_t    nr_cpus;
+};
+struct xen_v2d5_setvcpumap {
+    uint32_t   vcpu;
+    struct xen_v2d5_cpumap cpumap;
+};
+typedef struct xen_v2d5_setvcpumap xen_v2d5_setvcpumap;
+
 /*
  * The informations for an vcpuinfo system hypercall
  */
@@ -370,11 +451,22 @@ struct xen_v2_vcpuinfo {
 };
 typedef struct xen_v2_vcpuinfo xen_v2_vcpuinfo;
 
+struct xen_v2d5_vcpuinfo {
+    uint32_t   vcpu;           /* the vcpu number */
+    uint8_t    online;         /* seen as on line */
+    uint8_t    blocked;        /* blocked on event */
+    uint8_t    running;        /* scheduled on CPU */
+    uint64_t    cpu_time ALIGN_64; /* nanosecond of CPU used */
+    uint32_t   cpu;            /* current mapping */
+};
+typedef struct xen_v2d5_vcpuinfo xen_v2d5_vcpuinfo;
+
 /*
  * from V2 the pinning of a vcpu is read with a separate call
  */
 #define XEN_V2_OP_GETVCPUMAP   25
 typedef struct xen_v2_setvcpumap xen_v2_getvcpumap;
+typedef struct xen_v2d5_setvcpumap xen_v2d5_getvcpumap;
 
 /*
  * The hypercall operation structures also have changed on
@@ -402,7 +494,8 @@ struct xen_op_v2_sys {
     uint32_t cmd;
     uint32_t interface_version;
     union {
-        xen_v2_getdomaininfolistop getdomaininfolist;
+        xen_v2_getdomaininfolistop   getdomaininfolist;
+        xen_v2s3_getdomaininfolistop getdomaininfolists3;
         uint8_t padding[128];
     } u;
 };
@@ -415,10 +508,14 @@ struct xen_op_v2_dom {
     domid_t  domain;
     union {
         xen_v2_setmaxmem         setmaxmem;
+        xen_v2d5_setmaxmem       setmaxmemd5;
         xen_v2_setmaxvcpu        setmaxvcpu;
         xen_v2_setvcpumap        setvcpumap;
+        xen_v2d5_setvcpumap      setvcpumapd5;
         xen_v2_vcpuinfo          getvcpuinfo;
+        xen_v2d5_vcpuinfo        getvcpuinfod5;
         xen_v2_getvcpumap        getvcpumap;
+        xen_v2d5_getvcpumap      getvcpumapd5;
         uint8_t padding[128];
     } u;
 };
@@ -726,13 +823,26 @@ virXen_getdomaininfolist(int handle, int first_domain, int maxids,
 
         memset(&op, 0, sizeof(op));
         op.cmd = XEN_V2_OP_GETDOMAININFOLIST;
-        op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
-        op.u.getdomaininfolist.max_domains = maxids;
-        op.u.getdomaininfolist.buffer = dominfos->v2;
-        op.u.getdomaininfolist.num_domains = maxids;
+
+        if (sys_interface_version < 3) {
+            op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
+            op.u.getdomaininfolist.max_domains = maxids;
+            op.u.getdomaininfolist.buffer = dominfos->v2;
+            op.u.getdomaininfolist.num_domains = maxids;
+        } else {
+            op.u.getdomaininfolists3.first_domain = (domid_t) first_domain;
+            op.u.getdomaininfolists3.max_domains = maxids;
+            op.u.getdomaininfolists3.buffer.v = dominfos->v2d5;
+            op.u.getdomaininfolists3.num_domains = maxids;
+        }
         ret = xenHypervisorDoV2Sys(handle, &op);
-        if (ret == 0)
-            ret = op.u.getdomaininfolist.num_domains;
+
+        if (ret == 0) {
+            if (sys_interface_version < 3)
+                ret = op.u.getdomaininfolist.num_domains;
+            else
+                ret = op.u.getdomaininfolists3.num_domains;
+        }
     } else if (hypervisor_version == 1) {
         xen_op_v1 op;
 
@@ -921,7 +1031,10 @@ virXen_setmaxmem(int handle, int id, unsigned long memory)
         memset(&op, 0, sizeof(op));
         op.cmd = XEN_V2_OP_SETMAXMEM;
         op.domain = (domid_t) id;
-        op.u.setmaxmem.maxmem = memory;
+        if (dom_interface_version < 5)
+            op.u.setmaxmem.maxmem = memory;
+        else
+            op.u.setmaxmemd5.maxmem = memory;
         ret = xenHypervisorDoV2Dom(handle, &op);
     } else if (hypervisor_version == 1) {
         xen_op_v1 op;
@@ -1014,10 +1127,17 @@ virXen_setvcpumap(int handle, int id, unsigned int vcpu,
         memset(&op, 0, sizeof(op));
         op.cmd = XEN_V2_OP_SETVCPUMAP;
         op.domain = (domid_t) id;
-        op.u.setvcpumap.vcpu = vcpu;
-        op.u.setvcpumap.cpumap.bitmap = cpumap;
-        op.u.setvcpumap.cpumap.nr_cpus = maplen * 8;
+        if (dom_interface_version < 5) {
+            op.u.setvcpumap.vcpu = vcpu;
+            op.u.setvcpumap.cpumap.bitmap = cpumap;
+            op.u.setvcpumap.cpumap.nr_cpus = maplen * 8;
+        } else {
+            op.u.setvcpumapd5.vcpu = vcpu;
+            op.u.setvcpumapd5.cpumap.bitmap.v = cpumap;
+            op.u.setvcpumapd5.cpumap.nr_cpus = maplen * 8;
+        }
         ret = xenHypervisorDoV2Dom(handle, &op);
+
         if (munlock(cpumap, maplen) < 0) {
             virXenError(VIR_ERR_XEN_CALL, " release", maplen);
             ret = -1;
@@ -1082,29 +1202,56 @@ virXen_getvcpusinfo(int handle, int id, unsigned int vcpu, virVcpuInfoPtr ipt,
         memset(&op, 0, sizeof(op));
         op.cmd = XEN_V2_OP_GETVCPUINFO;
         op.domain = (domid_t) id;
-        op.u.getvcpuinfo.vcpu = (uint16_t) vcpu;
+        if (dom_interface_version < 5)
+            op.u.getvcpuinfo.vcpu = (uint16_t) vcpu;
+        else
+            op.u.getvcpuinfod5.vcpu = (uint16_t) vcpu;
         ret = xenHypervisorDoV2Dom(handle, &op);
+
         if (ret < 0)
             return(-1);
         ipt->number = vcpu;
-        if (op.u.getvcpuinfo.online) {
-            if (op.u.getvcpuinfo.running) ipt->state = VIR_VCPU_RUNNING;
-            if (op.u.getvcpuinfo.blocked) ipt->state = VIR_VCPU_BLOCKED;
+        if (dom_interface_version < 5) {
+            if (op.u.getvcpuinfo.online) {
+                if (op.u.getvcpuinfo.running)
+                    ipt->state = VIR_VCPU_RUNNING;
+                if (op.u.getvcpuinfo.blocked)
+                    ipt->state = VIR_VCPU_BLOCKED;
+            } else
+                ipt->state = VIR_VCPU_OFFLINE;
+
+            ipt->cpuTime = op.u.getvcpuinfo.cpu_time;
+            ipt->cpu = op.u.getvcpuinfo.online ? (int)op.u.getvcpuinfo.cpu : -1;
+        } else {
+            if (op.u.getvcpuinfod5.online) {
+                if (op.u.getvcpuinfod5.running)
+                    ipt->state = VIR_VCPU_RUNNING;
+                if (op.u.getvcpuinfod5.blocked)
+                    ipt->state = VIR_VCPU_BLOCKED;
+            } else
+                ipt->state = VIR_VCPU_OFFLINE;
+
+            ipt->cpuTime = op.u.getvcpuinfod5.cpu_time;
+            ipt->cpu = op.u.getvcpuinfod5.online ? (int)op.u.getvcpuinfod5.cpu : -1;
         }
-        else ipt->state = VIR_VCPU_OFFLINE;
-        ipt->cpuTime = op.u.getvcpuinfo.cpu_time;
-        ipt->cpu = op.u.getvcpuinfo.online ? (int)op.u.getvcpuinfo.cpu : -1;
         if ((cpumap != NULL) && (maplen > 0)) {
             if (mlock(cpumap, maplen) < 0) {
                 virXenError(VIR_ERR_XEN_CALL, " locking", maplen);
                 return (-1);
             }
+            memset(cpumap, 0, maplen);
             memset(&op, 0, sizeof(op));
             op.cmd = XEN_V2_OP_GETVCPUMAP;
             op.domain = (domid_t) id;
-            op.u.setvcpumap.vcpu = vcpu;
-            op.u.setvcpumap.cpumap.bitmap = cpumap;
-            op.u.setvcpumap.cpumap.nr_cpus = maplen * 8;
+            if (dom_interface_version < 5) {
+                op.u.getvcpumap.vcpu = vcpu;
+                op.u.getvcpumap.cpumap.bitmap = cpumap;
+                op.u.getvcpumap.cpumap.nr_cpus = maplen * 8;
+            } else {
+                op.u.getvcpumapd5.vcpu = vcpu;
+                op.u.getvcpumapd5.cpumap.bitmap.v = cpumap;
+                op.u.getvcpumapd5.cpumap.nr_cpus = maplen * 8;
+            }
             ret = xenHypervisorDoV2Dom(handle, &op);
             if (munlock(cpumap, maplen) < 0) {
                 virXenError(VIR_ERR_XEN_CALL, " release", maplen);
@@ -1802,10 +1949,18 @@ xenHypervisorNumOfDomains(virConnectPtr conn)
         return (-1);
 
     nbids = ret;
+    /* Can't possibly have more than 65,000 concurrent guests
+     * so limit how many times we try, to avoid increasing
+     * without bound & thus allocating all of system memory !
+     * XXX I'll regret this comment in a few years time ;-)
+     */
     if (nbids == maxids) {
-        last_maxids *= 2;
-        maxids *= 2;
-        goto retry;
+        if (maxids < 65000) {
+            last_maxids *= 2;
+            maxids *= 2;
+            goto retry;
+        }
+        nbids = -1;
     }
     if ((nbids < 0) || (nbids > maxids))
         return(-1);
@@ -1994,7 +2149,8 @@ xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info)
         return (-1);
 
     domain_flags = XEN_GETDOMAININFO_FLAGS(dominfo);
-    domain_state = domain_flags & 0xFF;
+    domain_flags &= ~DOMFLAGS_HVM; /* Mask out HVM flags */
+    domain_state = domain_flags & 0xFF; /* Mask out high bits */
     switch (domain_state) {
        case DOMFLAGS_DYING:
            info->state = VIR_DOMAIN_SHUTDOWN;
index a8a29c9bc88686a4fdceb944ae4d0d7b44ce8cfa..fe8eb81b0d01f560547b98abc42bad875be5e859 100644 (file)
@@ -546,13 +546,14 @@ xenUnifiedDomainGetVcpus (virDomainPtr dom,
                           virVcpuInfoPtr info, int maxinfo,
                           unsigned char *cpumaps, int maplen)
 {
-    int i;
+    int i, ret;
 
     for (i = 0; i < nb_drivers; ++i)
-        if (drivers[i]->domainGetVcpus &&
-            drivers[i]->domainGetVcpus (dom, info, maxinfo, cpumaps, maplen) == 0)
-            return 0;
-
+        if (drivers[i]->domainGetVcpus) {
+            ret = drivers[i]->domainGetVcpus (dom, info, maxinfo, cpumaps, maplen);
+            if (ret > 0)
+                return ret;
+        }
     return -1;
 }
 
index c296ad615dfeb209ecfda6182d3ae3ce6d6c50be..66a2e4a42f04cabbd44d39a79ffecb0b57a7434d 100644 (file)
@@ -54,6 +54,7 @@ static virDomainPtr xenDaemonLookupByUUID(virConnectPtr conn,
 static virDomainPtr xenDaemonCreateLinux(virConnectPtr conn,
                                          const char *xmlDesc,
                                         unsigned int flags);
+static char *xenDaemonDomainGetOSType(virDomainPtr domain);
 static int xenDaemonAttachDevice(virDomainPtr domain, char *xml);
 static int xenDaemonDetachDevice(virDomainPtr domain, char *xml);
 static int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename,
@@ -85,7 +86,7 @@ virDriver xenDaemonDriver = {
     xenDaemonDomainShutdown, /* domainShutdown */
     xenDaemonDomainReboot, /* domainReboot */
     xenDaemonDomainDestroy, /* domainDestroy */
-    NULL, /* domainGetOSType */
+    xenDaemonDomainGetOSType, /* domainGetOSType */
     xenDaemonDomainGetMaxMemory, /* domainGetMaxMemory */
     xenDaemonDomainSetMaxMemory, /* domainSetMaxMemory */
     xenDaemonDomainSetMemory, /* domainMaxMemory */
@@ -1151,7 +1152,7 @@ xend_detect_config_version(virConnectPtr conn) {
         priv->xendConfigVersion = 1;
     }
     sexpr_free(root);
-    return priv->xendConfigVersion;
+    return (0);
 }
 
 /**
@@ -1251,13 +1252,14 @@ xend_log(virConnectPtr xend, char *buffer, size_t n_buffer)
  * @node: the root of the parsed S-Expression
  * @buf: output buffer object
  * @hvm: true or 1 if no contains HVM S-Expression 
+ * @bootloader: true or 1 if a bootloader is defined
  *
  * Parse the xend sexp for description of os and append it to buf.
  *
  * Returns 0 in case of success and -1 in case of error
  */
 static int
-xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf, int hvm)
+xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf, int hvm, int bootloader)
 {
     const char *tmp;
 
@@ -1269,37 +1271,44 @@ xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf
     if (hvm) {
         virBufferVSprintf(buf, "    <type>hvm</type>\n");
         tmp = sexpr_node(node, "domain/image/hvm/kernel");
-        if (tmp == NULL) {
+        if (tmp == NULL && !bootloader) {
             virXendError(xend, VIR_ERR_INTERNAL_ERROR,
-                         _("domain information incomplete, missing kernel"));
+                         _("domain information incomplete, missing kernel & bootloader"));
             return(-1);
-       }
-        virBufferVSprintf(buf, "    <loader>%s</loader>\n", tmp);
+        }
+        if (tmp)
+            virBufferVSprintf(buf, "    <loader>%s</loader>\n", tmp);
         tmp = sexpr_node(node, "domain/image/hvm/boot");
         if ((tmp != NULL) && (tmp[0] != 0)) {
-           if (tmp[0] == 'a')
-               /* XXX no way to deal with boot from 2nd floppy */
-               virBufferAdd(buf, "    <boot dev='fd'/>\n", 21 );
-           else if (tmp[0] == 'c')
-          /*
-            * Don't know what to put here.  Say the vm has been given 3
-            * disks - hda, hdb, hdc.  How does one identify the boot disk?
-                * We're going to assume that first disk is the boot disk since
-                * this is most common practice
-           */
-               virBufferAdd(buf, "    <boot dev='hd'/>\n", 21 );
-           else if (strcmp(tmp, "d") == 0)
-               virBufferAdd(buf, "    <boot dev='cdrom'/>\n", 24 );
+            while (*tmp) {
+                if (*tmp == 'a')
+                    /* XXX no way to deal with boot from 2nd floppy */
+                    virBufferAdd(buf, "    <boot dev='fd'/>\n", 21 );
+                else if (*tmp == 'c')
+                    /*
+                     * Don't know what to put here.  Say the vm has been given 3
+                     * disks - hda, hdb, hdc.  How does one identify the boot disk?
+                     * We're going to assume that first disk is the boot disk since
+                     * this is most common practice
+                     */
+                    virBufferAdd(buf, "    <boot dev='hd'/>\n", 21 );
+                else if (*tmp == 'd')
+                    virBufferAdd(buf, "    <boot dev='cdrom'/>\n", 24 );
+                else if (*tmp == 'n')
+                    virBufferAdd(buf, "    <boot dev='network'/>\n", 26 );
+                tmp++;
+            }
         }
     } else {
         virBufferVSprintf(buf, "    <type>linux</type>\n");
         tmp = sexpr_node(node, "domain/image/linux/kernel");
-        if (tmp == NULL) {
+        if (tmp == NULL && !bootloader) {
             virXendError(xend, VIR_ERR_INTERNAL_ERROR,
-                         _("domain information incomplete, missing kernel"));
+                         _("domain information incomplete, missing kernel & bootloader"));
             return(-1);
-       }
-        virBufferVSprintf(buf, "    <kernel>%s</kernel>\n", tmp);
+        }
+        if (tmp)
+            virBufferVSprintf(buf, "    <kernel>%s</kernel>\n", tmp);
         tmp = sexpr_node(node, "domain/image/linux/ramdisk");
         if ((tmp != NULL) && (tmp[0] != 0))
            virBufferVSprintf(buf, "    <initrd>%s</initrd>\n", tmp);
@@ -1334,7 +1343,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
     const char *tmp;
     char *tty;
     virBuffer buf;
-    int hvm = 0;
+    int hvm = 0, bootloader = 0;
     int domid = -1;
     int max_mem, cur_mem;
 
@@ -1385,12 +1394,20 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
            virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", compact);
     }
     tmp = sexpr_node(root, "domain/bootloader");
-    if (tmp != NULL)
+    if (tmp != NULL) {
+        bootloader = 1;
         virBufferVSprintf(&buf, "  <bootloader>%s</bootloader>\n", tmp);
+    }
 
-    if (sexpr_lookup(root, "domain/image")) {
-        hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0;
-        xend_parse_sexp_desc_os(conn, root, &buf, hvm);
+    if (domid == 0) {
+        virBufferAdd(&buf, "  <os>\n", -1);
+        virBufferAdd(&buf, "    <type>linux</type>\n", -1);
+        virBufferAdd(&buf, "  </os>\n", -1);
+    } else {
+        if (sexpr_lookup(root, "domain/image")) {
+            hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0;
+            xend_parse_sexp_desc_os(conn, root, &buf, hvm, bootloader);
+        }
     }
 
     max_mem = (int) (sexpr_u64(root, "domain/maxmem") << 10);
@@ -1585,9 +1602,9 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
         } else if (sexpr_lookup(node, "device/vif")) {
             const char *tmp2;
             tmp2 = sexpr_node(node, "device/vif/script");
-            if (tmp2 && strstr(tmp2, "bridge")) {
+            tmp = sexpr_node(node, "device/vif/bridge");
+            if ((tmp2 && strstr(tmp2, "bridge")) || tmp) {
                 virBufferVSprintf(&buf, "    <interface type='bridge'>\n");
-                tmp = sexpr_node(node, "device/vif/bridge");
                 if (tmp != NULL)
                     virBufferVSprintf(&buf, "      <source bridge='%s'/>\n",
                                       tmp);
@@ -1612,9 +1629,9 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
                                   tmp2);
 
             virBufferAdd(&buf, "    </interface>\n", 17);
-        } else if (!hvm &&
-                   sexpr_lookup(node, "device/vfb")) {
-            /* New style graphics config for PV guests only in 3.0.4 */
+        } else if (sexpr_lookup(node, "device/vfb")) {
+            /* New style graphics config for PV guests in >= 3.0.4,
+             * or for HVM guests in >= 3.0.5 */
             tmp = sexpr_node(node, "device/vfb/type");
 
             if (tmp && !strcmp(tmp, "sdl")) {
@@ -1663,7 +1680,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
         }
     }
 
-    /* Graphics device (HVM, or old (pre-3.0.4) style PV vnc config) */
+    /* Graphics device (HVM <= 3.0.4, or PV <= 3.0.4) vnc config */
     tmp = sexpr_fmt_node(root, "domain/image/%s/vnc", hvm ? "hvm" : "linux");
     if (tmp != NULL) {
         if (tmp[0] == '1') {
@@ -1901,7 +1918,6 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
 {
     xmlURIPtr uri = NULL;
     int ret;
-    unsigned long version;
 
     /* If the name is just "xen" (it might originally have been NULL, see
      * xenUnifiedOpen) then try default paths and methods to get to the
@@ -1914,8 +1930,8 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
         ret = xenDaemonOpen_unix(conn, "/var/lib/xend/xend-socket");
         if (ret < 0)
             goto try_http;
-        ret = xenDaemonGetVersion(conn, &version);
-        if (ret == 0)
+        ret = xend_detect_config_version(conn);
+        if (ret != -1)
             goto done;
 
     try_http:
@@ -1925,8 +1941,8 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
         ret = xenDaemonOpen_tcp(conn, "localhost", 8000);
         if (ret < 0)
             goto failed;
-        ret = xenDaemonGetVersion(conn, &version);
-        if (ret < 0)
+        ret = xend_detect_config_version(conn);
+        if (ret == -1)
             goto failed;
     } else {
         /*
@@ -1950,15 +1966,15 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
             if (ret < 0)
                 goto failed;
 
-            ret = xenDaemonGetVersion(conn, &version);
-            if (ret < 0)
+            ret = xend_detect_config_version(conn);
+            if (ret == -1)
                 goto failed;
         } else if (!strcasecmp(uri->scheme, "http")) {
             ret = xenDaemonOpen_tcp(conn, uri->server, uri->port);
             if (ret < 0)
                 goto failed;
-            ret = xenDaemonGetVersion(conn, &version);
-            if (ret < 0)
+            ret = xend_detect_config_version(conn);
+            if (ret == -1)
                 goto failed;
         } else {
             if (!(flags & VIR_DRV_OPEN_QUIET))
@@ -1967,17 +1983,7 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
         }
     }
 
- done: 
-   /* The XenD config version is used to determine
-     * which APIs / features to activate. Lookup & cache
-     * it now to avoid repeated HTTP calls
-     */
-    if (xend_detect_config_version(conn) < 0) {
-        virXendError(conn, VIR_ERR_INTERNAL_ERROR,
-                     "cannot determine xend config version");
-        goto failed;
-    }
-
+ done:
     if (uri != NULL)
         xmlFreeURI(uri);
     return(ret);
@@ -2122,6 +2128,49 @@ xenDaemonDomainDestroy(virDomainPtr domain)
     return xend_op(domain->conn, domain->name, "op", "destroy", NULL);
 }
 
+/**
+ * xenDaemonDomainGetOSType:
+ * @domain: a domain object
+ *
+ * Get the type of domain operation system.
+ *
+ * Returns the new string or NULL in case of error, the string must be
+ *         freed by the caller.
+ */
+static char *
+xenDaemonDomainGetOSType(virDomainPtr domain)
+{
+    char *type;
+    struct sexpr *root;
+    xenUnifiedPrivatePtr priv;
+
+    if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
+        virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
+                    __FUNCTION__);
+        return(NULL);
+    }
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (domain->id < 0 && priv->xendConfigVersion < 3)
+        return(NULL);
+
+    /* can we ask for a subset ? worth it ? */
+    root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
+    if (root == NULL)
+        return(NULL);
+
+    if (sexpr_lookup(root, "domain/image/hvm")) {
+        type = strdup("hvm");
+    } else {
+        type = strdup("linux");
+    }
+
+    sexpr_free(root);
+
+    return(type);
+}
+
 /**
  * xenDaemonDomainSave:
  * @domain: pointer to the Domain block
@@ -2892,7 +2941,7 @@ xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
                  uuid[4], uuid[5], uuid[6], uuid[7],
                  uuid[8], uuid[9], uuid[10], uuid[11],
                  uuid[12], uuid[13], uuid[14], uuid[15]);
-        printf("Dpooing %s\n", uuidstr);
+
         root = sexpr_get(conn, "/xend/domain/%s?detail=1", uuidstr);
         if (root == NULL)
             return (NULL);
index 89913cf6b2e579f693cdef847dd7a4fa7276d689..6796d53ecec4fbfbe08aa39cfb3012c51602c76e 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -591,7 +591,8 @@ virDomainParseXMLOSDescHVM(virConnectPtr conn, xmlNodePtr node, virBufferPtr buf
     xmlNodePtr cur, txt;
     xmlChar *type = NULL;
     xmlChar *loader = NULL;
-    xmlChar *boot_dev = NULL;
+    char bootorder[5];
+    int nbootorder = 0;
     int res;
     char *str;
 
@@ -610,13 +611,32 @@ virDomainParseXMLOSDescHVM(virConnectPtr conn, xmlNodePtr node, virBufferPtr buf
                 if ((txt != NULL) && (txt->type == XML_TEXT_NODE) &&
                     (txt->next == NULL))
                     loader = txt->content;
-            } else if ((boot_dev == NULL) &&
-                       (xmlStrEqual(cur->name, BAD_CAST "boot"))) {
-                boot_dev = xmlGetProp(cur, BAD_CAST "dev");
+            } else if ((xmlStrEqual(cur->name, BAD_CAST "boot"))) {
+                xmlChar *boot_dev = xmlGetProp(cur, BAD_CAST "dev");
+                if (nbootorder == ((sizeof(bootorder)/sizeof(bootorder[0]))-1)) {
+                    virXMLError(conn, VIR_ERR_XML_ERROR, "too many boot devices", 0);
+                    return (-1);
+                }
+                if (xmlStrEqual(boot_dev, BAD_CAST "fd")) {
+                    bootorder[nbootorder++] = 'a';
+                } else if (xmlStrEqual(boot_dev, BAD_CAST "cdrom")) {
+                    bootorder[nbootorder++] = 'd';
+                } else if (xmlStrEqual(boot_dev, BAD_CAST "network")) {
+                    bootorder[nbootorder++] = 'n';
+                } else if (xmlStrEqual(boot_dev, BAD_CAST "hd")) {
+                    bootorder[nbootorder++] = 'c';
+                } else {
+                    xmlFree(boot_dev);
+                    /* Any other type of boot dev is unsupported right now */
+                    virXMLError(conn, VIR_ERR_XML_ERROR, NULL, 0);
+                    return (-1);
+                }
+                xmlFree(boot_dev);
             }
         }
         cur = cur->next;
     }
+    bootorder[nbootorder] = '\0';
     if ((type == NULL) || (!xmlStrEqual(type, BAD_CAST "hvm"))) {
         /* VIR_ERR_OS_TYPE */
         virXMLError(conn, VIR_ERR_OS_TYPE, (const char *) type, 0);
@@ -641,73 +661,58 @@ virDomainParseXMLOSDescHVM(virConnectPtr conn, xmlNodePtr node, virBufferPtr buf
 
     virBufferVSprintf(buf, "(vcpus %d)", vcpus);
 
-    if (boot_dev) {
-        if (xmlStrEqual(boot_dev, BAD_CAST "fd")) {
-            virBufferVSprintf(buf, "(boot a)" /*, (const char *) boot_dev*/);
-        } else if (xmlStrEqual(boot_dev, BAD_CAST "cdrom")) {
-            virBufferVSprintf(buf, "(boot d)" /*, (const char *) boot_dev*/);
-        } else if (xmlStrEqual(boot_dev, BAD_CAST "hd")) {
-            virBufferVSprintf(buf, "(boot c)" /*, (const char *) boot_dev*/);
-        } else {
-            /* Any other type of boot dev is unsupported right now */
-            virXMLError(conn, VIR_ERR_XML_ERROR, NULL, 0);
-        }
+    if (nbootorder)
+        virBufferVSprintf(buf, "(boot %s)", bootorder);
 
-        /* get the 1st floppy device file */
-       cur = virXPathNode(
-         "/domain/devices/disk[@device='floppy' and target/@dev='fda']/source",
-                          ctxt);
+    /* get the 1st floppy device file */
+       cur = virXPathNode("/domain/devices/disk[@device='floppy' and target/@dev='fda']/source",
+                       ctxt);
        if (cur != NULL) {
-            xmlChar *fdfile;
-
-            fdfile = xmlGetProp(cur, BAD_CAST "file");
+        xmlChar *fdfile;
+        fdfile = xmlGetProp(cur, BAD_CAST "file");
            if (fdfile != NULL) {
-               virBufferVSprintf(buf, "(fda '%s')", fdfile);
-               free(fdfile);
+            virBufferVSprintf(buf, "(fda '%s')", fdfile);
+            free(fdfile);
            }
-        }
+    }
 
-        /* get the 2nd floppy device file */
-       cur = virXPathNode(
-         "/domain/devices/disk[@device='floppy' and target/@dev='fdb']/source",
-                          ctxt);
+    /* get the 2nd floppy device file */
+       cur = virXPathNode("/domain/devices/disk[@device='floppy' and target/@dev='fdb']/source",
+                       ctxt);
        if (cur != NULL) {
-            xmlChar *fdfile;
-
-            fdfile = xmlGetProp(cur, BAD_CAST "file");
+        xmlChar *fdfile;
+        fdfile = xmlGetProp(cur, BAD_CAST "file");
            if (fdfile != NULL) {
-               virBufferVSprintf(buf, "(fdb '%s')", fdfile);
-               free(fdfile);
+            virBufferVSprintf(buf, "(fdb '%s')", fdfile);
+            free(fdfile);
            }
-        }
+    }
 
 
-        /* get the cdrom device file */
-        /* Only XenD <= 3.0.2 wants cdrom config here */
-        if (xendConfigVersion == 1) {
-           cur = virXPathNode(
-       "/domain/devices/disk[@device='cdrom' and target/@dev='hdc']/source",
+    /* get the cdrom device file */
+    /* Only XenD <= 3.0.2 wants cdrom config here */
+    if (xendConfigVersion == 1) {
+           cur = virXPathNode("/domain/devices/disk[@device='cdrom' and target/@dev='hdc']/source",
                               ctxt);
            if (cur != NULL) {
-                xmlChar *cdfile;
-
-                cdfile = xmlGetProp(cur, BAD_CAST "file");
-               if (cdfile != NULL) {
-                   virBufferVSprintf(buf, "(cdrom '%s')",
-                                     (const char *)cdfile);
-                   xmlFree(cdfile);
-               }
+            xmlChar *cdfile;
+
+            cdfile = xmlGetProp(cur, BAD_CAST "file");
+            if (cdfile != NULL) {
+                virBufferVSprintf(buf, "(cdrom '%s')",
+                                  (const char *)cdfile);
+                xmlFree(cdfile);
             }
         }
-
-        if (virXPathNode("/domain/features/acpi", ctxt) != NULL)
-            virBufferAdd(buf, "(acpi 1)", 8);
-        if (virXPathNode("/domain/features/apic", ctxt) != NULL)
-            virBufferAdd(buf, "(apic 1)", 8);
-        if (virXPathNode("/domain/features/pae", ctxt) != NULL)
-            virBufferAdd(buf, "(pae 1)", 7);
     }
 
+    if (virXPathNode("/domain/features/acpi", ctxt) != NULL)
+        virBufferAdd(buf, "(acpi 1)", 8);
+    if (virXPathNode("/domain/features/apic", ctxt) != NULL)
+        virBufferAdd(buf, "(apic 1)", 8);
+    if (virXPathNode("/domain/features/pae", ctxt) != NULL)
+        virBufferAdd(buf, "(pae 1)", 7);
+
     res = virXPathBoolean("count(domain/devices/console) > 0", ctxt);
     if (res < 0) {
         virXMLError(conn, VIR_ERR_XML_ERROR, NULL, 0);
@@ -717,25 +722,24 @@ virDomainParseXMLOSDescHVM(virConnectPtr conn, xmlNodePtr node, virBufferPtr buf
         virBufferAdd(buf, "(serial pty)", 12);
     }
 
-    /* Is a graphics device specified? */
-    cur = virXPathNode("/domain/devices/graphics[1]", ctxt);
-    if (cur != NULL) {
-        res = virDomainParseXMLGraphicsDescImage(conn, cur, buf,
-                                                xendConfigVersion);
-        if (res != 0) {
-            goto error;
+    /* HVM graphics for xen <= 3.0.5 */
+    if (xendConfigVersion < 4) {
+        /* Is a graphics device specified? */
+        cur = virXPathNode("/domain/devices/graphics[1]", ctxt);
+        if (cur != NULL) {
+            res = virDomainParseXMLGraphicsDescImage(conn, cur, buf,
+                                                     xendConfigVersion);
+            if (res != 0) {
+                goto error;
+            }
         }
     }
 
     virBufferAdd(buf, "))", 2);
 
-    if (boot_dev)
-        xmlFree(boot_dev);
-
     return (0);
+
  error:
-    if (boot_dev)
-        xmlFree(boot_dev);
     return(-1);
 }
 
@@ -821,13 +825,12 @@ virDomainParseXMLOSDescPV(virConnectPtr conn, xmlNodePtr node, virBufferPtr buf,
     if (cmdline != NULL)
         virBufferVSprintf(buf, "(args '%s')", (const char *) cmdline);
 
-    /* Is a graphics device specified? */
-    /* Old style config before merge of PVFB */
+    /* PV graphics for xen <= 3.0.4 */
     if (xendConfigVersion < 3) {
         cur = virXPathNode("/domain/devices/graphics[1]", ctxt);
         if (cur != NULL) {
             res = virDomainParseXMLGraphicsDescImage(conn, cur, buf,
-                                                    xendConfigVersion);
+                                                     xendConfigVersion);
             if (res != 0) {
                 goto error;
             }
@@ -1326,7 +1329,7 @@ virDomainParseXMLDesc(virConnectPtr conn, const char *xmldesc, char **name, int
                 goto error;
             }
         }
-       free(nodes);
+        free(nodes);
     }
 
     nb_nodes = virXPathNodeSet("/domain/devices/interface", ctxt, &nodes);
@@ -1340,21 +1343,23 @@ virDomainParseXMLDesc(virConnectPtr conn, const char *xmldesc, char **name, int
             }
             virBufferAdd(&buf, ")", 1);
         }
-       free(nodes);
+        free(nodes);
     }
 
-    /* New style PVFB config  - 3.0.4 merge */
-    if (xendConfigVersion >= 3 && !hvm) {
+    /* New style PV graphics config xen >= 3.0.4,
+     * or HVM graphics config xen >= 3.0.5 */
+    if ((xendConfigVersion >= 3 && !hvm) ||
+        (xendConfigVersion >= 4 && hvm)) {
         nb_nodes = virXPathNodeSet("/domain/devices/graphics", ctxt, &nodes);
-       if (nb_nodes > 0) {
+        if (nb_nodes > 0) {
             for (i = 0; i < nb_nodes; i++) {
                 res = virDomainParseXMLGraphicsDescVFB(conn, nodes[i], &buf);
                 if (res != 0) {
-                   free(nodes);
+                    free(nodes);
                     goto error;
                 }
             }
-           free(nodes);
+            free(nodes);
         }
     }
 
index 78dda410f3cef01f0db259127c4306a93a95bbfa..35189eee05a79c430d7f7a4429ea7b0b522b4319 100644 (file)
@@ -741,8 +741,6 @@ xenStoreDomainGetOSType(virDomainPtr domain) {
         str = virDomainGetVMInfo(domain, vm, "image/ostype");
         free(vm);
     }
-    if (str == NULL)
-        str = strdup("linux");
 
     return (str);
 }
index 5b9c7f61f2bd9681085a22805d8b92316d784c27..c11ee9183c0f2f7e904e67f31389337dec0060b6 100644 (file)
@@ -19,7 +19,8 @@
   </features>
   <devices>
     <emulator>/usr/lib/xen/bin/qemu-dm</emulator>
-    <interface type='ethernet'>
+    <interface type='bridge'>
+      <source bridge='xenbr0'/>
       <mac address='00:16:3e:0a:7b:39'/>
     </interface>
     <disk type='block' device='disk'>