]> xenbits.xensource.com Git - libvirt.git/commitdiff
storage: support more scaling suffixes
authorEric Blake <eblake@redhat.com>
Mon, 5 Mar 2012 21:06:33 +0000 (14:06 -0700)
committerEric Blake <eblake@redhat.com>
Thu, 8 Mar 2012 01:24:43 +0000 (18:24 -0700)
Disk manufacturers are fond of quoting sizes in powers of 10,
rather than powers of 2 (after all, 2.1 GB sounds larger than
2.0 GiB, even though the exact opposite is true).  So, we might
as well follow coreutils' lead in supporting three types of
suffix: single letter ${u} (which we already had) and ${u}iB
for the power of 2, and ${u}B for power of 10.

Additionally, it is impossible to create a file with more than
2**63 bytes, since off_t is signed (if you have enough storage
to even create one 8EiB file, I'm jealous).  This now reports
failure up front rather than down the road when the kernel
finally refuses an impossible size.

* docs/schemas/basictypes.rng (unit): Add suffixes.
* src/conf/storage_conf.c (virStorageSize): Use new function.
* docs/formatstorage.html.in: Document it.
* tests/storagevolxml2xmlin/vol-file-backing.xml: Test it.
* tests/storagevolxml2xmlin/vol-file.xml: Likewise.

docs/formatstorage.html.in
docs/schemas/basictypes.rng
src/conf/storage_conf.c
tests/storagevolxml2xmlin/vol-file-backing.xml
tests/storagevolxml2xmlin/vol-file.xml

index acb21faa81445c0932921524a465be71d3dc086a..d0e4319c509dcb00ec6dc38e31c54025c191a757 100644 (file)
         <br/>
         By default this is specified in bytes, but an optional attribute
         <code>unit</code> can be specified to adjust the passed value.
-        Values can be: 'K' (kibibytes, 2<sup>10</sup> or 1024 bytes),
-        'M' (mebibytes, 2<sup>20</sup> or 1,048,576 bytes), 'G'
-        (gibibytes, 2<sup>30</sup> or 1,073,741,824 bytes), 'T'
-        (tebibytes, 2<sup>40</sup> or 1,099,511,627,776 bytes), 'P'
-        (pebibytes, 2<sup>50</sup> or 1,125,899,906,842,624 bytes), or
-        'E' (exbibytes, 2<sup>60</sup> or 1,152,921,504,606,846,976
-        bytes).  <span class="since">Since 0.4.1</span></dd>
+        Values can be: 'B' or 'bytes' for bytes, 'KB' (kilobytes,
+        10<sup>3</sup> or 1000 bytes), 'K' or 'KiB' (kibibytes,
+        2<sup>10</sup> or 1024 bytes), 'MB' (megabytes, 10<sup>6</sup>
+        or 1,000,000 bytes), 'M' or 'MiB' (mebibytes, 2<sup>20</sup>
+        or 1,048,576 bytes), 'GB' (gigabytes, 10<sup>9</sup> or
+        1,000,000,000 bytes), 'G' or 'GiB' (gibibytes, 2<sup>30</sup>
+        or 1,073,741,824 bytes), 'TB' (terabytes, 10<sup>12</sup> or
+        1,000,000,000,000 bytes), 'T' or 'TiB' (tebibytes,
+        2<sup>40</sup> or 1,099,511,627,776 bytes), 'PB' (petabytes,
+        10<sup>15</sup> or 1,000,000,000,000,000 bytes), 'P' or 'PiB'
+        (pebibytes, 2<sup>50</sup> or 1,125,899,906,842,624 bytes),
+        'EB' (exabytes, 10<sup>18</sup> or 1,000,000,000,000,000,000
+        bytes), or 'E' or 'EiB' (exbibytes, 2<sup>60</sup> or
+        1,152,921,504,606,846,976 bytes).  <span class="since">Since
+        0.4.1, multi-character <code>unit</code> since
+        0.9.11</span></dd>
       <dt><code>capacity</code></dt>
       <dd>Providing the logical capacity for the volume. This value is
         in bytes by default, but a <code>unit</code> attribute can be
index a50349c60234c2c682a07a274e29ac198264e69d..cc0bc1286d508648a4c57125eef96eb8a8d45ca1 100644 (file)
 
   <define name='unit'>
     <data type='string'>
-      <param name='pattern'>(bytes)|[kKmMgGtTpPeE]</param>
+      <param name='pattern'>([bB]([yY][tT][eE][sS]?)?)|([kKmMgGtTpPeE]([iI]?[bB])?)</param>
     </data>
   </define>
   <define name='scaledInteger'>
index 07f3f5b6dc8a56af9a432745ec54233769d8b691..bdf62184c4d7f8ec1f88bbf07d4a73d7853ba271 100644 (file)
@@ -944,64 +944,17 @@ virStoragePoolDefFormat(virStoragePoolDefPtr def) {
 static int
 virStorageSize(const char *unit,
                const char *val,
-               unsigned long long *ret) {
-    unsigned long long mult;
-    char *end;
-
-    if (!unit) {
-        mult = 1;
-    } else {
-        switch (unit[0]) {
-        case 'k':
-        case 'K':
-            mult = 1024ull;
-            break;
-
-        case 'm':
-        case 'M':
-            mult = 1024ull * 1024ull;
-            break;
-
-        case 'g':
-        case 'G':
-            mult = 1024ull * 1024ull * 1024ull;
-            break;
-
-        case 't':
-        case 'T':
-            mult = 1024ull * 1024ull * 1024ull * 1024ull;
-            break;
-
-        case 'p':
-        case 'P':
-            mult = 1024ull * 1024ull * 1024ull * 1024ull * 1024ull;
-            break;
-
-        case 'e':
-        case 'E':
-            mult = 1024ull * 1024ull * 1024ull * 1024ull * 1024ull *
-                1024ull;
-            break;
-
-        default:
-            virStorageReportError(VIR_ERR_XML_ERROR,
-                                  _("unknown size units '%s'"), unit);
-            return -1;
-        }
-    }
-
-    if (virStrToLong_ull (val, &end, 10, ret) < 0) {
+               unsigned long long *ret)
+{
+    if (virStrToLong_ull(val, NULL, 10, ret) < 0) {
         virStorageReportError(VIR_ERR_XML_ERROR,
                               "%s", _("malformed capacity element"));
         return -1;
     }
-    if (*ret > (ULLONG_MAX / mult)) {
-        virStorageReportError(VIR_ERR_XML_ERROR,
-                              "%s", _("capacity element value too large"));
-            return -1;
-    }
-
-    *ret *= mult;
+    /* off_t is signed, so you cannot create a file larger than 2**63
+     * bytes in the first place.  */
+    if (virScaleInteger(ret, unit, 1, LLONG_MAX) < 0)
+        return -1;
 
     return 0;
 }
index c1a5837c6a92280118d6221102138cd3866439b3..d23349e658aa03a558e5295b8482cc2d641613d4 100644 (file)
@@ -1,8 +1,8 @@
 <volume>
   <name>sparse.img</name>
   <source/>
-  <capacity>10000000000</capacity>
-  <allocation>0</allocation>
+  <capacity unit='GB'>10</capacity>
+  <allocation unit='MiB'>0</allocation>
   <target>
     <path>/var/lib/libvirt/images/sparse.img</path>
     <permissions>
index d7de0aa23ce3e938070e5a84a89bb0980b4685f7..fdca510101f3608210fc92e55bfe5882059d0599 100644 (file)
@@ -1,8 +1,8 @@
 <volume>
   <name>sparse.img</name>
   <source/>
-  <capacity unit="T">1</capacity>
-  <allocation>0</allocation>
+  <capacity unit="TiB">1</capacity>
+  <allocation unit="bytes">0</allocation>
   <target>
     <path>/var/lib/libvirt/images/sparse.img</path>
     <permissions>