[libvirt] [PATCH 2/3] Support loading a configuration file for sanlock plugin

Daniel P. Berrange berrange at redhat.com
Fri Jun 17 12:38:20 UTC 2011


Introduce a configuration file with a single parameter
'require_lease_for_disks', which is used to decide whether
it is allowed to start a guest which has read/write disks,
but without any leases.

* libvirt.spec.in: Add sanlock config file and augeas
  lens
* src/Makefile.am: Install sanlock config file and
  augeas lens
* src/locking/libvirt_sanlock.aug: Augeas master lens
* src/locking/test_libvirt_sanlock.aug: Augeas test file
* src/locking/sanlock.conf: Example sanlock config
* src/locking/lock_driver_sanlock.c: Wire up loading
  of configuration file
---
 libvirt.spec.in                      |    3 +
 src/Makefile.am                      |   25 ++++++++++-
 src/locking/libvirt_sanlock.aug      |   31 ++++++++++++++
 src/locking/lock_driver_sanlock.c    |   77 ++++++++++++++++++++++++++++++++-
 src/locking/sanlock.conf             |    6 +++
 src/locking/test_libvirt_sanlock.aug |    7 +++
 6 files changed, 144 insertions(+), 5 deletions(-)
 create mode 100644 src/locking/libvirt_sanlock.aug
 create mode 100644 src/locking/sanlock.conf
 create mode 100644 src/locking/test_libvirt_sanlock.aug

diff --git a/libvirt.spec.in b/libvirt.spec.in
index 97ebd65..a8d7026 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1024,7 +1024,10 @@ fi
 %if %{with_sanlock}
 %files lock-sanlock
 %defattr(-, root, root)
+%config(noreplace) %{_sysconfdir}/libvirt/qemu-sanlock.conf
 %attr(0755, root, root) %{_libdir}/libvirt/lock-driver/sanlock.so
+%{_datadir}/augeas/lenses/libvirt_sanlock.aug
+%{_datadir}/augeas/lenses/tests/test_libvirt_sanlock.aug
 %endif
 
 %files client -f %{name}.lang
diff --git a/src/Makefile.am b/src/Makefile.am
index 4f9bfc9..16e8548 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1037,6 +1037,10 @@ if WITH_LXC
 	    $(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:
@@ -1184,9 +1188,26 @@ lockdriver_LTLIBRARIES = sanlock.la
 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
 
 libexec_PROGRAMS =
diff --git a/src/locking/libvirt_sanlock.aug b/src/locking/libvirt_sanlock.aug
new file mode 100644
index 0000000..baa639a
--- /dev/null
+++ b/src/locking/libvirt_sanlock.aug
@@ -0,0 +1,31 @@
+(* /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
diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c
index 3eab23e..7ad54e8 100644
--- a/src/locking/lock_driver_sanlock.c
+++ b/src/locking/lock_driver_sanlock.c
@@ -45,9 +45,19 @@
     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];
@@ -62,22 +72,76 @@ struct _virLockManagerSanlockPrivate {
 /*
  * 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,
@@ -90,6 +154,12 @@ static int virLockManagerSanlockNew(virLockManagerPtr lock,
 
     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);
@@ -245,7 +315,8 @@ static int virLockManagerSanlockAcquire(virLockManagerPtr lock,
                   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;
diff --git a/src/locking/sanlock.conf b/src/locking/sanlock.conf
new file mode 100644
index 0000000..818b529
--- /dev/null
+++ b/src/locking/sanlock.conf
@@ -0,0 +1,6 @@
+#
+# Flag to determine whether we allow starting of guests
+# which do not have any <lease> elements defined in their
+# configuration.
+#
+#require_lease_for_disks = 1
diff --git a/src/locking/test_libvirt_sanlock.aug b/src/locking/test_libvirt_sanlock.aug
new file mode 100644
index 0000000..2f1f57a
--- /dev/null
+++ b/src/locking/test_libvirt_sanlock.aug
@@ -0,0 +1,7 @@
+module Test_libvirt_sanlock =
+
+   let conf = "require_lease_for_disks = 1
+"
+
+   test Libvirt_sanlock.lns get conf =
+{ "require_lease_for_disks" = "1" }
-- 
1.7.4.4




More information about the libvir-list mailing list