diff --git a/WHATS_NEW b/WHATS_NEW index aff09b666..ba89ece20 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.85 - =================================== + Fix to make resuming exclusive cluster mirror use local target type. Version 2.02.84 - 9th February 2011 =================================== diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c index 81e8b884f..b5a0e4ec6 100644 --- a/daemons/clvmd/lvm-functions.c +++ b/daemons/clvmd/lvm-functions.c @@ -399,7 +399,7 @@ error: /* Resume the LV if it was active */ static int do_resume_lv(char *resource, unsigned char lock_flags) { - int oldmode; + int oldmode, origin_only, exclusive; /* Is it open ? */ oldmode = get_current_lock(resource); @@ -407,8 +407,10 @@ static int do_resume_lv(char *resource, unsigned char lock_flags) DEBUGLOG("do_resume_lv, lock not already held\n"); return 0; /* We don't need to do anything */ } + origin_only = (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0; + exclusive = (oldmode == LCK_EXCL) ? 1 : 0; - if (!lv_resume_if_active(cmd, resource, (lock_flags & LCK_ORIGIN_ONLY_MODE) ? 1 : 0)) + if (!lv_resume_if_active(cmd, resource, origin_only, exclusive)) return EIO; return 0; diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 9edb0114f..cdd499d07 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -1156,8 +1156,18 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s) } ***********/ + /* + * _lv_resume + * @cmd + * @lvid_s + * @origin_only + * @exclusive: This parameter only has an affect in cluster-context. + * It forces local target type to be used (instead of + * cluster-aware type). + * @error_if_not_active + */ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s, - unsigned origin_only, + unsigned origin_only, unsigned exclusive, int error_if_not_active) { struct logical_volume *lv; @@ -1189,6 +1199,14 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s, goto out; } + /* + * When targets are activated exclusively in a cluster, the + * non-clustered target should be used. This only happens + * if ACTIVATE_EXCL is set in lv->status. + */ + if (exclusive) + lv->status |= ACTIVATE_EXCL; + if (!_lv_activate_lv(lv, origin_only)) goto_out; @@ -1206,14 +1224,15 @@ out: } /* Returns success if the device is not active */ -int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only) +int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, + unsigned origin_only, unsigned exclusive) { - return _lv_resume(cmd, lvid_s, origin_only, 0); + return _lv_resume(cmd, lvid_s, origin_only, exclusive, 0); } int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only) { - return _lv_resume(cmd, lvid_s, origin_only, 1); + return _lv_resume(cmd, lvid_s, origin_only, 0, 1); } static int _lv_has_open_snapshots(struct logical_volume *lv) diff --git a/lib/activate/activate.h b/lib/activate/activate.h index c054c6db7..53ab19262 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -56,7 +56,8 @@ void activation_exit(void); /* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only); int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only); -int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only); +int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s, + unsigned origin_only, unsigned exclusive); int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive); int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive); diff --git a/lib/locking/file_locking.c b/lib/locking/file_locking.c index 68b0420b8..95883b919 100644 --- a/lib/locking/file_locking.c +++ b/lib/locking/file_locking.c @@ -293,7 +293,7 @@ static int _file_lock_resource(struct cmd_context *cmd, const char *resource, switch (flags & LCK_TYPE_MASK) { case LCK_UNLOCK: log_very_verbose("Unlocking LV %s%s", resource, origin_only ? " without snapshots" : ""); - if (!lv_resume_if_active(cmd, resource, origin_only)) + if (!lv_resume_if_active(cmd, resource, origin_only, 0)) return 0; break; case LCK_NULL: diff --git a/lib/locking/no_locking.c b/lib/locking/no_locking.c index 3ad0d38b2..65ac29fb0 100644 --- a/lib/locking/no_locking.c +++ b/lib/locking/no_locking.c @@ -46,7 +46,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource, case LCK_NULL: return lv_deactivate(cmd, resource); case LCK_UNLOCK: - return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0); + return lv_resume_if_active(cmd, resource, (flags & LCK_ORIGIN_ONLY) ? 1: 0, 0); case LCK_READ: return lv_activate_with_filter(cmd, resource, 0); case LCK_WRITE: