[lvm-devel] [PATCH 1 of 1] LVM: 2 preserve exclusive target table loading

Jonathan Brassow jbrassow at redhat.com
Thu Feb 17 20:55:24 UTC 2011


There is perhaps a simpler way of doing this....  Simply check  
'lv_is_active_exclusive_locally' inside '_lv_resume'.  If so, then 'lv- 
 >status |= ACTIVATE_EXCL'.  However, there is a bug preventing this  
approach from working.

The function 'remote_lock_held' immediately calls  
'locking_is_clustered'.  This function doesn't work in clvmd because  
the '_locking' structure is never initialized.  Should it be?  This  
would cause clvmd to try to communicate with itself - perhaps this is  
a bad idea(?).

The below solution works well, but I don't want to overlook a more  
obvious/trivial solution.
  brassow


On Feb 17, 2011, at 2:20 PM, Jonathan Brassow wrote:

> Patch name: lvm2-preserve-exclusive-target-table-loading.patch
>
> Fix for bug 677739: removing final exclusive cmirror snapshot,
> 		    results in clvmd deadlock
>
> When a logical volume is activated exclusively in a cluster, the
> local (non-cluster-aware) target is used.  However, when creating
> a snapshot on the exclusive LV, the resulting suspend/resume fails
> to load the appropriate device-mapper table - instead loading the
> cluster-aware target.
>
> This patch adds an 'exclusive' parameter to the pertinent resume
> functions to allow for the right target type to be loaded.
>
>
> Index: LVM2/daemons/clvmd/lvm-functions.c
> ===================================================================
> --- LVM2.orig/daemons/clvmd/lvm-functions.c
> +++ LVM2/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,
> 		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;
> Index: LVM2/lib/activate/activate.c
> ===================================================================
> --- LVM2.orig/lib/activate/activate.c
> +++ LVM2/lib/activate/activate.c
> @@ -1157,7 +1157,7 @@ int lv_suspend(struct cmd_context *cmd,
> ***********/
>
> 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 +1189,9 @@ static int _lv_resume(struct cmd_context
> 		goto out;
> 	}
>
> +	if (exclusive)
> +		lv->status |= ACTIVATE_EXCL;
> +
> 	if (!_lv_activate_lv(lv, origin_only))
> 		goto_out;
>
> @@ -1206,14 +1209,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)
> Index: LVM2/lib/activate/activate.h
> ===================================================================
> --- LVM2.orig/lib/activate/activate.h
> +++ LVM2/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);
> Index: LVM2/lib/locking/file_locking.c
> ===================================================================
> --- LVM2.orig/lib/locking/file_locking.c
> +++ LVM2/lib/locking/file_locking.c
> @@ -293,7 +293,7 @@ static int _file_lock_resource(struct cm
> 		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:
> Index: LVM2/lib/locking/no_locking.c
> ===================================================================
> --- LVM2.orig/lib/locking/no_locking.c
> +++ LVM2/lib/locking/no_locking.c
> @@ -46,7 +46,7 @@ static int _no_lock_resource(struct cmd_
> 		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:
>
> --
> lvm-devel mailing list
> lvm-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/lvm-devel




More information about the lvm-devel mailing list