Signed-off-by: Olga Krishtal <okrishtal@xxxxxxxxxxxxx> --- 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@xxxxxxxxxxxxx> + * + * 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@xxxxxxxxxxxxx> + * + * 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list