[linux-lvm] Redhat patches to LVM-1.0.3 tools
Luca Berra
bluca at comedia.it
Tue Mar 5 02:25:02 UTC 2002
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
/ \
-------------- next part --------------
--- 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);
}
}
More information about the linux-lvm
mailing list