Signed-off-by: Olga Krishtal <okrishtal(a)virtuozzo.com>
---
daemon/Makefile.am | 4 +
daemon/libvirtd.c | 9 +
po/POTFILES.in | 1 +
src/Makefile.am | 33 ++-
src/fs/fs_backend.h | 94 +++++++
src/fs/fs_driver.c | 729 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/fs/fs_driver.h | 10 +
7 files changed, 879 insertions(+), 1 deletion(-)
create mode 100644 src/fs/fs_backend.h
create mode 100644 src/fs/fs_driver.c
create mode 100644 src/fs/fs_driver.h
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 927d16f..5e95106 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -260,6 +260,10 @@ endif WITH_SECRETS
if WITH_NWFILTER
libvirtd_LDADD += ../src/libvirt_driver_nwfilter.la
endif WITH_NWFILTER
+
+if WITH_FS
+ libvirtd_LDADD += ../src/libvirt_driver_fs.la
+endif WITH_FS
endif ! WITH_DRIVER_MODULES
libvirtd_LDADD += ../src/libvirt.la
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index cd25b50..e978075 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -92,6 +92,9 @@
# ifdef WITH_STORAGE
# include "storage/storage_driver.h"
# endif
+# ifdef WITH_FS
+# include "fs/fs_driver.h"
+# endif
# ifdef WITH_NODE_DEVICES
# include "node_device/node_device_driver.h"
# endif
@@ -374,6 +377,9 @@ static void daemonInitialize(void)
# ifdef WITH_NWFILTER
virDriverLoadModule("nwfilter");
# endif
+# ifdef WITH_FS
+ virDriverLoadModule("fs");
+# endif
# ifdef WITH_XEN
virDriverLoadModule("xen");
# endif
@@ -408,6 +414,9 @@ static void daemonInitialize(void)
# ifdef WITH_STORAGE
storageRegister();
# endif
+# ifdef WITH_FS
+ fsRegister();
+# endif
# ifdef WITH_NODE_DEVICES
nodedevRegister();
# endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 2d4c191..942e099 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -60,6 +60,7 @@ src/esx/esx_vi.c
src/esx/esx_vi_methods.c
src/esx/esx_vi_types.c
src/fdstream.c
+src/fs/fs_driver.c
src/hyperv/hyperv_driver.c
src/hyperv/hyperv_util.c
src/hyperv/hyperv_wmi.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 07e55ec..d18d3f4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -651,7 +651,8 @@ DRIVER_SOURCE_FILES = \
$(VMWARE_DRIVER_SOURCES) \
$(XEN_DRIVER_SOURCES) \
$(XENAPI_DRIVER_SOURCES) \
- $(NULL)
+ $(FS_DRIVER_SOURCES)\
+ $(NULL)
STATEFUL_DRIVER_SOURCE_FILES = \
$(BHYVE_DRIVER_SOURCES) \
@@ -667,6 +668,7 @@ STATEFUL_DRIVER_SOURCE_FILES = \
$(UML_DRIVER_SOURCES) \
$(XEN_DRIVER_SOURCES) \
$(VZ_DRIVER_SOURCES) \
+ $(FS_DRIVER_SOURCES)\
$(NULL)
@@ -1113,6 +1115,10 @@ XENCONFIG_SOURCES += \
xenconfig/xen_xl.c xenconfig/xen_xl.h
endif WITH_LIBXL
+FS_DRIVER_SOURCES = \
+ fs/fs_driver.h fs/fs_driver.c \
+ fs/fs_backend.h
+
pkgdata_DATA = cpu/cpu_map.xml
EXTRA_DIST += $(pkgdata_DATA)
@@ -1637,6 +1643,30 @@ endif WITH_DRIVER_MODULES
libvirt_driver_secret_la_SOURCES = $(SECRET_DRIVER_SOURCES)
endif WITH_SECRETS
+libvirt_driver_fs_impl_la_SOURCES =
+libvirt_driver_fs_impl_la_CFLAGS = \
+ -I$(srcdir)/access \
+ -I$(srcdir)/conf \
+ $(AM_CFLAGS)
+libvirt_driver_fs_impl_la_LDFLAGS = $(AM_LDFLAGS)
+libvirt_driver_fs_impl_la_LIBADD =
+libvirt_driver_fs_impl_la_LIBADD += $(SECDRIVER_LIBS) $(LIBXML_LIBS)
+if WITH_FS
+noinst_LTLIBRARIES += libvirt_driver_fs_impl.la
+libvirt_driver_fs_la_SOURCES =
+libvirt_driver_fs_la_LIBADD = libvirt_driver_fs_impl.la
+if WITH_DRIVER_MODULES
+mod_LTLIBRARIES += libvirt_driver_fs.la
+libvirt_driver_fs_la_LIBADD += ../gnulib/lib/libgnu.la
+libvirt_driver_fs_la_LDFLAGS = -module -avoid-version $(AM_LDFLAGS)
+else ! WITH_DRIVER_MODULES
+noinst_LTLIBRARIES += libvirt_driver_fs.la
+# Stateful, so linked to daemon instead
+#libvirt_la_BUILT_LIBADD += libvirt_driver_fs.la
+endif ! WITH_DRIVER_MODULES
+libvirt_driver_fs_impl_la_SOURCES += $(FS_DRIVER_SOURCES)
+endif WITH_FS
+
# Needed to keep automake quiet about conditionals
libvirt_driver_storage_impl_la_SOURCES =
libvirt_driver_storage_impl_la_CFLAGS = \
@@ -1908,6 +1938,7 @@ EXTRA_DIST += \
$(BHYVE_DRIVER_SOURCES) \
$(NETWORK_DRIVER_SOURCES) \
$(INTERFACE_DRIVER_SOURCES) \
+ $(FS_DRIVER_SOURCES) \
$(STORAGE_DRIVER_SOURCES) \
$(STORAGE_DRIVER_FS_SOURCES) \
$(STORAGE_DRIVER_LVM_SOURCES) \
diff --git a/src/fs/fs_backend.h b/src/fs/fs_backend.h
new file mode 100644
index 0000000..67ea30c
--- /dev/null
+++ b/src/fs/fs_backend.h
@@ -0,0 +1,94 @@
+/*
+ * fs_backend.h: file system backend implementation
+ * Author: Olga Krishtal <okrishtal(a)virtuozzo.com>
+ *
+ * Copyright (C) 2016 Parallels IP Holdings GmbH
+ *
+ * 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, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef __VIR_FS_BACKEND_H__
+# define __VIR_FS_BACKEND_H__
+
+# include <sys/stat.h>
+
+# include "internal.h"
+# include "fs_conf.h"
+# include "fs_driver.h"
+
+typedef char * (*virFSBackendFindFSpoolSources)(virConnectPtr conn,
+ const char *srcSpec,
+ unsigned int flags);
+typedef int (*virFSBackendCheckFSpool)(virFSPoolObjPtr fspool,
+ bool *active);
+typedef int (*virFSBackendStartFSpool)(virConnectPtr conn,
+ virFSPoolObjPtr fspool);
+typedef int (*virFSBackendBuildFSpool)(virConnectPtr conn,
+ virFSPoolObjPtr fspool,
+ unsigned int flags);
+typedef int (*virFSBackendRefreshFSpool)(virConnectPtr conn,
+ virFSPoolObjPtr fspool);
+typedef int (*virFSBackendStopFSpool)(virConnectPtr conn,
+ virFSPoolObjPtr fspool);
+typedef int (*virFSBackendDeleteFSpool)(virConnectPtr conn,
+ virFSPoolObjPtr fspool,
+ unsigned int flags);
+typedef int (*virFSBackendBuildItem)(virConnectPtr conn,
+ virFSPoolObjPtr fspool,
+ virFSItemDefPtr item,
+ unsigned int flags);
+typedef int (*virFSBackendCreateItem)(virConnectPtr conn,
+ virFSPoolObjPtr fspool,
+ virFSItemDefPtr item);
+typedef int (*virFSBackendRefreshItem)(virConnectPtr conn,
+ virFSPoolObjPtr fspool,
+ virFSItemDefPtr item);
+typedef int (*virFSBackendDeleteItem)(virConnectPtr conn,
+ virFSPoolObjPtr fspool,
+ virFSItemDefPtr item,
+ unsigned int flags);
+typedef int (*virFSBackendBuildItemFrom)(virConnectPtr conn,
+ virFSPoolObjPtr fspool,
+ virFSItemDefPtr origitem,
+ virFSItemDefPtr newitem,
+ unsigned int flags);
+
+typedef struct _virFSBackend virFSBackend;
+typedef virFSBackend *virFSBackendPtr;
+
+/* Callbacks are optional unless documented otherwise; but adding more
+ * callbacks provides better fspool support. */
+struct _virFSBackend {
+ int type;
+
+ virFSBackendBuildFSpool buildFSpool;
+ virFSBackendCheckFSpool checkFSpool;
+ virFSBackendStartFSpool startFSpool;
+ virFSBackendRefreshFSpool refreshFSpool; /* Must be non-NULL */
+ virFSBackendStopFSpool stopFSpool;
+ virFSBackendDeleteFSpool deleteFSpool;
+
+ virFSBackendBuildItem buildItem;
+ virFSBackendBuildItemFrom buildItemFrom;
+ virFSBackendCreateItem createItem;
+ virFSBackendRefreshItem refreshItem;
+ virFSBackendDeleteItem deleteItem;
+};
+
+# define VIR_FS_DEFAULT_POOL_PERM_MODE 0755
+# define VIR_FS_DEFAULT_ITEM_PERM_MODE 0600
+
+#endif /* __VIR_FS_BACKEND_H__ */
diff --git a/src/fs/fs_driver.c b/src/fs/fs_driver.c
new file mode 100644
index 0000000..98d91fa
--- /dev/null
+++ b/src/fs/fs_driver.c
@@ -0,0 +1,729 @@
+/*
+ * fs_driver.c: file system driver implementation
+ * Author: Olga Krishtal <okrishtal(a)virtuozzo.com>
+ *
+ * Copyright (C) 2016 Parallels IP Holdings GmbH
+ *
+ * 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, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <fcntl.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include "virerror.h"
+#include "datatypes.h"
+#include "driver.h"
+#include "fs_driver.h"
+#include "fs_conf.h"
+#include "fs_backend.h"
+#include "viralloc.h"
+#include "virlog.h"
+#include "virfile.h"
+#include "virstoragefile.h"
+#include "virpoolcommon.h"
+#include "fdstream.h"
+#include "configmake.h"
+#include "virstring.h"
+#include "viraccessapicheck.h"
+#include "dirname.h"
+
+#define VIR_FROM_THIS VIR_FROM_FSPOOL
+VIR_LOG_INIT("fs.fs_driver");
+
+static virFSDriverStatePtr driver;
+
+static int fsStateCleanup(void);
+
+static void fsDriverLock(void)
+{
+ virMutexLock(&driver->lock);
+}
+
+static void fsDriverUnlock(void)
+{
+ virMutexUnlock(&driver->lock);
+}
+
+static virFSBackendPtr backends[] = {};
+
+static virFSBackendPtr
+virFSBackendForType(int type)
+{
+ size_t i;
+ for (i = 0; backends[i]; i++)
+ if (backends[i]->type == type)
+ return backends[i];
+
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("missing backend for fspool type %d (%s)"),
+ type, NULLSTR(virFSPoolTypeToString(type)));
+ return NULL;
+}
+
+/* General fspool/item implementation */
+static int
+fsConnectListAllFSPools(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virFSPoolPtr **fspools ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, -1);
+
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static virFSPoolPtr
+fsPoolLookupByName(virConnectPtr conn ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static virFSPoolPtr
+fsPoolLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSED,
+ const unsigned char *uuid ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static virFSPoolPtr
+fsPoolLookupByItem(virFSItemPtr item ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static virFSPoolPtr
+fsPoolCreateXML(virConnectPtr conn ATTRIBUTE_UNUSED,
+ const char *xml ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, NULL);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static virFSPoolPtr
+fsPoolDefineXML(virConnectPtr conn ATTRIBUTE_UNUSED,
+ const char *xml ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, NULL);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static int
+fsPoolCreate(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, -1);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolBuild(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, -1);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolUndefine(virFSPoolPtr obj ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolDestroy(virFSPoolPtr obj ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolDelete(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, -1);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolRefresh(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, -1);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolGetInfo(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ virFSPoolInfoPtr info ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static char *
+fsPoolGetXMLDesc(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, NULL);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static int
+fsPoolGetAutostart(virFSPoolPtr obj ATTRIBUTE_UNUSED, int *autostart ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolSetAutostart(virFSPoolPtr obj ATTRIBUTE_UNUSED, int autostart ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolNumOfItems(virFSPoolPtr obj ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolListItems(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ char **const names ATTRIBUTE_UNUSED,
+ int maxnames ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolListAllItems(virFSPoolPtr fspool ATTRIBUTE_UNUSED,
+ virFSItemPtr **items ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, -1);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static virFSItemPtr
+fsItemLookupByName(virFSPoolPtr obj ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static virFSItemPtr
+fsItemLookupByKey(virConnectPtr conn ATTRIBUTE_UNUSED, const char *key ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static virFSItemPtr
+fsItemLookupByPath(virConnectPtr conn ATTRIBUTE_UNUSED,
+ const char *path ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static virFSItemPtr
+fsItemCreateXML(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ const char *xmldesc ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, NULL);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static virFSItemPtr
+fsItemCreateXMLFrom(virFSPoolPtr obj ATTRIBUTE_UNUSED,
+ const char *xmldesc ATTRIBUTE_UNUSED,
+ virFSItemPtr vobj ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, NULL);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static int
+fsItemGetInfo(virFSItemPtr obj ATTRIBUTE_UNUSED,
+ virFSItemInfoPtr info ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static char *
+fsItemGetXMLDesc(virFSItemPtr obj ATTRIBUTE_UNUSED, unsigned int flags)
+{
+ virCheckFlags(0, NULL);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static char *
+fsItemGetPath(virFSItemPtr obj ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return NULL;
+}
+
+static int
+fsPoolIsActive(virFSPoolPtr fspool ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsPoolIsPersistent(virFSPoolPtr fspool ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static int
+fsItemDelete(virFSItemPtr obj ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ virCheckFlags(0, -1);
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("the operation is not yet supported"));
+
+ return -1;
+}
+
+static virFSDriver fsDriver = {
+ .name = "fs",
+ .connectListAllFSPools = fsConnectListAllFSPools, /* 2.3.0 */
+ .fsPoolLookupByName = fsPoolLookupByName, /* 2.3.0 */
+ .fsPoolLookupByUUID = fsPoolLookupByUUID, /* 2.3.0 */
+ .fsPoolLookupByItem = fsPoolLookupByItem, /* 2.3.0 */
+ .fsPoolCreateXML = fsPoolCreateXML, /* 2.3.0 */
+ .fsPoolDefineXML = fsPoolDefineXML, /* 2.3.0 */
+ .fsPoolBuild = fsPoolBuild, /* 2.3.0 */
+ .fsPoolCreate = fsPoolCreate, /* 2.3.0 */
+ .fsPoolUndefine = fsPoolUndefine, /* 2.3.0 */
+ .fsPoolDestroy = fsPoolDestroy, /* 2.3.0 */
+ .fsPoolDelete = fsPoolDelete, /* 2.3.0 */
+ .fsPoolRefresh = fsPoolRefresh, /* 2.3.0 */
+ .fsPoolGetInfo = fsPoolGetInfo, /* 2.3.0 */
+ .fsPoolGetXMLDesc = fsPoolGetXMLDesc, /* 2.3.0 */
+ .fsPoolGetAutostart = fsPoolGetAutostart, /* 2.3.0 */
+ .fsPoolSetAutostart = fsPoolSetAutostart, /* 2.3.0 */
+ .fsPoolNumOfItems = fsPoolNumOfItems, /* 2.3.0 */
+ .fsPoolListItems = fsPoolListItems, /* 2.3.0 */
+ .fsPoolListAllItems = fsPoolListAllItems, /* 2.3.0 */
+ .fsItemLookupByName = fsItemLookupByName, /* 2.3.0 */
+ .fsItemLookupByKey = fsItemLookupByKey, /* 2.3.0 */
+ .fsItemLookupByPath = fsItemLookupByPath, /* 2.3.0 */
+ .fsItemCreateXML = fsItemCreateXML, /* 2.3.0 */
+ .fsItemCreateXMLFrom = fsItemCreateXMLFrom, /* 2.3.0 */
+ .fsItemDelete = fsItemDelete, /* 2.3.0 */
+ .fsItemGetInfo = fsItemGetInfo, /* 2.3.0 */
+ .fsItemGetXMLDesc = fsItemGetXMLDesc, /* 2.3.0 */
+ .fsItemGetPath = fsItemGetPath, /* 2.3.0 */
+ .fsPoolIsActive = fsPoolIsActive, /* 2.3.0 */
+ .fsPoolIsPersistent = fsPoolIsPersistent, /* 2.3.0 */
+};
+
+
+static void
+fsPoolUpdateState(virFSPoolObjPtr fspool)
+{
+ bool active;
+ virFSBackendPtr backend;
+ int ret = -1;
+ char *stateFile;
+
+ if (!(stateFile = virFileBuildPath(driver->stateDir,
+ fspool->def->name, ".xml")))
+ goto error;
+
+ if ((backend = virFSBackendForType(fspool->def->type)) == NULL) {
+ VIR_ERROR(_("Missing backend %d"), fspool->def->type);
+ goto error;
+ }
+
+ /* Backends which do not support 'checkFSpool' are considered
+ * inactive by default.
+ */
+ active = false;
+ if (backend->checkFSpool &&
+ backend->checkFSpool(fspool, &active) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to initialize fspool '%s': %s"),
+ fspool->def->name, err ? err->message :
+ _("no error message found"));
+ goto error;
+ }
+
+ /* We can pass NULL as connection, most backends do not use
+ * it anyway, but if they do and fail, we want to log error and
+ * continue with other fspools.
+ */
+ if (active) {
+ virFSPoolObjClearItems(fspool);
+ if (backend->refreshFSpool(NULL, fspool) < 0) {
+ virErrorPtr err = virGetLastError();
+ if (backend->stopFSpool)
+ backend->stopFSpool(NULL, fspool);
+ VIR_ERROR(_("Failed to restart fspool '%s': %s"),
+ fspool->def->name, err ? err->message :
+ _("no error message found"));
+ goto error;
+ }
+ }
+
+ fspool->active = active;
+ ret = 0;
+ error:
+ if (ret < 0) {
+ if (stateFile)
+ unlink(stateFile);
+ }
+ VIR_FREE(stateFile);
+
+ return;
+}
+
+static void
+fsPoolUpdateAllState(void)
+{
+ size_t i;
+
+ for (i = 0; i < driver->fspools.count; i++) {
+ virFSPoolObjPtr fspool = driver->fspools.objs[i];
+
+ virFSPoolObjLock(fspool);
+ fsPoolUpdateState(fspool);
+ virFSPoolObjUnlock(fspool);
+ }
+}
+
+static void
+fsDriverAutostart(void)
+{
+ size_t i;
+ virConnectPtr conn = NULL;
+
+ /* XXX Remove hardcoding of QEMU URI */
+ if (driver->privileged)
+ conn = virConnectOpen("qemu:///system");
+ else
+ conn = virConnectOpen("qemu:///session");
+ /* Ignoring NULL conn - let backends decide */
+
+ for (i = 0; i < driver->fspools.count; i++) {
+ virFSPoolObjPtr fspool = driver->fspools.objs[i];
+ virFSBackendPtr backend;
+ bool started = false;
+
+ virFSPoolObjLock(fspool);
+ if ((backend = virFSBackendForType(fspool->def->type)) == NULL) {
+ virFSPoolObjUnlock(fspool);
+ continue;
+ }
+
+ if (fspool->autostart &&
+ !virFSPoolObjIsActive(fspool)) {
+ if (backend->startFSpool &&
+ backend->startFSpool(conn, fspool) < 0) {
+ virErrorPtr err = virGetLastError();
+ VIR_ERROR(_("Failed to autostart fspool '%s': %s"),
+ fspool->def->name, err ? err->message :
+ _("no error message found"));
+ virFSPoolObjUnlock(fspool);
+ continue;
+ }
+ started = true;
+ }
+
+ if (started) {
+ char *stateFile;
+
+ virFSPoolObjClearItems(fspool);
+ stateFile = virFileBuildPath(driver->stateDir,
+ fspool->def->name, ".xml");
+ if (!stateFile ||
+ virFSPoolSaveState(stateFile, fspool->def) < 0 ||
+ backend->refreshFSpool(conn, fspool) < 0) {
+ virErrorPtr err = virGetLastError();
+ if (stateFile)
+ unlink(stateFile);
+ if (backend->stopFSpool)
+ backend->stopFSpool(conn, fspool);
+ VIR_ERROR(_("Failed to autostart fspool '%s': %s"),
+ fspool->def->name, err ? err->message :
+ _("no error message found"));
+ } else {
+ fspool->active = true;
+ }
+ VIR_FREE(stateFile);
+ }
+ virFSPoolObjUnlock(fspool);
+ }
+
+ virObjectUnref(conn);
+}
+
+/**
+ * virFSStartup:
+ *
+ * Initialization function for the FS Driver
+ */
+static int
+fsStateInitialize(bool privileged,
+ virStateInhibitCallback callback ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ int ret = -1;
+ char *configdir = NULL;
+ char *rundir = NULL;
+
+ if (VIR_ALLOC(driver) < 0)
+ return ret;
+
+ if (virMutexInit(&driver->lock) < 0) {
+ VIR_FREE(driver);
+ return ret;
+ }
+ fsDriverLock();
+
+ if (privileged) {
+ if (VIR_STRDUP(driver->configDir,
+ SYSCONFDIR "/libvirt/fs") < 0 ||
+ VIR_STRDUP(driver->autostartDir,
+ SYSCONFDIR "/libvirt/fs/autostart") < 0 ||
+ VIR_STRDUP(driver->stateDir,
+ LOCALSTATEDIR "/run/libvirt/fs") < 0)
+ goto error;
+ } else {
+ configdir = virGetUserConfigDirectory();
+ rundir = virGetUserRuntimeDirectory();
+ if (!(configdir && rundir))
+ goto error;
+
+ if ((virAsprintf(&driver->configDir,
+ "%s/fs", configdir) < 0) ||
+ (virAsprintf(&driver->autostartDir,
+ "%s/fs/autostart", configdir) < 0) ||
+ (virAsprintf(&driver->stateDir,
+ "%s/fs/run", rundir) < 0))
+ goto error;
+ }
+ driver->privileged = privileged;
+
+ if (virFileMakePath(driver->stateDir) < 0) {
+ virReportError(errno,
+ _("cannot create directory %s"),
+ driver->stateDir);
+ goto error;
+ }
+
+ if (virFSPoolLoadAllState(&driver->fspools,
+ driver->stateDir) < 0)
+ goto error;
+
+ if (virFSPoolLoadAllConfigs(&driver->fspools,
+ driver->configDir,
+ driver->autostartDir) < 0)
+ goto error;
+
+ fsPoolUpdateAllState();
+ fsDriverUnlock();
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(configdir);
+ VIR_FREE(rundir);
+ return ret;
+
+ error:
+ fsDriverUnlock();
+ fsStateCleanup();
+ goto cleanup;
+}
+
+/**
+ * fsStateAutoStart:
+ *
+ * Function to auto start the fs_driver
+ * At the moment it doing nothing
+ */
+static void
+fsStateAutoStart(void)
+{
+ if (!driver)
+ return;
+
+ fsDriverLock();
+ fsDriverAutostart();
+ fsDriverUnlock();
+}
+
+/**
+ * fsStateReload:
+ *
+ * Function to restart the fs_driver, it will recheck the configuration
+ * files and update its state
+ */
+static int
+fsStateReload(void)
+{
+ if (!driver)
+ return -1;
+
+ fsDriverLock();
+ virFSPoolLoadAllState(&driver->fspools,
+ driver->stateDir);
+ virFSPoolLoadAllConfigs(&driver->fspools,
+ driver->configDir,
+ driver->autostartDir);
+ fsDriverAutostart();
+ fsDriverUnlock();
+
+ return 0;
+}
+
+/**
+ * fsStateCleanup
+ *
+ * Shutdown the fs driver, it will stop all active fspools
+ */
+static int
+fsStateCleanup(void)
+{
+ if (!driver)
+ return -1;
+
+ fsDriverLock();
+
+ /* free inactive fspools */
+ virFSPoolObjListFree(&driver->fspools);
+
+ VIR_FREE(driver->configDir);
+ VIR_FREE(driver->autostartDir);
+ VIR_FREE(driver->stateDir);
+ fsDriverUnlock();
+ virMutexDestroy(&driver->lock);
+ VIR_FREE(driver);
+
+ return 0;
+}
+
+static virStateDriver stateDriver = {
+ .name = "fs",
+ .stateInitialize = fsStateInitialize,
+ .stateAutoStart = fsStateAutoStart,
+ .stateCleanup = fsStateCleanup,
+ .stateReload = fsStateReload,
+};
+
+int fsRegister(void)
+{
+ if (virSetSharedFSDriver(&fsDriver) < 0)
+ return -1;
+ if (virRegisterStateDriver(&stateDriver) < 0)
+ return -1;
+ return 0;
+}
diff --git a/src/fs/fs_driver.h b/src/fs/fs_driver.h
new file mode 100644
index 0000000..aaf0258
--- /dev/null
+++ b/src/fs/fs_driver.h
@@ -0,0 +1,10 @@
+#ifndef __VIR_FS_DRIVER_H__
+# define __VIR_FS_DRIVER_H__
+
+# include <sys/stat.h>
+
+# include "domain_conf.h"
+# include "fs_conf.h"
+
+int fsRegister(void);
+#endif /* __VIR_FS_DRIVER_H__ */
--
1.8.3.1