diff --git a/.gitignore b/.gitignore index e5d5db9170b21798bcce888cb62d19e750d9479b..46dbcdfcac8a9cb4018f5e0c61825e0edf09e79c 100644 --- a/.gitignore +++ b/.gitignore @@ -145,6 +145,7 @@ /tests/sockettest /tests/ssh /tests/statstest +/tests/storagebackendsheepdogtest /tests/utiltest /tests/virauthconfigtest /tests/virbuftest diff --git a/AUTHORS b/AUTHORS index 43cc0a17f78fd7cb4eed2ce5e745db0da9f7d8d5..092e279d1f9fed1f9e4d5e9bc3595e38cd53c998 100644 --- a/AUTHORS +++ b/AUTHORS @@ -249,7 +249,7 @@ Patches have also been contributed by: Eiichi Tsukata Sascha Peilicke Chuck Short - + Sebastian Wiedenroth [....send patches to get your name here....] The libvirt Logo was designed by Diana Fong diff --git a/configure.ac b/configure.ac index ae814cb8669512127e78da71824c95540f45eb0e..3cc7b3c2fa5b0c4e93aeb124843097fe749eb7ee 100644 --- a/configure.ac +++ b/configure.ac @@ -1825,6 +1825,8 @@ AC_ARG_WITH([storage-disk], AC_HELP_STRING([--with-storage-disk], [with GPartd Disk backend for the storage driver @<:@default=check@:>@]),[],[with_storage_disk=check]) AC_ARG_WITH([storage-rbd], AC_HELP_STRING([--with-storage-rbd], [with RADOS Block Device backend for the storage driver @<:@default=check@:>@]),[],[with_storage_rbd=check]) +AC_ARG_WITH([storage-sheepdog], + AC_HELP_STRING([--with-storage-sheepdog], [with Sheepdog backend for the storage driver @<:@default=check@:>@]),[],[with_storage_sheepdog=check]) if test "$with_libvirtd" = "no"; then with_storage_dir=no @@ -1835,6 +1837,7 @@ if test "$with_libvirtd" = "no"; then with_storage_mpath=no with_storage_disk=no with_storage_rbd=no + with_storage_sheepdog=no fi if test "$with_storage_dir" = "yes" ; then AC_DEFINE_UNQUOTED([WITH_STORAGE_DIR], 1, [whether directory backend for storage driver is enabled]) @@ -2009,6 +2012,34 @@ fi AM_CONDITIONAL([WITH_STORAGE_RBD], [test "$with_storage_rbd" = "yes"]) AC_SUBST([LIBRBD_LIBS]) +if test "$with_storage_sheepdog" = "yes" || + test "$with_storage_sheepdog" = "check"; then + AC_PATH_PROG([COLLIE], [collie], [], [$PATH:/sbin:/usr/sbin]) + + if test "$with_storage_sheepdog" = "yes"; then + if test -z "$COLLIE"; then + AC_MSG_ERROR([We need collie for Sheepdog storage driver]) + fi + else + if test -z "$COLLIE"; then + with_storage_sheepdog=no + fi + + if test "$with_storage_sheepdog" = "check"; then + with_storage_sheepdog=yes + fi + fi + + if test "$with_storage_sheepdog" = "yes"; then + AC_DEFINE_UNQUOTED([WITH_STORAGE_SHEEPDOG], 1, + [whether Sheepdog backend for storage driver is enabled]) + AC_DEFINE_UNQUOTED([COLLIE],["$COLLIE"],[Location of collie program]) + fi +fi +AM_CONDITIONAL([WITH_STORAGE_SHEEPDOG], + [test "$with_storage_sheepdog" = "yes"]) + + LIBPARTED_CFLAGS= LIBPARTED_LIBS= if test "$with_storage_disk" = "yes" || @@ -2824,6 +2855,7 @@ AC_MSG_NOTICE([ SCSI: $with_storage_scsi]) AC_MSG_NOTICE([ mpath: $with_storage_mpath]) AC_MSG_NOTICE([ Disk: $with_storage_disk]) AC_MSG_NOTICE([ RBD: $with_storage_rbd]) +AC_MSG_NOTICE([Sheepdog: $with_storage_sheepdog]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Security Drivers]) AC_MSG_NOTICE([]) diff --git a/docs/drivers.html.in b/docs/drivers.html.in index 8ad2c33218db51e3d8fc5d365d975e2d9e04c38d..90b61962ebb4898c087222e9aacf640d3632c834 100644 --- a/docs/drivers.html.in +++ b/docs/drivers.html.in @@ -43,6 +43,7 @@
  • SCSI backend
  • Multipath backend
  • RBD (RADOS Block Device) backend
  • +
  • Sheepdog backend
  • diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng index 75b6b514b2b03bbc4d42921f9ce8ae2bb2fabe42..039798a9ba02ca177e6d964bf63db8c0421533f7 100644 --- a/docs/schemas/storagepool.rng +++ b/docs/schemas/storagepool.rng @@ -20,6 +20,7 @@ + @@ -115,6 +116,15 @@ + + + sheepdog + + + + + + @@ -496,6 +506,13 @@ + + + + + + + [a-zA-Z0-9_\+\-]+ diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 7a74331cd7e3481b1f1779d5376577b4aeba2e3b..0b9933d56c057ff5e1adf6241bcc91759010ac3d 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -67,7 +67,7 @@ - + @@ -144,6 +144,7 @@ + unknown raw dir bochs diff --git a/docs/storage.html.in b/docs/storage.html.in index b3484e811bc9269a8b533990927dcc58d3abf794..26a949a7d16f6d120d422916ef14ba89ae51f6a5 100644 --- a/docs/storage.html.in +++ b/docs/storage.html.in @@ -110,6 +110,9 @@
  • RBD (RADOS Block Device) backend
  • +
  • + Sheepdog backend +
  • Directory pool

    @@ -565,5 +568,64 @@ The RBD pool does not use the volume format type element.

    +

    Sheepdog pools

    +

    + This provides a pool based on a Sheepdog Cluster. + Sheepdog is a distributed storage system for QEMU/KVM. + It provides highly available block level storage volumes that + can be attached to QEMU/KVM virtual machines. + + The cluster must already be formatted. + + Since 0.9.13 +

    + +

    Example pool input

    +
    +      <pool type="sheepdog">
    +        <name>mysheeppool</name>
    +        <source>
    +          <name>mysheeppool</name>
    +          <host name='localhost' port='7000'/>
    +        </source>
    +      </pool>
    + +

    Example volume output

    +
    +       <volume>
    +         <name>myvol</name>
    +         <key>sheep/myvol</key>
    +         <source>
    +         </source>
    +         <capacity unit='bytes'>53687091200</capacity>
    +         <allocation unit='bytes'>53687091200</allocation>
    +         <target>
    +           <path>sheepdog:myvol</path>
    +           <format type='unknown'/>
    +           <permissions>
    +             <mode>00</mode>
    +             <owner>0</owner>
    +             <group>0</group>
    +           </permissions>
    +         </target>
    +       </volume>
    + +

    Example disk attachment

    +

    Sheepdog images can be attached to Qemu guests. + Information about attaching a Sheepdog image to a + guest can be found + at the format domain + page.

    + +

    Valid pool format types

    +

    + The Sheepdog pool does not use the pool format type element. +

    + +

    Valid volume format types

    +

    + The Sheepdog pool does not use the volume format type element. +

    + diff --git a/libvirt.spec.in b/libvirt.spec.in index ec2b3b44e747dd6d86b43021143c7d7962db07ad..2253d8686ad06324d225a4eb4dff123d61f07747 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -69,19 +69,24 @@ %define with_xenapi 0%{!?_without_xenapi:1} # Then the secondary host drivers, which run inside libvirtd -%define with_network 0%{!?_without_network:%{server_drivers}} -%define with_storage_fs 0%{!?_without_storage_fs:%{server_drivers}} -%define with_storage_lvm 0%{!?_without_storage_lvm:%{server_drivers}} -%define with_storage_iscsi 0%{!?_without_storage_iscsi:%{server_drivers}} -%define with_storage_disk 0%{!?_without_storage_disk:%{server_drivers}} -%define with_storage_mpath 0%{!?_without_storage_mpath:%{server_drivers}} +%define with_network 0%{!?_without_network:%{server_drivers}} +%define with_storage_fs 0%{!?_without_storage_fs:%{server_drivers}} +%define with_storage_lvm 0%{!?_without_storage_lvm:%{server_drivers}} +%define with_storage_iscsi 0%{!?_without_storage_iscsi:%{server_drivers}} +%define with_storage_disk 0%{!?_without_storage_disk:%{server_drivers}} +%define with_storage_mpath 0%{!?_without_storage_mpath:%{server_drivers}} %if 0%{?fedora} >= 16 -%define with_storage_rbd 0%{!?_without_storage_rbd:%{server_drivers}} +%define with_storage_rbd 0%{!?_without_storage_rbd:%{server_drivers}} %else -%define with_storage_rbd 0 +%define with_storage_rbd 0 %endif -%define with_numactl 0%{!?_without_numactl:%{server_drivers}} -%define with_selinux 0%{!?_without_selinux:%{server_drivers}} +%if 0%{?fedora} >= 17 +%define with_storage_sheepdog 0%{!?_without_storage_sheepdog:%{server_drivers}} +%else +%define with_storage_sheepdog 0 +%endif +%define with_numactl 0%{!?_without_numactl:%{server_drivers}} +%define with_selinux 0%{!?_without_selinux:%{server_drivers}} # A few optional bits off by default, we enable later %define with_polkit 0%{!?_without_polkit:0} @@ -224,6 +229,7 @@ %define with_storage_iscsi 0 %define with_storage_mpath 0 %define with_storage_rbd 0 +%define with_storage_sheepdog 0 %define with_storage_disk 0 %endif @@ -603,6 +609,10 @@ Requires: device-mapper # For RBD support Requires: ceph %endif +%if %{with_storage_sheepdog} +# For Sheepdog support +Requires: sheepdog +%endif %if %{with_cgconfig} Requires: libcgroup %endif @@ -1080,6 +1090,10 @@ of recent versions of Linux (and other OSes). %define _without_storage_rbd --without-storage-rbd %endif +%if ! %{with_storage_sheepdog} +%define _without_storage_sheepdog --without-storage-sheepdog +%endif + %if ! %{with_numactl} %define _without_numactl --without-numactl %endif @@ -1178,6 +1192,7 @@ autoreconf -if %{?_without_storage_disk} \ %{?_without_storage_mpath} \ %{?_without_storage_rbd} \ + %{?_without_storage_sheepdog} \ %{?_without_numactl} \ %{?_without_numad} \ %{?_without_capng} \ diff --git a/po/POTFILES.in b/po/POTFILES.in index 6ca40d9913307d943d8bb20905ebd14119c54d23..594519a406b9804927acc85ec6426fc64b9a7b6c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -108,6 +108,7 @@ src/storage/storage_backend_logical.c src/storage/storage_backend_mpath.c src/storage/storage_backend_rbd.c src/storage/storage_backend_scsi.c +src/storage/storage_backend_sheepdog.c src/storage/storage_driver.c src/test/test_driver.c src/uml/uml_conf.c diff --git a/src/Makefile.am b/src/Makefile.am index bfe74d39fd61b5c4ec9d9d7b6c50ea5426a27629..4fc42c91bc93f35bdbaffd52fd782ab94271dd67 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -515,6 +515,9 @@ STORAGE_DRIVER_DISK_SOURCES = \ STORAGE_DRIVER_RBD_SOURCES = \ storage/storage_backend_rbd.h storage/storage_backend_rbd.c +STORAGE_DRIVER_SHEEPDOG_SOURCES = \ + storage/storage_backend_sheepdog.h storage/storage_backend_sheepdog.c + STORAGE_HELPER_DISK_SOURCES = \ storage/parthelper.c @@ -1018,6 +1021,10 @@ libvirt_driver_storage_la_SOURCES += $(STORAGE_DRIVER_RBD_SOURCES) libvirt_driver_storage_la_LIBADD += $(LIBRBD_LIBS) endif +if WITH_STORAGE_SHEEPDOG +libvirt_driver_storage_la_SOURCES += $(STORAGE_DRIVER_SHEEPDOG_SOURCES) +endif + if WITH_NODE_DEVICES # Needed to keep automake quiet about conditionals if WITH_DRIVER_MODULES @@ -1116,6 +1123,7 @@ EXTRA_DIST += \ $(STORAGE_DRIVER_MPATH_SOURCES) \ $(STORAGE_DRIVER_DISK_SOURCES) \ $(STORAGE_DRIVER_RBD_SOURCES) \ + $(STORAGE_DRIVER_SHEEPDOG_SOURCES) \ $(NODE_DEVICE_DRIVER_SOURCES) \ $(NODE_DEVICE_DRIVER_HAL_SOURCES) \ $(NODE_DEVICE_DRIVER_UDEV_SOURCES) \ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 44387b26310532849526617d14e28354bef138f3..6ce9208947c590a6be4a7902fcdb7a5fcd16d232 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -54,7 +54,7 @@ VIR_ENUM_IMPL(virStoragePool, VIR_STORAGE_POOL_LAST, "dir", "fs", "netfs", "logical", "disk", "iscsi", - "scsi", "mpath", "rbd") + "scsi", "mpath", "rbd", "sheepdog") VIR_ENUM_IMPL(virStoragePoolFormatFileSystem, VIR_STORAGE_POOL_FS_LAST, @@ -208,6 +208,17 @@ static virStoragePoolTypeInfo poolTypeInfo[] = { .formatToString = virStoragePoolFormatDiskTypeToString, } }, + { .poolType = VIR_STORAGE_POOL_SHEEPDOG, + .poolOptions = { + .flags = (VIR_STORAGE_POOL_SOURCE_HOST | + VIR_STORAGE_POOL_SOURCE_NETWORK | + VIR_STORAGE_POOL_SOURCE_NAME), + }, + .volOptions = { + .defaultFormat = VIR_STORAGE_FILE_RAW, + .formatToString = virStoragePoolFormatDiskTypeToString, + } + }, { .poolType = VIR_STORAGE_POOL_MPATH, .volOptions = { .formatToString = virStoragePoolFormatDiskTypeToString, @@ -1014,9 +1025,9 @@ virStoragePoolDefFormat(virStoragePoolDefPtr def) { if (virStoragePoolSourceFormat(&buf, options, &def->source) < 0) goto cleanup; - /* RBD devices are not local block devs nor files, so it doesn't + /* RBD and Sheepdog devices are not local block devs nor files, so it doesn't * have a target */ - if (def->type != VIR_STORAGE_POOL_RBD) { + if (def->type != VIR_STORAGE_POOL_RBD && def->type != VIR_STORAGE_POOL_SHEEPDOG) { virBufferAddLit(&buf," \n"); if (def->target.path) @@ -1301,7 +1312,7 @@ virStorageVolDefFormat(virStoragePoolDefPtr pool, virBufferAddLit(&buf, "\n"); virBufferAsprintf(&buf," %s\n", def->name); - virBufferAsprintf(&buf," %s\n", def->key); + virBufferAsprintf(&buf," %s\n", def->key ? def->key : "(null)"); virBufferAddLit(&buf, " \n"); if (def->source.nextent) { diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 6e63671325f8b6d2c876dc8eeb693c523edbbd05..6f8434050499daa29f117d57a5ea421d43218df6 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -121,6 +121,7 @@ enum virStoragePoolType { VIR_STORAGE_POOL_SCSI, /* SCSI HBA */ VIR_STORAGE_POOL_MPATH, /* Multipath devices */ VIR_STORAGE_POOL_RBD, /* RADOS Block Device */ + VIR_STORAGE_POOL_SHEEPDOG, /* Sheepdog device */ VIR_STORAGE_POOL_LAST, }; diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 0c17aea42cb1cebc4e9dd30b8b3f47aa7e917a18..10956155fc6253458742855c40f3ec05d5df9fc6 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -79,6 +79,9 @@ #if WITH_STORAGE_RBD # include "storage_backend_rbd.h" #endif +#if WITH_STORAGE_SHEEPDOG +# include "storage_backend_sheepdog.h" +#endif #define VIR_FROM_THIS VIR_FROM_STORAGE @@ -107,6 +110,9 @@ static virStorageBackendPtr backends[] = { #endif #if WITH_STORAGE_RBD &virStorageBackendRBD, +#endif +#if WITH_STORAGE_SHEEPDOG + &virStorageBackendSheepdog, #endif NULL }; diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_backend_sheepdog.c new file mode 100644 index 0000000000000000000000000000000000000000..55ca5c1ae2bb8f8587b7c146795a8dd7449db2ff --- /dev/null +++ b/src/storage/storage_backend_sheepdog.c @@ -0,0 +1,311 @@ +/* + * storage_backend_sheepdog.c: storage backend for Sheepdog handling + * + * Copyright (C) 2012 Wido den Hollander + * Copyright (C) 2012 Frank Spijkerman + * Copyright (C) 2012 Sebastian Wiedenroth + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Wido den Hollander + * Frank Spijkerman + * Sebastian Wiedenroth + */ + +#include + +#include "virterror_internal.h" +#include "storage_backend_sheepdog.h" +#include "storage_conf.h" +#include "util/command.h" +#include "util.h" +#include "memory.h" +#include "logging.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +static int virStorageBackendSheepdogRefreshVol(virConnectPtr conn, + virStoragePoolObjPtr pool, + virStorageVolDefPtr vol); + +void virStorageBackendSheepdogAddHostArg(virCommandPtr cmd, + virStoragePoolObjPtr pool); + +int +virStorageBackendSheepdogParseNodeInfo(virStoragePoolDefPtr pool, + char *output) +{ + /* fields: + * node id/total, size, used, use%, [total vdi size] + * + * example output: + * 0 15245667872 117571104 0% + * Total 15245667872 117571104 0% 20972341 + */ + + const char *p, *next; + + pool->allocation = pool->capacity = pool->available = 0; + + p = output; + do { + char *end; + + if ((next = strchr(p, '\n'))) + ++next; + else + return -1; + + if (!STRPREFIX(p, "Total ")) + continue; + + p = p + 6; + + if (virStrToLong_ull(p, &end, 10, &pool->capacity) < 0) + return -1; + + if ((p = end + 1) > next) + return -1; + + if (virStrToLong_ull(p, &end, 10, &pool->allocation) < 0) + return -1; + + pool->available = pool->capacity - pool->allocation; + return 0; + + } while ((p = next)); + + return -1; +} + +void +virStorageBackendSheepdogAddHostArg(virCommandPtr cmd, + virStoragePoolObjPtr pool) +{ + const char *address = "localhost"; + int port = 7000; + if (pool->def->source.nhost > 0) { + if (pool->def->source.hosts[0].name != NULL) { + address = pool->def->source.hosts[0].name; + } + if (pool->def->source.hosts[0].port) { + port = pool->def->source.hosts[0].port; + } + } + virCommandAddArg(cmd, "-a"); + virCommandAddArgFormat(cmd, "%s", address); + virCommandAddArg(cmd, "-p"); + virCommandAddArgFormat(cmd, "%d", port); +} + + +static int +virStorageBackendSheepdogRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool) +{ + int ret; + char *output = NULL; + virCommandPtr cmd; + + cmd = virCommandNewArgList(COLLIE, "node", "info", "-r", NULL); + virStorageBackendSheepdogAddHostArg(cmd, pool); + virCommandSetOutputBuffer(cmd, &output); + ret = virCommandRun(cmd, NULL); + if (ret == 0) + ret = virStorageBackendSheepdogParseNodeInfo(pool->def, output); + + virCommandFree(cmd); + VIR_FREE(output); + return ret; +} + + +static int +virStorageBackendSheepdogDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + virStorageVolDefPtr vol, + unsigned int flags) +{ + + virCheckFlags(0, -1); + + virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "delete", vol->name, NULL); + virStorageBackendSheepdogAddHostArg(cmd, pool); + int ret = virCommandRun(cmd, NULL); + + virCommandFree(cmd); + return ret; +} + + +static int +virStorageBackendSheepdogCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + virStorageVolDefPtr vol) +{ + + int ret; + + if (vol->target.encryption != NULL) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Sheepdog does not support encrypted volumes")); + return -1; + } + + virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "create", vol->name, NULL); + virCommandAddArgFormat(cmd, "%llu", vol->capacity); + virStorageBackendSheepdogAddHostArg(cmd, pool); + ret = virCommandRun(cmd, NULL); + + virStorageBackendSheepdogRefreshVol(conn, pool, vol); + + virCommandFree(cmd); + return ret; +} + + +int +virStorageBackendSheepdogParseVdiList(virStorageVolDefPtr vol, + char *output) +{ + /* fields: + * current/clone/snapshot, name, id, size, used, shared, creation time, vdi id, [tag] + * + * example output: + * s test 1 10 0 0 1336556634 7c2b25 + * s test 2 10 0 0 1336557203 7c2b26 + * = test 3 10 0 0 1336557216 7c2b27 + */ + + int id; + const char *p, *next; + + vol->allocation = vol->capacity = 0; + + p = output; + do { + char *end; + + if ((next = strchr(p, '\n'))) + ++next; + + /* ignore snapshots */ + if (*p != '=') + continue; + + /* skip space */ + if (p + 2 < next) { + p += 2; + } else { + return -1; + } + + /* skip name */ + while (*p != '\0' && *p != ' ') { + if (*p == '\\') + ++p; + ++p; + } + + if (virStrToLong_i(p, &end, 10, &id) < 0) + return -1; + + p = end + 1; + + if (virStrToLong_ull(p, &end, 10, &vol->capacity) < 0) + return -1; + + p = end + 1; + + if (virStrToLong_ull(p, &end, 10, &vol->allocation) < 0) + return -1; + + return 0; + } while ((p = next)); + + return -1; +} + +static int +virStorageBackendSheepdogRefreshVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + virStorageVolDefPtr vol) +{ + int ret; + char *output = NULL; + + virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "list", vol->name, "-r", NULL); + virStorageBackendSheepdogAddHostArg(cmd, pool); + virCommandSetOutputBuffer(cmd, &output); + ret = virCommandRun(cmd, NULL); + + if (ret < 0) + goto cleanup; + + if ((ret = virStorageBackendSheepdogParseVdiList(vol, output)) < 0) + goto cleanup; + + vol->type = VIR_STORAGE_VOL_NETWORK; + + VIR_FREE(vol->key); + if (virAsprintf(&vol->key, "%s/%s", + pool->def->source.name, vol->name) == -1) { + virReportOOMError(); + goto cleanup; + } + + VIR_FREE(vol->target.path); + if (virAsprintf(&vol->target.path, "%s", vol->name) == -1) { + virReportOOMError(); + goto cleanup; + } + +cleanup: + virCommandFree(cmd); + return ret; +} + + +static int +virStorageBackendSheepdogResizeVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool, + virStorageVolDefPtr vol, + unsigned long long capacity, + unsigned int flags) +{ + + virCheckFlags(0, -1); + + virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "resize", vol->name, NULL); + virCommandAddArgFormat(cmd, "%llu", capacity); + virStorageBackendSheepdogAddHostArg(cmd, pool); + int ret = virCommandRun(cmd, NULL); + + virCommandFree(cmd); + return ret; + +} + + + +virStorageBackend virStorageBackendSheepdog = { + .type = VIR_STORAGE_POOL_SHEEPDOG, + + .refreshPool = virStorageBackendSheepdogRefreshPool, + .createVol = virStorageBackendSheepdogCreateVol, + .refreshVol = virStorageBackendSheepdogRefreshVol, + .deleteVol = virStorageBackendSheepdogDeleteVol, + .resizeVol = virStorageBackendSheepdogResizeVol, +}; diff --git a/src/storage/storage_backend_sheepdog.h b/src/storage/storage_backend_sheepdog.h new file mode 100644 index 0000000000000000000000000000000000000000..51ef7a4a70f2d0f46153ad983f91594b354e6846 --- /dev/null +++ b/src/storage/storage_backend_sheepdog.h @@ -0,0 +1,39 @@ +/* + * storage_backend_sheepog.h: storage backend for Sheepdog handling + * + * Copyright (C) 2012 Wido den Hollander + * Copyright (C) 2012 Frank Spijkerman + * Copyright (C) 2012 Sebastian Wiedenroth + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Wido den Hollander + * Frank Spijkerman + * Sebastian Wiedenroth + */ + +#ifndef __VIR_STORAGE_BACKEND_SHEEPDOG_H__ +# define __VIR_STORAGE_BACKEND_SHEEPDOG_H__ + +# include "storage_backend.h" + +int virStorageBackendSheepdogParseNodeInfo(virStoragePoolDefPtr pool, + char *output); +int virStorageBackendSheepdogParseVdiList(virStorageVolDefPtr vol, + char *output); + +extern virStorageBackend virStorageBackendSheepdog; + +#endif /* __VIR_STORAGE_BACKEND_SHEEPDOG_H__ */ diff --git a/tests/Makefile.am b/tests/Makefile.am index e3bd6d1528636a35bf59c5156c0f4664a120c0df..a46648047e5ec5f86ff6d2a51dd89908d77893d7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -141,6 +141,10 @@ if WITH_NETWORK test_programs += networkxml2argvtest endif +if WITH_STORAGE_SHEEPDOG +test_programs += storagebackendsheepdogtest +endif + test_programs += nwfilterxml2xmltest test_programs += storagevolxml2xmltest storagepoolxml2xmltest @@ -398,6 +402,15 @@ else EXTRA_DIST += networkxml2argvtest.c endif +if WITH_STORAGE_SHEEPDOG +storagebackendsheepdogtest_SOURCES = \ + storagebackendsheepdogtest.c \ + testutils.c testutils.h +storagebackendsheepdogtest_LDADD = ../src/libvirt_driver_storage.la $(LDADDS) +else +EXTRA_DIST += storagebackendsheepdogtest.c +endif + nwfilterxml2xmltest_SOURCES = \ nwfilterxml2xmltest.c \ testutils.c testutils.h diff --git a/tests/storagebackendsheepdogtest.c b/tests/storagebackendsheepdogtest.c new file mode 100644 index 0000000000000000000000000000000000000000..08708296ea3d5af9e4661ce434dde3df06285d7a --- /dev/null +++ b/tests/storagebackendsheepdogtest.c @@ -0,0 +1,214 @@ +/* + * storagebackendsheepdogtest.c: storage backend for Sheepdog handling + * + * Copyright (C) 2012 Sebastian Wiedenroth + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sebastian Wiedenroth + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "internal.h" +#include "testutils.h" +#include "storage/storage_backend_sheepdog.h" + + +typedef struct { + const char *output; + int expected_return; + uint64_t expected_capacity; + uint64_t expected_allocation; +} collie_test; + + +static int +test_node_info_parser(collie_test test, char *poolxml) +{ + int ret = -1; + char *output = NULL; + char *poolXmlData = NULL; + virStoragePoolDefPtr pool = NULL; + + if (virtTestLoadFile(poolxml, &poolXmlData) < 0) + goto cleanup; + + if (!(pool = virStoragePoolDefParseString(poolXmlData))) + goto cleanup; + + output = strdup(test.output); + if (!output) + goto cleanup; + + if (virStorageBackendSheepdogParseNodeInfo(pool, output) != + test.expected_return) + goto cleanup; + + if (test.expected_return) { + ret = 0; + goto cleanup; + } + + if (pool->capacity == test.expected_capacity && + pool->allocation == test.expected_allocation) + ret = 0; + + cleanup: + VIR_FREE(output); + VIR_FREE(poolXmlData); + virStoragePoolDefFree(pool); + return ret; +} + +static int +test_vdi_list_parser(collie_test test, char *poolxml, char *volxml) +{ + int ret = -1; + char *poolXmlData = NULL; + char *volXmlData = NULL; + char *output = NULL; + virStoragePoolDefPtr pool = NULL; + virStorageVolDefPtr vol = NULL; + + if (virtTestLoadFile(poolxml, &poolXmlData) < 0) + goto cleanup; + if (virtTestLoadFile(volxml, &volXmlData) < 0) + goto cleanup; + + if (!(pool = virStoragePoolDefParseString(poolXmlData))) + goto cleanup; + + if (!(vol = virStorageVolDefParseString(pool, volXmlData))) + goto cleanup; + + output = strdup(test.output); + if (!output) + goto cleanup; + + if (virStorageBackendSheepdogParseVdiList(vol, output) != + test.expected_return) + goto cleanup; + + if (test.expected_return) { + ret = 0; + goto cleanup; + } + + if (vol->capacity == test.expected_capacity && + vol->allocation == test.expected_allocation) + ret = 0; + + cleanup: + VIR_FREE(output); + VIR_FREE(poolXmlData); + VIR_FREE(volXmlData); + virStoragePoolDefFree(pool); + virStorageVolDefFree(vol); + return ret; +} + + +static int +mymain(void) +{ + int ret = -1; + char *poolxml = NULL; + char *volxml = NULL; + + collie_test node_info_tests[] = { + {"", -1, 0, 0}, + {"Total 15245667872 117571104 0% 20972341\n", 0, 15245667872, 117571104}, + {"To", -1, 0, 0}, + {"asdf\nasdf", -1, 0, 0}, + {"Total ", -1, 0, 0}, + {"Total 1", -1, 0, 0}, + {"Total 1\n", -1, 0, 0}, + {"Total 1 ", -1, 0, 0}, + {"Total 1 2", -1, 0, 0}, + {"Total 1 2 ", -1, 0, 0}, + {"Total 1 2\n", 0, 1, 2}, + {"Total 1 2 \n", 0, 1, 2}, + {"Total a 2 \n", -1, 0, 0}, + {"Total 1 b \n", -1, 0, 0}, + {"Total a b \n", -1, 0, 0}, + {"stuff\nTotal 1 2 \n", 0, 1, 2}, + {"0 1 2 3\nTotal 1 2 \n", 0, 1, 2}, + {NULL, 0, 0, 0} + }; + + collie_test vdi_list_tests[] = { + {"", -1, 0, 0}, + {"= test 3 10 20 0 1336557216 7c2b27\n", 0, 10, 20}, + {"= test\\ with\\ spaces 3 10 20 0 1336557216 7c2b27\n", 0, 10, 20}, + {"= backslashattheend\\\\ 3 10 20 0 1336557216 7c2b27\n", 0, 10, 20}, + {"s test 1 10 20 0 1336556634 7c2b25\n= test 3 50 60 0 1336557216 7c2b27\n", 0, 50, 60}, + {"=", -1, 0, 0}, + {"= test", -1, 0, 0}, + {"= test ", -1, 0, 0}, + {"= test 1", -1, 0, 0}, + {"= test 1 ", -1, 0, 0}, + {"= test 1 2", -1, 0, 0}, + {"= test 1 2 ", -1, 0, 0}, + {"= test 1 2 3", -1, 0, 0}, + {NULL, 0, 0, 0} + }; + + collie_test *test = node_info_tests; + + if (virAsprintf(&poolxml, "%s/storagepoolxml2xmlin/pool-sheepdog.xml", + abs_srcdir) < 0) + goto cleanup; + + if (virAsprintf(&volxml, "%s/storagevolxml2xmlin/vol-sheepdog.xml", + abs_srcdir) < 0) + goto cleanup; + + while (test->output != NULL) { + ret = test_node_info_parser(*test, poolxml); + virtTestResult("node_info_parser", ret, NULL); + ++test; + if (ret < 0) + return EXIT_FAILURE; + } + + test = vdi_list_tests; + + while (test->output != NULL) { + ret = test_vdi_list_parser(*test, poolxml, volxml); + virtTestResult("vdi_list_parser", ret, NULL); + ++test; + if (ret < 0) + return EXIT_FAILURE; + } + + ret = 0; + + cleanup: + VIR_FREE(poolxml); + VIR_FREE(volxml); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIRT_TEST_MAIN(mymain) diff --git a/tests/storagepoolxml2xmlin/pool-sheepdog.xml b/tests/storagepoolxml2xmlin/pool-sheepdog.xml new file mode 100644 index 0000000000000000000000000000000000000000..1287047d2b4497d2f6e58a218697bf46d4871dbc --- /dev/null +++ b/tests/storagepoolxml2xmlin/pool-sheepdog.xml @@ -0,0 +1,8 @@ + + sheepdog + 65fcba04-5b13-bd93-cff3-52ce48e11ad7 + + + sheepdog + + diff --git a/tests/storagepoolxml2xmlout/pool-sheepdog.xml b/tests/storagepoolxml2xmlout/pool-sheepdog.xml new file mode 100644 index 0000000000000000000000000000000000000000..000c06867745ae1f1206fe0847cc31d51e512aac --- /dev/null +++ b/tests/storagepoolxml2xmlout/pool-sheepdog.xml @@ -0,0 +1,11 @@ + + sheepdog + 65fcba04-5b13-bd93-cff3-52ce48e11ad7 + 0 + 0 + 0 + + + sheepdog + + diff --git a/tests/storagepoolxml2xmltest.c b/tests/storagepoolxml2xmltest.c index d73fc8ae68b400b151156c654db9bfa0743a36ff..8cac978319d0d354165e7cb3cd3754c9c8d2193d 100644 --- a/tests/storagepoolxml2xmltest.c +++ b/tests/storagepoolxml2xmltest.c @@ -93,6 +93,7 @@ mymain(void) DO_TEST("pool-mpath"); DO_TEST("pool-iscsi-multiiqn"); DO_TEST("pool-iscsi-vendor-product"); + DO_TEST("pool-sheepdog"); return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/storagevolxml2xmlin/vol-sheepdog.xml b/tests/storagevolxml2xmlin/vol-sheepdog.xml new file mode 100644 index 0000000000000000000000000000000000000000..49e221ca5547c5ce4890eaee6fd35f1ee6ffe27e --- /dev/null +++ b/tests/storagevolxml2xmlin/vol-sheepdog.xml @@ -0,0 +1,10 @@ + + test2 + + + 1024 + 0 + + sheepdog:test2 + + diff --git a/tests/storagevolxml2xmlout/vol-sheepdog.xml b/tests/storagevolxml2xmlout/vol-sheepdog.xml new file mode 100644 index 0000000000000000000000000000000000000000..2f19af8f1942fd132b08b6623a3c557e8fc4923a --- /dev/null +++ b/tests/storagevolxml2xmlout/vol-sheepdog.xml @@ -0,0 +1,17 @@ + + test2 + (null) + + + 1024 + 0 + + sheepdog:test2 + + + 0600 + 4294967295 + 4294967295 + + + diff --git a/tests/storagevolxml2xmltest.c b/tests/storagevolxml2xmltest.c index 37c92cd4ff8be99e8c1e9379f7ff13a916f915a1..ee85988195b05ba5a6aad8135f3f72f40204d887 100644 --- a/tests/storagevolxml2xmltest.c +++ b/tests/storagevolxml2xmltest.c @@ -112,6 +112,7 @@ mymain(void) DO_TEST("pool-disk", "vol-partition"); DO_TEST("pool-logical", "vol-logical"); DO_TEST("pool-logical", "vol-logical-backing"); + DO_TEST("pool-sheepdog", "vol-sheepdog"); return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/virsh.c b/tools/virsh.c index 1e00049ca87dbbc02ba5e7eeac6e22cec6d684fc..b9e159b34aa768f654ba01a00f32231140658b90 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -20873,6 +20873,9 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #endif #ifdef WITH_STORAGE_RBD vshPrint(ctl, " RBD"); +#endif +#ifdef WITH_STORAGE_SHEEPDOG + vshPrint(ctl, " Sheepdog"); #endif vshPrint(ctl, "\n");