]> xenbits.xensource.com Git - libvirt.git/commitdiff
snapshot: also support disks by path
authorEric Blake <eblake@redhat.com>
Sat, 20 Aug 2011 02:38:36 +0000 (20:38 -0600)
committerEric Blake <eblake@redhat.com>
Mon, 5 Sep 2011 13:03:04 +0000 (07:03 -0600)
I got confused when 'virsh domblkinfo dom disk' required the
path to a disk (which can be ambiguous, since a single file
can back multiple disks), rather than the unambiguous target
device name that I was using in disk snapshots.  So, in true
developer fashion, I went for the best of both worlds - all
interfaces that operate on a disk (aka block) now accept
either the target name or the unambiguous path to the backing
file used by the disk.

* src/conf/domain_conf.h (virDomainDiskIndexByName): Add
parameter.
(virDomainDiskPathByName): New prototype.
* src/libvirt_private.syms (domain_conf.h): Export it.
* src/conf/domain_conf.c (virDomainDiskIndexByName): Also allow
searching by path, and decide whether ambiguity is okay.
(virDomainDiskPathByName): New function.
(virDomainDiskRemoveByName, virDomainSnapshotAlignDisks): Update
callers.
* src/qemu/qemu_driver.c (qemudDomainBlockPeek)
(qemuDomainAttachDeviceConfig, qemuDomainUpdateDeviceConfig)
(qemuDomainGetBlockInfo, qemuDiskPathToAlias): Likewise.
* src/qemu/qemu_process.c (qemuProcessFindDomainDiskByPath):
Likewise.
* src/libxl/libxl_driver.c (libxlDomainAttachDeviceDiskLive)
(libxlDomainDetachDeviceDiskLive, libxlDomainAttachDeviceConfig)
(libxlDomainUpdateDeviceConfig): Likewise.
* src/uml/uml_driver.c (umlDomainBlockPeek): Likewise.
* src/xen/xend_internal.c (xenDaemonDomainBlockPeek): Likewise.
* docs/formatsnapshot.html.in: Update documentation.
* tools/virsh.pod (domblkstat, domblkinfo): Likewise.
* docs/schemas/domaincommon.rng (diskTarget): Tighten pattern on
disk targets.
* docs/schemas/domainsnapshot.rng (disksnapshot): Update to match.
* tests/domainsnapshotxml2xmlin/disk_snapshot.xml: Update test.

13 files changed:
docs/formatsnapshot.html.in
docs/schemas/domaincommon.rng
docs/schemas/domainsnapshot.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/libxl/libxl_driver.c
src/qemu/qemu_driver.c
src/qemu/qemu_process.c
src/uml/uml_driver.c
src/xen/xend_internal.c
tests/domainsnapshotxml2xmlin/disk_snapshot.xml
tools/virsh.pod

index 5c6b28202e3b62caf4c785f2022b7f1cbb24ce33..ec5ebf345108c5c7a04700c93046b57ee0ba2ae8 100644 (file)
           <dt><code>disk</code></dt>
           <dd>This sub-element describes the snapshot properties of a
             specific disk.  The attribute <code>name</code> is
-            mandatory, and must match the <code>&lt;target
-            dev='name'/&gt;</code> of one of
+            mandatory, and must match either the <code>&lt;target
+            dev='name'/&gt;</code> or an unambiguous <code>&lt;source
+            file='name'/&gt;</code> of one of
             the <a href="formatdomain.html#elementsDisks">disk
             devices</a> specified for the domain at the time of the
             snapshot.  The attribute <code>snapshot</code> is
 &lt;domainsnapshot&gt;
   &lt;description&gt;Snapshot of OS install and updates&lt;/description&gt;
   &lt;disks&gt;
-    &lt;disk name='vda'&gt;
+    &lt;disk name='/path/to/old'&gt;
       &lt;source file='/path/to/new'/&gt;
     &lt;/disk&gt;
     &lt;disk name='vdb' snapshot='no'/&gt;
index e622cede6fac4fef0c9b65e716a2b45a0e42ac14..e2269d004ce31b2a6064499fecba80c842b50182 100644 (file)
       </choice>
     </element>
   </define>
+  <define name="diskTarget">
+    <data type="string">
+      <param name="pattern">(ioemu:)?(fd|hd|sd|vd|xvd|ubd)[a-zA-Z0-9_]+</param>
+    </data>
+  </define>
   <define name="target">
     <element name="target">
       <attribute name="dev">
-        <ref name="deviceName"/>
+        <ref name="diskTarget"/>
       </attribute>
       <optional>
         <attribute name="bus">
index 671fbe0698fe493d251453cf4b277d17b6bf5fb9..0ef0631246c003952023675f306fc8857fc90957 100644 (file)
   <define name='disksnapshot'>
     <element name='disk'>
       <attribute name='name'>
-        <ref name='deviceName'/>
+        <choice>
+          <ref name='diskTarget'/>
+          <ref name='absFilePath'/>
+        </choice>
       </attribute>
       <choice>
         <attribute name='snapshot'>
index 1881d3f8c1c96c67e62d226ea78a4c80d5117ae8..77428f5aa7b992f91f9eda1558419140e5ad176c 100644 (file)
@@ -5811,17 +5811,44 @@ virDomainChrTargetTypeToString(int deviceType,
     return type;
 }
 
-int virDomainDiskIndexByName(virDomainDefPtr def, const char *name)
+int
+virDomainDiskIndexByName(virDomainDefPtr def, const char *name,
+                         bool allow_ambiguous)
 {
     virDomainDiskDefPtr vdisk;
     int i;
+    int candidate = -1;
 
+    /* We prefer the <target dev='name'/> name (it's shorter, required
+     * for all disks, and should be unambiguous), but also support
+     * <source file='name'/> (if unambiguous).  Assume dst if there is
+     * no leading slash, source name otherwise.  */
     for (i = 0; i < def->ndisks; i++) {
         vdisk = def->disks[i];
-        if (STREQ(vdisk->dst, name))
-            return i;
+        if (*name != '/') {
+            if (STREQ(vdisk->dst, name))
+                return i;
+        } else if (vdisk->src &&
+                   STREQ(vdisk->src, name)) {
+            if (allow_ambiguous)
+                return i;
+            if (candidate >= 0)
+                return -1;
+            candidate = i;
+        }
     }
-    return -1;
+    return candidate;
+}
+
+/* Return the path to a disk image if a string identifies at least one
+ * disk belonging to the domain (both device strings 'vda' and paths
+ * '/path/to/file' are converted into '/path/to/file').  */
+const char *
+virDomainDiskPathByName(virDomainDefPtr def, const char *name)
+{
+    int i = virDomainDiskIndexByName(def, name, true);
+
+    return i < 0 ? NULL : def->disks[i]->src;
 }
 
 int virDomainDiskInsert(virDomainDefPtr def,
@@ -5897,7 +5924,7 @@ void virDomainDiskRemove(virDomainDefPtr def, size_t i)
 
 int virDomainDiskRemoveByName(virDomainDefPtr def, const char *name)
 {
-    int i = virDomainDiskIndexByName(def, name);
+    int i = virDomainDiskIndexByName(def, name, false);
     if (i < 0)
         return -1;
     virDomainDiskRemove(def, i);
@@ -11651,11 +11678,12 @@ disksorter(const void *a, const void *b)
 
 /* Align def->disks to def->domain.  Sort the list of def->disks,
  * filling in any missing disks or snapshot state defaults given by
- * the domain, with a fallback to a passed in default.  Issue an error
- * and return -1 if any def->disks[n]->name appears more than once or
- * does not map to dom->disks.  If require_match, also require that
- * existing def->disks snapshot states do not override explicit
- * def->dom settings.  */
+ * the domain, with a fallback to a passed in default.  Convert paths
+ * to disk targets for uniformity.  Issue an error and return -1 if
+ * any def->disks[n]->name appears more than once or does not map to
+ * dom->disks.  If require_match, also require that existing
+ * def->disks snapshot states do not override explicit def->dom
+ * settings.  */
 int
 virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
                             int default_snapshot,
@@ -11693,7 +11721,7 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
     /* Double check requested disks.  */
     for (i = 0; i < def->ndisks; i++) {
         virDomainSnapshotDiskDefPtr disk = &def->disks[i];
-        int idx = virDomainDiskIndexByName(def->dom, disk->name);
+        int idx = virDomainDiskIndexByName(def->dom, disk->name, false);
         int disk_snapshot;
 
         if (idx < 0) {
@@ -11731,6 +11759,13 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
                                  disk->file, disk->name);
             goto cleanup;
         }
+        if (STRNEQ(disk->name, def->dom->disks[idx]->dst)) {
+            VIR_FREE(disk->name);
+            if (!(disk->name = strdup(def->dom->disks[idx]->dst))) {
+                virReportOOMError();
+                goto cleanup;
+            }
+        }
     }
 
     /* Provide defaults for all remaining disks.  */
index fd4dbced62efd614b766701f492595249c50e1a0..bb9d3dbc766fb22c8869e391eb181e53f7b8879a 100644 (file)
@@ -1648,7 +1648,9 @@ int virDomainVcpuPinAdd(virDomainDefPtr def,
 
 int virDomainVcpuPinDel(virDomainDefPtr def, int vcpu);
 
-int virDomainDiskIndexByName(virDomainDefPtr def, const char *name);
+int virDomainDiskIndexByName(virDomainDefPtr def, const char *name,
+                             bool allow_ambiguous);
+const char *virDomainDiskPathByName(virDomainDefPtr, const char *name);
 int virDomainDiskInsert(virDomainDefPtr def,
                         virDomainDiskDefPtr disk);
 void virDomainDiskInsertPreAlloced(virDomainDefPtr def,
index 8c100e7237c966399e7bd412a928cd8d436246c0..0780f2d03347382b194dcdf69aa5e186dbcdacb3 100644 (file)
@@ -287,6 +287,7 @@ virDomainDiskInsert;
 virDomainDiskInsertPreAlloced;
 virDomainDiskIoTypeFromString;
 virDomainDiskIoTypeToString;
+virDomainDiskPathByName;
 virDomainDiskRemove;
 virDomainDiskRemoveByName;
 virDomainDiskSnapshotTypeFromString;
index 91da438175d2bf9c9c52cc478f4480556a9e759e..4302c8be93506b0380eceb9bd6d54c71e3c26d9a 100644 (file)
@@ -2929,7 +2929,7 @@ libxlDomainAttachDeviceDiskLive(libxlDomainObjPrivatePtr priv,
             break;
         case VIR_DOMAIN_DISK_DEVICE_DISK:
             if (l_disk->bus == VIR_DOMAIN_DISK_BUS_XEN) {
-                if (virDomainDiskIndexByName(vm->def, l_disk->dst) >= 0) {
+                if (virDomainDiskIndexByName(vm->def, l_disk->dst, true) >= 0) {
                     libxlError(VIR_ERR_OPERATION_FAILED,
                             _("target %s already exists"), l_disk->dst);
                     goto cleanup;
@@ -2991,7 +2991,8 @@ libxlDomainDetachDeviceDiskLive(libxlDomainObjPrivatePtr priv,
             if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_XEN) {
 
                 if ((i = virDomainDiskIndexByName(vm->def,
-                                                  dev->data.disk->dst)) < 0) {
+                                                  dev->data.disk->dst,
+                                                  false)) < 0) {
                     libxlError(VIR_ERR_OPERATION_FAILED,
                                _("disk %s not found"), dev->data.disk->dst);
                     goto cleanup;
@@ -3061,7 +3062,7 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
     switch (dev->type) {
         case VIR_DOMAIN_DEVICE_DISK:
             disk = dev->data.disk;
-            if (virDomainDiskIndexByName(vmdef, disk->dst) >= 0) {
+            if (virDomainDiskIndexByName(vmdef, disk->dst, true) >= 0) {
                 libxlError(VIR_ERR_INVALID_ARG,
                         _("target %s already exists."), disk->dst);
                 return -1;
@@ -3172,9 +3173,9 @@ libxlDomainUpdateDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
     switch (dev->type) {
         case VIR_DOMAIN_DEVICE_DISK:
             disk = dev->data.disk;
-            if ((i = virDomainDiskIndexByName(vmdef, disk->dst)) < 0) {
+            if ((i = virDomainDiskIndexByName(vmdef, disk->dst, false)) < 0) {
                 libxlError(VIR_ERR_INVALID_ARG,
-                           _("target %s doesn't exists."), disk->dst);
+                           _("target %s doesn't exist."), disk->dst);
                 goto cleanup;
             }
             orig = vmdef->disks[i];
index 843a4971da9f2380b06aae336c9b200edfab137b..d1c8659fcb7e7e8704101cea777a37d6c9001d0b 100644 (file)
@@ -5495,7 +5495,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
         disk = dev->data.disk;
-        if (virDomainDiskIndexByName(vmdef, disk->dst) >= 0) {
+        if (virDomainDiskIndexByName(vmdef, disk->dst, true) >= 0) {
             qemuReportError(VIR_ERR_INVALID_ARG,
                             _("target %s already exists."), disk->dst);
             return -1;
@@ -5613,10 +5613,10 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
     switch (dev->type) {
     case VIR_DOMAIN_DEVICE_DISK:
         disk = dev->data.disk;
-        pos = virDomainDiskIndexByName(vmdef, disk->dst);
+        pos = virDomainDiskIndexByName(vmdef, disk->dst, false);
         if (pos < 0) {
             qemuReportError(VIR_ERR_INVALID_ARG,
-                            _("target %s doesn't exists."), disk->dst);
+                            _("target %s doesn't exist."), disk->dst);
             return -1;
         }
         orig = vmdef->disks[pos];
@@ -7355,7 +7355,8 @@ qemudDomainBlockPeek (virDomainPtr dom,
 {
     struct qemud_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    int fd = -1, ret = -1, i;
+    int fd = -1, ret = -1;
+    const char *actual;
 
     virCheckFlags(0, -1);
 
@@ -7377,42 +7378,35 @@ qemudDomainBlockPeek (virDomainPtr dom,
         goto cleanup;
     }
 
-    /* Check the path belongs to this domain. */
-    for (i = 0 ; i < vm->def->ndisks ; i++) {
-        if (vm->def->disks[i]->src != NULL &&
-            STREQ (vm->def->disks[i]->src, path)) {
-            ret = 0;
-            break;
-        }
+    /* Check the path belongs to this domain.  */
+    if (!(actual = virDomainDiskPathByName(vm->def, path))) {
+        qemuReportError(VIR_ERR_INVALID_ARG,
+                        _("invalid path '%s'"), path);
+        goto cleanup;
     }
+    path = actual;
 
-    if (ret == 0) {
-        ret = -1;
-        /* The path is correct, now try to open it and get its size. */
-        fd = open (path, O_RDONLY);
-        if (fd == -1) {
-            virReportSystemError(errno,
-                                 _("%s: failed to open"), path);
-            goto cleanup;
-        }
-
-        /* Seek and read. */
-        /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
-         * be 64 bits on all platforms.
-         */
-        if (lseek (fd, offset, SEEK_SET) == (off_t) -1 ||
-            saferead (fd, buffer, size) == (ssize_t) -1) {
-            virReportSystemError(errno,
-                                 _("%s: failed to seek or read"), path);
-            goto cleanup;
-        }
+    /* The path is correct, now try to open it and get its size. */
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+        virReportSystemError(errno,
+                             _("%s: failed to open"), path);
+        goto cleanup;
+    }
 
-        ret = 0;
-    } else {
-        qemuReportError(VIR_ERR_INVALID_ARG,
-                        "%s", _("invalid path"));
+    /* Seek and read. */
+    /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
+     * be 64 bits on all platforms.
+     */
+    if (lseek(fd, offset, SEEK_SET) == (off_t) -1 ||
+        saferead(fd, buffer, size) == (ssize_t) -1) {
+        virReportSystemError(errno,
+                             _("%s: failed to seek or read"), path);
+        goto cleanup;
     }
 
+    ret = 0;
+
 cleanup:
     VIR_FORCE_CLOSE(fd);
     if (vm)
@@ -7491,7 +7485,7 @@ qemudDomainMemoryPeek (virDomainPtr dom,
     qemuDomainObjExitMonitor(driver, vm);
 
     /* Read the memory file into buffer. */
-    if (saferead (fd, buffer, size) == (ssize_t) -1) {
+    if (saferead(fd, buffer, size) == (ssize_t) -1) {
         virReportSystemError(errno,
                              _("failed to read temporary file "
                                "created with template %s"), tmp);
@@ -7527,8 +7521,8 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
     virStorageFileMetadata *meta = NULL;
     virDomainDiskDefPtr disk = NULL;
     struct stat sb;
-    int i;
     int format;
+    const char *actual;
 
     virCheckFlags(0, -1);
 
@@ -7550,22 +7544,15 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
     }
 
     /* Check the path belongs to this domain. */
-    for (i = 0 ; i < vm->def->ndisks ; i++) {
-        if (vm->def->disks[i]->src != NULL &&
-            STREQ (vm->def->disks[i]->src, path)) {
-            disk = vm->def->disks[i];
-            break;
-        }
-    }
-
-    if (!disk) {
+    if (!(actual = virDomainDiskPathByName(vm->def, path))) {
         qemuReportError(VIR_ERR_INVALID_ARG,
                         _("invalid path %s not assigned to domain"), path);
         goto cleanup;
     }
+    path = actual;
 
     /* The path is correct, now try to open it and get its size. */
-    fd = open (path, O_RDONLY);
+    fd = open(path, O_RDONLY);
     if (fd == -1) {
         virReportSystemError(errno,
                              _("failed to open path '%s'"), path);
@@ -7624,7 +7611,7 @@ static int qemuDomainGetBlockInfo(virDomainPtr dom,
         /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
          * be 64 bits on all platforms.
          */
-        end = lseek (fd, 0, SEEK_END);
+        end = lseek(fd, 0, SEEK_END);
         if (end == (off_t)-1) {
             virReportSystemError(errno,
                                  _("failed to seek to end of %s"), path);
@@ -9831,23 +9818,26 @@ static const char *
 qemuDiskPathToAlias(virDomainObjPtr vm, const char *path) {
     int i;
     char *ret = NULL;
+    virDomainDiskDefPtr disk;
 
-    for (i = 0 ; i < vm->def->ndisks ; i++) {
-        virDomainDiskDefPtr disk = vm->def->disks[i];
+    i = virDomainDiskIndexByName(vm->def, path, true);
+    if (i < 0)
+        goto cleanup;
 
-        if (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK &&
-            disk->type != VIR_DOMAIN_DISK_TYPE_FILE)
-            continue;
+    disk = vm->def->disks[i];
 
-        if (disk->src != NULL && STREQ(disk->src, path)) {
-            if (virAsprintf(&ret, "drive-%s", disk->info.alias) < 0) {
-                virReportOOMError();
-                return NULL;
-            }
-            break;
+    if (disk->type != VIR_DOMAIN_DISK_TYPE_BLOCK &&
+        disk->type != VIR_DOMAIN_DISK_TYPE_FILE)
+        goto cleanup;
+
+    if (disk->src) {
+        if (virAsprintf(&ret, "drive-%s", disk->info.alias) < 0) {
+            virReportOOMError();
+            return NULL;
         }
     }
 
+cleanup:
     if (!ret) {
         qemuReportError(VIR_ERR_INVALID_ARG,
                         "%s", _("No device found for specified path"));
index c22974fcc6e94374b333d1dc5927116e6d09ba7a..f36efeaf9548fc73407ecc24c1ec6b6113d9497e 100644 (file)
@@ -192,15 +192,10 @@ static virDomainDiskDefPtr
 qemuProcessFindDomainDiskByPath(virDomainObjPtr vm,
                                 const char *path)
 {
-    int i;
-
-    for (i = 0; i < vm->def->ndisks; i++) {
-        virDomainDiskDefPtr disk;
+    int i = virDomainDiskIndexByName(vm->def, path, true);
 
-        disk = vm->def->disks[i];
-        if (disk->src != NULL && STREQ(disk->src, path))
-            return disk;
-    }
+    if (i >= 0)
+        return vm->def->disks[i];
 
     qemuReportError(VIR_ERR_INTERNAL_ERROR,
                     _("no disk found with path %s"),
index 19b6c55859cfa0d3a294a4b53f83607fda781484..32f09d2e9436ec4947786b8cfd5e3ab08dc61047 100644 (file)
@@ -2175,7 +2175,8 @@ umlDomainBlockPeek(virDomainPtr dom,
 {
     struct uml_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
-    int fd = -1, ret = -1, i;
+    int fd = -1, ret = -1;
+    const char *actual;
 
     virCheckFlags(0, -1);
 
@@ -2196,41 +2197,34 @@ umlDomainBlockPeek(virDomainPtr dom,
     }
 
     /* Check the path belongs to this domain. */
-    for (i = 0 ; i < vm->def->ndisks ; i++) {
-        if (vm->def->disks[i]->src != NULL &&
-            STREQ (vm->def->disks[i]->src, path)) {
-            ret = 0;
-            break;
-        }
+    if (!(actual = virDomainDiskPathByName(vm->def, path))) {
+        umlReportError(VIR_ERR_INVALID_ARG,
+                       _("invalid path '%s'"), path);
+        goto cleanup;
     }
+    path = actual;
 
-    if (ret == 0) {
-        ret = -1;
-        /* The path is correct, now try to open it and get its size. */
-        fd = open (path, O_RDONLY);
-        if (fd == -1) {
-            virReportSystemError(errno,
-                                 _("cannot open %s"), path);
-            goto cleanup;
-        }
-
-        /* Seek and read. */
-        /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
-         * be 64 bits on all platforms.
-         */
-        if (lseek (fd, offset, SEEK_SET) == (off_t) -1 ||
-            saferead (fd, buffer, size) == (ssize_t) -1) {
-            virReportSystemError(errno,
-                                 _("cannot read %s"), path);
-            goto cleanup;
-        }
+    /* The path is correct, now try to open it and get its size. */
+    fd = open(path, O_RDONLY);
+    if (fd == -1) {
+        virReportSystemError(errno,
+                             _("cannot open %s"), path);
+        goto cleanup;
+    }
 
-        ret = 0;
-    } else {
-        umlReportError(VIR_ERR_INVALID_ARG, "%s",
-                       _("invalid path"));
+    /* Seek and read. */
+    /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should
+     * be 64 bits on all platforms.
+     */
+    if (lseek(fd, offset, SEEK_SET) == (off_t) -1 ||
+        saferead(fd, buffer, size) == (ssize_t) -1) {
+        virReportSystemError(errno,
+                             _("cannot read %s"), path);
+        goto cleanup;
     }
 
+    ret = 0;
+
 cleanup:
     VIR_FORCE_CLOSE(fd);
     if (vm)
index 0a7fb4806e92d575218b09fd9a49d66dc5c054fe..8e2170122c07b598e9625201b6b86edddd244122 100644 (file)
@@ -3849,11 +3849,11 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
     xenUnifiedPrivatePtr priv;
     struct sexpr *root = NULL;
     int fd = -1, ret = -1;
-    int found = 0, i;
     virDomainDefPtr def;
     int id;
     char * tty;
     int vncport;
+    const char *actual;
 
     priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
 
@@ -3889,18 +3889,12 @@ xenDaemonDomainBlockPeek (virDomainPtr domain, const char *path,
                              vncport)))
         goto cleanup;
 
-    for (i = 0 ; i < def->ndisks ; i++) {
-        if (def->disks[i]->src &&
-            STREQ(def->disks[i]->src, path)) {
-            found = 1;
-            break;
-        }
-    }
-    if (!found) {
+    if (!(actual = virDomainDiskPathByName(def, path))) {
         virXendError(VIR_ERR_INVALID_ARG,
                       _("%s: invalid path"), path);
         goto cleanup;
     }
+    path = actual;
 
     /* The path is correct, now try to open it and get its size. */
     fd = open (path, O_RDONLY);
index 1f0beb6b06f86d0596a0364ce8de8639a7b5204d..ee6b46a86345794131004a9c07bb64b862d09d4b 100644 (file)
@@ -2,7 +2,7 @@
   <name>my snap name</name>
   <description>!@#$%^</description>
   <disks>
-    <disk name='hda'/>
+    <disk name='/dev/HostVG/QEMUGuest1'/>
     <disk name='hdb' snapshot='no'/>
     <disk name='hdc' snapshot='internal'/>
     <disk name='hdd' snapshot='external'>
index 8edf30efdd1ab52db73160855d5f357b47e2188e..f92444af3cbfbba519e936b58465a797745281ce 100644 (file)
@@ -503,7 +503,9 @@ snapshot metadata with B<snapshot-create>.
 
 =item B<domblkstat> I<domain> I<block-device>
 
-Get device block stats for a running domain.
+Get device block stats for a running domain.  A I<block-device> corresponds
+to a unique target name (<target dev='name'/>) or source file (<source
+file='name'/>) for one of the disk devices attached to I<domain>.
 
 =item B<domifstat> I<domain> I<interface-device>
 
@@ -515,7 +517,9 @@ Get memory stats for a running domain.
 
 =item B<domblkinfo> I<domain> I<block-device>
 
-Get block device size info for a domain.
+Get block device size info for a domain.  A I<block-device> corresponds
+to a unique target name (<target dev='name'/>) or source file (<source
+file='name'/>) for one of the disk devices attached to I<domain>.
 
 =item B<blockpull> I<domain> I<path> [I<bandwidth>]