mirror of https://gitee.com/openkylin/libvirt.git
Support loading a configuration file for sanlock plugin
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
This commit is contained in:
parent
5df29ebc25
commit
58eb4f2cbb
|
@ -1031,7 +1031,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
|
||||
|
|
|
@ -1035,6 +1035,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:
|
||||
|
@ -1189,9 +1193,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
|
||||
|
||||
noinst_LTLIBRARIES += libvirt-net-rpc.la libvirt-net-rpc-server.la libvirt-net-rpc-client.la
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
||||
static int virLockManagerSanlockInit(unsigned int version ATTRIBUTE_UNUSED,
|
||||
const char *configFile ATTRIBUTE_UNUSED,
|
||||
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,
|
||||
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);
|
||||
|
@ -246,7 +316,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;
|
||||
|
|
|
@ -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
|
|
@ -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" }
|
Loading…
Reference in New Issue