diff --git a/m4/virt-sanlock.m4 b/m4/virt-sanlock.m4 index c7c0186f86..d2a607d045 100644 --- a/m4/virt-sanlock.m4 +++ b/m4/virt-sanlock.m4 @@ -46,6 +46,13 @@ AC_DEFUN([LIBVIRT_CHECK_SANLOCK],[ [whether sanlock supports sanlock_inq_lockspace]) fi + AC_CHECK_LIB([sanlock_client], [sanlock_add_lockspace_timeout], + [sanlock_add_lockspace_timeout=yes], [sanlock_add_lockspace_timeout=no]) + if test "x$sanlock_add_lockspace_timeout" = "xyes" ; then + AC_DEFINE_UNQUOTED([HAVE_SANLOCK_ADD_LOCKSPACE_TIMEOUT], 1, + [whether Sanlock supports sanlock_add_lockspace_timeout]) + fi + CPPFLAGS="$old_cppflags" LIBS="$old_libs" fi diff --git a/src/locking/libvirt_sanlock.aug b/src/locking/libvirt_sanlock.aug index a78a4445c0..88435902d2 100644 --- a/src/locking/libvirt_sanlock.aug +++ b/src/locking/libvirt_sanlock.aug @@ -22,6 +22,7 @@ module Libvirt_sanlock = | int_entry "host_id" | bool_entry "require_lease_for_disks" | bool_entry "ignore_readonly_and_shared_disks" + | int_entry "io_timeout" | str_entry "user" | str_entry "group" let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ] diff --git a/src/locking/lock_driver_sanlock.c b/src/locking/lock_driver_sanlock.c index e052875e25..3069b82f5f 100644 --- a/src/locking/lock_driver_sanlock.c +++ b/src/locking/lock_driver_sanlock.c @@ -73,6 +73,7 @@ struct _virLockManagerSanlockDriver { int hostID; bool autoDiskLease; char *autoDiskLeasePath; + unsigned int io_timeout; /* under which permissions does sanlock run */ uid_t user; @@ -151,6 +152,10 @@ static int virLockManagerSanlockLoadConfig(const char *configFile) else driver->requireLeaseForDisks = !driver->autoDiskLease; + p = virConfGetValue(conf, "io_timeout"); + CHECK_TYPE("io_timeout", VIR_CONF_ULONG); + if (p) driver->io_timeout = p->l; + p = virConfGetValue(conf, "user"); CHECK_TYPE("user", VIR_CONF_STRING); if (p) { @@ -338,7 +343,17 @@ static int virLockManagerSanlockSetupLockspace(void) * or we can fallback to polling. */ retry: - if ((rv = sanlock_add_lockspace(&ls, 0)) < 0) { +#ifdef HAVE_SANLOCK_ADD_LOCKSPACE_TIMEOUT + rv = sanlock_add_lockspace_timeout(&ls, 0, driver->io_timeout); +#else + if (driver->io_timeout) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("unable to use io_timeout with this version of sanlock")); + goto error; + } + rv = sanlock_add_lockspace(&ls, 0); +#endif + if (rv < 0) { if (-rv == EINPROGRESS && --retries) { #ifdef HAVE_SANLOCK_INQ_LOCKSPACE /* we have this function which blocks until lockspace change the @@ -404,6 +419,7 @@ static int virLockManagerSanlockInit(unsigned int version, driver->requireLeaseForDisks = true; driver->hostID = 0; driver->autoDiskLease = false; + driver->io_timeout = 0; driver->user = (uid_t) -1; driver->group = (gid_t) -1; if (VIR_STRDUP(driver->autoDiskLeasePath, LOCALSTATEDIR "/lib/libvirt/sanlock") < 0) { diff --git a/src/locking/sanlock.conf b/src/locking/sanlock.conf index e5566efec8..3a1a51c5f9 100644 --- a/src/locking/sanlock.conf +++ b/src/locking/sanlock.conf @@ -53,6 +53,13 @@ # #require_lease_for_disks = 1 +# +# Sanlock is able to kill qemu processes on IO timeout. By its internal +# implementation, the current default is 80 seconds. If you need to adjust +# the value change the following variable. Value of zero means use the +# default sanlock timeout. +#io_timeout = 0 + # # The combination of user and group under which the sanlock # daemon runs. Libvirt will chown created files (like diff --git a/src/locking/test_libvirt_sanlock.aug.in b/src/locking/test_libvirt_sanlock.aug.in index ef98ea6374..7f66f8192b 100644 --- a/src/locking/test_libvirt_sanlock.aug.in +++ b/src/locking/test_libvirt_sanlock.aug.in @@ -6,5 +6,6 @@ module Test_libvirt_sanlock = { "disk_lease_dir" = "/var/lib/libvirt/sanlock" } { "host_id" = "1" } { "require_lease_for_disks" = "1" } +{ "io_timeout" = "0" } { "user" = "root" } { "group" = "root" }