[linux-lvm] Redhat patches to LVM-1.0.3 tools

Heinz J . Mauelshagen mauelshagen at sistina.com
Wed Mar 6 04:17:01 UTC 2002


Luca,

I heard about it yesterday.

TTBOMK none of the RedHat folks came back to us directly or on any LVM list :-(

They definitely should feed back the code changes to us or give
pointers, where to retrieve them.

Regards,
Heinz    -- The LVM Guy --


On Tue, Mar 05, 2002 at 09:25:46AM +0100, Luca Berra wrote:
> hello i took a peek to redhat rawhide lvm 1.0.3 patches
> and i found something interesting:
> 
> there is a patch for a new version of the pvmove call, which is
> probably accompained by a kernel patch, which i did not search
> for.
> 
> i don't recall seeing anything like this on the list, but maybe
> i just missed it.
> anyone here has any details about this?
> 
> regards,
> L.
> 
> 
> -- 
> Luca Berra -- bluca at comedia.it
>         Communication Media & Services S.r.l.
>  /"\
>  \ /     ASCII RIBBON CAMPAIGN
>   X        AGAINST HTML MAIL
>  / \

> --- LVM/1.0.3/kernel/lvm.h.~1~	Tue Feb 19 16:23:56 2002
> +++ LVM/1.0.3/kernel/lvm.h	Wed Feb 20 17:52:51 2002
> @@ -352,6 +352,7 @@
>  
>  /* physical extent */
>  #define	PE_LOCK_UNLOCK          _IOW ( 0xfe, 0x50, 1)
> +#define	PE_LOCKED_COPY          _IOW ( 0xfe, 0x51, 1)
>  
>  /* i/o protocol version */
>  #define	LVM_GET_IOP_VERSION     _IOR ( 0xfe, 0x98, 1)
> @@ -709,6 +710,16 @@
>  } pe_lock_req_t;
>  
>  
> +/* Request structure PE_COPY */
> +typedef struct {
> +	char lv_name[NAME_LEN];
> +	kdev_t old_dev;
> +	kdev_t new_dev;
> +	uint32_t old_pe;
> +	uint32_t new_pe;
> +} pe_copy_req_t;
> +
> +
>  /* Request structure LV_STATUS_BYNAME */
>  typedef struct {
>  	char lv_name[NAME_LEN];
> --- LVM/1.0.3/tools/lib/liblvm.h.~1~	Wed Feb 20 17:52:21 2002
> +++ LVM/1.0.3/tools/lib/liblvm.h	Wed Feb 20 17:53:53 2002
> @@ -329,6 +329,7 @@
>  int    pv_write_pe ( char*, pv_t *);
>  int    pv_write_with_pe ( char*, pv_t *);
>  int    pv_check_partitioned_whole(char *pv_name);
> +int    pv_locked_copy_pe( vg_t *, char *, kdev_t, kdev_t, uint, uint);
>  
>  /* LV functions */
>  char   *lv_change_vgname ( char *, char *);
> @@ -816,7 +817,8 @@
>  #define LVM_EVG_WRITE_WRITE                                                 404
>  #define LVM_ELV_PV_CREATE_NAME_FROM_KDEV_T                                  405
>  #define LVM_EPV_FLUSH_STAT                                                  406
> -#define LVM_MAX_ERROR							    407
> +#define LVM_EPV_LOCKED_COPY_EINVAL					    407
> +#define LVM_MAX_ERROR							    408
>  
>  
>  /*
> --- LVM/1.0.3/tools/lib/pv_move.c.~1~	Mon Feb 18 16:37:18 2002
> +++ LVM/1.0.3/tools/lib/pv_move.c	Wed Feb 20 18:03:33 2002
> @@ -347,11 +347,16 @@
>  
>  
>  /* perform the move of a physical extent */
> +/* Dynamically choose between the old and new version of the pvmove
> +   mechanism.  The old-style code performs the buffer copy, locking and
> +   remap in separate operations, and copies the chunks in user space.
> +   The new version uses a single kernel ioctl to do it all, but that
> +   (obviously) relies on having an updated kernel. */
>  int pv_move_pe ( vg_t *vg, char *buffer, size_t buffer_size,
> -                 long src_pv_index, long dst_pv_index,
> -                 long pe_source,    long pe_dest,
> -                 int opt_v, int opt_t,
> -                 int act_pe, int off_pe) {
> +		 long src_pv_index, long dst_pv_index,
> +		 long pe_source,    long pe_dest,
> +		 int opt_v, int opt_t,
> +		 int act_pe, int off_pe) {
>     int in = -1;
>     int out = -1;
>     int l = 0;
> @@ -362,7 +367,10 @@
>     char *lv_name_this = NULL;
>     size_t size = 0;
>     le_remap_req_t le_remap_req;
> -
> +   /* Record whether we are definitely using old- or new-style pvmove, or
> +      whether we don't know which yet. */
> +   static int old_style = 0, new_style = 0;
> +   
>     debug_enter ( "pv_move_pe -- CALLED\n");
>  
>     if ( src_pv_index < 0 || src_pv_index >= vg->pv_cur ||
> @@ -375,11 +383,13 @@
>        goto pv_move_pe_end;
>     }
>  
> -   if ( ( in = open ( vg->pv[src_pv_index]->pv_name, O_RDONLY)) == -1) {
> -      fprintf ( stderr, "%s -- couldn't open input physical volume %s\n",
> -                cmd, vg->pv[src_pv_index]->pv_name);
> -      ret = -LVM_EPV_MOVE_PE_OPEN_IN;
> -      goto pv_move_pe_end;
> +   if ( !new_style ) {
> +      if ( ( in = open ( vg->pv[src_pv_index]->pv_name, O_RDONLY)) == -1) {
> +	 fprintf ( stderr, "%s -- couldn't open input physical volume %s\n",
> +		   cmd, vg->pv[src_pv_index]->pv_name);
> +	 ret = -LVM_EPV_MOVE_PE_OPEN_IN;
> +	 goto pv_move_pe_end;
> +      }
>     }
>     
>     /* is this LV not allready on destination PV?
> @@ -447,43 +457,45 @@
>                 le_remap_req.new_pe);
>     }
>  
> -   if ( opt_v > 1) printf ( "%s -- opening output physical volume \"%s\"\n",
> -                            cmd, vg->pv[dst_pv_index]->pv_name);
> -   if ( ( out = open ( vg->pv[dst_pv_index]->pv_name,
> -                       O_WRONLY)) == -1) {
> -      fprintf ( stderr, "%s -- couldn't open output "
> -                        "physical volume \"%s\"\n",
> -                cmd, vg->pv[dst_pv_index]->pv_name);
> -      ret = -LVM_EPV_MOVE_PE_OPEN;
> -      goto pv_move_pe_end;
> -   }
> -
> -   if ( opt_v > 1) printf ( "%s -- llseeking input physical volume \"%s\"\n",
> -                            cmd, vg->pv[src_pv_index]->pv_name);
> -   offset = ( loff_t) le_remap_req.old_pe * SECTOR_SIZE;
> -   if ( ( result = _llseek ( in, offset, SEEK_SET)) == -1) {
> -      fprintf ( stderr, "%s -- couldn't llseek to sector %u on input "
> -                        "physical volume \"%s\"\n",
> -                cmd,
> -                le_remap_req.old_pe,
> -                vg->pv[src_pv_index]->pv_name);
> -      ret = -LVM_EPV_MOVE_PE_LLSEEK_IN;
> -      goto pv_move_pe_end;
> -   }
> -
> -   if ( opt_v > 1) printf ( "%s -- llseeking output physical volume \"%s\"\n",
> -                            cmd, vg->pv[dst_pv_index]->pv_name);
> -   offset = ( loff_t) le_remap_req.new_pe * SECTOR_SIZE;
> -   if ( ( result = llseek ( out, offset, SEEK_SET)) == -1) {
> -      fprintf ( stderr, "%s -- couldn't llseek to sector %u on output "
> -                        "physical volume \"%s\"\n",
> -                cmd,
> -                le_remap_req.new_pe,
> -                vg->pv[dst_pv_index]->pv_name);
> -      ret = -LVM_EPV_MOVE_PE_LLSEEK_OUT;
> -      goto pv_move_pe_end;
> +   if ( !new_style ) {
> +      if ( opt_v > 1) printf ( "%s -- opening output physical volume \"%s\"\n",
> +			       cmd, vg->pv[dst_pv_index]->pv_name);
> +      if ( ( out = open ( vg->pv[dst_pv_index]->pv_name,
> +			  O_WRONLY)) == -1) {
> +	 fprintf ( stderr, "%s -- couldn't open output "
> +			   "physical volume \"%s\"\n",
> +		   cmd, vg->pv[dst_pv_index]->pv_name);
> +	 ret = -LVM_EPV_MOVE_PE_OPEN;
> +	 goto pv_move_pe_end;
> +      }
> +
> +      if ( opt_v > 1) printf ( "%s -- llseeking input physical volume \"%s\"\n",
> +			       cmd, vg->pv[src_pv_index]->pv_name);
> +      offset = ( loff_t) le_remap_req.old_pe * SECTOR_SIZE;
> +      if ( ( result = llseek ( in, offset, SEEK_SET)) == -1) {
> +	 fprintf ( stderr, "%s -- couldn't llseek to sector %u on input "
> +			   "physical volume \"%s\"\n",
> +		   cmd,
> +		   le_remap_req.old_pe,
> +		   vg->pv[src_pv_index]->pv_name);
> +	 ret = -LVM_EPV_MOVE_PE_LLSEEK_IN;
> +	 goto pv_move_pe_end;
> +      }
> +
> +      if ( opt_v > 1) printf ( "%s -- llseeking output physical volume \"%s\"\n",
> +			       cmd, vg->pv[dst_pv_index]->pv_name);
> +      offset = ( loff_t) le_remap_req.new_pe * SECTOR_SIZE;
> +      if ( ( result = llseek ( out, offset, SEEK_SET)) == -1) {
> +	 fprintf ( stderr, "%s -- couldn't llseek to sector %u on output "
> +			   "physical volume \"%s\"\n",
> +		   cmd,
> +		   le_remap_req.new_pe,
> +		   vg->pv[dst_pv_index]->pv_name);
> +	 ret = -LVM_EPV_MOVE_PE_LLSEEK_OUT;
> +	 goto pv_move_pe_end;
> +      }
>     }
> -
> +   
>     if ( opt_v > 0)
>         printf ( "%s -- %s [PE %lu [%s [LE %d]] -> %s [PE %lu] [%d/%d]\n",
>                  cmd,
> @@ -498,6 +510,55 @@
>                  act_pe,
>                  off_pe);
>  
> +   /* Setup done, now comes crunch time.  Will the new-style
> +    * PV_LOCKED_COPY ioctl work? */
> +
> +   if ( !old_style ) {
> +      if ( opt_v > 1) printf ( "%s -- copying extent from %s::%s(0x%04x):%d "
> +			       "to %s(0x%04x):%d on disk\n", 
> +			       cmd, vg->pv[src_pv_index]->pv_name,
> +			       lv_name_this,
> +			       le_remap_req.old_dev, le_remap_req.old_pe,
> +			       vg->pv[dst_pv_index]->pv_name, 
> +			       le_remap_req.new_dev, le_remap_req.new_pe);
> +      if ( opt_t != 0 )
> +         /* Special case --- if we end up in this path, we skip the 
> +	  * new-style copy but we also want to bypass the fallback 
> +	  * into the old-style copy, too. */
> +	 goto done_new_pv_move;
> +      if ( ( ret = pv_locked_copy_pe(vg, lv_name_this,
> +				     le_remap_req.old_dev, 
> +				     le_remap_req.new_dev,
> +				     le_remap_req.old_pe, 
> +				     le_remap_req.new_pe) ) == 0 ) {
> +	 /* New style works --- next time we enter this function, we can
> +	  * skip all the setup for old-style copy. */
> +	 new_style = 1;
> +	 goto done_new_pv_move;
> +      }
> +      
> +      fprintf ( stderr, "%s -- ERROR \"%s\" copying extent "
> +		"from \"%s\"\n\n",
> +		cmd, lvm_error ( ret),
> +		vg->pv[src_pv_index]->pv_name);
> +
> +      /* If this is the first time we've tried new-style, and we
> +       * got an EINVAL back from the kernel, assume the ioctl
> +       * doesn't exist and try old-style pvmove instead. */
> +      if ( ret == -LVM_EPV_LOCKED_COPY_EINVAL && !old_style ) {
> +	  if ( opt_v > 1)
> +		printf ( "%s -- -EINVAL using PE_LOCKED_COPY, "
> +			 "falling back to old style pv_move "
> +			 "on \"%s\"\n",
> +			 cmd, vg->vg_name);
> +	  old_style = 1;
> +      } else
> +	  goto pv_move_pe_end;
> +   }
> +
> +   /* We failed.  <sniff>  OK, time to fall back to the old, buggy,
> +    * data-corrupting, deadlock-prone pvmove version. */
> +
>     /* lock extent in kernel */
>     if ( opt_v > 1) printf ( "%s -- locking physical extent %lu "
>                              "of \"%s\" in kernel\n",
> @@ -592,6 +653,8 @@
>        }
>     }
>  
> +done_new_pv_move:
> +
>     if ( opt_v > 1) printf ( "%s -- changing source \"%s\" in VGDA "
>                              "of kernel\n",
>                              cmd, vg->pv[src_pv_index]->pv_name);
> @@ -654,7 +717,7 @@
>  
>     debug_leave ( "pv_move_pe -- LEAVING with ret: %d\n", ret);
>     return ret;
> -} /* pv_move_pe() */
> +} /* pv_move_pe_old() */
>  
>  
>  void pv_move_interrupt ( int sig) {
> @@ -761,3 +824,46 @@
>     else
>        return 0;
>  }
> +
> +
> +int pv_locked_copy_pe( vg_t *vg, char *lv_name, 
> +		       kdev_t old_dev, kdev_t new_dev,
> +		       uint old_pe, uint new_pe) 
> +{
> +	pe_copy_req_t pe_copy_req;
> +	int group = -1;
> +	int ret;
> +	char group_file[NAME_LEN];
> +	
> +	debug_enter ( "pv_locked_copy_pe -- CALLED\n");
> +
> +	sprintf ( group_file, LVM_DIR_PREFIX "%s/group%c", vg->vg_name, 0);
> +	
> +	if ( ( group = open ( group_file, O_RDONLY)) == -1) {
> +		ret = -LVM_EPE_LOCK; /* FIX THIS ERR CODE */
> +		goto out;
> +	}
> +
> +	strcpy (pe_copy_req.lv_name, lv_name);
> +	pe_copy_req.old_dev = old_dev;
> +	pe_copy_req.new_dev = new_dev;
> +	pe_copy_req.old_pe = old_pe;
> +	pe_copy_req.new_pe = new_pe;
> +	
> +	printf("%s::%s: %04x %d, %04x %d\n", 
> +	       group_file, pe_copy_req.lv_name,
> +	       pe_copy_req.old_dev, pe_copy_req.old_pe,
> +	       pe_copy_req.new_dev, pe_copy_req.new_pe);
> +
> +	ret = ioctl(group, PE_LOCKED_COPY, &pe_copy_req);
> +	if (ret < 0)
> +		ret = -errno;
> +	if (ret == -EINVAL)
> +		ret = -LVM_EPV_LOCKED_COPY_EINVAL;
> +	
> +	close(group);
> +out:
> +	debug_leave ( "pv_locked_copy_pe -- LEAVING with ret: %d\n", ret);
> +	return ret;
> +}
> +
> --- LVM/1.0.3/tools/lib/pv_write.c.~1~	Wed Feb  6 14:17:47 2002
> +++ LVM/1.0.3/tools/lib/pv_write.c	Wed Feb 20 17:52:51 2002
> @@ -60,7 +60,7 @@
>  
>        /* convert core to disk data */
>        pv_disk = pv_copy_to_disk ( pv);
> -      if ( ( pv_handle = open ( pv_name, O_WRONLY)) == -1)
> +      if ( ( pv_handle = open ( pv_name, O_WRONLY, O_SYNC)) == -1)
>           ret = -LVM_EPV_WRITE_OPEN;
>        else if ( lseek ( pv_handle, pv->pv_on_disk.base, SEEK_SET) !=
>                  pv->pv_on_disk.base) ret = -LVM_EPV_WRITE_LSEEK;
> @@ -91,7 +91,6 @@
>        free ( pv_disk);
>     
>        if ( pv_handle != -1) {
> -         fsync ( pv_handle);
>           close ( pv_handle);
>        }
>     }
> --- LVM/1.0.3/tools/lib/pv_write_pe.c.~1~	Fri Jun 22 10:09:12 2001
> +++ LVM/1.0.3/tools/lib/pv_write_pe.c	Wed Feb 20 17:52:51 2002
> @@ -54,7 +54,7 @@
>        size = pv->pe_total * sizeof ( pe_disk_t);
>        if ( size + pv->pe_on_disk.base > LVM_VGDA_SIZE ( pv))
>           ret = -LVM_EPV_WRITE_PE_SIZE;;
> -      if ( ( pv_handle = open ( pv_name, O_WRONLY)) == -1)
> +      if ( ( pv_handle = open ( pv_name, O_WRONLY | O_SYNC)) == -1)
>           ret = -LVM_EPV_WRITE_PE_OPEN;
>        else if ( lseek ( pv_handle,  pv->pe_on_disk.base, SEEK_SET) !=
>                   pv->pe_on_disk.base)
> @@ -67,7 +67,6 @@
>        }
>     
>        if ( pv_handle != -1) {
> -         fsync ( pv_handle);
>           close ( pv_handle);
>        }
>     }

*** Software bugs are stupid.
    Nevertheless it needs not so stupid people to solve them ***

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Heinz Mauelshagen                                 Sistina Software Inc.
Senior Consultant/Developer                       Am Sonnenhang 11
                                                  56242 Marienrachdorf
                                                  Germany
Mauelshagen at Sistina.com                           +49 2626 141200
                                                       FAX 924446
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-




More information about the linux-lvm mailing list