[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