diff options
-rw-r--r-- | WHATS_NEW | 1 | ||||
-rw-r--r-- | doc/example.conf | 7 | ||||
-rw-r--r-- | lib/config/defaults.h | 1 | ||||
-rw-r--r-- | lib/locking/file_locking.c | 37 |
4 files changed, 45 insertions, 1 deletions
@@ -1,5 +1,6 @@ Version 2.02.52 - ================================= + Implement write lock prioritisation for file locking and make it default. Fix clogd build direcory. Drop unrequired clogd Makefile. Fix clvmd autodetection check and cleanup related configure messages. diff --git a/doc/example.conf b/doc/example.conf index 5bb20722..eaf922ba 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -288,6 +288,13 @@ global { # in progress. A directory like /tmp that may get wiped on reboot is OK. locking_dir = "/var/lock/lvm" + # Whenever a read-only and read-write access compete on a single volume + # group, ensure that the write lock gets priority over the read lock. + # Without this setting, write access may be stalled by high volume of + # read-only traffic on LVM metadata. NB. This option only affects + # locking_type = 1, i.e. local file-based locking. + prioritise_write_locks = 1 + # Other entries can go here to allow you to load shared libraries # e.g. if support for LVM1 metadata was compiled as a shared library use # format_libraries = "liblvm2format1.so" diff --git a/lib/config/defaults.h b/lib/config/defaults.h index 68dceb10..d483492b 100644 --- a/lib/config/defaults.h +++ b/lib/config/defaults.h @@ -42,6 +42,7 @@ #define DEFAULT_FALLBACK_TO_LOCAL_LOCKING 1 #define DEFAULT_FALLBACK_TO_CLUSTERED_LOCKING 1 #define DEFAULT_WAIT_FOR_LOCKS 1 +#define DEFAULT_PRIORITISE_WRITE_LOCKS 1 #define DEFAULT_MIRRORLOG "disk" #define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate" diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index 0e1e8124..0ee8bbf8 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -38,6 +38,7 @@ struct lock_list { static struct dm_list _lock_list; static char _lock_dir[NAME_LEN]; +static int _prioritise_write_locks; static sig_t _oldhandler; static sigset_t _fullsigset, _intsigset; @@ -47,6 +48,7 @@ static void _undo_flock(const char *file, int fd) { struct stat buf1, buf2; + log_debug("_undo_flock %s", file); if (!flock(fd, LOCK_NB | LOCK_EX) && !stat(file, &buf1) && !fstat(fd, &buf2) && @@ -135,6 +137,8 @@ static int _do_flock(const char *file, int *fd, int operation, uint32_t nonblock int old_errno; struct stat buf1, buf2; + log_debug("_do_flock %s %c%c", + file, operation == LOCK_EX ? 'W' : 'R', nonblock ? ' ' : 'B'); do { if ((*fd > -1) && close(*fd)) log_sys_error("close", file); @@ -169,6 +173,29 @@ static int _do_flock(const char *file, int *fd, int operation, uint32_t nonblock return_0; } +#define AUX_LOCK_SUFFIX ":aux" + +static int _do_write_priority_flock(const char *file, int *fd, int operation, uint32_t nonblock) +{ + int r, fd_aux = -1; + char *file_aux = alloca(strlen(file) + sizeof(AUX_LOCK_SUFFIX)); + + strcpy(file_aux, file); + strcat(file_aux, AUX_LOCK_SUFFIX); + + if ((r = _do_flock(file_aux, &fd_aux, LOCK_EX, 0))) { + if (operation == LOCK_EX) { + r = _do_flock(file, fd, operation, nonblock); + _undo_flock(file_aux, fd_aux); + } else { + _undo_flock(file_aux, fd_aux); + r = _do_flock(file, fd, operation, nonblock); + } + } + + return r; +} + static int _lock_file(const char *file, uint32_t flags) { int operation; @@ -207,7 +234,11 @@ static int _lock_file(const char *file, uint32_t flags) log_very_verbose("Locking %s %c%c", ll->res, state, nonblock ? ' ' : 'B'); - r = _do_flock(file, &ll->lf, operation, nonblock); + if (_prioritise_write_locks) + r = _do_write_priority_flock(file, &ll->lf, operation, nonblock); + else + r = _do_flock(file, &ll->lf, operation, nonblock); + if (r) dm_list_add(&_lock_list, &ll->list); else { @@ -299,6 +330,10 @@ int init_file_locking(struct locking_type *locking, struct cmd_context *cmd) DEFAULT_LOCK_DIR), sizeof(_lock_dir)); + _prioritise_write_locks = + find_config_tree_bool(cmd, "global/prioritise_write_locks", + DEFAULT_PRIORITISE_WRITE_LOCKS); + if (!dm_create_dir(_lock_dir)) return 0; |