mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
clvmd: fix test mode race
When TEST_MODE flag is passed around the cluster, it's been use in thread unprotected way, so it may have influenced behaviour of other running parallel lvm commands (activation/deactivation/suspend/resume). Fix it by set/query function only under lvm mutex. For hold_un/lock function calls check lock_flags bits directly.
This commit is contained in:
parent
bd3e44643d
commit
91f4e09b48
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.107 -
|
Version 2.02.107 -
|
||||||
==================================
|
==================================
|
||||||
|
Fix usage of --test option in clvmd.
|
||||||
Skip more libraries to be mlocked in memory.
|
Skip more libraries to be mlocked in memory.
|
||||||
Remove LOCKED flag for pvmove replaced with error target.
|
Remove LOCKED flag for pvmove replaced with error target.
|
||||||
Return invalid command when specifying negative polling interval.
|
Return invalid command when specifying negative polling interval.
|
||||||
|
@ -78,9 +78,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
|||||||
unsigned char lock_cmd;
|
unsigned char lock_cmd;
|
||||||
unsigned char lock_flags;
|
unsigned char lock_flags;
|
||||||
|
|
||||||
/* Reset test mode before we start */
|
|
||||||
init_test(0);
|
|
||||||
|
|
||||||
/* Do the command */
|
/* Do the command */
|
||||||
switch (msg->cmd) {
|
switch (msg->cmd) {
|
||||||
/* Just a test message */
|
/* Just a test message */
|
||||||
@ -112,8 +109,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
|||||||
lockname = &args[2];
|
lockname = &args[2];
|
||||||
/* Check to see if the VG is in use by LVM1 */
|
/* Check to see if the VG is in use by LVM1 */
|
||||||
status = do_check_lvm1(lockname);
|
status = do_check_lvm1(lockname);
|
||||||
if (lock_flags & LCK_TEST_MODE)
|
|
||||||
init_test(1);
|
|
||||||
do_lock_vg(lock_cmd, lock_flags, lockname);
|
do_lock_vg(lock_cmd, lock_flags, lockname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -122,8 +117,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
|
|||||||
lock_cmd = args[0];
|
lock_cmd = args[0];
|
||||||
lock_flags = args[1];
|
lock_flags = args[1];
|
||||||
lockname = &args[2];
|
lockname = &args[2];
|
||||||
if (lock_flags & LCK_TEST_MODE)
|
|
||||||
init_test(1);
|
|
||||||
status = do_lock_lv(lock_cmd, lock_flags, lockname);
|
status = do_lock_lv(lock_cmd, lock_flags, lockname);
|
||||||
/* Replace EIO with something less scary */
|
/* Replace EIO with something less scary */
|
||||||
if (status == EIO) {
|
if (status == EIO) {
|
||||||
@ -252,7 +245,6 @@ int do_pre_command(struct local_client *client)
|
|||||||
int status = 0;
|
int status = 0;
|
||||||
char *lockname;
|
char *lockname;
|
||||||
|
|
||||||
init_test(0);
|
|
||||||
switch (header->cmd) {
|
switch (header->cmd) {
|
||||||
case CLVMD_CMD_TEST:
|
case CLVMD_CMD_TEST:
|
||||||
status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
|
status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
|
||||||
@ -271,8 +263,6 @@ int do_pre_command(struct local_client *client)
|
|||||||
lock_cmd = args[0];
|
lock_cmd = args[0];
|
||||||
lock_flags = args[1];
|
lock_flags = args[1];
|
||||||
lockname = &args[2];
|
lockname = &args[2];
|
||||||
if (lock_flags & LCK_TEST_MODE)
|
|
||||||
init_test(1);
|
|
||||||
status = pre_lock_lv(lock_cmd, lock_flags, lockname);
|
status = pre_lock_lv(lock_cmd, lock_flags, lockname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -304,7 +294,6 @@ int do_post_command(struct local_client *client)
|
|||||||
char *args = header->node + strlen(header->node) + 1;
|
char *args = header->node + strlen(header->node) + 1;
|
||||||
char *lockname;
|
char *lockname;
|
||||||
|
|
||||||
init_test(0);
|
|
||||||
switch (header->cmd) {
|
switch (header->cmd) {
|
||||||
case CLVMD_CMD_TEST:
|
case CLVMD_CMD_TEST:
|
||||||
status = sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
|
status = sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
|
||||||
@ -315,8 +304,6 @@ int do_post_command(struct local_client *client)
|
|||||||
lock_cmd = args[0];
|
lock_cmd = args[0];
|
||||||
lock_flags = args[1];
|
lock_flags = args[1];
|
||||||
lockname = &args[2];
|
lockname = &args[2];
|
||||||
if (lock_flags & LCK_TEST_MODE)
|
|
||||||
init_test(1);
|
|
||||||
status = post_lock_lv(lock_cmd, lock_flags, lockname);
|
status = post_lock_lv(lock_cmd, lock_flags, lockname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1762,7 +1762,6 @@ static int process_local_command(struct clvm_header *msg, int msglen,
|
|||||||
if (msg->flags & CLVMD_FLAG_REMOTE)
|
if (msg->flags & CLVMD_FLAG_REMOTE)
|
||||||
status = 0;
|
status = 0;
|
||||||
else
|
else
|
||||||
/* FIXME: usage of init_test() is unprotected */
|
|
||||||
status = do_command(client, msg, msglen, &replybuf, buflen, &replylen);
|
status = do_command(client, msg, msglen, &replybuf, buflen, &replylen);
|
||||||
|
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -251,9 +251,6 @@ static int hold_lock(char *resource, int mode, int flags)
|
|||||||
int saved_errno;
|
int saved_errno;
|
||||||
struct lv_info *lvi;
|
struct lv_info *lvi;
|
||||||
|
|
||||||
if (test_mode())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Mask off invalid options */
|
/* Mask off invalid options */
|
||||||
flags &= LCKF_NOQUEUE | LCKF_CONVERT;
|
flags &= LCKF_NOQUEUE | LCKF_CONVERT;
|
||||||
|
|
||||||
@ -319,9 +316,6 @@ static int hold_unlock(char *resource)
|
|||||||
int status;
|
int status;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
|
|
||||||
if (test_mode())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!(lvi = lookup_info(resource))) {
|
if (!(lvi = lookup_info(resource))) {
|
||||||
DEBUGLOG("hold_unlock, lock not already held\n");
|
DEBUGLOG("hold_unlock, lock not already held\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -381,7 +375,7 @@ static int do_activate_lv(char *resource, unsigned char command, unsigned char l
|
|||||||
* Use lock conversion only if requested, to prevent implicit conversion
|
* Use lock conversion only if requested, to prevent implicit conversion
|
||||||
* of exclusive lock to shared one during activation.
|
* of exclusive lock to shared one during activation.
|
||||||
*/
|
*/
|
||||||
if (command & LCK_CLUSTER_VG) {
|
if (!test_mode() && command & LCK_CLUSTER_VG) {
|
||||||
status = hold_lock(resource, mode, LCKF_NOQUEUE | (lock_flags & LCK_CONVERT ? LCKF_CONVERT:0));
|
status = hold_lock(resource, mode, LCKF_NOQUEUE | (lock_flags & LCK_CONVERT ? LCKF_CONVERT:0));
|
||||||
if (status) {
|
if (status) {
|
||||||
/* Return an LVM-sensible error for this.
|
/* Return an LVM-sensible error for this.
|
||||||
@ -415,7 +409,7 @@ static int do_activate_lv(char *resource, unsigned char command, unsigned char l
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (oldmode == -1 || oldmode != mode)
|
if (!test_mode() && (oldmode == -1 || oldmode != mode))
|
||||||
(void)hold_unlock(resource);
|
(void)hold_unlock(resource);
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
@ -479,7 +473,7 @@ static int do_deactivate_lv(char *resource, unsigned char command, unsigned char
|
|||||||
if (!lv_deactivate(cmd, resource, NULL))
|
if (!lv_deactivate(cmd, resource, NULL))
|
||||||
return EIO;
|
return EIO;
|
||||||
|
|
||||||
if (command & LCK_CLUSTER_VG) {
|
if (!test_mode() && command & LCK_CLUSTER_VG) {
|
||||||
status = hold_unlock(resource);
|
status = hold_unlock(resource);
|
||||||
if (status)
|
if (status)
|
||||||
return errno;
|
return errno;
|
||||||
@ -526,6 +520,8 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&lvm_lock);
|
pthread_mutex_lock(&lvm_lock);
|
||||||
|
init_test((lock_flags & LCK_TEST_MODE) ? 1 : 0);
|
||||||
|
|
||||||
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
|
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
|
||||||
init_mirror_in_sync(1);
|
init_mirror_in_sync(1);
|
||||||
|
|
||||||
@ -578,6 +574,7 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
|
|||||||
|
|
||||||
/* clean the pool for another command */
|
/* clean the pool for another command */
|
||||||
dm_pool_empty(cmd->mem);
|
dm_pool_empty(cmd->mem);
|
||||||
|
init_test(0);
|
||||||
pthread_mutex_unlock(&lvm_lock);
|
pthread_mutex_unlock(&lvm_lock);
|
||||||
|
|
||||||
DEBUGLOG("Command return is %d, critical_section is %d\n", status, critical_section());
|
DEBUGLOG("Command return is %d, critical_section is %d\n", status, critical_section());
|
||||||
@ -597,7 +594,8 @@ 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, LCK_WRITE, LCKF_NOQUEUE | LCKF_CONVERT))
|
if (!(lock_flags & LCK_TEST_MODE) &&
|
||||||
|
hold_lock(resource, LCK_WRITE, LCKF_NOQUEUE | LCKF_CONVERT))
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -629,11 +627,13 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
|
|||||||
if (!status)
|
if (!status)
|
||||||
return EIO;
|
return EIO;
|
||||||
|
|
||||||
if (lvi.exists) {
|
if (!(lock_flags & LCK_TEST_MODE)) {
|
||||||
if (hold_lock(resource, LCK_READ, LCKF_CONVERT))
|
if (lvi.exists) {
|
||||||
|
if (hold_lock(resource, LCK_READ, LCKF_CONVERT))
|
||||||
|
return errno;
|
||||||
|
} else if (hold_unlock(resource))
|
||||||
return errno;
|
return errno;
|
||||||
} else if (hold_unlock(resource))
|
}
|
||||||
return errno;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -697,6 +697,8 @@ void do_lock_vg(unsigned char command, unsigned char lock_flags, char *resource)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&lvm_lock);
|
pthread_mutex_lock(&lvm_lock);
|
||||||
|
init_test((lock_flags & LCK_TEST_MODE) ? 1 : 0);
|
||||||
|
|
||||||
switch (lock_cmd) {
|
switch (lock_cmd) {
|
||||||
case LCK_VG_COMMIT:
|
case LCK_VG_COMMIT:
|
||||||
DEBUGLOG("vg_commit notification for VG %s\n", vgname);
|
DEBUGLOG("vg_commit notification for VG %s\n", vgname);
|
||||||
@ -711,6 +713,8 @@ void do_lock_vg(unsigned char command, unsigned char lock_flags, char *resource)
|
|||||||
DEBUGLOG("Invalidating cached metadata for VG %s\n", vgname);
|
DEBUGLOG("Invalidating cached metadata for VG %s\n", vgname);
|
||||||
lvmcache_drop_metadata(vgname, 0);
|
lvmcache_drop_metadata(vgname, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_test(0);
|
||||||
pthread_mutex_unlock(&lvm_lock);
|
pthread_mutex_unlock(&lvm_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user