[lvm-devel] Re: [PATCH 4/4] Update vgcreate and vgextend to allow uninitialized devices as input.

Dave Wysochanski dwysocha at redhat.com
Sun Nov 30 14:39:37 UTC 2008


On Sat, 2008-11-29 at 16:02 -0500, Dave Wysochanski wrote:

> Modify pvcreate_single() to first check whether the VG_ORPHANS lock is
> held before trying to obtain it.  This is necessary for the vgexten
> code path, which must obtain VG_ORPHANS before obtaining the appropriate
> VG lock, and befroe calling vg_extend().  The other paths calling
> pvcreate_single() are pvcreate() and vgcreate(), and neither of these
> paths hold VG_ORPHANS.  Without this modification vgextend() will hang
> trying to obtain VG_ORPHANS which it already holds.
> 
> Signed-off-by: Dave Wysochanski <dwysocha at redhat.com>
> ---
>  WHATS_NEW               |    1 +
>  lib/metadata/metadata.c |   32 ++++++++++++++++++++++++++++----
>  man/vgcreate.8.in       |   15 +++++++++------
>  man/vgextend.8.in       |    6 ++++++
>  4 files changed, 44 insertions(+), 10 deletions(-)
> 
> diff --git a/WHATS_NEW b/WHATS_NEW
> index 459533a..03ec238 100644
> --- a/WHATS_NEW
> +++ b/WHATS_NEW
> @@ -1,5 +1,6 @@
>  Version 2.02.44 - 
>  ====================================
> +  Update vgcreate and vgextend to allow uninitialized devices as input.
>    Don't skip updating pvid hash when lvmcache_info struct got swapped.
>    Add tinfo to termcap search path for pld-linux.
>    Fix startup race in clvmd.
> diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
> index 4b231d3..4e375f5 100644
> --- a/lib/metadata/metadata.c
> +++ b/lib/metadata/metadata.c
> @@ -422,9 +422,22 @@ int vg_extend(struct volume_group *vg, int pv_count, char **pv_names)
>  	/* attach each pv */
>  	for (i = 0; i < pv_count; i++) {
>  		if (!(pv = pv_by_path(vg->fid->fmt->cmd, pv_names[i]))) {
> -			log_error("%s not identified as an existing "
> -				  "physical volume", pv_names[i]);
> -			goto bad;
> +			if (yes_no_prompt("%s not identified as an existing "
> +					  "physical volume.\nInitialize "
> +					  "device and add to volume "
> +					  "group %s? [y/n]: ", pv_names[i],
> +					  vg->name) == 'n') {
> +				goto bad;
> +			} else {
> +				pv = pvcreate_single(vg->cmd, pv_names[i],
> +						     NULL);
> +				if (!pv) {
> +					log_error("Failed to setup physical "
> +						  "volume \"%s\"",
> +						  pv_names[i]);
> +					goto bad;
> +				}
> +			}
>  		}
>  		
>  		if (!add_pv_to_vg(vg, pv_names[i], pv))
> @@ -990,6 +1003,16 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name,
>  	return 1;
>  }
>  
> +/*
> + * pvcreate_single() - initialize a device with PV label and metadata
> + *
> + * Locking: Ok (but not required) for caller to hold VG_ORPHAN lock
> + * before calling
> + *
> + * Parameters:
> + * - pv_name: device path to initialize
> + * - handle: options to pass to pv_create; NULL indicates use defaults
> + */
>  pv_t *pvcreate_single(struct cmd_context *cmd, const char *pv_name,
>  		      void *handle)
>  {
> @@ -1025,7 +1048,8 @@ pv_t *pvcreate_single(struct cmd_context *cmd, const char *pv_name,
>  		}
>  	}
>  
> -	if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
> +	if (!vgname_is_locked(VG_ORPHANS) &&
> +	    (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE))) {
>  		log_error("Can't get lock for orphan PVs");
>  		return NULL;
>  	}

Upon further consideration, I'm not sure putting the pvcreate_single()
calls into vg_extend() is the best way to do this since it causes
complications with VG_ORPHANS lock in pvcreate_single().  Even with the
above code to check the lock before obtaining, pvcreate_single() will
release VG_ORPHANS lock in a different sequence than was obtained (in
vgextend case).  Might be better to place this logic higher up in
vgcreate() and vgextend(), or try to refactor.  I will work on another
patch.




More information about the lvm-devel mailing list