diff -up ./src/storage_backend_logical.c.p4 ./src/storage_backend_logical.c
--- ./src/storage_backend_logical.c.p4	2008-10-21 15:01:50.000000000 +0200
+++ ./src/storage_backend_logical.c	2008-10-21 15:06:55.000000000 +0200
@@ -23,6 +23,8 @@
 
 #include <config.h>
 
+#include <libxml/xmlsave.h>
+
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <stdio.h>
@@ -255,31 +257,77 @@ virStorageBackendLogicalRefreshPoolFunc(
 
 
 static int
-virStorageBackendLogicalFindPoolSourcesFunc(virConnectPtr conn ATTRIBUTE_UNUSED,
+virStorageBackendLogicalFindPoolSourcesFunc(virConnectPtr conn,
                                             virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
                                             char **const groups,
                                             void *data)
 {
-    virStringList **rest = data;
-    virStringList *newItem;
-    const char *name = groups[0];
+    const char *const pvname = groups[0];
+    const char *const vgname = groups[1];
+    char *content;
+    xmlDoc *xml = data;
+    xmlNode *root;
+    xmlNode *device;
+    xmlNode *curr;
+    xmlNode *child;
+    xmlNode *topNode;
+    int vgmatch;
+
+    root = xmlDocGetRootElement(xml);
+    if (root == NULL) {
+        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                              _("Unexpected NULL root element"));
+        return -1;
+    }
 
-    /* Append new XML desc to list */
+    /*
+     * The idea here is to try to find this vgname in the current XML.  If it
+     * already exists, then we just add a new device section to it.  If it
+     * doesn't yet exist, then we create new <source><name>foo</name></source>,
+     * then add the device section to it.
+     */
+    topNode = NULL;
+    curr = root->children;
+    while (curr != NULL) {
+        child = curr->children;
+        while (child != NULL) {
+            content = (char *)xmlNodeGetContent(child);
+            vgmatch = STREQ(vgname, content);
+            free(content);
+            if (STREQ((char *)child->name, "name") && vgmatch) {
+                topNode = curr;
+                break;
+            }
+            child = child->next;
+        }
+        curr = curr->next;
+    }
 
-    if (VIR_ALLOC(newItem) != 0) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("new xml desc"));
-        return -1;
+    if (topNode == NULL) {
+        topNode = xmlNewChild(root, NULL, BAD_CAST "source", NULL);
+        if (topNode == NULL) {
+            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                                  _("Failed to create new XML source child"));
+            return -1;
+        }
+        if (xmlNewChild(topNode, NULL, BAD_CAST "name", BAD_CAST vgname) == NULL) {
+            virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                                  _("Failed to create new XML name child"));
+            return -1;
+        }
     }
 
-    if (asprintf(&newItem->val, "<source><name>%s</name></source>", name) <= 0) {
-        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("asprintf failed"));
-        VIR_FREE(newItem);
+    device = xmlNewChild(topNode, NULL, BAD_CAST "device", NULL);
+    if (device == NULL) {
+        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                              _("Failed to create new XML device child"));
+        return -1;
+    }
+    if (xmlSetNsProp(device, NULL, BAD_CAST "path", BAD_CAST pvname) == NULL) {
+        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                              _("Failed to add device XML path property"));
         return -1;
     }
-
-    newItem->len = strlen(newItem->val);
-    newItem->next = *rest;
-    *rest = newItem;
 
     return 0;
 }
@@ -290,36 +338,76 @@ virStorageBackendLogicalFindPoolSources(
                                         unsigned int flags ATTRIBUTE_UNUSED)
 {
     /*
-     * # vgs --noheadings -o vg_name
-     *   VolGroup00
-     *   VolGroup01
+     * # pvs --noheadings -o pv_name,vg_name
+     *   /dev/sdb
+     *   /dev/sdc VolGroup00
      */
     const char *regexes[] = {
-        "^\\s*(\\S+)\\s*$"
+        "^\\s*(\\S+)\\s+(\\S+)\\s*$"
     };
     int vars[] = {
-        1
+        2
     };
-    virStringList *descs = NULL;
-    const char *prog[] = { VGS, "--noheadings", "-o", "vg_name", NULL };
+    const char *const prog[] = { PVS, "--noheadings", "-o", "pv_name,vg_name", NULL };
     int exitstatus;
-    char *retval = NULL;
-
+    xmlDoc *xml = NULL;
+    xmlNode *root;
+    xmlSaveCtxt *saveCtxt;
+    xmlBuffer *buffer;
+    char *output = NULL;
+
+    /* First setup the XML document */
+    xml = xmlNewDoc(NULL);
+    if (xml == NULL) {
+        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s",
+                              _("Failed to create new XML document"));
+        return NULL;
+    }
+    root = xmlNewNode(NULL, BAD_CAST "sources");
+    if (root == NULL) {
+        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s",
+                              _("Failed to create new XML source node"));
+        goto cleanup_doc;
+    }
+    xmlDocSetRootElement(xml, root);
+
+    /* Now run PVS and get the output */
     if (virStorageBackendRunProgRegex(conn, NULL, prog, 1, regexes, vars,
                                       virStorageBackendLogicalFindPoolSourcesFunc,
-                                      &descs, &exitstatus) < 0)
-        return NULL;
+                                      xml, &exitstatus) < 0)
+        goto cleanup_doc;
 
-    retval = virStringListJoin(descs, SOURCES_START_TAG, SOURCES_END_TAG, "\n");
-    if (retval == NULL) {
-        virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("retval"));
-        goto cleanup;
-    }
+    /* Finally dump the XML to a buffer, and return it */
+    buffer = xmlBufferCreate();
+    if (buffer == NULL) {
+        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                              _("Failed to allocate XML buffer"));
+        goto cleanup_doc;
+    }
+    saveCtxt = xmlSaveToBuffer(buffer, NULL, XML_SAVE_NO_DECL);
+    if (saveCtxt == NULL) {
+        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                              _("Failed to setup XML save buffer"));
+        goto free_buffer;
+    }
+    if (xmlSaveTree(saveCtxt, root) < 0) {
+        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                              _("Failed to save XML tree"));
+        xmlSaveClose(saveCtxt);
+        goto free_buffer;
+    }
+
+    /* NOTE: xmlSaveClose must be before xmlBufferContent so we flush */
+    xmlSaveClose(saveCtxt);
+    output = strdup((char *)xmlBufferContent(buffer));
 
- cleanup:
-    virStringListFree(descs);
+ free_buffer:
+    xmlBufferFree(buffer);
+
+ cleanup_doc:
+    xmlFreeDoc(xml);
 
-    return retval;
+    return output;
 }
 
 
