Hi, the old patch didn't work very well (deadlocks with writeable snapshots). I made a better one. It includes tow ioctls required for xfs. On Mon, 19 Nov 2001, Anselm Kruis wrote: > Hi, > > I have made a new writeable snapshot patch against latest cvs. It consists > of a kernel patch and a patch for lvchange. The patch is based on previous > work from Dale J. Stephenson <steph@connex.com>. > > If you create a snapshot, the snapshot is still read-only at first. You > can now use lvchange, to make the snapshot writeable. Use it i.e. to > repair file systems on the snapshot. > > lvcreate -s -n snap ... > lvchange -p rw /dev/vg00/snap > e2fsck # or something similar > sync > lvchange -p r /dev/vg00/snap > mount -o ro /dev/vg00/snap .... > > The kernel patch consists mainly of two parts: > - the actual COW remapping for the snapshot > - an ioctl to let the user space tools detect the presence of the > writeable snapshot support in the kernel. > > The later ist required, because current kernels have no protection against > making a snapshot-LV writeable. The protection is in lvchange. If you > make a snapshot-LV writeable, the writes end on the original volume. > Bad bad bad. :-( > Therefore lvchange needs a way to detect the presence of writeable > snapshot support in the kernel. > > I decided to add a new ioctl on the /dev/lvm device: LVM_GET_FEATURE_BITS. > The ioctl returns a bit field. Every set bit indicates the presence of a > feature. If the ioctl is not present, no features are present. For now the > only feature defined is: LVM_FEATURE_WRITEABLE_SNAPSHOTS. > > Known Problems: > --------------- > > - If a writeable snapshot runs out of space, all processes writing to the > snapshot hang. fixed > > - Needs more testing. > > Comments and criticism are very much appreciated. > > Anselm Kruis > Software Engineer > > The diff is against the current cvs version of LVM as of Jan 01 2002 diff -c -r -b -B -N -x CVS LVM.vanilla/PATCHES/linux-2.4.15-writeable-snapshots.patch LVM/PATCHES/linux-2.4.15-writeable-snapshots.patch *** LVM.vanilla/PATCHES/linux-2.4.15-writeable-snapshots.patch Thu Jan 1 01:00:00 1970 --- LVM/PATCHES/linux-2.4.15-writeable-snapshots.patch Sun Nov 18 11:05:14 2001 *************** *** 0 **** --- 1,27 ---- + diff -u --recursive --new-file linux-2.4.15pre4.vanilla/Documentation/Configure.help linux/Documentation/Configure.help + --- linux-2.4.15pre4.vanilla/Documentation/Configure.help Sun Nov 18 10:46:17 2001 + +++ linux/Documentation/Configure.help Sat Nov 17 22:55:13 2001 + @@ -1693,6 +1693,13 @@ + want), say M here and read <file:Documentation/modules.txt>. The + module will be called lvm-mod.o. + + +Support for writeable snapshots + +CONFIG_LVM_WRITEABLE_SNAPSHOTS + + The LVM driver allows you to make snapshots of a logocal volume. + + Usually these snapshots are read-only. This options add support for + + writeable snapshots. You can use a writeable snapshot to run a + + filesystem check on the snapshot prior to mounting it. + + + Multiple devices driver support (RAID and LVM) + CONFIG_MD + Support multiple physical spindles through a single logical device. + diff -u --recursive --new-file linux-2.4.15pre4.vanilla/drivers/md/Config.in linux/drivers/md/Config.in + --- linux-2.4.15pre4.vanilla/drivers/md/Config.in Fri Sep 14 23:22:18 2001 + +++ linux/drivers/md/Config.in Sat Nov 17 22:41:02 2001 + @@ -14,5 +14,6 @@ + dep_tristate ' Multipath I/O support' CONFIG_MD_MULTIPATH $CONFIG_BLK_DEV_MD + + dep_tristate ' Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM $CONFIG_MD + +dep_mbool ' Support for writeable snapshots' CONFIG_LVM_WRITEABLE_SNAPSHOTS $CONFIG_BLK_DEV_LVM $CONFIG_EXPERIMENTAL + + endmenu diff -c -r -b -B -N -x CVS LVM.vanilla/kernel/lvm.c LVM/kernel/lvm.c *** LVM.vanilla/kernel/lvm.c Tue Jan 1 21:49:48 2002 --- LVM/kernel/lvm.c Tue Jan 1 22:04:01 2002 *************** *** 214,219 **** --- 214,220 ---- * in the LV each time. [AED] * 12/10/2001 - Use add/del_gendisk() routines in 2.4.10+ * 01/11/2001 - Backport read_ahead change from Linus kernel [AED] + * 01/01/2002 - Support for writeable snapshots [A.Kruis@science-computing.de] * */ *************** *** 374,379 **** --- 375,385 ---- ushort lvm_iop_version = LVM_DRIVER_IOP_VERSION; int loadtime = 0; const char *const lvm_name = LVM_NAME; + ushort lvm_feature_bits = + #ifdef CONFIG_LVM_WRITEABLE_SNAPSHOTS + LVM_FEATURE_WRITEABLE_SNAPSHOTS | + #endif + 0; /* volume group descriptor area pointers */ *************** *** 717,722 **** --- 723,735 ---- /* Main command switch */ switch (command) { + case LVM_GET_FEATURE_BITS: + /* return a the feature bits. These bits indicate particular + features supported by this kernel. */ + if (copy_to_user(arg, &lvm_feature_bits, sizeof(ushort)) != 0) + return -EFAULT; + return 0; + case LVM_LOCK_LVM: /* lock the LVM */ return lvm_do_lock_lvm(); *************** *** 1063,1068 **** --- 1076,1084 ---- return -EFAULT; break; + case BLKBSZGET: + case BLKBSZSET: + return blk_ioctl (inode->i_rdev, command, a); case HDIO_GETGEO: /* get disk geometry */ *************** *** 1293,1298 **** --- 1309,1315 ---- lv_t *lv = vg_this->lv[LV_BLK(minor)]; + restart: down_read(&lv->lv_lock); if (!(lv->lv_status & LV_ACTIVE)) { printk(KERN_ALERT *************** *** 1381,1389 **** goto out; if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */ ! if (lvm_snapshot_remap_block(&rdev_map, &rsector_map, ! pe_start, lv) < 0) goto bad; } else if (rw == WRITE || rw == WRITEA) { /* snapshot origin */ lv_t *snap; --- 1398,1425 ---- goto out; if (lv->lv_access & LV_SNAPSHOT) { /* remap snapshot */ ! int ret; ! ret = lvm_snapshot_remap_block(&rdev_map, &rsector_map, ! pe_start, lv); ! if (ret < 0) goto bad; + if (ret > 0 || !(rw == WRITE || rw == WRITEA)) + goto out; /* already remapped or read access */ + + #ifdef CONFIG_LVM_WRITEABLE_SNAPSHOTS + /* remap the block */ + + /* Serializes the COW with the accesses to the + snapshot device. + + __remap_snapshot acquires the write lock. */ + up_read(&lv->lv_lock); + __remap_snapshot(rdev_map, rsector_map, + pe_start, lv, vg_this); + goto restart; + #else + goto bad; + #endif } else if (rw == WRITE || rw == WRITEA) { /* snapshot origin */ lv_t *snap; diff -c -r -b -B -N -x CVS LVM.vanilla/kernel/lvm.h LVM/kernel/lvm.h *** LVM.vanilla/kernel/lvm.h Tue Jan 1 21:49:48 2002 --- LVM/kernel/lvm.h Thu Nov 29 22:06:46 2001 *************** *** 72,77 **** --- 72,78 ---- * 22/06/2001 - added Andreas Dilger's PE on 4k boundary alignment enhancements * 19/07/2001 - added rwsem compatibility macros for 2.2 kernels * 13/11/2001 - reduced userspace inclusion of kernel headers to a minimum + * 18/11/2001 - added defines for LVM_GET_FEATURE_BITS ioctl [A.Kruis] * */ *************** *** 368,374 **** --- 369,384 ---- /* This is actually the same as _IO ( 0xff, 0x00), oops. Remove for IOP 12+ */ #define LVM_LOCK_LVM _IO ( 0xfe, 0x100) #endif + /* get lvm feature bits */ + #define LVM_GET_FEATURE_BITS _IOR ( 0xfe, 0x9b, 1) /* END ioctls */ + + + /* + * Feature Bits + */ + /* makeing a snapshot witeable is save */ + #define LVM_FEATURE_WRITEABLE_SNAPSHOTS 0x01 /* diff -c -r -b -B -N -x CVS LVM.vanilla/tools/lib/liblvm.h LVM/tools/lib/liblvm.h *** LVM.vanilla/tools/lib/liblvm.h Tue Jan 1 21:49:48 2002 --- LVM/tools/lib/liblvm.h Thu Nov 29 22:06:46 2001 *************** *** 409,414 **** --- 409,415 ---- void lvm_dont_interrupt ( int); int lvm_get_col_numbers ( char *, long **); int lvm_get_iop_version ( void); + int lvm_get_feature_bits ( void); void lvm_init(int argc, char **argv); void lvm_interrupt ( void); int lvm_lock ( void); diff -c -r -b -B -N -x CVS LVM.vanilla/tools/lib/lvm_get_feature_bits.c LVM/tools/lib/lvm_get_feature_bits.c *** LVM.vanilla/tools/lib/lvm_get_feature_bits.c Thu Jan 1 01:00:00 1970 --- LVM/tools/lib/lvm_get_feature_bits.c Mon Nov 19 19:49:11 2001 *************** *** 0 **** --- 1,60 ---- + /* + * tools/lib/lvm_get_iop_version.c + * + * Copyright (C) 2001 Anselm Kruis + * + * November 2001 + * + * + * This LVM library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This LVM library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this LVM library; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA + * + */ + + /* + * Changelog + * + * 18/11/2001 - created + * + */ + + #include <liblvm.h> + + int lvm_get_feature_bits ( void) { + int group = -1; + int ret = 0; + ushort lvm_feature_bits = 0; + + debug_enter ( "lvm_get_feature_bits -- CALLED\n"); + + /* just to ensure existance of /dev/lvm interface special */ + lvm_check_special (); + + if ( ( group = open ( LVM_DEV, O_RDONLY)) == -1) + ret = -LVM_ELVM_IOP_VERSION_OPEN; + else if ( ( ret = ioctl ( group, LVM_GET_FEATURE_BITS, + &lvm_feature_bits)) == -1) ret = -errno; + debug ( "lvm_get_feature_bits -- AFTER ioctl ret: %d\n", ret); + if ( group != -1) close ( group); + /* older kernels didn't have this IOCTL */ + if ( -ret == EINVAL ) { + ret = 0; + lvm_feature_bits = 0; /* no special features */ + } + if ( ret == 0) ret = lvm_feature_bits; + + debug_leave ( "lvm_get_feature_bits -- LEAVING with ret: %d\n", ret); + return ret; + } diff -c -r -b -B -N -x CVS LVM.vanilla/tools/lvchange.c LVM/tools/lvchange.c *** LVM.vanilla/tools/lvchange.c Wed Jul 25 16:52:19 2001 --- LVM/tools/lvchange.c Mon Nov 19 19:46:12 2001 *************** *** 323,334 **** continue; } ! if ( lv->lv_access & LV_SNAPSHOT) { fprintf ( stderr, "%s -- change on snapshot logical " "volume \"%s\" not allowed\n", cmd, lv_name); continue; } if ( lv->lv_access & LV_SNAPSHOT_ORG) { fprintf ( stderr, "%s -- change on logical volume \"%s\" under " "snapshot not allowed\n", cmd, lv_name); --- 323,345 ---- continue; } ! if ( ( lv->lv_access & LV_SNAPSHOT) && ! ( (opt_C) || (opt_a) || (opt_r))) { fprintf ( stderr, "%s -- change on snapshot logical " "volume \"%s\" not allowed\n", cmd, lv_name); continue; } + if ( ( lv->lv_access & LV_SNAPSHOT) && (opt_p)) { + int feature_bits = lvm_get_feature_bits(); + if ( feature_bits < 0 || !(feature_bits & LVM_FEATURE_WRITEABLE_SNAPSHOTS)) { + fprintf ( stderr, "%s -- change on snapshot logical " + "volume \"%s\" not allowed\n", cmd, lv_name); + continue; + } + } + + /* fixme: opt_p should be save */ if ( lv->lv_access & LV_SNAPSHOT_ORG) { fprintf ( stderr, "%s -- change on logical volume \"%s\" under " "snapshot not allowed\n", cmd, lv_name); *************** *** 364,370 **** if ( doit > 0) { doit_sum++; ! lv->lv_access = lv_access; if ( opt_v > 0) printf ( "%s -- changing access permissions " "of logical volume \"%s\"\n", cmd, lv_name); --- 375,383 ---- if ( doit > 0) { doit_sum++; ! /* don't clear access flags except for LV_WRITE and LV_READ */ ! lv->lv_access &= ~( LV_READ | LV_WRITE ) | lv_access; ! lv->lv_access |= lv_access; if ( opt_v > 0) printf ( "%s -- changing access permissions " "of logical volume \"%s\"\n", cmd, lv_name); --- Anselm Kruis Tel. +49 (0)89-356386-74 science + computing ag FAX +49 (0)89-356386-37 Ingolstädter Str. 22 mailto: A.Kruis@science-computing.de D-80807 München WWW: http://www.science-computing.de/ ********************************************************************** *** CeBIT 2002 *** *** Besuchen Sie uns auf der CeBIT vom 13.-20.03.2002 *** *** auf dem Messegelände in Hannover, Halle 11 *** **********************************************************************