c401cc
From ff5593568d20e5208cdd077c7508567106764ac1 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <ff5593568d20e5208cdd077c7508567106764ac1@dist-git>
c401cc
From: Eric Blake <eblake@redhat.com>
c401cc
Date: Wed, 26 Feb 2014 14:54:16 +0100
c401cc
Subject: [PATCH] storage: use valid XML for awkward volume names
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
c401cc
c401cc
$ touch /var/lib/libvirt/images/'ac'
c401cc
$ virsh pool-refresh default
c401cc
$ virsh vol-dumpxml 'ac' default | head -n2
c401cc
<volume>
c401cc
  <name>ac</name>
c401cc
c401cc
Oops.  That's not valid XML.  And when we fix the XML
c401cc
generation, it fails RelaxNG validation.
c401cc
c401cc
I'm also tired of seeing <key>(null)</key> in the example
c401cc
output for volume xml; while we used NULLSTR() to avoid
c401cc
a NULL deref rather than relying on glibc's printf
c401cc
extension behavior, it's even better if we avoid the issue
c401cc
in the first place.  But this requires being careful that
c401cc
we don't invalidate any storage backends that were relying
c401cc
on key being unassigned during virStoragVolCreateXML[From].
c401cc
c401cc
I would have split this into two patches (one for escaping,
c401cc
one for avoiding <key>(null)</key>), but since they both
c401cc
end up touching a lot of the same test files, I ended up
c401cc
merging it into one.
c401cc
c401cc
Note that this patch allows pretty much any volume name
c401cc
that can appear in a directory (excluding . and .. because
c401cc
those are special), but does nothing to change the current
c401cc
(unenforced) RelaxNG claim that pool names will consist
c401cc
only of letters, numbers, _, -, and +.  Tightening the C
c401cc
code to match RelaxNG patterns and/or relaxing the grammar
c401cc
to match the C code for pool names is a task for another
c401cc
day (but remember, we DID recently tighten C code for
c401cc
domain names to exclude a leading '.').
c401cc
c401cc
* src/conf/storage_conf.c (virStoragePoolSourceFormat)
c401cc
(virStoragePoolDefFormat, virStorageVolTargetDefFormat)
c401cc
(virStorageVolDefFormat): Escape user-controlled strings.
c401cc
(virStorageVolDefParseXML): Parse key, for use in unit tests.
c401cc
* src/storage/storage_driver.c (storageVolCreateXML)
c401cc
(storageVolCreateXMLFrom): Ensure parsed key doesn't confuse
c401cc
volume creation.
c401cc
* docs/schemas/basictypes.rng (volName): Relax definition.
c401cc
* tests/storagepoolxml2xmltest.c (mymain): Test it.
c401cc
* tests/storagevolxml2xmltest.c (mymain): Likewise.
c401cc
* tests/storagepoolxml2xmlin/pool-dir-naming.xml: New file.
c401cc
* tests/storagepoolxml2xmlout/pool-dir-naming.xml: Likewise.
c401cc
* tests/storagevolxml2xmlin/vol-file-naming.xml: Likewise.
c401cc
* tests/storagevolxml2xmlout/vol-file-naming.xml: Likewise.
c401cc
* tests/storagevolxml2xmlout/vol-*.xml: Fix fallout.
c401cc
c401cc
Signed-off-by: Eric Blake <eblake@redhat.com>
c401cc
(cherry picked from commit 6cc4d6a3fe82653c607c4f159901790298e80e1f)
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 docs/schemas/basictypes.rng                        |  9 ++-
c401cc
 src/conf/storage_conf.c                            | 72 ++++++++++------------
c401cc
 src/storage/storage_driver.c                       |  8 ++-
c401cc
 tests/storagepoolxml2xmlin/pool-dir-naming.xml     | 18 ++++++
c401cc
 tests/storagepoolxml2xmlout/pool-dir-naming.xml    | 18 ++++++
c401cc
 tests/storagepoolxml2xmltest.c                     |  1 +
c401cc
 tests/storagevolxml2xmlin/vol-file-backing.xml     |  1 +
c401cc
 tests/storagevolxml2xmlin/vol-file-naming.xml      | 20 ++++++
c401cc
 tests/storagevolxml2xmlout/vol-file-backing.xml    |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-file-naming.xml     | 17 +++++
c401cc
 tests/storagevolxml2xmlout/vol-file.xml            |  1 -
c401cc
 tests/storagevolxml2xmlout/vol-logical-backing.xml |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-logical.xml         |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-partition.xml       |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-qcow2-0.10-lazy.xml |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-qcow2-1.1.xml       |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-qcow2-lazy.xml      |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-qcow2-nobacking.xml |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-qcow2.xml           |  2 +-
c401cc
 tests/storagevolxml2xmlout/vol-sheepdog.xml        |  1 -
c401cc
 tests/storagevolxml2xmltest.c                      |  1 +
c401cc
 21 files changed, 132 insertions(+), 53 deletions(-)
c401cc
 create mode 100644 tests/storagepoolxml2xmlin/pool-dir-naming.xml
c401cc
 create mode 100644 tests/storagepoolxml2xmlout/pool-dir-naming.xml
c401cc
 create mode 100644 tests/storagevolxml2xmlin/vol-file-naming.xml
c401cc
 create mode 100644 tests/storagevolxml2xmlout/vol-file-naming.xml
c401cc
c401cc
diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
c401cc
index dcd846e..e42779d 100644
c401cc
--- a/docs/schemas/basictypes.rng
c401cc
+++ b/docs/schemas/basictypes.rng
c401cc
@@ -291,8 +291,15 @@
c401cc
   </define>
c401cc
 
c401cc
   <define name='volName'>
c401cc
+    
c401cc
     <data type='string'>
c401cc
-      <param name="pattern">[a-zA-Z0-9_\+\-\.]+</param>
c401cc
+      <param name="pattern">[^/]+</param>
c401cc
+      <except>
c401cc
+        <choice>
c401cc
+          <value>.</value>
c401cc
+          <value>..</value>
c401cc
+        </choice>
c401cc
+      </except>
c401cc
     </data>
c401cc
   </define>
c401cc
 
c401cc
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
c401cc
index 7cd7742..c9127b0 100644
c401cc
--- a/src/conf/storage_conf.c
c401cc
+++ b/src/conf/storage_conf.c
c401cc
@@ -1056,7 +1056,8 @@ virStoragePoolSourceFormat(virBufferPtr buf,
c401cc
     virBufferAddLit(buf, "  <source>\n");
c401cc
     if ((options->flags & VIR_STORAGE_POOL_SOURCE_HOST) && src->nhost) {
c401cc
         for (i = 0; i < src->nhost; i++) {
c401cc
-            virBufferAsprintf(buf, "    <host name='%s'", src->hosts[i].name);
c401cc
+            virBufferEscapeString(buf, "    
c401cc
+                                  src->hosts[i].name);
c401cc
             if (src->hosts[i].port)
c401cc
                 virBufferAsprintf(buf, " port='%d'", src->hosts[i].port);
c401cc
             virBufferAddLit(buf, "/>\n");
c401cc
@@ -1067,8 +1068,8 @@ virStoragePoolSourceFormat(virBufferPtr buf,
c401cc
         src->ndevice) {
c401cc
         for (i = 0; i < src->ndevice; i++) {
c401cc
             if (src->devices[i].nfreeExtent) {
c401cc
-                virBufferAsprintf(buf, "    <device path='%s'>\n",
c401cc
-                                  src->devices[i].path);
c401cc
+                virBufferEscapeString(buf, "    <device path='%s'>\n",
c401cc
+                                      src->devices[i].path);
c401cc
                 for (j = 0; j < src->devices[i].nfreeExtent; j++) {
c401cc
                     virBufferAsprintf(buf, "    <freeExtent start='%llu' end='%llu'/>\n",
c401cc
                                       src->devices[i].freeExtents[j].start,
c401cc
@@ -1076,15 +1077,14 @@ virStoragePoolSourceFormat(virBufferPtr buf,
c401cc
                 }
c401cc
                 virBufferAddLit(buf, "    </device>\n");
c401cc
             } else {
c401cc
-                virBufferAsprintf(buf, "    <device path='%s'/>\n",
c401cc
-                                  src->devices[i].path);
c401cc
+                virBufferEscapeString(buf, "    <device path='%s'/>\n",
c401cc
+                                      src->devices[i].path);
c401cc
             }
c401cc
         }
c401cc
     }
c401cc
 
c401cc
-    if ((options->flags & VIR_STORAGE_POOL_SOURCE_DIR) &&
c401cc
-        src->dir)
c401cc
-        virBufferAsprintf(buf, "    <dir path='%s'/>\n", src->dir);
c401cc
+    if (options->flags & VIR_STORAGE_POOL_SOURCE_DIR)
c401cc
+        virBufferEscapeString(buf, "    <dir path='%s'/>\n", src->dir);
c401cc
 
c401cc
     if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER)) {
c401cc
         if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST ||
c401cc
@@ -1104,9 +1104,8 @@ virStoragePoolSourceFormat(virBufferPtr buf,
c401cc
         }
c401cc
     }
c401cc
 
c401cc
-    if ((options->flags & VIR_STORAGE_POOL_SOURCE_NAME) &&
c401cc
-        src->name)
c401cc
-        virBufferAsprintf(buf, "    <name>%s</name>\n", src->name);
c401cc
+    if (options->flags & VIR_STORAGE_POOL_SOURCE_NAME)
c401cc
+        virBufferEscapeString(buf, "    <name>%s</name>\n", src->name);
c401cc
 
c401cc
     if ((options->flags & VIR_STORAGE_POOL_SOURCE_INITIATOR_IQN) &&
c401cc
         src->initiator.iqn) {
c401cc
@@ -1129,11 +1128,12 @@ virStoragePoolSourceFormat(virBufferPtr buf,
c401cc
 
c401cc
     if (src->authType == VIR_STORAGE_POOL_AUTH_CHAP ||
c401cc
         src->authType == VIR_STORAGE_POOL_AUTH_CEPHX) {
c401cc
-        virBufferAsprintf(buf, "    <auth type='%s' username='%s'>\n",
c401cc
-                          virStoragePoolAuthTypeTypeToString(src->authType),
c401cc
-                          (src->authType == VIR_STORAGE_POOL_AUTH_CHAP ?
c401cc
-                           src->auth.chap.username :
c401cc
-                           src->auth.cephx.username));
c401cc
+        virBufferAsprintf(buf, "    
c401cc
+                          virStoragePoolAuthTypeTypeToString(src->authType));
c401cc
+        virBufferEscapeString(buf, "username='%s'>\n",
c401cc
+                              (src->authType == VIR_STORAGE_POOL_AUTH_CHAP ?
c401cc
+                               src->auth.chap.username :
c401cc
+                               src->auth.cephx.username));
c401cc
 
c401cc
         virBufferAddLit(buf, "      
c401cc
         if (src->auth.cephx.secret.uuidUsable) {
c401cc
@@ -1149,13 +1149,8 @@ virStoragePoolSourceFormat(virBufferPtr buf,
c401cc
         virBufferAddLit(buf, "    </auth>\n");
c401cc
     }
c401cc
 
c401cc
-    if (src->vendor != NULL) {
c401cc
-        virBufferEscapeString(buf, "    <vendor name='%s'/>\n", src->vendor);
c401cc
-    }
c401cc
-
c401cc
-    if (src->product != NULL) {
c401cc
-        virBufferEscapeString(buf, "    <product name='%s'/>\n", src->product);
c401cc
-    }
c401cc
+    virBufferEscapeString(buf, "    <vendor name='%s'/>\n", src->vendor);
c401cc
+    virBufferEscapeString(buf, "    <product name='%s'/>\n", src->product);
c401cc
 
c401cc
     virBufferAddLit(buf, "  </source>\n");
c401cc
 
c401cc
@@ -1182,7 +1177,7 @@ virStoragePoolDefFormat(virStoragePoolDefPtr def)
c401cc
         goto cleanup;
c401cc
     }
c401cc
     virBufferAsprintf(&buf, "<pool type='%s'>\n", type);
c401cc
-    virBufferAsprintf(&buf, "  <name>%s</name>\n", def->name);
c401cc
+    virBufferEscapeString(&buf, "  <name>%s</name>\n", def->name);
c401cc
 
c401cc
     virUUIDFormat(def->uuid, uuid);
c401cc
     virBufferAsprintf(&buf, "  <uuid>%s</uuid>\n", uuid);
c401cc
@@ -1203,8 +1198,7 @@ virStoragePoolDefFormat(virStoragePoolDefPtr def)
c401cc
         def->type != VIR_STORAGE_POOL_SHEEPDOG) {
c401cc
         virBufferAddLit(&buf, "  <target>\n");
c401cc
 
c401cc
-        if (def->target.path)
c401cc
-            virBufferAsprintf(&buf, "    <path>%s</path>\n", def->target.path);
c401cc
+        virBufferEscapeString(&buf, "    <path>%s</path>\n", def->target.path);
c401cc
 
c401cc
         virBufferAddLit(&buf, "    <permissions>\n");
c401cc
         virBufferAsprintf(&buf, "      <mode>0%o</mode>\n",
c401cc
@@ -1214,9 +1208,8 @@ virStoragePoolDefFormat(virStoragePoolDefPtr def)
c401cc
         virBufferAsprintf(&buf, "      <group>%d</group>\n",
c401cc
                           (int) def->target.perms.gid);
c401cc
 
c401cc
-        if (def->target.perms.label)
c401cc
-            virBufferAsprintf(&buf, "      <label>%s</label>\n",
c401cc
-                            def->target.perms.label);
c401cc
+        virBufferEscapeString(&buf, "      <label>%s</label>\n",
c401cc
+                              def->target.perms.label);
c401cc
 
c401cc
         virBufferAddLit(&buf, "    </permissions>\n");
c401cc
         virBufferAddLit(&buf, "  </target>\n");
c401cc
@@ -1282,8 +1275,8 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
c401cc
         goto error;
c401cc
     }
c401cc
 
c401cc
-    /* Auto-generated so deliberately ignore */
c401cc
-    /* ret->key = virXPathString("string(./key)", ctxt); */
c401cc
+    /* Normally generated by pool refresh, but useful for unit tests */
c401cc
+    ret->key = virXPathString("string(./key)", ctxt);
c401cc
 
c401cc
     capacity = virXPathString("string(./capacity)", ctxt);
c401cc
     unit = virXPathString("string(./capacity/@unit)", ctxt);
c401cc
@@ -1485,11 +1478,11 @@ static int
c401cc
 virStorageVolTargetDefFormat(virStorageVolOptionsPtr options,
c401cc
                              virBufferPtr buf,
c401cc
                              virStorageVolTargetPtr def,
c401cc
-                             const char *type) {
c401cc
+                             const char *type)
c401cc
+{
c401cc
     virBufferAsprintf(buf, "  <%s>\n", type);
c401cc
 
c401cc
-    if (def->path)
c401cc
-        virBufferAsprintf(buf, "    <path>%s</path>\n", def->path);
c401cc
+    virBufferEscapeString(buf, "    <path>%s</path>\n", def->path);
c401cc
 
c401cc
     if (options->formatToString) {
c401cc
         const char *format = (options->formatToString)(def->format);
c401cc
@@ -1511,8 +1504,7 @@ virStorageVolTargetDefFormat(virStorageVolOptionsPtr options,
c401cc
                       (unsigned int) def->perms.gid);
c401cc
 
c401cc
 
c401cc
-    if (def->perms.label)
c401cc
-        virBufferAsprintf(buf, "      <label>%s</label>\n",
c401cc
+    virBufferEscapeString(buf, "      <label>%s</label>\n",
c401cc
                           def->perms.label);
c401cc
 
c401cc
     virBufferAddLit(buf, "    </permissions>\n");
c401cc
@@ -1572,8 +1564,8 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool,
c401cc
         return NULL;
c401cc
 
c401cc
     virBufferAddLit(&buf, "<volume>\n");
c401cc
-    virBufferAsprintf(&buf, "  <name>%s</name>\n", def->name);
c401cc
-    virBufferAsprintf(&buf, "  <key>%s</key>\n", NULLSTR(def->key));
c401cc
+    virBufferEscapeString(&buf, "  <name>%s</name>\n", def->name);
c401cc
+    virBufferEscapeString(&buf, "  <key>%s</key>\n", def->key);
c401cc
     virBufferAddLit(&buf, "  <source>\n");
c401cc
 
c401cc
     if (def->source.nextent) {
c401cc
@@ -1585,8 +1577,8 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool,
c401cc
                 if (thispath != NULL)
c401cc
                     virBufferAddLit(&buf, "    </device>\n");
c401cc
 
c401cc
-                virBufferAsprintf(&buf, "    <device path='%s'>\n",
c401cc
-                                  def->source.extents[i].path);
c401cc
+                virBufferEscapeString(&buf, "    <device path='%s'>\n",
c401cc
+                                      def->source.extents[i].path);
c401cc
             }
c401cc
 
c401cc
             virBufferAsprintf(&buf,
c401cc
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
c401cc
index 72786dd..2eb751d 100644
c401cc
--- a/src/storage/storage_driver.c
c401cc
+++ b/src/storage/storage_driver.c
c401cc
@@ -1553,6 +1553,9 @@ storageVolCreateXML(virStoragePoolPtr obj,
c401cc
         goto cleanup;
c401cc
     }
c401cc
 
c401cc
+    /* Wipe any key the user may have suggested, as volume creation
c401cc
+     * will generate the canonical key.  */
c401cc
+    VIR_FREE(voldef->key);
c401cc
     if (backend->createVol(obj->conn, pool, voldef) < 0) {
c401cc
         goto cleanup;
c401cc
     }
c401cc
@@ -1724,7 +1727,10 @@ storageVolCreateXMLFrom(virStoragePoolPtr obj,
c401cc
                       pool->volumes.count+1) < 0)
c401cc
         goto cleanup;
c401cc
 
c401cc
-    /* 'Define' the new volume so we get async progress reporting */
c401cc
+    /* 'Define' the new volume so we get async progress reporting.
c401cc
+     * Wipe any key the user may have suggested, as volume creation
c401cc
+     * will generate the canonical key.  */
c401cc
+    VIR_FREE(newvol->key);
c401cc
     if (backend->createVol(obj->conn, pool, newvol) < 0) {
c401cc
         goto cleanup;
c401cc
     }
c401cc
diff --git a/tests/storagepoolxml2xmlin/pool-dir-naming.xml b/tests/storagepoolxml2xmlin/pool-dir-naming.xml
c401cc
new file mode 100644
c401cc
index 0000000..aa043be
c401cc
--- /dev/null
c401cc
+++ b/tests/storagepoolxml2xmlin/pool-dir-naming.xml
c401cc
@@ -0,0 +1,18 @@
c401cc
+<pool type='dir'>
c401cc
+  <name>virtimages</name>
c401cc
+  <uuid>70a7eb15-6c34-ee9c-bf57-69e8e5ff3fb2</uuid>
c401cc
+  <capacity>0</capacity>
c401cc
+  <allocation>0</allocation>
c401cc
+  <available>0</available>
c401cc
+  <source>
c401cc
+  </source>
c401cc
+  <target>
c401cc
+    <path>///var/////lib/libvirt/<images>//</path>
c401cc
+    <permissions>
c401cc
+      <mode>0700</mode>
c401cc
+      <owner>-1</owner>
c401cc
+      <group>-1</group>
c401cc
+      <label>some_label_t</label>
c401cc
+    </permissions>
c401cc
+  </target>
c401cc
+</pool>
c401cc
diff --git a/tests/storagepoolxml2xmlout/pool-dir-naming.xml b/tests/storagepoolxml2xmlout/pool-dir-naming.xml
c401cc
new file mode 100644
c401cc
index 0000000..536f58c
c401cc
--- /dev/null
c401cc
+++ b/tests/storagepoolxml2xmlout/pool-dir-naming.xml
c401cc
@@ -0,0 +1,18 @@
c401cc
+<pool type='dir'>
c401cc
+  <name>virtimages</name>
c401cc
+  <uuid>70a7eb15-6c34-ee9c-bf57-69e8e5ff3fb2</uuid>
c401cc
+  <capacity unit='bytes'>0</capacity>
c401cc
+  <allocation unit='bytes'>0</allocation>
c401cc
+  <available unit='bytes'>0</available>
c401cc
+  <source>
c401cc
+  </source>
c401cc
+  <target>
c401cc
+    <path>/var/lib/libvirt/<images></path>
c401cc
+    <permissions>
c401cc
+      <mode>0700</mode>
c401cc
+      <owner>-1</owner>
c401cc
+      <group>-1</group>
c401cc
+      <label>some_label_t</label>
c401cc
+    </permissions>
c401cc
+  </target>
c401cc
+</pool>
c401cc
diff --git a/tests/storagepoolxml2xmltest.c b/tests/storagepoolxml2xmltest.c
c401cc
index 8e4ea42..c75480b 100644
c401cc
--- a/tests/storagepoolxml2xmltest.c
c401cc
+++ b/tests/storagepoolxml2xmltest.c
c401cc
@@ -85,6 +85,7 @@ mymain(void)
c401cc
         ret = -1
c401cc
 
c401cc
     DO_TEST("pool-dir");
c401cc
+    DO_TEST("pool-dir-naming");
c401cc
     DO_TEST("pool-fs");
c401cc
     DO_TEST("pool-logical");
c401cc
     DO_TEST("pool-logical-nopath");
c401cc
diff --git a/tests/storagevolxml2xmlin/vol-file-backing.xml b/tests/storagevolxml2xmlin/vol-file-backing.xml
c401cc
index d23349e..73e7f28 100644
c401cc
--- a/tests/storagevolxml2xmlin/vol-file-backing.xml
c401cc
+++ b/tests/storagevolxml2xmlin/vol-file-backing.xml
c401cc
@@ -1,5 +1,6 @@
c401cc
 <volume>
c401cc
   <name>sparse.img</name>
c401cc
+  <key>/var/lib/libvirt/images/sparse.img</key>
c401cc
   <source/>
c401cc
   <capacity unit='GB'>10</capacity>
c401cc
   <allocation unit='MiB'>0</allocation>
c401cc
diff --git a/tests/storagevolxml2xmlin/vol-file-naming.xml b/tests/storagevolxml2xmlin/vol-file-naming.xml
c401cc
new file mode 100644
c401cc
index 0000000..9a33e2b
c401cc
--- /dev/null
c401cc
+++ b/tests/storagevolxml2xmlin/vol-file-naming.xml
c401cc
@@ -0,0 +1,20 @@
c401cc
+<volume>
c401cc
+  <name><sparse>.img</name>
c401cc
+  <source/>
c401cc
+  <capacity unit="TiB">1</capacity>
c401cc
+  <allocation unit="bytes">0</allocation>
c401cc
+  <target>
c401cc
+    <path>/var/lib/libvirt/images/<sparse>.img</path>
c401cc
+    <permissions>
c401cc
+      <mode>0</mode>
c401cc
+      <owner>0744</owner>
c401cc
+      <group>0</group>
c401cc
+      <label>virt_image_t</label>
c401cc
+    </permissions>
c401cc
+    <timestamps>
c401cc
+      <atime>1341933637.273190990</atime>
c401cc
+      <mtime>1341930622.047245868</mtime>
c401cc
+      <ctime>1341930622.047245868</ctime>
c401cc
+    </timestamps>
c401cc
+  </target>
c401cc
+</volume>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-file-backing.xml b/tests/storagevolxml2xmlout/vol-file-backing.xml
c401cc
index c0f152e..8d2fb57 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-file-backing.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-file-backing.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>sparse.img</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>/var/lib/libvirt/images/sparse.img</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>10000000000</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-file-naming.xml b/tests/storagevolxml2xmlout/vol-file-naming.xml
c401cc
new file mode 100644
c401cc
index 0000000..7022b02
c401cc
--- /dev/null
c401cc
+++ b/tests/storagevolxml2xmlout/vol-file-naming.xml
c401cc
@@ -0,0 +1,17 @@
c401cc
+<volume>
c401cc
+  <name><sparse>.img</name>
c401cc
+  <source>
c401cc
+  </source>
c401cc
+  <capacity unit='bytes'>1099511627776</capacity>
c401cc
+  <allocation unit='bytes'>0</allocation>
c401cc
+  <target>
c401cc
+    <path>/var/lib/libvirt/images/<sparse>.img</path>
c401cc
+    <format type='raw'/>
c401cc
+    <permissions>
c401cc
+      <mode>00</mode>
c401cc
+      <owner>744</owner>
c401cc
+      <group>0</group>
c401cc
+      <label>virt_image_t</label>
c401cc
+    </permissions>
c401cc
+  </target>
c401cc
+</volume>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-file.xml b/tests/storagevolxml2xmlout/vol-file.xml
c401cc
index a3d6473..b97dd50 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-file.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-file.xml
c401cc
@@ -1,6 +1,5 @@
c401cc
 <volume>
c401cc
   <name>sparse.img</name>
c401cc
-  <key>(null)</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>1099511627776</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-logical-backing.xml b/tests/storagevolxml2xmlout/vol-logical-backing.xml
c401cc
index 6b010e3..bf34b08 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-logical-backing.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-logical-backing.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>Swap</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>r4xkCv-MQhr-WKIT-R66x-Epn2-e8hG-1Z5gY0</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>2080374784</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-logical.xml b/tests/storagevolxml2xmlout/vol-logical.xml
c401cc
index 7bf309e..e9b4e4b 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-logical.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-logical.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>Swap</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>r4xkCv-MQhr-WKIT-R66x-Epn2-e8hG-1Z5gY0</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>2080374784</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-partition.xml b/tests/storagevolxml2xmlout/vol-partition.xml
c401cc
index 271964f..9be1cf1 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-partition.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-partition.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>sda1</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>/dev/sda1</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>106896384</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-qcow2-0.10-lazy.xml b/tests/storagevolxml2xmlout/vol-qcow2-0.10-lazy.xml
c401cc
index a7b5fed..fd3d606 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-qcow2-0.10-lazy.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-qcow2-0.10-lazy.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>OtherDemo.img</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>/var/lib/libvirt/images/OtherDemo.img</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>5368709120</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-qcow2-1.1.xml b/tests/storagevolxml2xmlout/vol-qcow2-1.1.xml
c401cc
index b7df8a6..99fb5ac 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-qcow2-1.1.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-qcow2-1.1.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>OtherDemo.img</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>/var/lib/libvirt/images/OtherDemo.img</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>5368709120</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-qcow2-lazy.xml b/tests/storagevolxml2xmlout/vol-qcow2-lazy.xml
c401cc
index 92b7875..3708ea7 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-qcow2-lazy.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-qcow2-lazy.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>OtherDemo.img</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>/var/lib/libvirt/images/OtherDemo.img</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>5368709120</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-qcow2-nobacking.xml b/tests/storagevolxml2xmlout/vol-qcow2-nobacking.xml
c401cc
index e2da702..f6a2e21 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-qcow2-nobacking.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-qcow2-nobacking.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>OtherDemo.img</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>/var/lib/libvirt/images/OtherDemo.img</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>5368709120</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-qcow2.xml b/tests/storagevolxml2xmlout/vol-qcow2.xml
c401cc
index f931a62..b9adcb4 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-qcow2.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-qcow2.xml
c401cc
@@ -1,6 +1,6 @@
c401cc
 <volume>
c401cc
   <name>OtherDemo.img</name>
c401cc
-  <key>(null)</key>
c401cc
+  <key>/var/lib/libvirt/images/OtherDemo.img</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>5368709120</capacity>
c401cc
diff --git a/tests/storagevolxml2xmlout/vol-sheepdog.xml b/tests/storagevolxml2xmlout/vol-sheepdog.xml
c401cc
index 2f19af8..bd5d6d8 100644
c401cc
--- a/tests/storagevolxml2xmlout/vol-sheepdog.xml
c401cc
+++ b/tests/storagevolxml2xmlout/vol-sheepdog.xml
c401cc
@@ -1,6 +1,5 @@
c401cc
 <volume>
c401cc
   <name>test2</name>
c401cc
-  <key>(null)</key>
c401cc
   <source>
c401cc
   </source>
c401cc
   <capacity unit='bytes'>1024</capacity>
c401cc
diff --git a/tests/storagevolxml2xmltest.c b/tests/storagevolxml2xmltest.c
c401cc
index 5b0a60b..d62c29f 100644
c401cc
--- a/tests/storagevolxml2xmltest.c
c401cc
+++ b/tests/storagevolxml2xmltest.c
c401cc
@@ -110,6 +110,7 @@ mymain(void)
c401cc
     while (0);
c401cc
 
c401cc
     DO_TEST("pool-dir", "vol-file");
c401cc
+    DO_TEST("pool-dir", "vol-file-naming");
c401cc
     DO_TEST("pool-dir", "vol-file-backing");
c401cc
     DO_TEST("pool-dir", "vol-qcow2");
c401cc
     DO_TEST("pool-dir", "vol-qcow2-1.1");
c401cc
-- 
c401cc
1.9.0
c401cc