    Do not search xenstore for disk/network/PCI device IDs
    
    Disk, network, and PCI devices can be referenced by name in Xen,
    e.g. when modifying their configuration or remvoving them.  As such,
    don't search xenstore for a device ID corresponding to these devices.
    Instead, search the devices contained in the domain definition and use
    the devices's target name if found.

    Note that for network devices, the mac address is used for the device
    name.  For PCI devices, the bdf (bus:dev:fun) specifier is used for
    the device name.
    
    This approach allows removing a disk/network/PCI device when domain
    is inactive.  We obviously can't search xenstore when the domain is
    inactive.

Index: libvirt-1.2.5/src/xen/xend_internal.c
===================================================================
--- libvirt-1.2.5.orig/src/xen/xend_internal.c
+++ libvirt-1.2.5/src/xen/xend_internal.c
@@ -3335,30 +3335,29 @@ virDomainXMLDevID(virConnectPtr conn,
                   char *ref,
                   int ref_len)
 {
-    xenUnifiedPrivatePtr priv = conn->privateData;
-    char *xref;
-    char *tmp;
     const char *driver = virDomainDiskGetDriver(dev->data.disk);
+    size_t i;
 
     if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+        if (dev->data.disk->dst == NULL)
+            return -1;
+
         if (STREQ_NULLABLE(driver, "tap") || STREQ_NULLABLE(driver, "tap2"))
             strcpy(class, driver);
         else
             strcpy(class, "vbd");
 
-        if (dev->data.disk->dst == NULL)
-            return -1;
-        xenUnifiedLock(priv);
-        xref = xenStoreDomainGetDiskID(conn, def->id,
-                                       dev->data.disk->dst);
-        xenUnifiedUnlock(priv);
-        if (xref == NULL)
-            return -1;
-
-        tmp = virStrcpy(ref, xref, ref_len);
-        VIR_FREE(xref);
-        if (tmp == NULL)
-            return -1;
+        /* For disks, the device name can be used directly. */
+        for (i = 0; i < def->ndisks; i++) {
+            virDomainDiskDefPtr disk = def->disks[i];
+            if (STREQ(dev->data.disk->dst, disk->dst)) {
+                if (virStrcpy(ref, disk->dst, ref_len) == NULL)
+                    return -1;
+                else
+                    return 0;
+            }
+        }
+        return -1;
     } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
         char mac[VIR_MAC_STRING_BUFLEN];
         virDomainNetDefPtr netdef = dev->data.net;
@@ -3366,16 +3365,22 @@ virDomainXMLDevID(virConnectPtr conn,
 
         strcpy(class, "vif");
 
-        xenUnifiedLock(priv);
-        xref = xenStoreDomainGetNetworkID(conn, def->id, mac);
-        xenUnifiedUnlock(priv);
-        if (xref == NULL)
-            return -1;
-
-        tmp = virStrcpy(ref, xref, ref_len);
-        VIR_FREE(xref);
-        if (tmp == NULL)
-            return -1;
+        /* For nics, the mac address can be used directly. */
+        for (i = 0; i < def->nnets; i++) {
+            char dst_mac[30];
+            virDomainNetDefPtr dst_net = def->nets[i];
+            snprintf(dst_mac, sizeof(dst_mac), "%02x:%02x:%02x:%02x:%02x:%02x",
+                     dst_net->mac.addr[0], dst_net->mac.addr[1],
+                     dst_net->mac.addr[2], dst_net->mac.addr[3],
+                     dst_net->mac.addr[4], dst_net->mac.addr[5]);
+            if (STREQ(mac, dst_mac)) {
+                if (virStrcpy(ref, dst_mac, ref_len) == NULL)
+                    return -1;
+                else
+                    return 0;
+            }
+        }
+        return -1;
     } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
                dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
                dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
@@ -3391,17 +3396,44 @@ virDomainXMLDevID(virConnectPtr conn,
 
         strcpy(class, "pci");
 
-        xenUnifiedLock(priv);
-        xref = xenStoreDomainGetPCIID(conn, def->id, bdf);
-        xenUnifiedUnlock(priv);
-        VIR_FREE(bdf);
-        if (xref == NULL)
-            return -1;
+        /* For PCI devices, the device BFD can be used directly. */
+        for (i = 0 ; i < def->nhostdevs ; i++) {
+            char *dst_bdf;
+            virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+
+            if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+                continue;
+            if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+                continue;
+
+            if (virAsprintf(&dst_bdf, "%04x:%02x:%02x.%0x",
+                            hostdev->source.subsys.u.pci.addr.domain,
+                            hostdev->source.subsys.u.pci.addr.bus,
+                            hostdev->source.subsys.u.pci.addr.slot,
+                            hostdev->source.subsys.u.pci.addr.function) < 0) {
+                virReportOOMError();
+                VIR_FREE(bdf);
+                return -1;
+            }
+
+            if (STREQ(bdf, dst_bdf)) {
+                if (virStrcpy(ref, dst_bdf, ref_len) == NULL) {
+                    virReportOOMError();
+                    VIR_FREE(dst_bdf);
+                    VIR_FREE(bdf);
+                    return -1;
+                }
+                else {
+                    VIR_FREE(dst_bdf);
+                    VIR_FREE(bdf);
+                    return 0;
+                }
+            }
+            VIR_FREE(dst_bdf);
+        }
 
-        tmp = virStrcpy(ref, xref, ref_len);
-        VIR_FREE(xref);
-        if (tmp == NULL)
-            return -1;
+        VIR_FREE(bdf);
+        return -1;
     } else {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("hotplug of device type not supported"));
