1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Stop clvmd from automatically doing lock conversions. Now, if a lock

is granted at one mode and an attempt to convert it wthout the LCK_CONVERT
flag set then it will return errno=EBUSY.

This fixes a pretty bad bug in which an LV could be activated exclusively on
one node and lvchange -ay on another would convert it to shared!

It might break some things in other areas, but I doubt it.
This commit is contained in:
Christine Caulfield 2009-10-01 14:14:17 +00:00
parent 3d32c5f88b
commit 29846c24a8
2 changed files with 18 additions and 9 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.54 - Version 2.02.54 -
===================================== =====================================
Only do lock conversions in clvmd if we are explicitly asked for one.
Introduce percent_range_t and centralise snapshot full/mirror in-sync checks. Introduce percent_range_t and centralise snapshot full/mirror in-sync checks.
Factor out poll_mirror_progress and introduce progress_t. Factor out poll_mirror_progress and introduce progress_t.
Distinguish between powers of 1000 and powers of 1024 in unit suffixes. Distinguish between powers of 1000 and powers of 1024 in unit suffixes.

View File

@ -143,10 +143,11 @@ static const char *decode_flags(unsigned char flags)
{ {
static char buf[128]; static char buf[128];
sprintf(buf, "0x%x (%s%s%s)", flags, sprintf(buf, "0x%x (%s%s%s%s)", flags,
flags & LCK_PARTIAL_MODE ? "PARTIAL_MODE " : "", flags & LCK_PARTIAL_MODE ? "PARTIAL_MODE " : "",
flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC " : "", flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC " : "",
flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR " : ""); flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR " : "",
flags & LCK_CONVERT ? "CONVERT " : "");
return buf; return buf;
} }
@ -239,13 +240,20 @@ int hold_lock(char *resource, int mode, int flags)
int saved_errno; int saved_errno;
struct lv_info *lvi; struct lv_info *lvi;
flags &= LKF_NOQUEUE; /* Only LKF_NOQUEUE is valid here */ /* Mask off invalid options */
flags &= LKF_NOQUEUE | LKF_CONVERT;
if ((lvi = lookup_info(resource))) { lvi = lookup_info(resource);
/* Only allow explicit conversions */
if (lvi && !(flags & LKF_CONVERT)) {
errno = EBUSY;
return -1;
}
if (lvi) {
/* Already exists - convert it */ /* Already exists - convert it */
status = status =
sync_lock(resource, mode, LKF_CONVERT | flags, sync_lock(resource, mode, flags, &lvi->lock_id);
&lvi->lock_id);
saved_errno = errno; saved_errno = errno;
if (!status) if (!status)
lvi->lock_mode = mode; lvi->lock_mode = mode;
@ -337,7 +345,7 @@ static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
/* Try to get the lock if it's a clustered volume group */ /* Try to get the lock if it's a clustered volume group */
if (lock_flags & LCK_CLUSTER_VG) { if (lock_flags & LCK_CLUSTER_VG) {
status = hold_lock(resource, mode, LKF_NOQUEUE); status = hold_lock(resource, mode, LKF_NOQUEUE | (lock_flags & LCK_CONVERT?LKF_CONVERT:0));
if (status) { if (status) {
/* Return an LVM-sensible error for this. /* Return an LVM-sensible error for this.
* Forcing EIO makes the upper level return this text * Forcing EIO makes the upper level return this text
@ -538,7 +546,7 @@ int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
DEBUGLOG("pre_lock_lv: resource '%s', cmd = %s, flags = %s\n", DEBUGLOG("pre_lock_lv: resource '%s', cmd = %s, flags = %s\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags)); resource, decode_locking_cmd(command), decode_flags(lock_flags));
if (hold_lock(resource, LKM_PWMODE, LKF_NOQUEUE)) if (hold_lock(resource, LKM_PWMODE, LKF_NOQUEUE| (lock_flags & LCK_CONVERT?LKF_CONVERT:0)))
return errno; return errno;
} }
return 0; return 0;
@ -570,7 +578,7 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
return EIO; return EIO;
if (lvi.exists) { if (lvi.exists) {
if (hold_lock(resource, LKM_CRMODE, 0)) if (hold_lock(resource, LKM_CRMODE, lock_flags & LCK_CONVERT?LKF_CONVERT:0))
return errno; return errno;
} else { } else {
if (hold_unlock(resource)) if (hold_unlock(resource))