mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
Fix wrong use of LCK_WRITE
In all top vg read functions only LCK_VG_READ/WRITE can be used. All other vg lock definitions are low-level backend machinery. Moreover, LCK_WRITE cannot be tested through bitmask. This patch fixes these mistakes. For _recover_vg() we do not need lock_flags, it can be only two of above and we always upgrading to LCK_VG_WRITE lock there. (N.B. that code is racy) There is no functional change in code (despite wrong masking it produces correct bits:-)
This commit is contained in:
parent
727f7bfa49
commit
586b56b18c
@ -4,6 +4,7 @@ Version 2.02.74 -
|
|||||||
Remove assumption that --yes must be used only in --force mode.
|
Remove assumption that --yes must be used only in --force mode.
|
||||||
Fix file descriptor leak in swap signature detection error path.
|
Fix file descriptor leak in swap signature detection error path.
|
||||||
Detect and allow abort in pvcreate if LUKS signature is detected.
|
Detect and allow abort in pvcreate if LUKS signature is detected.
|
||||||
|
Use proper locks mask when checking for LCK_WRITE.
|
||||||
|
|
||||||
Version 2.02.73 - 18th August 2010
|
Version 2.02.73 - 18th August 2010
|
||||||
==================================
|
==================================
|
||||||
|
@ -155,11 +155,13 @@ static int _lock_resource(const char *resource, int mode, int flags, int *lockid
|
|||||||
if (!_resources[i])
|
if (!_resources[i])
|
||||||
break;
|
break;
|
||||||
if (!strcmp(_resources[i], resource)) {
|
if (!strcmp(_resources[i], resource)) {
|
||||||
if ((_locks[i] & LCK_WRITE) || (_locks[i] & LCK_EXCL)) {
|
if ((_locks[i] & LCK_TYPE_MASK) == LCK_WRITE ||
|
||||||
|
(_locks[i] & LCK_TYPE_MASK) == LCK_EXCL) {
|
||||||
DEBUGLOG("%s already write/exclusively locked...\n", resource);
|
DEBUGLOG("%s already write/exclusively locked...\n", resource);
|
||||||
goto maybe_retry;
|
goto maybe_retry;
|
||||||
}
|
}
|
||||||
if ((mode & LCK_WRITE) || (mode & LCK_EXCL)) {
|
if ((mode & LCK_TYPE_MASK) == LCK_WRITE ||
|
||||||
|
(mode & LCK_TYPE_MASK) == LCK_EXCL) {
|
||||||
DEBUGLOG("%s already locked and WRITE/EXCL lock requested...\n",
|
DEBUGLOG("%s already locked and WRITE/EXCL lock requested...\n",
|
||||||
resource);
|
resource);
|
||||||
goto maybe_retry;
|
goto maybe_retry;
|
||||||
|
@ -3834,20 +3834,16 @@ int vg_check_status(const struct volume_group *vg, uint64_t status)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct volume_group *_recover_vg(struct cmd_context *cmd,
|
static struct volume_group *_recover_vg(struct cmd_context *cmd,
|
||||||
const char *vg_name, const char *vgid,
|
const char *vg_name, const char *vgid)
|
||||||
uint32_t lock_flags)
|
|
||||||
{
|
{
|
||||||
int consistent = 1;
|
int consistent = 1;
|
||||||
struct volume_group *vg;
|
struct volume_group *vg;
|
||||||
|
|
||||||
lock_flags &= ~LCK_TYPE_MASK;
|
|
||||||
lock_flags |= LCK_WRITE;
|
|
||||||
|
|
||||||
unlock_vg(cmd, vg_name);
|
unlock_vg(cmd, vg_name);
|
||||||
|
|
||||||
dev_close_all();
|
dev_close_all();
|
||||||
|
|
||||||
if (!lock_vol(cmd, vg_name, lock_flags))
|
if (!lock_vol(cmd, vg_name, LCK_VG_WRITE))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
|
|
||||||
if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent)))
|
if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent)))
|
||||||
@ -3882,7 +3878,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
|
|||||||
uint32_t failure = 0;
|
uint32_t failure = 0;
|
||||||
int already_locked;
|
int already_locked;
|
||||||
|
|
||||||
if (misc_flags & READ_ALLOW_INCONSISTENT || !(lock_flags & LCK_WRITE))
|
if (misc_flags & READ_ALLOW_INCONSISTENT || lock_flags != LCK_VG_WRITE)
|
||||||
consistent = 0;
|
consistent = 0;
|
||||||
|
|
||||||
if (!validate_name(vg_name) && !is_orphan_vg(vg_name)) {
|
if (!validate_name(vg_name) && !is_orphan_vg(vg_name)) {
|
||||||
@ -3927,7 +3923,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
|
|||||||
/* consistent == 0 when VG is not found, but failed == FAILED_NOTFOUND */
|
/* consistent == 0 when VG is not found, but failed == FAILED_NOTFOUND */
|
||||||
if (!consistent && !failure) {
|
if (!consistent && !failure) {
|
||||||
vg_release(vg);
|
vg_release(vg);
|
||||||
if (!(vg = _recover_vg(cmd, vg_name, vgid, lock_flags))) {
|
if (!(vg = _recover_vg(cmd, vg_name, vgid))) {
|
||||||
log_error("Recovery of volume group \"%s\" failed.",
|
log_error("Recovery of volume group \"%s\" failed.",
|
||||||
vg_name);
|
vg_name);
|
||||||
failure |= FAILED_INCONSISTENT;
|
failure |= FAILED_INCONSISTENT;
|
||||||
@ -3941,7 +3937,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (!cmd->handles_missing_pvs && vg_missing_pv_count(vg) &&
|
if (!cmd->handles_missing_pvs && vg_missing_pv_count(vg) &&
|
||||||
(lock_flags & LCK_WRITE)) {
|
lock_flags == LCK_VG_WRITE) {
|
||||||
log_error("Cannot change VG %s while PVs are missing.", vg->name);
|
log_error("Cannot change VG %s while PVs are missing.", vg->name);
|
||||||
log_error("Consider vgreduce --removemissing.");
|
log_error("Consider vgreduce --removemissing.");
|
||||||
failure |= FAILED_INCONSISTENT; /* FIXME new failure code here? */
|
failure |= FAILED_INCONSISTENT; /* FIXME new failure code here? */
|
||||||
@ -3949,7 +3945,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!cmd->handles_unknown_segments && vg_has_unknown_segments(vg) &&
|
if (!cmd->handles_unknown_segments && vg_has_unknown_segments(vg) &&
|
||||||
(lock_flags & LCK_WRITE)) {
|
lock_flags == LCK_VG_WRITE) {
|
||||||
log_error("Cannot change VG %s with unknown segments in it!",
|
log_error("Cannot change VG %s with unknown segments in it!",
|
||||||
vg->name);
|
vg->name);
|
||||||
failure |= FAILED_INCONSISTENT; /* FIXME new failure code here? */
|
failure |= FAILED_INCONSISTENT; /* FIXME new failure code here? */
|
||||||
|
Loading…
Reference in New Issue
Block a user