$(srcdir)/lxc/test_libvirtd_lxc.aug; \
fi
endif
+ $(AM_V_GEN)if test -x '$(AUGPARSE)'; then \
+ '$(AUGPARSE)' -I $(srcdir)/locking \
+ $(srcdir)/locking/test_libvirt_sanlock.aug; \
+ fi
#
# Build our version script. This is composed of three parts:
sanlock_la_SOURCES = $(LOCK_DRIVER_SANLOCK_SOURCES)
sanlock_la_CFLAGS = $(AM_CLFAGS)
sanlock_la_LDFLAGS = -module -avoid-version
-sanlock_la_LIBADD = -lsanlock
+sanlock_la_LIBADD = -lsanlock \
+ ../gnulib/lib/libgnu.la
+
+augeas_DATA += locking/libvirt_sanlock.aug
+augeastest_DATA += locking/test_libvirt_sanlock.aug
+
+EXTRA_DIST += locking/sanlock.conf \
+ locking/libvirt_sanlock.aug \
+ locking/test_libvirt_sanlock.aug
+
+$(builddir)/locking/%-sanlock.conf: $(srcdir)/locking/sanlock.conf
+ $(AM_V_GEN)mkdir locking ; \
+ cp $< $@
+
+if WITH_QEMU
+conf_DATA += locking/qemu-sanlock.conf
+BUILT_SOURCES += locking/qemu-sanlock.conf
+endif
else
-EXTRA_DIST += $(LOCK_DRIVER_SANLOCK_SOURCES)
+EXTRA_DIST += $(LOCK_DRIVER_SANLOCK_SOURCES) locking/sanlock.conf
endif
noinst_LTLIBRARIES += libvirt-net-rpc.la libvirt-net-rpc-server.la libvirt-net-rpc-client.la
--- /dev/null
+(* /etc/libvirt/qemu-sanlock.conf *)
+
+module Libvirt_sanlock =
+ autoload xfm
+
+ let eol = del /[ \t]*\n/ "\n"
+ let value_sep = del /[ \t]*=[ \t]*/ " = "
+ let indent = del /[ \t]*/ ""
+
+ let str_val = del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\""
+ let bool_val = store /0|1/
+ let int_val = store /[0-9]+/
+
+ let str_entry (kw:string) = [ key kw . value_sep . str_val ]
+ let bool_entry (kw:string) = [ key kw . value_sep . bool_val ]
+ let int_entry (kw:string) = [ key kw . value_sep . int_val ]
+
+
+ (* Each enty in the config is one of the following three ... *)
+ let entry = bool_entry "require_lease_for_disks"
+ let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
+ let empty = [ label "#empty" . eol ]
+
+ let record = indent . entry . eol
+
+ let lns = ( record | comment | empty ) *
+
+ let filter = incl "/etc/libvirt/qemu-sanlock.conf"
+ . Util.stdexcl
+
+ let xfm = transform lns filter
virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
__FUNCTION__, __LINE__, __VA_ARGS__)
+
+typedef struct _virLockManagerSanlockDriver virLockManagerSanlockDriver;
+typedef virLockManagerSanlockDriver *virLockManagerSanlockDriverPtr;
+
typedef struct _virLockManagerSanlockPrivate virLockManagerSanlockPrivate;
typedef virLockManagerSanlockPrivate *virLockManagerSanlockPrivatePtr;
+struct _virLockManagerSanlockDriver {
+ bool requireLeaseForDisks;
+};
+
+static virLockManagerSanlockDriver *driver = NULL;
+
struct _virLockManagerSanlockPrivate {
char vm_name[SANLK_NAME_LEN];
char vm_uuid[VIR_UUID_BUFLEN];
/*
* sanlock plugin for the libvirt virLockManager API
*/
+static int virLockManagerSanlockLoadConfig(const char *configFile)
+{
+ virConfPtr conf;
+ virConfValuePtr p;
+
+ if (access(configFile, R_OK) == -1) {
+ if (errno != ENOENT) {
+ virReportSystemError(errno,
+ _("Unable to access config file %s"),
+ configFile);
+ return -1;
+ }
+ return 0;
+ }
+
+ if (!(conf = virConfReadFile(configFile, 0)))
+ return -1;
+
+#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) { \
+ virLockError(VIR_ERR_INTERNAL_ERROR, \
+ "%s: %s: expected type " #typ, \
+ configFile, (name)); \
+ virConfFree(conf); \
+ return -1; \
+ }
+
+ p = virConfGetValue(conf, "require_lease_for_disks");
+ CHECK_TYPE("require_lease_for_disks", VIR_CONF_LONG);
+ if (p)
+ driver->requireLeaseForDisks = p->l;
+
+ virConfFree(conf);
+ return 0;
+}
-static int virLockManagerSanlockInit(unsigned int version ATTRIBUTE_UNUSED,
- const char *configFile ATTRIBUTE_UNUSED,
+
+static int virLockManagerSanlockInit(unsigned int version,
+ const char *configFile,
unsigned int flags)
{
+ VIR_DEBUG("version=%u configFile=%s flags=%u", version, NULLSTR(configFile), flags);
virCheckFlags(0, -1);
+
+ if (driver)
+ return 0;
+
+ if (VIR_ALLOC(driver) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ driver->requireLeaseForDisks = true;
+
+ if (virLockManagerSanlockLoadConfig(configFile) < 0)
+ return -1;
+
return 0;
}
static int virLockManagerSanlockDeinit(void)
{
+ if (!driver)
+ return 0;
+
virLockError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unloading sanlock plugin is forbidden"));
return -1;
}
+
static int virLockManagerSanlockNew(virLockManagerPtr lock,
unsigned int type,
size_t nparams,
virCheckFlags(0, -1);
+ if (!driver) {
+ virLockError(VIR_ERR_INTERNAL_ERROR,
+ _("Sanlock plugin is not initialized"));
+ return -1;
+ }
+
if (type != VIR_LOCK_MANAGER_OBJECT_TYPE_DOMAIN) {
virLockError(VIR_ERR_INTERNAL_ERROR,
_("Unsupported object type %d"), type);
VIR_LOCK_MANAGER_ACQUIRE_REGISTER_ONLY, -1);
if (priv->res_count == 0 &&
- priv->hasRWDisks) {
+ priv->hasRWDisks &&
+ driver->requireLeaseForDisks) {
virLockError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Read/write, exclusive access, disks were present, but no leases specified"));
return -1;