r205 - in lvm2/upstream/current: . daemons/clvmd doc include lib lib/activate lib/cache lib/commands lib/config lib/datastruct lib/device lib/display lib/error lib/filters lib/format1 lib/format_pool lib/format_text lib/label lib/locking lib/log lib/metadata lib/mirror lib/misc lib/mm lib/regex lib/report lib/snapshot lib/striped lib/zero man scripts test/config test/datastruct test/device test/filters test/format1 test/mm test/regex tools

Bastian Blank waldi at costa.debian.org
Tue Nov 15 17:45:38 UTC 2005


Author: waldi
Date: Tue Nov 15 17:45:32 2005
New Revision: 205

Added:
   lvm2/upstream/current/lib/misc/lvm-exec.c
   lvm2/upstream/current/lib/misc/lvm-exec.h
   lvm2/upstream/current/man/pvresize.8
   lvm2/upstream/current/tools/pvresize.c
Removed:
   lvm2/upstream/current/lib/datastruct/bitset.c
   lvm2/upstream/current/lib/datastruct/bitset.h
   lvm2/upstream/current/lib/datastruct/hash.c
   lvm2/upstream/current/lib/datastruct/hash.h
   lvm2/upstream/current/lib/misc/selinux.c
   lvm2/upstream/current/lib/misc/selinux.h
   lvm2/upstream/current/lib/mm/dbg_malloc.c
   lvm2/upstream/current/lib/mm/dbg_malloc.h
   lvm2/upstream/current/lib/mm/pool-debug.c
   lvm2/upstream/current/lib/mm/pool-fast.c
   lvm2/upstream/current/lib/mm/pool.c
   lvm2/upstream/current/lib/mm/pool.h
Modified:
   lvm2/upstream/current/VERSION
   lvm2/upstream/current/WHATS_NEW
   lvm2/upstream/current/configure
   lvm2/upstream/current/configure.in
   lvm2/upstream/current/daemons/clvmd/clvmd-command.c
   lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c
   lvm2/upstream/current/daemons/clvmd/clvmd.c
   lvm2/upstream/current/daemons/clvmd/lvm-functions.c
   lvm2/upstream/current/daemons/clvmd/tcp-comms.c
   lvm2/upstream/current/doc/example.conf
   lvm2/upstream/current/include/.symlinks
   lvm2/upstream/current/lib/Makefile.in
   lvm2/upstream/current/lib/activate/activate.c
   lvm2/upstream/current/lib/activate/activate.h
   lvm2/upstream/current/lib/activate/dev_manager.c
   lvm2/upstream/current/lib/activate/dev_manager.h
   lvm2/upstream/current/lib/activate/fs.c
   lvm2/upstream/current/lib/activate/targets.h
   lvm2/upstream/current/lib/cache/lvmcache.c
   lvm2/upstream/current/lib/cache/lvmcache.h
   lvm2/upstream/current/lib/commands/toolcontext.c
   lvm2/upstream/current/lib/commands/toolcontext.h
   lvm2/upstream/current/lib/config/config.c
   lvm2/upstream/current/lib/config/config.h
   lvm2/upstream/current/lib/datastruct/btree.c
   lvm2/upstream/current/lib/datastruct/btree.h
   lvm2/upstream/current/lib/datastruct/list.h
   lvm2/upstream/current/lib/datastruct/str_list.c
   lvm2/upstream/current/lib/datastruct/str_list.h
   lvm2/upstream/current/lib/device/dev-cache.c
   lvm2/upstream/current/lib/device/dev-cache.h
   lvm2/upstream/current/lib/device/dev-io.c
   lvm2/upstream/current/lib/device/device.c
   lvm2/upstream/current/lib/device/device.h
   lvm2/upstream/current/lib/display/display.c
   lvm2/upstream/current/lib/error/errseg.c
   lvm2/upstream/current/lib/filters/filter-composite.c
   lvm2/upstream/current/lib/filters/filter-md.c
   lvm2/upstream/current/lib/filters/filter-persistent.c
   lvm2/upstream/current/lib/filters/filter-regex.c
   lvm2/upstream/current/lib/filters/filter-sysfs.c
   lvm2/upstream/current/lib/filters/filter.c
   lvm2/upstream/current/lib/filters/filter.h
   lvm2/upstream/current/lib/format1/disk-rep.c
   lvm2/upstream/current/lib/format1/disk-rep.h
   lvm2/upstream/current/lib/format1/format1.c
   lvm2/upstream/current/lib/format1/import-export.c
   lvm2/upstream/current/lib/format1/import-extents.c
   lvm2/upstream/current/lib/format1/layout.c
   lvm2/upstream/current/lib/format1/lvm1-label.c
   lvm2/upstream/current/lib/format1/vg_number.c
   lvm2/upstream/current/lib/format_pool/disk_rep.c
   lvm2/upstream/current/lib/format_pool/disk_rep.h
   lvm2/upstream/current/lib/format_pool/format_pool.c
   lvm2/upstream/current/lib/format_pool/import_export.c
   lvm2/upstream/current/lib/format_pool/pool_label.c
   lvm2/upstream/current/lib/format_text/archive.c
   lvm2/upstream/current/lib/format_text/archiver.c
   lvm2/upstream/current/lib/format_text/export.c
   lvm2/upstream/current/lib/format_text/flags.c
   lvm2/upstream/current/lib/format_text/format-text.c
   lvm2/upstream/current/lib/format_text/format-text.h
   lvm2/upstream/current/lib/format_text/import-export.h
   lvm2/upstream/current/lib/format_text/import.c
   lvm2/upstream/current/lib/format_text/import_vsn1.c
   lvm2/upstream/current/lib/format_text/layout.h
   lvm2/upstream/current/lib/format_text/tags.c
   lvm2/upstream/current/lib/format_text/text_import.h
   lvm2/upstream/current/lib/format_text/text_label.c
   lvm2/upstream/current/lib/label/label.c
   lvm2/upstream/current/lib/locking/cluster_locking.c
   lvm2/upstream/current/lib/locking/file_locking.c
   lvm2/upstream/current/lib/locking/locking.c
   lvm2/upstream/current/lib/locking/locking.h
   lvm2/upstream/current/lib/locking/no_locking.c
   lvm2/upstream/current/lib/log/log.c
   lvm2/upstream/current/lib/log/log.h
   lvm2/upstream/current/lib/metadata/lv_alloc.h
   lvm2/upstream/current/lib/metadata/lv_manip.c
   lvm2/upstream/current/lib/metadata/merge.c
   lvm2/upstream/current/lib/metadata/metadata.c
   lvm2/upstream/current/lib/metadata/metadata.h
   lvm2/upstream/current/lib/metadata/mirror.c
   lvm2/upstream/current/lib/metadata/pv_alloc.h
   lvm2/upstream/current/lib/metadata/pv_manip.c
   lvm2/upstream/current/lib/metadata/pv_map.c
   lvm2/upstream/current/lib/metadata/pv_map.h
   lvm2/upstream/current/lib/metadata/segtype.h
   lvm2/upstream/current/lib/mirror/mirrored.c
   lvm2/upstream/current/lib/misc/lib.h
   lvm2/upstream/current/lib/misc/lvm-file.c
   lvm2/upstream/current/lib/misc/lvm-string.c
   lvm2/upstream/current/lib/misc/lvm-string.h
   lvm2/upstream/current/lib/misc/sharedlib.c
   lvm2/upstream/current/lib/mm/memlock.c
   lvm2/upstream/current/lib/regex/matcher.c
   lvm2/upstream/current/lib/regex/matcher.h
   lvm2/upstream/current/lib/regex/parse_rx.c
   lvm2/upstream/current/lib/regex/parse_rx.h
   lvm2/upstream/current/lib/regex/ttree.c
   lvm2/upstream/current/lib/regex/ttree.h
   lvm2/upstream/current/lib/report/columns.h
   lvm2/upstream/current/lib/report/report.c
   lvm2/upstream/current/lib/snapshot/snapshot.c
   lvm2/upstream/current/lib/striped/striped.c
   lvm2/upstream/current/lib/zero/zero.c
   lvm2/upstream/current/make.tmpl.in
   lvm2/upstream/current/man/Makefile.in
   lvm2/upstream/current/man/lvcreate.8
   lvm2/upstream/current/man/lvs.8
   lvm2/upstream/current/man/vgs.8
   lvm2/upstream/current/scripts/lvmconf.sh
   lvm2/upstream/current/test/config/config_t.c
   lvm2/upstream/current/test/datastruct/hash_t.c
   lvm2/upstream/current/test/device/dev_cache_t.c
   lvm2/upstream/current/test/filters/pfilter_t.c
   lvm2/upstream/current/test/filters/rfilter_t.c
   lvm2/upstream/current/test/format1/get_pvs_t.c
   lvm2/upstream/current/test/format1/get_vgs_t.c
   lvm2/upstream/current/test/format1/read_pv_t.c
   lvm2/upstream/current/test/format1/read_vg_t.c
   lvm2/upstream/current/test/format1/write_vg_t.c
   lvm2/upstream/current/test/mm/dbg_malloc_t.c
   lvm2/upstream/current/test/regex/matcher_t.c
   lvm2/upstream/current/test/regex/parse_t.c
   lvm2/upstream/current/tools/Makefile.in
   lvm2/upstream/current/tools/commands.h
   lvm2/upstream/current/tools/lvchange.c
   lvm2/upstream/current/tools/lvconvert.c
   lvm2/upstream/current/tools/lvcreate.c
   lvm2/upstream/current/tools/lvmcmdline.c
   lvm2/upstream/current/tools/lvremove.c
   lvm2/upstream/current/tools/lvrename.c
   lvm2/upstream/current/tools/lvresize.c
   lvm2/upstream/current/tools/lvscan.c
   lvm2/upstream/current/tools/polldaemon.c
   lvm2/upstream/current/tools/pvcreate.c
   lvm2/upstream/current/tools/pvmove.c
   lvm2/upstream/current/tools/pvremove.c
   lvm2/upstream/current/tools/reporter.c
   lvm2/upstream/current/tools/stub.h
   lvm2/upstream/current/tools/toollib.c
   lvm2/upstream/current/tools/toollib.h
   lvm2/upstream/current/tools/tools.h
   lvm2/upstream/current/tools/vgcfgbackup.c
   lvm2/upstream/current/tools/vgchange.c
   lvm2/upstream/current/tools/vgconvert.c
   lvm2/upstream/current/tools/vgcreate.c
   lvm2/upstream/current/tools/vgextend.c
   lvm2/upstream/current/tools/vgmerge.c
   lvm2/upstream/current/tools/vgreduce.c
   lvm2/upstream/current/tools/vgremove.c
Log:
Load LVM2.2.02.00 into /lvm2/upstream/current.


Modified: lvm2/upstream/current/VERSION
==============================================================================
--- lvm2/upstream/current/VERSION	(original)
+++ lvm2/upstream/current/VERSION	Tue Nov 15 17:45:32 2005
@@ -1 +1 @@
-2.01.14 (2005-08-04)
+2.02.00 (2005-11-10)

Modified: lvm2/upstream/current/WHATS_NEW
==============================================================================
--- lvm2/upstream/current/WHATS_NEW	(original)
+++ lvm2/upstream/current/WHATS_NEW	Tue Nov 15 17:45:32 2005
@@ -1,3 +1,67 @@
+Version 2.02.00 - 10th November 2005
+====================================
+  Extend allocation areas to avoid overflow with contiguous with other PVs.
+  Stop lvcreate attempting to wipe zero or error segments.
+  Added new lvs table attributes.
+  Separated out activation preload.
+  Moved activation functions into libdevmapper.
+  Fixed build_dm_name.
+  Add return macros.
+  Added xen xvd devices.
+  Clear up precommitted metadata better.
+  A pvresize implementation.
+  Fix contiguous allocation when there are no preceding segments.
+  Add mirror_seg pointer to lv_segment struct.
+  Only keep a device open if it's known to belong to a locked VG.
+  Fix lvdisplay to show all mirror destinations.
+  Replacement suspend code using libdevmapper dependency tree.
+  Add DEFS to make.tmpl.
+  Use dm_is_dm_major instead of local copy.
+  Allow mapped devices to be used as PVs.
+  Move set_selinux_context into libdevmapper.
+  Fix automatic text metadata buffer expansion (using macro).
+  Cache formatted text metadata buffer between metadata area writes.
+  Add pe_start field to pvs.
+  Add 'LVM-' prefix to uuids.
+  Split lv_segment_area from lv_segment to permit extension.
+  Replacement deactivation code using libdevmapper dependency tree.
+  Simplify dev_manager_info().
+  Attempt to load missing targets using modprobe.
+  Add -a to lvscan.
+  Move mknodes into libdevmapper.
+  Move bitset, hash, pool and dbg_malloc into libdevmapper.
+
+Version 2.01.15 - 16th October 2005
+===================================
+  Refuse to run pvcreate/pvremove on devices we can't open exclusively.
+  Use ORPHAN lock definition throughout.
+  Validate chunksize in lvcreate.
+  Reduce chunksize limit to 512k.
+  Fix chunksize field in reports.
+  Don't hide snapshots from default 'lvs' output.
+  Add is_dm_major() for use in duplicate device detection in lvmcache_add().
+  Really switch device number in lvmcache when it says it is doing so.
+  Option for bitset memory allocation using malloc as well as pool.
+  Don't assume exactly two mirrors when parsing mirror status.
+  Suppress fsync() error message on filesystems that don't support it.
+  Fix yes_no_prompt() error handling.
+  Add lvm.conf comment warning against multiple filter lines.
+  Tidy lvmconf.sh.
+  Add format1 dev_write debug messages.
+  Add clustered VG attribute to report.
+  Move lvconvert parameters into struct lvconvert_params.
+  Add clustered VG flag to LV lock requests.
+  Change LV locking macros to take lv instead of lvid.
+  Prepend 'cluster' activation parameter to mirror log when appropriate.
+  Pass exclusive flag to lv_activate and on to target activation code.
+  Prevent snapshot creation in a clustered VG for now.
+  Factor out adjusted_mirror_region_size() and generate_log_name_format().
+  Move compose_log_line() into mirror directory.
+  Factor out _get_library_path().
+  Don't kill idling clvmd threads.
+  clvmd no longer takes out locks for non-clustered LVs.
+  Recognise ATA over Ethernet (aoe) devices.
+
 Version 2.01.14 - 4th August 2005
 =================================
   Fix lvconvert PV parameter in help string.

Modified: lvm2/upstream/current/configure
==============================================================================
--- lvm2/upstream/current/configure	(original)
+++ lvm2/upstream/current/configure	Tue Nov 15 17:45:32 2005
@@ -310,7 +310,7 @@
 #endif"
 
 ac_default_prefix=/usr
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB CPP EGREP ALLOCA LIBOBJS POW_LIB MSGFMT JOBS STATIC_LINK LVM1 POOL SNAPSHOTS MIRRORS OWNER GROUP COPTIMISE_FLAG CLDFLAGS CLDWHOLEARCHIVE CLDNOWHOLEARCHIVE LDDEPS SOFLAG LVM_VERSION LVM1_FALLBACK DEBUG DEVMAPPER HAVE_LIBDL HAVE_SELINUX CMDLIB LOCALEDIR CONFDIR STATICDIR INTL_PACKAGE INTL CLVMD CLUSTER FSADM LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os AWK CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S SET_MAKE RANLIB ac_ct_RANLIB CPP EGREP ALLOCA LIBOBJS POW_LIB MSGFMT MODPROBE_CMD JOBS STATIC_LINK LVM1 POOL SNAPSHOTS MIRRORS OWNER GROUP COPTIMISE_FLAG CLDFLAGS CLDWHOLEARCHIVE CLDNOWHOLEARCHIVE LDDEPS SOFLAG LVM_VERSION LVM1_FALLBACK DEBUG DEVMAPPER HAVE_LIBDL HAVE_SELINUX CMDLIB LOCALEDIR CONFDIR STATICDIR INTL_PACKAGE INTL CLVMD CLUSTER FSADM LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -1465,7 +1465,7 @@
 		LDDEPS="$LDDEPS"
 		LDFLAGS="$LDFLAGS"
 		SOFLAG="-dynamiclib"
-		DEVMAPPER=no
+		DEVMAPPER=yes
 		ODIRECT=no
 		SELINUX=no
 		CLUSTER=none
@@ -10769,6 +10769,51 @@
 fi
 
 ################################################################################
+# Extract the first word of "modprobe", so it can be a program name with args.
+set dummy modprobe; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_MODPROBE_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MODPROBE_CMD in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MODPROBE_CMD="$MODPROBE_CMD" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_MODPROBE_CMD="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+MODPROBE_CMD=$ac_cv_path_MODPROBE_CMD
+
+if test -n "$MODPROBE_CMD"; then
+  echo "$as_me:$LINENO: result: $MODPROBE_CMD" >&5
+echo "${ECHO_T}$MODPROBE_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+if test x$MODPROBE_CMD != x; then
+	CFLAGS="$CFLAGS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
+fi
+
+################################################################################
 if test "-f VERSION"; then
   LVM_VERSION="\"`cat VERSION`\""
 else
@@ -11501,6 +11546,7 @@
 s, at LIBOBJS@,$LIBOBJS,;t t
 s, at POW_LIB@,$POW_LIB,;t t
 s, at MSGFMT@,$MSGFMT,;t t
+s, at MODPROBE_CMD@,$MODPROBE_CMD,;t t
 s, at JOBS@,$JOBS,;t t
 s, at STATIC_LINK@,$STATIC_LINK,;t t
 s, at LVM1@,$LVM1,;t t

Modified: lvm2/upstream/current/configure.in
==============================================================================
--- lvm2/upstream/current/configure.in	(original)
+++ lvm2/upstream/current/configure.in	Tue Nov 15 17:45:32 2005
@@ -50,7 +50,7 @@
 		LDDEPS="$LDDEPS"
 		LDFLAGS="$LDFLAGS"
 		SOFLAG="-dynamiclib"
-		DEVMAPPER=no
+		DEVMAPPER=yes
 		ODIRECT=no
 		SELINUX=no
 		CLUSTER=none
@@ -516,6 +516,13 @@
 fi
 
 ################################################################################
+AC_PATH_PROG(MODPROBE_CMD, modprobe)
+
+if test x$MODPROBE_CMD != x; then
+	CFLAGS="$CFLAGS -DMODPROBE_CMD=\\\"$MODPROBE_CMD\\\""
+fi
+
+################################################################################
 if test "-f VERSION"; then
   LVM_VERSION="\"`cat VERSION`\""
 else

Modified: lvm2/upstream/current/daemons/clvmd/clvmd-command.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-command.c	(original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-command.c	Tue Nov 15 17:45:32 2005
@@ -65,8 +65,8 @@
 #include <unistd.h>
 #include <errno.h>
 
+#include "libdevmapper.h"
 #include "list.h"
-#include "hash.h"
 #include "locking.h"
 #include "log.h"
 #include "lvm-functions.h"
@@ -109,7 +109,7 @@
 
 	case CLVMD_CMD_LOCK_LV:
 		/* This is the biggie */
-		lock_cmd = args[0];
+		lock_cmd = args[0] & 0x3F;
 		lock_flags = args[1];
 		lockname = &args[2];
 		status = do_lock_lv(lock_cmd, lock_flags, lockname);
@@ -138,7 +138,7 @@
 
 static int lock_vg(struct local_client *client)
 {
-    struct hash_table *lock_hash;
+    struct dm_hash_table *lock_hash;
     struct clvm_header *header =
 	(struct clvm_header *) client->bits.localsock.cmd;
     unsigned char lock_cmd;
@@ -152,23 +152,23 @@
        practice there should only ever be more than two VGs locked
        if a user tries to merge lots of them at once */
     if (client->bits.localsock.private) {
-	lock_hash = (struct hash_table *)client->bits.localsock.private;
+	lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
     }
     else {
-	lock_hash = hash_create(3);
+	lock_hash = dm_hash_create(3);
 	if (!lock_hash)
 	    return ENOMEM;
 	client->bits.localsock.private = (void *)lock_hash;
     }
 
-    lock_cmd = args[0];
+    lock_cmd = args[0] & 0x3F;
     lock_flags = args[1];
     lockname = &args[2];
     DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
 
     if (lock_cmd == LCK_UNLOCK) {
 
-	lkid = (int)(long)hash_lookup(lock_hash, lockname);
+	lkid = (int)(long)dm_hash_lookup(lock_hash, lockname);
 	if (lkid == 0)
 	    return EINVAL;
 
@@ -176,7 +176,7 @@
 	if (status)
 	    status = errno;
 	else
-	    hash_remove(lock_hash, lockname);
+	    dm_hash_remove(lock_hash, lockname);
     }
     else {
 
@@ -184,7 +184,7 @@
 	if (status)
 	    status = errno;
 	else
-	    hash_insert(lock_hash, lockname, (void *)lkid);
+	    dm_hash_insert(lock_hash, lockname, (void *)lkid);
     }
 
     return status;
@@ -268,19 +268,19 @@
 {
     if (client->bits.localsock.private) {
 
-	struct hash_node *v;
-	struct hash_table *lock_hash =
-	    (struct hash_table *)client->bits.localsock.private;
-
-	hash_iterate(v, lock_hash) {
-		int lkid = (int)(long)hash_get_data(lock_hash, v);
-		char *lockname = hash_get_key(lock_hash, v);
+	struct dm_hash_node *v;
+	struct dm_hash_table *lock_hash =
+	    (struct dm_hash_table *)client->bits.localsock.private;
+
+	dm_hash_iterate(v, lock_hash) {
+		int lkid = (int)(long)dm_hash_get_data(lock_hash, v);
+		char *lockname = dm_hash_get_key(lock_hash, v);
 
 		DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
 		sync_unlock(lockname, lkid);
 	}
 
-	hash_destroy(lock_hash);
+	dm_hash_destroy(lock_hash);
 	client->bits.localsock.private = 0;
     }
 }

Modified: lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c	(original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd-gulm.c	Tue Nov 15 17:45:32 2005
@@ -41,6 +41,7 @@
 #include <syslog.h>
 #include <assert.h>
 
+#include "libdevmapper.h"
 #include "ccs.h"
 #include "list.h"
 #include "locking.h"
@@ -49,16 +50,14 @@
 #include "clvmd-comms.h"
 #include "lvm-functions.h"
 #include "clvmd.h"
-#include "hash.h"
 #include "clvmd-gulm.h"
 #include "libgulm.h"
-#include "hash.h"
 
 /* Hash list of nodes in the cluster */
-static struct hash_table *node_hash;
+static struct dm_hash_table *node_hash;
 
 /* hash list of outstanding lock requests */
-static struct hash_table *lock_hash;
+static struct dm_hash_table *lock_hash;
 
 /* Copy of the current quorate state */
 static uint8_t gulm_quorate = 0;
@@ -96,7 +95,7 @@
 static void _cluster_closedown(void);
 
 /* In tcp-comms.c */
-extern struct hash_table *sock_hash;
+extern struct dm_hash_table *sock_hash;
 
 static int add_internal_client(int fd, fd_callback_t callback)
 {
@@ -178,8 +177,8 @@
     pthread_mutex_lock(&lock_start_mutex);
     lock_start_flag = 1;
 
-    node_hash = hash_create(100);
-    lock_hash = hash_create(10);
+    node_hash = dm_hash_create(100);
+    lock_hash = dm_hash_create(10);
 
     /* Get all nodes from CCS */
     if (get_all_cluster_nodes())
@@ -317,8 +316,6 @@
 
 static void set_node_state(struct node_info *ninfo, char *csid, uint8_t nodestate)
 {
-    int oldstate = ninfo->state;
-
     if (nodestate == lg_core_Logged_in)
     {
 	/* Don't clobber NODE_CLVMD state */
@@ -349,15 +346,15 @@
      */
     tcp_remove_client(csid);
 
-    DEBUGLOG("set_node_state, '%s' state = %d (oldstate=%d), num_nodes=%d\n",
-	     ninfo->name, ninfo->state, oldstate, num_nodes);
+    DEBUGLOG("set_node_state, '%s' state = %d num_nodes=%d\n",
+	     ninfo->name, ninfo->state, num_nodes);
 }
 
 static struct node_info *add_or_set_node(char *name, struct in6_addr *ip, uint8_t state)
 {
     struct node_info *ninfo;
 
-    ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
+    ninfo = dm_hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
     if (!ninfo)
     {
 	/* If we can't find that node then re-read the config file in case it
@@ -366,7 +363,7 @@
 	get_all_cluster_nodes();
 
 	/* Now try again */
-	ninfo = hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
+	ninfo = dm_hash_lookup_binary(node_hash, (char *)ip, GULM_MAX_CSID_LEN);
 	if (!ninfo)
 	{
 	    DEBUGLOG("Ignoring node %s, not part of the SAN cluster\n", name);
@@ -512,7 +509,7 @@
     if (in_shutdown)
 	    return 0;
 
-    lwait = hash_lookup(lock_hash, key);
+    lwait = dm_hash_lookup(lock_hash, key);
     if (!lwait)
     {
 	DEBUGLOG("Can't find hash entry for resource %s\n", key);
@@ -557,22 +554,22 @@
     /* First node */
     if (!*context)
     {
-	*context = hash_get_first(node_hash);
+	*context = dm_hash_get_first(node_hash);
     }
     else
     {
-	*context = hash_get_next(node_hash, *context);
+	*context = dm_hash_get_next(node_hash, *context);
     }
     if (*context)
-	ninfo = hash_get_data(node_hash, *context);
+	ninfo = dm_hash_get_data(node_hash, *context);
 
     /* Find a node that is UP */
     while (*context && ninfo->state == NODE_DOWN)
     {
-	*context = hash_get_next(node_hash, *context);
+	*context = dm_hash_get_next(node_hash, *context);
 	if (*context)
 	{
-	    ninfo = hash_get_data(node_hash, *context);
+	    ninfo = dm_hash_get_data(node_hash, *context);
 	}
     }
 
@@ -581,7 +578,7 @@
 	return 0;
     }
 
-    memcpy(csid, hash_get_key(node_hash, *context), GULM_MAX_CSID_LEN);
+    memcpy(csid, dm_hash_get_key(node_hash, *context), GULM_MAX_CSID_LEN);
     return 1;
 }
 
@@ -589,7 +586,7 @@
 {
     struct node_info *ninfo;
 
-    ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
+    ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
     if (!ninfo)
     {
         sprintf(name, "UNKNOWN %s", print_csid(csid));
@@ -603,15 +600,15 @@
 
 static int _csid_from_name(char *csid, char *name)
 {
-    struct hash_node *hn;
+    struct dm_hash_node *hn;
     struct node_info *ninfo;
 
-    hash_iterate(hn, node_hash)
+    dm_hash_iterate(hn, node_hash)
     {
-	ninfo = hash_get_data(node_hash, hn);
+	ninfo = dm_hash_get_data(node_hash, hn);
 	if (strcmp(ninfo->name, name) == 0)
 	{
-	    memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
+	    memcpy(csid, dm_hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
 	    return 0;
 	}
     }
@@ -629,7 +626,7 @@
 {
     struct node_info *ninfo;
 
-    ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
+    ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
     if (!ninfo) {
 	    DEBUGLOG("gulm_add_up_node no node_hash entry for csid %s\n", print_csid(csid));
 	return;
@@ -649,7 +646,7 @@
 {
     struct node_info *ninfo;
 
-    ninfo = hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
+    ninfo = dm_hash_lookup_binary(node_hash, csid, GULM_MAX_CSID_LEN);
     if (!ninfo)
 	return;
 
@@ -666,27 +663,27 @@
 static int _cluster_do_node_callback(struct local_client *master_client,
 				     void (*callback)(struct local_client *, char *csid, int node_up))
 {
-    struct hash_node *hn;
+    struct dm_hash_node *hn;
     struct node_info *ninfo;
 
-    hash_iterate(hn, node_hash)
+    dm_hash_iterate(hn, node_hash)
     {
 	char csid[GULM_MAX_CSID_LEN];
 	struct local_client *client;
 
-	ninfo = hash_get_data(node_hash, hn);
-	memcpy(csid, hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
+	ninfo = dm_hash_get_data(node_hash, hn);
+	memcpy(csid, dm_hash_get_key(node_hash, hn), GULM_MAX_CSID_LEN);
 
 	DEBUGLOG("down_callback. node %s, state = %d\n", ninfo->name, ninfo->state);
 
-	client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+	client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
 	if (!client)
 	{
 	    /* If it's up but not connected, try to make contact */
 	    if (ninfo->state == NODE_UP)
 		    gulm_connect_csid(csid, &client);
 
-	    client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+	    client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
 
 	}
 	if (ninfo->state != NODE_DOWN)
@@ -735,7 +732,7 @@
     /* This needs to be converted from DLM/LVM2 value for GULM */
     if (flags == LCK_NONBLOCK) flags = lg_lock_flag_Try;
 
-    hash_insert(lock_hash, resource, &lwait);
+    dm_hash_insert(lock_hash, resource, &lwait);
     DEBUGLOG("lock_resource '%s', flags=%d, mode=%d\n", resource, flags, mode);
 
     status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
@@ -751,7 +748,7 @@
     pthread_cond_wait(&lwait.cond, &lwait.mutex);
     pthread_mutex_unlock(&lwait.mutex);
 
-    hash_remove(lock_hash, resource);
+    dm_hash_remove(lock_hash, resource);
     DEBUGLOG("lock-resource returning %d\n", lwait.status);
 
     return gulm_to_errno(lwait.status);
@@ -767,7 +764,7 @@
     pthread_mutex_init(&lwait.mutex, NULL);
     pthread_mutex_lock(&lwait.mutex);
 
-    hash_insert(lock_hash, resource, &lwait);
+    dm_hash_insert(lock_hash, resource, &lwait);
 
     DEBUGLOG("unlock_resource %s\n", resource);
     status = lg_lock_state_req(gulm_if, resource, strlen(resource)+1,
@@ -790,7 +787,7 @@
     pthread_cond_wait(&lwait.cond, &lwait.mutex);
     pthread_mutex_unlock(&lwait.mutex);
 
-    hash_remove(lock_hash, resource);
+    dm_hash_remove(lock_hash, resource);
 
     return gulm_to_errno(lwait.status);
 }
@@ -926,7 +923,7 @@
 	    struct node_info *ninfo;
 
 	    /* If it's not in the list, then add it */
-	    ninfo = hash_lookup_binary(node_hash, nodeip, GULM_MAX_CSID_LEN);
+	    ninfo = dm_hash_lookup_binary(node_hash, nodeip, GULM_MAX_CSID_LEN);
 	    if (!ninfo)
 	    {
 		ninfo = malloc(sizeof(struct node_info));
@@ -939,7 +936,7 @@
 		strcpy(ninfo->name, nodename);
 
 		ninfo->state = NODE_DOWN;
-		hash_insert_binary(node_hash, nodeip, GULM_MAX_CSID_LEN, ninfo);
+		dm_hash_insert_binary(node_hash, nodeip, GULM_MAX_CSID_LEN, ninfo);
 	    }
 	}
 	else

Modified: lvm2/upstream/current/daemons/clvmd/clvmd.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/clvmd.c	(original)
+++ lvm2/upstream/current/daemons/clvmd/clvmd.c	Tue Nov 15 17:45:32 2005
@@ -747,6 +747,7 @@
 
 		/* If the client went away in mid command then tidy up */
 		if (thisfd->bits.localsock.in_progress) {
+			pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
 			pthread_mutex_lock(&thisfd->bits.localsock.mutex);
 			thisfd->bits.localsock.state = POST_COMMAND;
 			pthread_cond_signal(&thisfd->bits.localsock.cond);
@@ -763,7 +764,6 @@
 			thisfd->bits.localsock.state = PRE_COMMAND;
 			pthread_cond_signal(&thisfd->bits.localsock.cond);
 			pthread_mutex_unlock(&thisfd->bits.localsock.mutex);
-			pthread_kill(thisfd->bits.localsock.threadid, SIGUSR2);
 
 			jstat =
 			    pthread_join(thisfd->bits.localsock.threadid,

Modified: lvm2/upstream/current/daemons/clvmd/lvm-functions.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/lvm-functions.c	(original)
+++ lvm2/upstream/current/daemons/clvmd/lvm-functions.c	Tue Nov 15 17:45:32 2005
@@ -31,6 +31,9 @@
 #include <syslog.h>
 #include <assert.h>
 
+#include "libdevmapper.h"
+#include "list.h"
+#include "lvm-types.h"
 #include "libdlm.h"
 #include "clvm.h"
 #include "clvmd-comms.h"
@@ -41,11 +44,10 @@
 #include "toolcontext.h"
 #include "log.h"
 #include "activate.h"
-#include "hash.h"
 #include "locking.h"
 
 static struct cmd_context *cmd = NULL;
-static struct hash_table *lv_hash = NULL;
+static struct dm_hash_table *lv_hash = NULL;
 static pthread_mutex_t lv_hash_lock;
 
 struct lv_info {
@@ -59,7 +61,7 @@
 	struct lv_info *lvi;
 
 	pthread_mutex_lock(&lv_hash_lock);
-	lvi = hash_lookup(lv_hash, resource);
+	lvi = dm_hash_lookup(lv_hash, resource);
 	pthread_mutex_unlock(&lv_hash_lock);
 	if (lvi) {
 		return lvi->lock_mode;
@@ -71,13 +73,13 @@
 /* Called at shutdown to tidy the lockspace */
 void unlock_all()
 {
-	struct hash_node *v;
+	struct dm_hash_node *v;
 
 	pthread_mutex_lock(&lv_hash_lock);
-	hash_iterate(v, lv_hash) {
-		struct lv_info *lvi = hash_get_data(lv_hash, v);
+	dm_hash_iterate(v, lv_hash) {
+		struct lv_info *lvi = dm_hash_get_data(lv_hash, v);
 
-		sync_unlock(hash_get_key(lv_hash, v), lvi->lock_id);
+		sync_unlock(dm_hash_get_key(lv_hash, v), lvi->lock_id);
 	}
 	pthread_mutex_unlock(&lv_hash_lock);
 }
@@ -92,7 +94,7 @@
 	flags &= LKF_NOQUEUE;	/* Only LKF_NOQUEUE is valid here */
 
 	pthread_mutex_lock(&lv_hash_lock);
-	lvi = hash_lookup(lv_hash, resource);
+	lvi = dm_hash_lookup(lv_hash, resource);
 	pthread_mutex_unlock(&lv_hash_lock);
 	if (lvi) {
 		/* Already exists - convert it */
@@ -122,7 +124,7 @@
 				 strerror(errno));
 		} else {
 		        pthread_mutex_lock(&lv_hash_lock);
-			hash_insert(lv_hash, resource, lvi);
+			dm_hash_insert(lv_hash, resource, lvi);
 			pthread_mutex_unlock(&lv_hash_lock);
 		}
 		errno = saved_errno;
@@ -138,7 +140,7 @@
 	int saved_errno;
 
 	pthread_mutex_lock(&lv_hash_lock);
-	lvi = hash_lookup(lv_hash, resource);
+	lvi = dm_hash_lookup(lv_hash, resource);
 	pthread_mutex_unlock(&lv_hash_lock);
 	if (!lvi) {
 		DEBUGLOG("hold_unlock, lock not already held\n");
@@ -149,7 +151,7 @@
 	saved_errno = errno;
 	if (!status) {
 	    	pthread_mutex_lock(&lv_hash_lock);
-		hash_remove(lv_hash, resource);
+		dm_hash_remove(lv_hash, resource);
 		pthread_mutex_unlock(&lv_hash_lock);
 		free(lvi);
 	} else {
@@ -168,11 +170,12 @@
 */
 
 /* Activate LV exclusive or non-exclusive */
-static int do_activate_lv(char *resource, int mode)
+static int do_activate_lv(char *resource, unsigned char lock_flags, int mode)
 {
 	int oldmode;
 	int status;
 	int activate_lv;
+	int exclusive = 0;
 	struct lvinfo lvi;
 
 	/* Is it already open ? */
@@ -189,13 +192,17 @@
 		return 0;	/* Success, we did nothing! */
 
 	/* Do we need to activate exclusively? */
-	if (activate_lv == 2)
+	if ((activate_lv == 2) || (mode == LKM_EXMODE)) {
+		exclusive = 1;
 		mode = LKM_EXMODE;
+	}
 
-	/* OK, try to get the lock */
-	status = hold_lock(resource, mode, LKF_NOQUEUE);
-	if (status)
-		return errno;
+	/* Try to get the lock if it's a clustered volume group */
+	if (lock_flags & LCK_CLUSTER_VG) {
+		status = hold_lock(resource, mode, LKF_NOQUEUE);
+		if (status)
+			return errno;
+	}
 
 	/* If it's suspended then resume it */
 	if (!lv_info_by_lvid(cmd, resource, &lvi, 0))
@@ -206,7 +213,7 @@
 			return EIO;
 
 	/* Now activate it */
-	if (!lv_activate(cmd, resource))
+	if (!lv_activate(cmd, resource, exclusive))
 		return EIO;
 
 	return 0;
@@ -255,14 +262,14 @@
 	return 0;
 }
 
-static int do_deactivate_lv(char *resource)
+static int do_deactivate_lv(char *resource, unsigned char lock_flags)
 {
 	int oldmode;
 	int status;
 
 	/* Is it open ? */
 	oldmode = get_current_lock(resource);
-	if (oldmode == -1) {
+	if (oldmode == -1 && (lock_flags & LCK_CLUSTER_VG)) {
 		DEBUGLOG("do_deactivate_lock, lock not already held\n");
 		return 0;	/* We don't need to do anything */
 	}
@@ -270,9 +277,11 @@
 	if (!lv_deactivate(cmd, resource))
 		return EIO;
 
-	status = hold_unlock(resource);
-	if (status)
-		return errno;
+	if (lock_flags & LCK_CLUSTER_VG) {
+		status = hold_unlock(resource);
+		if (status)
+			return errno;
+	}
 
 	return 0;
 }
@@ -283,7 +292,7 @@
 {
 	int status = 0;
 
-	DEBUGLOG("do_lock_lv: resource '%s', cmd = 0x%x, flags = %d\n",
+	DEBUGLOG("do_lock_lv: resource '%s', cmd = 0x%x, flags = %x\n",
 		 resource, command, lock_flags);
 
 	if (!cmd->config_valid || config_files_changed(cmd)) {
@@ -296,7 +305,7 @@
 
 	switch (command) {
 	case LCK_LV_EXCLUSIVE:
-		status = do_activate_lv(resource, LKM_EXMODE);
+		status = do_activate_lv(resource, lock_flags, LKM_EXMODE);
 		break;
 
 	case LCK_LV_SUSPEND:
@@ -309,11 +318,11 @@
 		break;
 
 	case LCK_LV_ACTIVATE:
-		status = do_activate_lv(resource, LKM_CRMODE);
+		status = do_activate_lv(resource, lock_flags, LKM_CRMODE);
 		break;
 
 	case LCK_LV_DEACTIVATE:
-		status = do_deactivate_lv(resource);
+		status = do_deactivate_lv(resource, lock_flags);
 		break;
 
 	default:
@@ -323,7 +332,7 @@
 	}
 
 	/* clean the pool for another command */
-	pool_empty(cmd->mem);
+	dm_pool_empty(cmd->mem);
 
 	DEBUGLOG("Command return is %d\n", status);
 	return status;
@@ -433,23 +442,24 @@
  */
 static void *get_initial_state()
 {
-	char lv[64], vg[64], flags[25];
+	char lv[64], vg[64], flags[25], vg_flags[25];
 	char uuid[65];
 	char line[255];
 	FILE *lvs =
 	    popen
-	    ("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr",
+	    ("lvm lvs --nolocking --noheadings -o vg_uuid,lv_uuid,lv_attr,vg_attr",
 	     "r");
 
 	if (!lvs)
 		return NULL;
 
 	while (fgets(line, sizeof(line), lvs)) {
-	        if (sscanf(line, "%s %s %s\n", vg, lv, flags) == 3) {
+	        if (sscanf(line, "%s %s %s %s\n", vg, lv, flags, vg_flags) == 4) {
 
 			/* States: s:suspended a:active S:dropped snapshot I:invalid snapshot */
 		        if (strlen(vg) == 38 &&                         /* is is a valid UUID ? */
-			    (flags[4] == 'a' || flags[4] == 's')) {	/* is it active or suspended? */
+			    (flags[4] == 'a' || flags[4] == 's') &&	/* is it active or suspended? */
+			    vg_flags[5] == 'c') {			/* is it clustered ? */
 				/* Convert hyphen-separated UUIDs into one */
 				memcpy(&uuid[0], &vg[0], 6);
 				memcpy(&uuid[6], &vg[7], 4);
@@ -503,7 +513,7 @@
 void init_lvhash()
 {
 	/* Create hash table for keeping LV locks & status */
-	lv_hash = hash_create(100);
+	lv_hash = dm_hash_create(100);
 	pthread_mutex_init(&lv_hash_lock, NULL);
 }
 

Modified: lvm2/upstream/current/daemons/clvmd/tcp-comms.c
==============================================================================
--- lvm2/upstream/current/daemons/clvmd/tcp-comms.c	(original)
+++ lvm2/upstream/current/daemons/clvmd/tcp-comms.c	Tue Nov 15 17:45:32 2005
@@ -35,17 +35,17 @@
 #include <netdb.h>
 #include <assert.h>
 
+#include "libdevmapper.h"
 #include "clvm.h"
 #include "clvmd-comms.h"
 #include "clvmd.h"
 #include "clvmd-gulm.h"
-#include "hash.h"
 
 #define DEFAULT_TCP_PORT 21064
 
 static int listen_fd = -1;
 static int tcp_port;
-struct hash_table *sock_hash;
+struct dm_hash_table *sock_hash;
 
 static int get_our_ip_address(char *addr, int *family);
 static int read_from_tcpsock(struct local_client *fd, char *buf, int len, char *csid,
@@ -56,7 +56,7 @@
 {
     struct sockaddr_in6 addr;
 
-    sock_hash = hash_create(100);
+    sock_hash = dm_hash_create(100);
     tcp_port = port ? port : DEFAULT_TCP_PORT;
 
     listen_fd = socket(AF_INET6, SOCK_STREAM, 0);
@@ -101,10 +101,10 @@
        job of clvmd.c whch will do the job when it notices the
        other end has gone. We just need to remove the client(s) from
        the hash table so we don't try to use it for sending any more */
-    client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+    client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
     if (client)
     {
-	hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+	dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
 	client->removeme = 1;
 	close(client->fd);
     }
@@ -112,10 +112,10 @@
     /* Look for a mangled one too */
     csid[0] ^= 0x80;
 
-    client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+    client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
     if (client)
     {
-	hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+	dm_hash_remove_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
 	client->removeme = 1;
 	close(client->fd);
     }
@@ -146,7 +146,7 @@
 	*new_client = client;
 
     /* Add to our list of node sockets */
-    if (hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
+    if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
     {
 	DEBUGLOG("alloc_client mangling CSID for second connection\n");
 	/* This is a duplicate connection but we can't close it because
@@ -159,7 +159,7 @@
 
         /* If it still exists then kill the connection as we should only
            ever have one incoming connection from each node */
-        if (hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
+        if (dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN))
         {
 	    DEBUGLOG("Multiple incoming connections from node\n");
             syslog(LOG_ERR, " Bogus incoming connection from %d.%d.%d.%d\n", csid[0],csid[1],csid[2],csid[3]);
@@ -169,7 +169,7 @@
             return -1;
         }
     }
-    hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
+    dm_hash_insert_binary(sock_hash, csid, GULM_MAX_CSID_LEN, client);
 
     return 0;
 }
@@ -302,7 +302,7 @@
 	/* If the csid was mangled, then make sure we remove the right entry */
 	if (client->bits.net.flags)
 	    remcsid[0] ^= 0x80;
-	hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
+	dm_hash_remove_binary(sock_hash, remcsid, GULM_MAX_CSID_LEN);
 
 	/* Tell cluster manager layer */
 	add_down_node(remcsid);
@@ -381,7 +381,7 @@
     if (memcmp(csid, ourcsid, GULM_MAX_CSID_LEN) == 0)
 	return msglen;
 
-    client = hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
+    client = dm_hash_lookup_binary(sock_hash, csid, GULM_MAX_CSID_LEN);
     if (!client)
     {
 	status = gulm_connect_csid(csid, &client);

Modified: lvm2/upstream/current/doc/example.conf
==============================================================================
--- lvm2/upstream/current/doc/example.conf	(original)
+++ lvm2/upstream/current/doc/example.conf	Tue Nov 15 17:45:32 2005
@@ -33,8 +33,12 @@
     # pattern, the device is accepted; otherwise if any name matches any 'r'
     # pattern it is rejected; otherwise it is accepted.
 
-    # Remember to run vgscan after you change this parameter to ensure 
-    # that the cache file gets regenerated (see below).
+    # Don't have more than one filter line active at once: only one gets used.
+
+    # Run vgscan after you change this parameter to ensure that
+    # the cache file gets regenerated (see below).
+    # If it doesn't do what you expect, check the output of 'vgscan -vvvv'.
+
 
     # By default we accept every block device:
     filter = [ "a/.*/" ]

Modified: lvm2/upstream/current/include/.symlinks
==============================================================================
--- lvm2/upstream/current/include/.symlinks	(original)
+++ lvm2/upstream/current/include/.symlinks	Tue Nov 15 17:45:32 2005
@@ -6,9 +6,7 @@
 ../lib/commands/toolcontext.h
 ../lib/config/config.h
 ../lib/config/defaults.h
-../lib/datastruct/bitset.h
 ../lib/datastruct/btree.h
-../lib/datastruct/hash.h
 ../lib/datastruct/list.h
 ../lib/datastruct/lvm-types.h
 ../lib/datastruct/str_list.h
@@ -34,16 +32,14 @@
 ../lib/metadata/metadata.h
 ../lib/metadata/pv_alloc.h
 ../lib/metadata/segtype.h
-../lib/mm/dbg_malloc.h
 ../lib/mm/memlock.h
-../lib/mm/pool.h
 ../lib/mm/xlate.h
 ../lib/misc/crc.h
 ../lib/misc/intl.h
 ../lib/misc/lib.h
+../lib/misc/lvm-exec.h
 ../lib/misc/lvm-file.h
 ../lib/misc/lvm-string.h
-../lib/misc/selinux.h
 ../lib/misc/sharedlib.h
 ../lib/regex/matcher.h
 ../lib/report/report.h

Modified: lvm2/upstream/current/lib/Makefile.in
==============================================================================
--- lvm2/upstream/current/lib/Makefile.in	(original)
+++ lvm2/upstream/current/lib/Makefile.in	Tue Nov 15 17:45:32 2005
@@ -1,6 +1,6 @@
 #
 # Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
-# Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
 #
 # This file is part of the LVM2.
 #
@@ -37,9 +37,7 @@
 	cache/lvmcache.c \
 	commands/toolcontext.c \
 	config/config.c \
-	datastruct/bitset.c \
 	datastruct/btree.c \
-	datastruct/hash.c \
 	datastruct/str_list.c \
 	device/dev-cache.c \
 	device/dev-io.c \
@@ -76,11 +74,10 @@
 	metadata/segtype.c \
 	metadata/snapshot_manip.c \
 	misc/crc.c \
+	misc/lvm-exec.c \
 	misc/lvm-file.c \
 	misc/lvm-string.c \
-	mm/dbg_malloc.c \
 	mm/memlock.c \
-	mm/pool.c \
 	regex/matcher.c \
 	regex/parse_rx.c \
 	regex/ttree.c \
@@ -136,10 +133,6 @@
 	misc/sharedlib.c
 endif
 
-ifeq ("@HAVE_SELINUX@", "yes")
-  SOURCES += misc/selinux.c
-endif
-
 LIB_STATIC = liblvm.a
 
 $(SUBDIRS): $(LIB_STATIC)

Modified: lvm2/upstream/current/lib/activate/activate.c
==============================================================================
--- lvm2/upstream/current/lib/activate/activate.c	(original)
+++ lvm2/upstream/current/lib/activate/activate.c	Tue Nov 15 17:45:32 2005
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -19,13 +19,14 @@
 #include "memlock.h"
 #include "display.h"
 #include "fs.h"
+#include "lvm-exec.h"
 #include "lvm-file.h"
 #include "lvm-string.h"
-#include "pool.h"
 #include "toolcontext.h"
 #include "dev_manager.h"
 #include "str_list.h"
 #include "config.h"
+#include "filter.h"
 
 #include <limits.h>
 #include <fcntl.h>
@@ -78,7 +79,7 @@
 {
 	return 0;
 }
-int lv_info(const struct logical_volume *lv, struct lvinfo *info,
+int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
 	    int with_open_count)
 {
 	return 0;
@@ -130,11 +131,11 @@
 {
 	return 1;
 }
-int lv_activate(struct cmd_context *cmd, const char *lvid_s)
+int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
 {
 	return 1;
 }
-int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
+int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
 {
 	return 1;
 }
@@ -144,6 +145,12 @@
 	return 1;
 }
 
+int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
+               struct volume_group *vg)
+{
+	return 0;
+}
+
 void activation_exit(void)
 {
 	return;
@@ -257,53 +264,28 @@
 	if (!activation())
 		return 0;
 
-	if (!dm_get_library_version(version, size))
-		return 0;
-	return 1;
+	return dm_get_library_version(version, size);
 }
 
 int driver_version(char *version, size_t size)
 {
-	int r = 0;
-	struct dm_task *dmt;
-
 	if (!activation())
 		return 0;
 
 	log_very_verbose("Getting driver version");
-	if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
-		stack;
-		return 0;
-	}
 
-	if (!dm_task_run(dmt))
-		log_error("Failed to get driver version");
-
-	if (!dm_task_get_driver_version(dmt, version, size))
-		goto out;
-
-	r = 1;
-
-      out:
-	dm_task_destroy(dmt);
-
-	return r;
+	return dm_driver_version(version, size);
 }
 
-int target_present(const char *target_name)
+static int _target_present(const char *target_name)
 {
 	int r = 0;
 	struct dm_task *dmt;
 	struct dm_versions *target, *last_target;
 
-	if (!activation())
-		return 0;
-
 	log_very_verbose("Getting target version for %s", target_name);
-	if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) {
-		stack;
-		return 0;
-	}
+	if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
+		return_0;
 
 	if (!dm_task_run(dmt)) {
 		log_debug("Failed to get %s target version", target_name);
@@ -330,26 +312,56 @@
 	return r;
 }
 
+int target_present(const char *target_name, int use_modprobe)
+{
+#ifdef MODPROBE_CMD
+	char module[128];
+#endif
+
+	if (!activation())
+		return 0;
+
+#ifdef MODPROBE_CMD
+	if (use_modprobe) {
+		if (_target_present(target_name))
+			return 1;
+
+		if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name)
+		    < 0) {
+			log_error("target_present module name too long: %s",
+				  target_name);
+			return 0;
+		}
+
+		if (!exec_cmd(MODPROBE_CMD, module, "", ""))
+			return_0;
+	}
+#endif
+
+	return _target_present(target_name);
+}
+
 /*
  * Returns 1 if info structure populated, else 0 on failure.
  */
-static int _lv_info(const struct logical_volume *lv, int mknodes,
+static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int with_mknodes,
 		    struct lvinfo *info, int with_open_count)
 {
-	int r;
-	struct dev_manager *dm;
 	struct dm_info dminfo;
+	char *name;
 
 	if (!activation())
 		return 0;
 
-	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
-		stack;
-		return 0;
-	}
+	if (!(name = build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL)))
+		return_0;
 
-	if (!(r = dev_manager_info(dm, lv, mknodes, with_open_count, &dminfo)))
-		stack;
+	log_debug("Getting device info for %s", name);
+	if (!dev_manager_info(lv->vg->cmd->mem, name, lv, with_mknodes,
+			      with_open_count, &dminfo)) {
+		dm_pool_free(cmd->mem, name);
+		return_0;
+	}
 
 	info->exists = dminfo.exists;
 	info->suspended = dminfo.suspended;
@@ -357,15 +369,17 @@
 	info->major = dminfo.major;
 	info->minor = dminfo.minor;
 	info->read_only = dminfo.read_only;
+	info->live_table = dminfo.live_table;
+	info->inactive_table = dminfo.inactive_table;
 
-	dev_manager_destroy(dm);
-	return r;
+	dm_pool_free(cmd->mem, name);
+	return 1;
 }
 
-int lv_info(const struct logical_volume *lv, struct lvinfo *info,
+int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
 	    int with_open_count)
 {
-	return _lv_info(lv, 0, info, with_open_count);
+	return _lv_info(cmd, lv, 0, info, with_open_count);
 }
 
 int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
@@ -373,10 +387,10 @@
 {
 	struct logical_volume *lv;
 
-	if (!(lv = lv_from_lvid(cmd, lvid_s)))
+	if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
 		return 0;
 
-	return _lv_info(lv, 0, info, with_open_count);
+	return _lv_info(cmd, lv, 0, info, with_open_count);
 }
 
 /*
@@ -390,10 +404,8 @@
 	if (!activation())
 		return 0;
 
-	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
-		stack;
-		return 0;
-	}
+	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
+		return_0;
 
 	if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
 		stack;
@@ -404,7 +416,7 @@
 }
 
 /* FIXME Merge with snapshot_percent */
-int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
+int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, int wait, float *percent,
 		      uint32_t *event_nr)
 {
 	int r;
@@ -414,18 +426,14 @@
 	if (!activation())
 		return 0;
 
-	if (!lv_info(lv, &info, 0)) {
-		stack;
-		return 0;
-	}
+	if (!lv_info(cmd, lv, &info, 0))
+		return_0;
 
 	if (!info.exists)
 		return 0;
 
-	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
-		stack;
-		return 0;
-	}
+	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
+		return_0;
 
 	if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
 		stack;
@@ -435,11 +443,11 @@
 	return r;
 }
 
-static int _lv_active(struct logical_volume *lv)
+static int _lv_active(struct cmd_context *cmd, struct logical_volume *lv)
 {
 	struct lvinfo info;
 
-	if (!lv_info(lv, &info, 0)) {
+	if (!lv_info(cmd, lv, &info, 0)) {
 		stack;
 		return -1;
 	}
@@ -447,11 +455,11 @@
 	return info.exists;
 }
 
-static int _lv_open_count(struct logical_volume *lv)
+static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
 {
 	struct lvinfo info;
 
-	if (!lv_info(lv, &info, 1)) {
+	if (!lv_info(cmd, lv, &info, 1)) {
 		stack;
 		return -1;
 	}
@@ -459,16 +467,13 @@
 	return info.open_count;
 }
 
-/* FIXME Need to detect and handle an lv rename */
 static int _lv_activate_lv(struct logical_volume *lv)
 {
 	int r;
 	struct dev_manager *dm;
 
-	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
-		stack;
-		return 0;
-	}
+	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
+		return_0;
 
 	if (!(r = dev_manager_activate(dm, lv)))
 		stack;
@@ -477,15 +482,28 @@
 	return r;
 }
 
-static int _lv_deactivate(struct logical_volume *lv)
+static int _lv_preload(struct logical_volume *lv)
 {
 	int r;
 	struct dev_manager *dm;
 
-	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
+	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
+		return_0;
+
+	if (!(r = dev_manager_preload(dm, lv)))
 		stack;
-		return 0;
-	}
+
+	dev_manager_destroy(dm);
+	return r;
+}
+
+static int _lv_deactivate(struct logical_volume *lv)
+{
+	int r;
+	struct dev_manager *dm;
+
+	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
+		return_0;
 
 	if (!(r = dev_manager_deactivate(dm, lv)))
 		stack;
@@ -499,10 +517,8 @@
 	int r;
 	struct dev_manager *dm;
 
-	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
-		stack;
-		return 0;
-	}
+	if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
+		return_0;
 
 	if (!(r = dev_manager_suspend(dm, lv)))
 		stack;
@@ -525,7 +541,7 @@
 
 	list_iterate_items(lvl, &vg->lvs) {
 		if (lvl->lv->status & VISIBLE_LV)
-			count += (_lv_active(lvl->lv) == 1);
+			count += (_lv_active(vg->cmd, lvl->lv) == 1);
 	}
 
 	return count;
@@ -541,7 +557,7 @@
 
 	list_iterate_items(lvl, &vg->lvs) {
 		if (lvl->lv->status & VISIBLE_LV)
-			count += (_lv_open_count(lvl->lv) > 0);
+			count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
 	}
 
 	return count;
@@ -556,7 +572,8 @@
 	if (!activation())
 		return 1;
 
-	if (!(lv = lv_from_lvid(cmd, lvid_s)))
+	/* Use precommitted metadata if present */
+	if (!(lv = lv_from_lvid(cmd, lvid_s, 1)))
 		return 0;
 
 	if (test_mode()) {
@@ -564,14 +581,20 @@
 		return 1;
 	}
 
-	if (!lv_info(lv, &info, 0)) {
-		stack;
-		return 0;
-	}
+	if (!lv_info(cmd, lv, &info, 0))
+		return_0;
 
 	if (!info.exists || info.suspended)
 		return error_if_not_suspended ? 0 : 1;
 
+	/* If VG was precommitted, preload devices for the LV */
+	if ((lv->vg->status & PRECOMMITTED)) {
+		if (!_lv_preload(lv)) {
+			/* FIXME Revert preloading */
+			return_0;
+		}
+	}
+
 	memlock_inc();
 	if (!_lv_suspend_lv(lv)) {
 		memlock_dec();
@@ -602,7 +625,7 @@
 	if (!activation())
 		return 1;
 
-	if (!(lv = lv_from_lvid(cmd, lvid_s)))
+	if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
 		return 0;
 
 	if (test_mode()) {
@@ -610,10 +633,8 @@
 		return 1;
 	}
 
-	if (!lv_info(lv, &info, 0)) {
-		stack;
-		return 0;
-	}
+	if (!lv_info(cmd, lv, &info, 0))
+		return_0;
 
 	if (!info.exists || !info.suspended)
 		return error_if_not_active ? 0 : 1;
@@ -647,7 +668,7 @@
 	if (!activation())
 		return 1;
 
-	if (!(lv = lv_from_lvid(cmd, lvid_s)))
+	if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
 		return 0;
 
 	if (test_mode()) {
@@ -655,16 +676,14 @@
 		return 1;
 	}
 
-	if (!lv_info(lv, &info, 1)) {
-		stack;
-		return 0;
-	}
+	if (!lv_info(cmd, lv, &info, 1))
+		return_0;
 
 	if (!info.exists)
 		return 1;
 
 	if (info.open_count && (lv->status & VISIBLE_LV)) {
-		log_error("LV %s/%s in use: not removing", lv->vg->name,
+		log_error("LV %s/%s in use: not deactivating", lv->vg->name,
 			  lv->name);
 		return 0;
 	}
@@ -686,7 +705,7 @@
 	if (!activation())
 		goto activate;
 
-	if (!(lv = lv_from_lvid(cmd, lvid_s)))
+	if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
 		return 0;
 
 	if (!_passes_activation_filter(cmd, lv)) {
@@ -701,7 +720,8 @@
 	return 1;
 }
 
-static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
+static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
+			int exclusive, int filter)
 {
 	struct logical_volume *lv;
 	struct lvinfo info;
@@ -710,7 +730,7 @@
 	if (!activation())
 		return 1;
 
-	if (!(lv = lv_from_lvid(cmd, lvid_s)))
+	if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
 		return 0;
 
 	if (filter && !_passes_activation_filter(cmd, lv)) {
@@ -724,14 +744,15 @@
 		return 1;
 	}
 
-	if (!lv_info(lv, &info, 0)) {
-		stack;
-		return 0;
-	}
+	if (!lv_info(cmd, lv, &info, 0))
+		return_0;
 
-	if (info.exists && !info.suspended)
+	if (info.exists && !info.suspended && info.live_table)
 		return 1;
 
+	if (exclusive)
+		lv->status |= ACTIVATE_EXCL;
+
 	memlock_inc();
 	r = _lv_activate_lv(lv);
 	memlock_dec();
@@ -741,15 +762,15 @@
 }
 
 /* Activate LV */
-int lv_activate(struct cmd_context *cmd, const char *lvid_s)
+int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
 {
-	return _lv_activate(cmd, lvid_s, 0);
+	return _lv_activate(cmd, lvid_s, exclusive, 0);
 }
 
 /* Activate LV only if it passes filter */
-int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
+int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
 {
-	return _lv_activate(cmd, lvid_s, 1);
+	return _lv_activate(cmd, lvid_s, exclusive, 1);
 }
 
 int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
@@ -758,15 +779,13 @@
 	int r = 1;
 
 	if (!lv) {
-		r = dev_manager_mknodes();
+		r = dm_mknodes(NULL);
 		fs_unlock();
 		return r;
 	}
 
-	if (!_lv_info(lv, 1, &info, 0)) {
-		stack;
-		return 0;
-	}
+	if (!_lv_info(cmd, lv, 1, &info, 0))
+		return_0;
 
 	if (info.exists)
 		r = dev_manager_lv_mknodes(lv);
@@ -778,6 +797,34 @@
 	return r;
 }
 
+/*
+ * Does PV use VG somewhere in its construction?
+ * Returns 1 on failure.
+ */
+int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
+               struct volume_group *vg)
+{
+	struct dev_manager *dm;
+	int r;
+
+	if (!activation())
+		return 0;
+
+	if (!dm_is_dm_major(MAJOR(pv->dev->dev)))
+		return 0;
+
+	if (!(dm = dev_manager_create(cmd, vg->name))) {
+		stack;
+		return 1;
+	}
+
+	r = dev_manager_device_uses_vg(dm, pv->dev, vg);
+
+	dev_manager_destroy(dm);
+
+	return r;
+}
+
 void activation_exit(void)
 {
 	dev_manager_exit();

Modified: lvm2/upstream/current/lib/activate/activate.h
==============================================================================
--- lvm2/upstream/current/lib/activate/activate.h	(original)
+++ lvm2/upstream/current/lib/activate/activate.h	Tue Nov 15 17:45:32 2005
@@ -18,10 +18,6 @@
 
 #include "metadata.h"
 
-#ifdef DEVMAPPER_SUPPORT
-#  include <libdevmapper.h>
-#endif
-
 struct lvinfo {
 	int exists;
 	int suspended;
@@ -29,6 +25,8 @@
 	int major;
 	int minor;
 	int read_only;
+	int live_table;
+	int inactive_table;
 };
 
 void set_activation(int activation);
@@ -38,7 +36,7 @@
 int library_version(char *version, size_t size);
 int lvm1_present(struct cmd_context *cmd);
 
-int target_present(const char *target_name);
+int target_present(const char *target_name, int use_modprobe);
 
 void activation_exit(void);
 
@@ -46,8 +44,9 @@
 int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s);
 int lv_resume(struct cmd_context *cmd, const char *lvid_s);
 int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s);
-int lv_activate(struct cmd_context *cmd, const char *lvid_s);
-int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s);
+int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive);
+int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s,
+			    int exclusive);
 int lv_deactivate(struct cmd_context *cmd, const char *lvid_s);
 
 int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
@@ -55,7 +54,7 @@
 /*
  * Returns 1 if info structure has been populated, else 0.
  */
-int lv_info(const struct logical_volume *lv, struct lvinfo *info,
+int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
 	    int with_open_count);
 int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
 		    struct lvinfo *info, int with_open_count);
@@ -70,7 +69,7 @@
  * Returns 1 if percent has been set, else 0.
  */
 int lv_snapshot_percent(struct logical_volume *lv, float *percent);
-int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
+int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, int wait, float *percent,
 		      uint32_t *event_nr);
 
 /*
@@ -79,6 +78,10 @@
 int lvs_in_vg_activated(struct volume_group *vg);
 int lvs_in_vg_opened(struct volume_group *vg);
 
-int lv_setup_cow_store(struct logical_volume *lv);
+/*
+ * Returns 1 if PV has a dependency tree that uses anything in VG.
+ */
+int pv_uses_vg(struct cmd_context *cmd, struct physical_volume *pv,
+	       struct volume_group *vg);
 
 #endif

Modified: lvm2/upstream/current/lib/activate/dev_manager.c
==============================================================================
--- lvm2/upstream/current/lib/activate/dev_manager.c	(original)
+++ lvm2/upstream/current/lib/activate/dev_manager.c	Tue Nov 15 17:45:32 2005
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.  
- * Copyright (C) 2004 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -16,8 +16,6 @@
 #include "lib.h"
 #include "str_list.h"
 #include "dev_manager.h"
-#include "pool.h"
-#include "hash.h"
 #include "lvm-string.h"
 #include "fs.h"
 #include "defaults.h"
@@ -26,94 +24,24 @@
 #include "toolcontext.h"
 #include "targets.h"
 #include "config.h"
+#include "filter.h"
 
-#include <libdevmapper.h>
 #include <limits.h>
 #include <dirent.h>
 
-/*
- * Algorithm
- * ---------
- *
- * 1) Examine dm directory, and store details of active mapped devices
- *    in the VG.  Indexed by lvid-layer. (_scan_existing_devices)
- *
- * 2) Build lists of visible devices that need to be left in each state:
- *    active, reloaded, suspended.
- *
- * 3) Run through these lists and set the appropriate marks on each device
- *    and its dependencies.
- *
- * 4) Add layers not marked active to remove_list for removal at the end.
- *
- * 5) Remove unmarked layers from core.
- *
- * 6) Activate remaining layers, recursing to handle dependedncies and
- *    skipping any that already exist unless they are marked as needing
- *    reloading.
- *
- * 7) Remove layers in the remove_list.  (_remove_old_layers)
- *
- */
-
 #define MAX_TARGET_PARAMSIZE 50000
-
-enum {
-	ACTIVE = 0,
-	RELOAD = 1,
-	VISIBLE = 2,
-	READWRITE = 3,
-	SUSPENDED = 4,
-	NOPROPAGATE = 5,
-	TOPLEVEL = 6,
-	REMOVE = 7,
-	RESUME_IMMEDIATE = 8
-};
+#define UUID_PREFIX "LVM-"
 
 typedef enum {
+	PRELOAD,
 	ACTIVATE,
 	DEACTIVATE,
 	SUSPEND,
-	RESUME
+	CLEAN
 } action_t;
 
-struct dev_layer {
-	char *name;
-
-	int flags;
-
-	/*
-	 * Setup the dm_task.
-	 */
-	int (*populate) (struct dev_manager * dm,
-			 struct dm_task * dmt, struct dev_layer * dl);
-	struct dm_info info;
-
-	/* lvid plus layer */
-	const char *dlid;
-
-	struct logical_volume *lv;
-
-	/*
-	 * Devices that must be created before this one can be created.
-	 * Reloads get propagated to this list.  Holds str_lists.
-	 */
-	struct list pre_create;
-
-	/* Inverse of pre_create */
-	struct list pre_suspend;
-
-};
-
-struct dl_list {
-	struct list list;
-	struct dev_layer *dl;
-};
-
-static const char *stripe_filler = NULL;
-
 struct dev_manager {
-	struct pool *mem;
+	struct dm_pool *mem;
 
 	struct cmd_context *cmd;
 
@@ -122,50 +50,16 @@
 	uint32_t pvmove_mirror_count;
 
 	char *vg_name;
-
-	/*
-	 * list of struct lv_list, contains lvs that we wish to
-	 * be active after execution.
-	 */
-	struct list active_list;
-
-	/*
-	 * Layers that need reloading.
-	 */
-	struct list reload_list;
-
-	/*
-	 * Layers that need suspending.
-	 */
-	struct list suspend_list;
-
-	/*
-	 * Layers that will need removing after activation.
-	 */
-	struct list remove_list;
-
-	struct hash_table *layers;
 };
 
-/*
- * Functions to manage the flags.
- */
-static inline int _get_flag(struct dev_layer *dl, int bit)
-{
-	return (dl->flags & (1 << bit)) ? 1 : 0;
-}
-
-static inline void _set_flag(struct dev_layer *dl, int bit)
-{
-	dl->flags |= (1 << bit);
-}
+struct lv_layer {
+	struct logical_volume *lv;
+	const char *old_name;
+};
 
-static inline void _clear_flag(struct dev_layer *dl, int bit)
-{
-	dl->flags &= ~(1 << bit);
-}
+static const char *stripe_filler = NULL;
 
-static char *_build_dlid(struct pool *mem, const char *lvid, const char *layer)
+static char *_build_dlid(struct dm_pool *mem, const char *lvid, const char *layer)
 {
 	char *dlid;
 	size_t len;
@@ -173,18 +67,29 @@
 	if (!layer)
 		layer = "";
 
-	len = strlen(lvid) + strlen(layer) + 2;
+	len = sizeof(UUID_PREFIX) + sizeof(union lvid) + strlen(layer);
 
-	if (!(dlid = pool_alloc(mem, len))) {
-		stack;
+	if (!(dlid = dm_pool_alloc(mem, len))) {
+		log_error("_build_dlid: pool allocation failed for %" PRIsize_t
+			  " %s %s.", len, lvid, layer);
 		return NULL;
 	}
 
-	sprintf(dlid, "%s%s%s", lvid, (*layer) ? "-" : "", layer);
+	sprintf(dlid, UUID_PREFIX "%s%s%s", lvid, (*layer) ? "-" : "", layer);
 
 	return dlid;
 }
 
+char *build_dlid(struct dev_manager *dm, const char *lvid, const char *layer)
+{
+	return _build_dlid(dm->mem, lvid, layer);
+}
+
+static inline int _read_only_lv(struct logical_volume *lv)
+{
+	return (!(lv->vg->status & LVM_WRITE) || !(lv->status & LVM_WRITE));
+}
+
 /*
  * Low level device-layer operations.
  */
@@ -210,8 +115,8 @@
 	return dmt;
 }
 
-static int _info_run(const char *name, const char *uuid, struct dm_info *info,
-		     int mknodes, int with_open_count, struct pool *mem,
+static int _info_run(const char *name, const char *dlid, struct dm_info *info,
+		     int mknodes, int with_open_count, struct dm_pool *mem,
 		     char **uuid_out)
 {
 	int r = 0;
@@ -221,7 +126,7 @@
 
 	dmtask = mknodes ? DM_DEVICE_MKNODES : DM_DEVICE_INFO;
 
-	if (!(dmt = _setup_task(name, uuid, 0, dmtask))) {
+	if (!(dmt = _setup_task(name, dlid, 0, dmtask))) {
 		stack;
 		return 0;
 	}
@@ -230,22 +135,16 @@
 		if (!dm_task_no_open_count(dmt))
 			log_error("Failed to disable open_count");
 
-	if (!dm_task_run(dmt)) {
-		stack;
-		goto out;
-	}
+	if (!dm_task_run(dmt))
+		goto_out;
 
-	if (!dm_task_get_info(dmt, info)) {
-		stack;
-		goto out;
-	}
+	if (!dm_task_get_info(dmt, info))
+		goto_out;
 
 	if (info->exists && uuid_out) {
-		if (!(u = dm_task_get_uuid(dmt))) {
-			stack;
-			goto out;
-		}
-		*uuid_out = pool_strdup(mem, u);
+		if (!(u = dm_task_get_uuid(dmt)))
+			goto_out;
+		*uuid_out = dm_pool_strdup(mem, u);
 	}
 	r = 1;
 
@@ -254,14 +153,20 @@
 	return r;
 }
 
-static int _info(const char *name, const char *uuid, int mknodes,
+static int _info(const char *name, const char *dlid, int mknodes,
 		 int with_open_count, struct dm_info *info,
-		 struct pool *mem, char **uuid_out)
+		 struct dm_pool *mem, char **uuid_out)
 {
-	if (!mknodes && uuid && *uuid &&
-	    _info_run(NULL, uuid, info, 0, with_open_count, mem, uuid_out) &&
-	    	      info->exists)
-		return 1;
+	if (!mknodes && dlid && *dlid) {
+		if (_info_run(NULL, dlid, info, 0, with_open_count, mem,
+			      uuid_out) &&
+	    	    info->exists)
+			return 1;
+		else if (_info_run(NULL, dlid + sizeof(UUID_PREFIX) - 1, info,
+				   0, with_open_count, mem, uuid_out) &&
+			 info->exists)
+			return 1;
+	}
 
 	if (name)
 		return _info_run(name, NULL, info, mknodes, with_open_count,
@@ -270,6 +175,21 @@
 	return 0;
 }
 
+int dev_manager_info(struct dm_pool *mem, const char *name,
+		     const struct logical_volume *lv, int with_mknodes,
+		     int with_open_count, struct dm_info *info)
+{
+	const char *dlid;
+
+	if (!(dlid = _build_dlid(mem, lv->lvid.s, NULL))) {
+		log_error("dlid build failed for %s", lv->name);
+		return 0;
+	}
+
+	return _info(name, dlid, with_mknodes, with_open_count, info,
+		     NULL, NULL);
+}
+
 /* FIXME Interface must cope with multiple targets */
 static int _status_run(const char *name, const char *uuid,
 		       unsigned long long *s, unsigned long long *l,
@@ -277,6 +197,7 @@
 {
 	int r = 0;
 	struct dm_task *dmt;
+	struct dm_info info;
 	void *next = NULL;
 	uint64_t start, length;
 	char *type = NULL;
@@ -290,10 +211,11 @@
 	if (!dm_task_no_open_count(dmt))
 		log_error("Failed to disable open_count");
 
-	if (!dm_task_run(dmt)) {
-		stack;
-		goto out;
-	}
+	if (!dm_task_run(dmt))
+		goto_out;
+
+	if (!dm_task_get_info(dmt, &info) || !info.exists)
+		goto_out;
 
 	do {
 		next = dm_get_next_target(dmt, next, &start, &length,
@@ -329,10 +251,17 @@
 		   char **type, uint32_t type_size, char **params,
 		   uint32_t param_size)
 {
-	if (uuid && *uuid && _status_run(NULL, uuid, start, length, type,
-					 type_size, params, param_size)
-	    && *params)
-		return 1;
+	if (uuid && *uuid) {
+		if (_status_run(NULL, uuid, start, length, type,
+				type_size, params, param_size) &&
+		    *params)
+			return 1;
+		else if (_status_run(NULL, uuid + sizeof(UUID_PREFIX) - 1, start,
+				     length, type, type_size, params,
+				     param_size) &&
+			 *params)
+			return 1;
+	}
 
 	if (name && _status_run(name, NULL, start, length, type, type_size,
 				params, param_size))
@@ -342,7 +271,7 @@
 }
 
 static int _percent_run(struct dev_manager *dm, const char *name,
-			const char *uuid,
+			const char *dlid,
 			const char *target_type, int wait,
 			struct logical_volume *lv, float *percent,
 			uint32_t *event_nr)
@@ -362,7 +291,7 @@
 
 	*percent = -1;
 
-	if (!(dmt = _setup_task(name, uuid, event_nr,
+	if (!(dmt = _setup_task(name, dlid, event_nr,
 				wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS))) {
 		stack;
 		return 0;
@@ -371,15 +300,11 @@
 	if (!dm_task_no_open_count(dmt))
 		log_error("Failed to disable open_count");
 
-	if (!dm_task_run(dmt)) {
-		stack;
-		goto out;
-	}
+	if (!dm_task_run(dmt))
+		goto_out;
 
-	if (!dm_task_get_info(dmt, &info) || !info.exists) {
-		stack;
-		goto out;
-	}
+	if (!dm_task_get_info(dmt, &info) || !info.exists)
+		goto_out;
 
 	if (event_nr)
 		*event_nr = info.event_nr;
@@ -407,10 +332,8 @@
 						  dm->cmd->cft, seg, params,
 						  &total_numerator,
 						  &total_denominator,
-						  percent)) {
-			stack;
-			goto out;
-		}
+						  percent))
+			goto_out;
 
 	} while (next);
 
@@ -433,15 +356,20 @@
 	return r;
 }
 
-static int _percent(struct dev_manager *dm, const char *name, const char *uuid,
+static int _percent(struct dev_manager *dm, const char *name, const char *dlid,
 		    const char *target_type, int wait,
 		    struct logical_volume *lv, float *percent,
 		    uint32_t *event_nr)
 {
-	if (uuid && *uuid
-	    && _percent_run(dm, NULL, uuid, target_type, wait, lv, percent,
-			    event_nr))
-		return 1;
+	if (dlid && *dlid) {
+		if (_percent_run(dm, NULL, dlid, target_type, wait, lv, percent,
+				 event_nr))
+			return 1;
+		else if (_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1,
+				      target_type, wait, lv, percent,
+				      event_nr))
+			return 1;
+	}
 
 	if (name && _percent_run(dm, name, NULL, target_type, wait, lv, percent,
 				 event_nr))
@@ -450,1430 +378,149 @@
 	return 0;
 }
 
-static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname)
+/*
+ * dev_manager implementation.
+ */
+struct dev_manager *dev_manager_create(struct cmd_context *cmd,
+				       const char *vg_name)
 {
-	int r = 1;
-	struct dm_task *dmt;
-	char *vgname, *lvname, *layer;
-
-	if (!split_dm_name(dm->mem, dl->name, &vgname, &lvname, &layer)) {
-		log_error("Couldn't split up dm layer name %s", dl->name);
-		return 0;
-	}
-
-	log_verbose("Renaming %s to %s", dl->name, newname);
+	struct dm_pool *mem;
+	struct dev_manager *dm;
 
-	if (!(dmt = _setup_task(dl->name, NULL, 0, DM_DEVICE_RENAME))) {
+	if (!(mem = dm_pool_create("dev_manager", 16 * 1024))) {
 		stack;
-		return 0;
+		return NULL;
 	}
 
-	if (!dm_task_set_newname(dmt, newname)) {
+	if (!(dm = dm_pool_alloc(mem, sizeof(*dm)))) {
 		stack;
-		r = 0;
-		goto out;
+		goto bad;
 	}
 
-	if (!dm_task_no_open_count(dmt))
-		log_error("Failed to disable open_count");
+	dm->cmd = cmd;
+	dm->mem = mem;
 
-	if (!(r = dm_task_run(dmt))) {
-		log_error("Couldn't rename device '%s'.", dl->name);
-		goto out;
+	if (!stripe_filler) {
+		stripe_filler = find_config_str(cmd->cft->root,
+						"activation/missing_stripe_filler",
+						DEFAULT_STRIPE_FILLER);
 	}
+	dm->stripe_filler = stripe_filler;
 
-	if (r && _get_flag(dl, VISIBLE))
-		fs_rename_lv(dl->lv, newname, lvname);
-
-	dl->name = newname;
-
-      out:
-	dm_task_destroy(dmt);
-	return r;
-}
-
-static int _suspend_or_resume(const char *name, action_t suspend)
-{
-	int r;
-	struct dm_task *dmt;
-	int sus = (suspend == SUSPEND) ? 1 : 0;
-	int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME;
-
-	log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name);
-	if (!(dmt = _setup_task(name, NULL, 0, task))) {
+	if (!(dm->vg_name = dm_pool_strdup(dm->mem, vg_name))) {
 		stack;
-		return 0;
+		goto bad;
 	}
 
-	if (!dm_task_no_open_count(dmt))
-		log_error("Failed to disable open_count");
+	dm->target_state = NULL;
 
-	if (!(r = dm_task_run(dmt)))
-		log_error("Couldn't %s device '%s'", sus ? "suspend" : "resume",
-			  name);
+	return dm;
 
-	dm_task_destroy(dmt);
-	return r;
+      bad:
+	dm_pool_destroy(mem);
+	return NULL;
 }
 
-static int _suspend(struct dev_layer *dl)
+void dev_manager_destroy(struct dev_manager *dm)
 {
-	if (!dl->info.exists || dl->info.suspended)
-		return 1;
-
-	if (!_suspend_or_resume(dl->name, SUSPEND)) {
-		stack;
-		return 0;
-	}
+	dm_pool_destroy(dm->mem);
+}
 
-	dl->info.suspended = 1;
-	return 1;
+void dev_manager_exit(void)
+{
+	dm_lib_exit();
 }
 
-static int _resume(struct dev_layer *dl)
+int dev_manager_snapshot_percent(struct dev_manager *dm,
+				 struct logical_volume *lv, float *percent)
 {
-	if (!dl->info.exists || !dl->info.suspended)
-		return 1;
+	char *name;
+	const char *dlid;
+
+	/*
+	 * Build a name for the top layer.
+	 */
+	if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL)))
+		return_0;
 
-	if (!_suspend_or_resume(dl->name, RESUME)) {
+	if (!(dlid = build_dlid(dm, lv->lvid.s, NULL)))
+		return_0;
+
+	/*
+	 * Try and get some info on this device.
+	 */
+	log_debug("Getting device status percentage for %s", name);
+	if (!(_percent(dm, name, dlid, "snapshot", 0, NULL, percent,
+		       NULL))) {
 		stack;
 		return 0;
 	}
 
-	dl->info.suspended = 0;
+	/* FIXME dm_pool_free ? */
+
+	/* If the snapshot isn't available, percent will be -1 */
 	return 1;
 }
 
-static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
+/* FIXME Merge with snapshot_percent, auto-detecting target type */
+/* FIXME Cope with more than one target */
+int dev_manager_mirror_percent(struct dev_manager *dm,
+			       struct logical_volume *lv, int wait,
+			       float *percent, uint32_t *event_nr)
 {
-	int r = 1;
-	struct dm_task *dmt;
-
-	log_verbose("Loading %s", dl->name);
-	if (!(dmt = _setup_task(task == DM_DEVICE_CREATE ? dl->name : NULL,
-				dl->dlid, 0, task))) {
-		stack;
-		return 0;
-	}
-
-	/*
-	 * Populate the table.
-	 */
-	if (!dl->populate(dm, dmt, dl)) {
-		log_error("Couldn't populate device '%s'.", dl->name);
-		r = 0;
-		goto out;
-	}
+	char *name;
+	const char *dlid;
 
 	/*
-	 * Do we want a specific device number ?
+	 * Build a name for the top layer.
 	 */
-	if (dl->lv->major >= 0 && _get_flag(dl, VISIBLE)) {
-		if (!dm_task_set_major(dmt, dl->lv->major)) {
-			log_error("Failed to set major number for %s to %d "
-				  "during activation.", dl->name,
-				  dl->lv->major);
-			goto out;
-		} else
-			log_very_verbose("Set major number for %s to %d.",
-					 dl->name, dl->lv->major);
-	}
-
-	if (dl->lv->minor >= 0 && _get_flag(dl, VISIBLE)) {
-		if (!dm_task_set_minor(dmt, dl->lv->minor)) {
-			log_error("Failed to set minor number for %s to %d "
-				  "during activation.", dl->name,
-				  dl->lv->minor);
-			goto out;
-		} else
-			log_very_verbose("Set minor number for %s to %d.",
-					 dl->name, dl->lv->minor);
-	}
-
-	if (!_get_flag(dl, READWRITE)) {
-		if (!dm_task_set_ro(dmt)) {
-			log_error("Failed to set %s read-only during "
-				  "activation.", dl->name);
-			goto out;
-		} else
-			log_very_verbose("Activating %s read-only", dl->name);
-	}
+	if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL)))
+		return_0;
 
-	if (!dm_task_no_open_count(dmt))
-		log_error("Failed to disable open_count");
+	/* FIXME dm_pool_free ? */
 
-	if (!(r = dm_task_run(dmt))) {
-		log_error("Couldn't load device '%s'.", dl->name);
-		if ((dl->lv->minor >= 0 || dl->lv->major >= 0) &&
-		    _get_flag(dl, VISIBLE))
-			    log_error("Perhaps the persistent device number "
-				      "%d:%d is already in use?",
-				      dl->lv->major, dl->lv->minor);
+	if (!(dlid = build_dlid(dm, lv->lvid.s, NULL))) {
+		log_error("dlid build failed for %s", lv->name);
+		return 0;
 	}
 
-	if (!dm_task_get_info(dmt, &dl->info)) {
+	log_debug("Getting device mirror status percentage for %s", name);
+	if (!(_percent(dm, name, dlid, "mirror", wait, lv, percent,
+		       event_nr))) {
 		stack;
-		r = 0;
-		goto out;
+		return 0;
 	}
 
-	if (!dl->info.exists || !dl->info.live_table) {
-		stack;
-		r = 0;
-		goto out;
-	}
+	return 1;
+}
 
-	if (_get_flag(dl, RESUME_IMMEDIATE) && dl->info.suspended &&
-	    !_resume(dl)) {
-		stack;
-		r = 0;
-		goto out;
-	}
+#if 0
+	log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name);
 
+	log_verbose("Loading %s", dl->name);
+			log_very_verbose("Activating %s read-only", dl->name);
 	log_very_verbose("Activated %s %s %03u:%03u", dl->name,
 			 dl->dlid, dl->info.major, dl->info.minor);
 
-	if (r && _get_flag(dl, VISIBLE))
-		fs_add_lv(dl->lv, dl->name);
-
-	_clear_flag(dl, RELOAD);
-
-      out:
-	dm_task_destroy(dmt);
-	return r;
-}
-
-static int _remove(struct dev_layer *dl)
-{
-	int r;
-	struct dm_task *dmt;
-
 	if (_get_flag(dl, VISIBLE))
 		log_verbose("Removing %s", dl->name);
 	else
 		log_very_verbose("Removing %s", dl->name);
 
-	if (!(dmt = _setup_task(dl->name, NULL, 0, DM_DEVICE_REMOVE))) {
-		stack;
-		return 0;
-	}
+	log_debug("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
+		  extent_size * seg->le, extent_size * seg->len, target, params);
 
-	if (!dm_task_no_open_count(dmt))
-		log_error("Failed to disable open_count");
-
-	/* Suppress error message if it's still in use - we'll log it later */
-	log_suppress(1);
-
-	if ((r = dm_task_run(dmt)))
-		dl->info.exists = 0;
-
-	log_suppress(0);
-
-	dm_task_destroy(dmt);
-
-	if (r && _get_flag(dl, VISIBLE))
-		fs_del_lv(dl->lv);
-
-	_clear_flag(dl, ACTIVE);
-
-	return r;
-}
-
-/*
- * The functions that populate the table in a dm_task as part of
- * a create/reload.
- */
-
-/*
- * Emit a target for a given segment.
- * FIXME: tidy this function.
- */
-static int _emit_target_line(struct dev_manager *dm, struct dm_task *dmt,
-			     struct lv_segment *seg, char *params,
-			     size_t paramsize)
-{
-	uint64_t esize = seg->lv->vg->extent_size;
-	int w = 0;
-	const char *target = NULL;
-	int r;
-
-	if (!seg->segtype->ops->compose_target_line) {
-		log_error("_emit_target: Internal error: Can't handle "
-			  "segment type %s", seg->segtype->name);
-		return 0;
-	}
-
-	if ((r = seg->segtype->ops->compose_target_line(dm, dm->mem,
-							dm->cmd->cft,
-							&dm->target_state, seg,
-							params, paramsize,
-							&target, &w,
-							&dm->
-							pvmove_mirror_count)) <=
-	    0) {
-		stack;
-		return r;
-	}
-
-	log_debug("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
-		  esize * seg->le, esize * seg->len, target, params);
-
-	if (!dm_task_add_target(dmt, esize * seg->le, esize * seg->len,
-				target, params)) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-static int _build_dev_string(struct dev_manager *dm, char *dlid,
-			     char *devbuf, size_t bufsize, const char *desc)
-{
-	struct dev_layer *dl;
-
-	if (!(dl = hash_lookup(dm->layers, dlid))) {
-		log_error("%s device layer %s missing from hash",
-			  desc, dlid);
-		return 0;
-	}
-
-	if (!dm_format_dev(devbuf, bufsize, dl->info.major,
-			   dl->info.minor)) {
-		log_error("Failed to format %s device number for %s as dm "
-			  "target (%u,%u)",
-			  desc, dlid, dl->info.major, dl->info.minor);
-		return 0;
-	}
-
-	return 1;
-}
-
-int compose_log_line(struct dev_manager *dm, struct lv_segment *seg,
-		     char *params, size_t paramsize, int *pos, int areas,
-		     uint32_t region_size)
-{
-	int tw;
-	char devbuf[10];
-	char *name;
-
-	if (!seg->log_lv)
-		tw = lvm_snprintf(params, paramsize, "core 1 %u %u ",
-				  region_size, areas);
-	else {
-		if (!(name = build_dm_name(dm->mem, seg->log_lv->vg->name,
-					   seg->log_lv->name, NULL))) {
-			stack;
-			return 0;
-		}
-
-		if (!_build_dev_string(dm, seg->log_lv->lvid.s, devbuf,
-				       sizeof(devbuf), "log")) {
-			stack;
-			return 0;
-		}
-
-		/* FIXME add sync parm? */
-		tw = lvm_snprintf(params, paramsize, "disk 2 %s %u %u ",
-				  devbuf, region_size, areas);
-	}
-
-	if (tw < 0) {
-		stack;
-		return -1;
-	}
-
-	*pos += tw;
-
-	return 1;
-}
-
-int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
-		       char *params, size_t paramsize, int *pos, int start_area,
-		       int areas)
-{
-	uint32_t s;
-	int tw = 0;
-	const char *trailing_space;
-	uint64_t esize = seg->lv->vg->extent_size;
-	char devbuf[10];
-
-	for (s = start_area; s < areas; s++, *pos += tw) {
-		trailing_space = (areas - s - 1) ? " " : "";
-		if ((seg_type(seg, s) == AREA_PV &&
-		     (!seg_pvseg(seg, s) ||
-		      !seg_pv(seg, s) ||
-		      !seg_dev(seg, s))) ||
-		    (seg_type(seg, s) == AREA_LV && !seg_lv(seg, s)))
-			tw = lvm_snprintf(params + *pos, paramsize - *pos,
-					  "%s 0%s", dm->stripe_filler,
-					  trailing_space);
-		else if (seg_type(seg, s) == AREA_PV)
-			tw = lvm_snprintf(params + *pos, paramsize - *pos,
-					  "%s %" PRIu64 "%s",
-					  dev_name(seg_dev(seg, s)),
-					  (seg_pv(seg, s)->pe_start +
-					   (esize * seg_pe(seg, s))),
-					  trailing_space);
-		else if (seg_type(seg, s) == AREA_LV) {
-			if (!_build_dev_string(dm, seg_lv(seg, s)->lvid.s, devbuf,
-					       sizeof(devbuf), "LV")) {
-				stack;
-				return 0;
-			}
-			tw = lvm_snprintf(params + *pos, paramsize - *pos,
-					  "%s %" PRIu64 "%s", devbuf,
-					  esize * seg_le(seg, s),
-					  trailing_space);
-		} else {
-			log_error("Internal error: Unassigned area found in LV %s.",
-				  seg->lv->name);
-			return 0;
-		}
-
-		if (tw < 0) {
-			stack;
-			return -1;
-		}
-	}
-
-	return 1;
-}
-
-static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
-			struct lv_segment *seg)
-{
-	char *params;
-	size_t paramsize = 4096;
-	int ret;
-
-	do {
-		if (!(params = dbg_malloc(paramsize))) {
-			log_error("Insufficient space for target parameters.");
-			return 0;
-		}
-
-		ret = _emit_target_line(dm, dmt, seg, params, paramsize);
-		dbg_free(params);
-
-		if (!ret)
-			stack;
-
-		if (ret >= 0)
-			return ret;
-
-		log_debug("Insufficient space in params[%" PRIsize_t
-			  "] for target parameters.", paramsize);
-
-		paramsize *= 2;
-	} while (paramsize < MAX_TARGET_PARAMSIZE);
-
-	log_error("Target parameter size too big. Aborting.");
-	return 0;
-}
-
-static int _populate_vanilla(struct dev_manager *dm,
-			     struct dm_task *dmt, struct dev_layer *dl)
-{
-	struct lv_segment *seg;
-	struct logical_volume *lv = dl->lv;
-
-	dm->pvmove_mirror_count = 0u;
-
-	list_iterate_items(seg, &lv->segments) {
-		if (!_emit_target(dm, dmt, seg)) {
-			log_error("Unable to build table for '%s'", lv->name);
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-static int _populate_origin(struct dev_manager *dm,
-			    struct dm_task *dmt, struct dev_layer *dl)
-{
-	char *real;
-	char params[PATH_MAX + 32];
-
-	if (!(real = _build_dlid(dm->mem, dl->lv->lvid.s, "real"))) {
-		stack;
-		return 0;
-	}
-
-	if (!_build_dev_string(dm, real, params, sizeof(params), "origin")) {
-		stack;
-		return 0;
-	}
-
-	log_debug("Adding target: 0 %" PRIu64 " snapshot-origin %s",
-		  dl->lv->size, params);
-	if (!dm_task_add_target(dmt, UINT64_C(0), dl->lv->size,
-				"snapshot-origin", params)) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-static int _populate_snapshot(struct dev_manager *dm,
-			      struct dm_task *dmt, struct dev_layer *dl)
-{
-	char *origin, *cow;
-	char params[PATH_MAX * 2 + 32];
-	struct lv_segment *snap_seg;
-	char devbufo[10], devbufc[10];
-	uint64_t size;
-
-	if (!(snap_seg = find_cow(dl->lv))) {
-		log_error("Couldn't find snapshot for '%s'.", dl->lv->name);
-		return 0;
-	}
-
-	if (!(origin = _build_dlid(dm->mem, snap_seg->origin->lvid.s,
-				   "real"))) {
-		stack;
-		return 0;
-	}
-
-	if (!(cow = _build_dlid(dm->mem, snap_seg->cow->lvid.s, "cow"))) {
-		stack;
-		return 0;
-	}
-
-	if (!_build_dev_string(dm, origin, devbufo, sizeof(devbufo),
-			       "origin")) {
-		stack;
-		return 0;
-	}
-
-	if (!_build_dev_string(dm, cow, devbufc, sizeof(devbufc), "cow")) {
-		stack;
-		return 0;
-	}
-
-	if (lvm_snprintf(params, sizeof(params), "%s %s P %d",
-			 devbufo, devbufc, snap_seg->chunk_size) == -1) {
-		stack;
-		return 0;
-	}
-
-	size = (uint64_t) snap_seg->len * snap_seg->origin->vg->extent_size;
-
-	log_debug("Adding target: 0 %" PRIu64 " snapshot %s", size, params);
-	if (!dm_task_add_target(dmt, UINT64_C(0), size, "snapshot", params)) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-/*
- * dev_manager implementation.
- */
-struct dev_manager *dev_manager_create(struct cmd_context *cmd,
-				       const char *vg_name)
-{
-	struct pool *mem;
-	struct dev_manager *dm;
-
-	if (!(mem = pool_create("dev_manager", 16 * 1024))) {
-		stack;
-		return NULL;
-	}
-
-	if (!(dm = pool_alloc(mem, sizeof(*dm)))) {
-		stack;
-		goto bad;
-	}
-
-	dm->cmd = cmd;
-	dm->mem = mem;
-
-	if (!stripe_filler) {
-		stripe_filler = find_config_str(cmd->cft->root,
-						"activation/missing_stripe_filler",
-						DEFAULT_STRIPE_FILLER);
-	}
-	dm->stripe_filler = stripe_filler;
-
-	if (!(dm->vg_name = pool_strdup(dm->mem, vg_name))) {
-		stack;
-		goto bad;
-	}
-
-	if (!(dm->layers = hash_create(32))) {
-		stack;
-		goto bad;
-	}
-
-	list_init(&dm->active_list);
-	list_init(&dm->reload_list);
-	list_init(&dm->remove_list);
-	list_init(&dm->suspend_list);
-
-	dm->target_state = NULL;
-
-	return dm;
-
-      bad:
-	pool_destroy(mem);
-	return NULL;
-}
-
-void dev_manager_destroy(struct dev_manager *dm)
-{
-	hash_destroy(dm->layers);
-	pool_destroy(dm->mem);
-}
-
-int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
-		     int mknodes, int with_open_count, struct dm_info *info)
-{
-	char *name;
-
-	/*
-	 * Build a name for the top layer.
-	 */
-	if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL))) {
-		stack;
-		return 0;
-	}
-
-	/*
-	 * Try and get some info on this device.
-	 */
-	log_debug("Getting device info for %s", name);
-	if (!_info(name, lv->lvid.s, mknodes, with_open_count, info, NULL,
-		   NULL)) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-int dev_manager_snapshot_percent(struct dev_manager *dm,
-				 struct logical_volume *lv, float *percent)
-{
-	char *name;
-
-	/*
-	 * Build a name for the top layer.
-	 */
-	if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL))) {
-		stack;
-		return 0;
-	}
-
-	/*
-	 * Try and get some info on this device.
-	 */
-	log_debug("Getting device status percentage for %s", name);
-	if (!(_percent(dm, name, lv->lvid.s, "snapshot", 0, NULL, percent,
-		       NULL))) {
-		stack;
-		return 0;
-	}
-
-	/* FIXME pool_free ? */
-
-	/* If the snapshot isn't available, percent will be -1 */
-	return 1;
-}
-
-/* FIXME Merge with snapshot_percent, auto-detecting target type */
-/* FIXME Cope with more than one target */
-int dev_manager_mirror_percent(struct dev_manager *dm,
-			       struct logical_volume *lv, int wait,
-			       float *percent, uint32_t *event_nr)
-{
-	char *name;
-
-	/*
-	 * Build a name for the top layer.
-	 */
-	if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL))) {
-		stack;
-		return 0;
-	}
-
-	/* FIXME pool_free ? */
-
-	log_debug("Getting device mirror status percentage for %s", name);
-	if (!(_percent(dm, name, lv->lvid.s, "mirror", wait, lv, percent,
-		       event_nr))) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
-				     const char *dlid)
-{
-	struct dev_layer *dl;
-	char *uuid;
-
-	if (!(dl = pool_zalloc(dm->mem, sizeof(*dl)))) {
-		stack;
-		return NULL;
-	}
-
-	dl->name = name;
-
-	log_debug("Getting device info for %s", dl->name);
-	if (!_info(dl->name, dlid, 0, 0, &dl->info, dm->mem, &uuid)) {
-		stack;
-		return NULL;
-	}
-
-	if (dl->info.exists)
-		dl->dlid = uuid;
-	else
-		dl->dlid = dlid;
-
-	list_init(&dl->pre_create);
-	list_init(&dl->pre_suspend);
-
-	if (!hash_insert(dm->layers, dl->dlid, dl)) {
-		stack;
-		return NULL;
-	}
-
-	return dl;
-}
-
-static inline int _read_only_lv(struct logical_volume *lv)
-{
-	return (!(lv->vg->status & LVM_WRITE) || !(lv->status & LVM_WRITE));
-}
-
-static struct dev_layer *_create_layer(struct dev_manager *dm,
-				       const char *layer,
-				       struct logical_volume *lv)
-{
-	char *name, *dlid;
-	struct dev_layer *dl;
-
-	if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer))) {
-		stack;
-		return NULL;
-	}
-
-	if (!(dlid = _build_dlid(dm->mem, lv->lvid.s, layer))) {
-		stack;
-		return NULL;
-	}
-
-	if (!(dl = hash_lookup(dm->layers, dlid)) &&
-	    !(dl = _create_dev(dm, name, dlid))) {
-		stack;
-		return NULL;
-	}
-
-	dl->lv = lv;
-
-	if (!_read_only_lv(lv))
-		_set_flag(dl, READWRITE);
-
-	return dl;
-}
-
-/*
- * Finds the specified layer.
- */
-static struct dev_layer *_lookup(struct dev_manager *dm,
-				 const char *lvid, const char *layer)
-{
-	char *dlid;
-	struct dev_layer *dl;
-
-	if (!(dlid = _build_dlid(dm->mem, lvid, layer))) {
-		stack;
-		return NULL;
-	}
-
-	dl = hash_lookup(dm->layers, dlid);
-	pool_free(dm->mem, dlid);
-	return dl;
-}
-
-static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv,
-			   int was_origin)
-{
-	/*
-	 * only one layer.
-	 */
-	struct dev_layer *dl, *dlr;
-	struct lv_segment *seg;
-	uint32_t s;
-
-	if (!(dl = _create_layer(dm, NULL, lv))) {
-		stack;
-		return 0;
-	}
-	dl->populate = _populate_vanilla;
-	if (lv->status & VISIBLE_LV) {
-		_set_flag(dl, VISIBLE);
-		_set_flag(dl, TOPLEVEL);
-	}
-
-	if (lv->status & PVMOVE)
-		_set_flag(dl, TOPLEVEL);
-
-	/* Add dependencies for any LVs that segments refer to */
-	list_iterate_items(seg, &lv->segments) {
-		// When do we need? _set_flag(dl, REMOVE) on the log?
-		if (seg->log_lv &&
-		    !str_list_add(dm->mem, &dl->pre_create,
-				  _build_dlid(dm->mem, seg->log_lv->lvid.s,
-					      NULL))) {
-			stack;
-			return 0;
-		}
-
-		for (s = 0; s < seg->area_count; s++) {
-			if (seg_type(seg, s) != AREA_LV)
-				continue;
-			if (!str_list_add(dm->mem, &dl->pre_create,
-					  _build_dlid(dm->mem,
-						      seg_lv(seg, s)->
-						      lvid.s, NULL))) {
-				stack;
-				return 0;
-			}
-
-			// ? if (seg_lv(seg, s)->status & PVMOVE)
-			_set_flag(dl, NOPROPAGATE);
-			// When do we need? _set_flag(dl, REMOVE) 
-		}
-	}
-
-	if (!was_origin)
-		return 1;
-
-	/* Deactivating the last snapshot */
-	if (!(dlr = _create_layer(dm, "real", lv))) {
-		stack;
-		return 0;
-	}
-
-	dlr->populate = _populate_vanilla;
-	_clear_flag(dlr, VISIBLE);
-	_clear_flag(dlr, TOPLEVEL);
-	_set_flag(dlr, REMOVE);
-
-	/* add the dependency on the real device */
-	if (!str_list_add(dm->mem, &dl->pre_create,
-			  pool_strdup(dm->mem, dlr->dlid))) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-static int _expand_origin_real(struct dev_manager *dm,
-			       struct logical_volume *lv)
-{
-	struct dev_layer *dl;
-	const char *real_dlid;
-
-	if (!(dl = _create_layer(dm, "real", lv))) {
-		stack;
-		return 0;
-	}
-	dl->populate = _populate_vanilla;
-	_clear_flag(dl, VISIBLE);
-	_clear_flag(dl, TOPLEVEL);
-
-	/* Size changes must take effect before tables using it are reloaded */
-	_set_flag(dl, RESUME_IMMEDIATE);
-
-	real_dlid = dl->dlid;
-
-	if (!(dl = _create_layer(dm, NULL, lv))) {
-		stack;
-		return 0;
-	}
-	dl->populate = _populate_origin;
-	_set_flag(dl, VISIBLE);
-	_set_flag(dl, TOPLEVEL);
-
-	/* add the dependency on the real device */
-	if (!str_list_add(dm->mem, &dl->pre_create,
-			  pool_strdup(dm->mem, real_dlid))) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-static int _expand_origin(struct dev_manager *dm, struct logical_volume *lv)
-{
-	struct logical_volume *active;
-	struct lv_segment *snap_seg;
-	struct lv_list *lvl;
-
-	/*
-	 * We only need to create an origin layer if one of our
-	 * snapshots is in the active list
-	 */
-	list_iterate_items(lvl, &dm->active_list) {
-		active = lvl->lv;
-		if ((snap_seg = find_cow(active)) && (snap_seg->origin == lv))
-			return _expand_origin_real(dm, lv);
-	}
-
-	/*
-	 * We're deactivating the last snapshot
-	 */
-	return _expand_vanilla(dm, lv, 1);
-}
-
-static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
-			    struct lv_segment *snap_seg)
-{
-	/*
-	 * snapshot(org, cow)
-	 * cow
-	 */
-	struct dev_layer *dl;
-	const char *cow_dlid;
-
-	if (!(dl = _create_layer(dm, "cow", lv))) {
-		stack;
-		return 0;
-	}
-	dl->populate = _populate_vanilla;
-	_clear_flag(dl, VISIBLE);
-	_clear_flag(dl, TOPLEVEL);
-	_set_flag(dl, READWRITE);
-
-	cow_dlid = dl->dlid;
-
-	if (!(dl = _create_layer(dm, NULL, lv))) {
-		stack;
-		return 0;
-	}
-	dl->populate = _populate_snapshot;
-	_set_flag(dl, VISIBLE);
-	_set_flag(dl, TOPLEVEL);
-
-	/* add the dependency on the cow device */
-	if (!str_list_add(dm->mem, &dl->pre_create,
-			  pool_strdup(dm->mem, cow_dlid))) {
-		stack;
-		return 0;
-	}
-
-	/* add the dependency on the real origin device */
-	if (!str_list_add(dm->mem, &dl->pre_create,
-			  _build_dlid(dm->mem, snap_seg->origin->lvid.s,
-				      "real"))) {
-		stack;
-		return 0;
-	}
-
-	/* add the dependency on the visible origin device */
-	if (!str_list_add(dm->mem, &dl->pre_suspend,
-			  snap_seg->origin->lvid.s)) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-/*
- * Inserts the appropriate dev_layers for a logical volume.
- */
-static int _expand_lv(struct dev_manager *dm, struct logical_volume *lv)
-{
-	struct lv_segment *snap_seg;
-
-	/*
-	 * FIXME: this doesn't cope with recursive snapshots yet.
-	 */
-	if ((snap_seg = find_cow(lv))) {
-		if (lv->vg->status & CLUSTERED) {
-			log_error("Clustered snapshots are not yet supported");
-			return 0;
-		}
-		return _expand_snapshot(dm, lv, snap_seg);
-	} else if (lv_is_origin(lv)) {
-		if (lv->vg->status & CLUSTERED) {
-			log_error("Clustered snapshots are not yet supported");
-			return 0;
-		}
-		return _expand_origin(dm, lv);
-	}
-
-	return _expand_vanilla(dm, lv, 0);
-}
-
-/*
- * Clears the mark bit on all layers.
- */
-static void _clear_marks(struct dev_manager *dm, int flag)
-{
-	struct hash_node *hn;
-	struct dev_layer *dl;
-
-	hash_iterate(hn, dm->layers) {
-		dl = hash_get_data(dm->layers, hn);
-		_clear_flag(dl, flag);
-	}
-}
-
-/*
- * Propogates marks via the pre_create dependency list.
- */
-static int _trace_layer_marks(struct dev_manager *dm, struct dev_layer *dl,
-			      int flag)
-{
-	struct str_list *strl;
-	const char *dlid;
-	struct dev_layer *dep;
-
-	list_iterate_items(strl, &dl->pre_create) {
-		dlid = strl->str;
-
-		if (!(dep = hash_lookup(dm->layers, dlid))) {
-			log_error("Couldn't find device layer '%s'.", dlid);
-			return 0;
-		}
-
-		if (_get_flag(dep, flag))
-			continue;
-
-		/* FIXME Only propagate LV ACTIVE dependencies for now */
-		if ((flag != ACTIVE) && _get_flag(dl, NOPROPAGATE))
-			continue;
-
-		_set_flag(dep, flag);
-
-		if (!_trace_layer_marks(dm, dep, flag)) {
-			stack;
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-/*
- * Calls _trace_single for every marked layer.
- */
-static int _trace_all_marks(struct dev_manager *dm, int flag)
-{
-	struct hash_node *hn;
-	struct dev_layer *dl;
-
-	hash_iterate(hn, dm->layers) {
-		dl = hash_get_data(dm->layers, hn);
-		if (_get_flag(dl, flag) && !_trace_layer_marks(dm, dl, flag)) {
-			stack;
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-/*
- * Marks the top layers, then traces these through the
- * dependencies.
- */
-static int _mark_lvs(struct dev_manager *dm, struct list *lvs, int flag)
-{
-	struct lv_list *lvl;
-	struct dev_layer *dl;
-
-	list_iterate_items(lvl, lvs) {
-		if (lvl->lv->status & SNAPSHOT)
-			continue;
-
-		if (!(dl = _lookup(dm, lvl->lv->lvid.s, NULL))) {
-			stack;
-			return 0;
-		}
-
-		_set_flag(dl, flag);
-	}
-
-	if (!_trace_all_marks(dm, flag)) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-static int _suspend_parents(struct dev_manager *dm, struct dev_layer *dl)
-{
-	struct str_list *strl;
-	struct dev_layer *dep;
-	const char *dlid;
-
-	list_iterate_items(strl, &dl->pre_suspend) {
-		dlid = strl->str;
-
-		if (!(dep = hash_lookup(dm->layers, dlid))) {
-			log_debug("_suspend_parents couldn't find device "
-				  "layer '%s' - skipping.", dlid);
-			continue;
-		}
-
-		if (!strcmp(dep->dlid, dl->dlid)) {
-			log_error("BUG: pre-suspend loop detected (%s)", dlid);
-			return 0;
-		}
-
-		if (!_suspend_parents(dm, dep)) {
-			stack;
-			return 0;
-		}
-
-		if (dep->info.exists & !_suspend(dep)) {
-			stack;
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-static int _resume_with_deps(struct dev_manager *dm, struct dev_layer *dl)
-{
-	struct str_list *strl;
-	struct dev_layer *dep;
-	const char *dlid;
-
-	list_iterate_items(strl, &dl->pre_create) {
-		dlid = strl->str;
-
-		if (!(dep = hash_lookup(dm->layers, dlid))) {
-			log_debug("_resume_with_deps couldn't find device "
-				  "layer '%s' - skipping.", dlid);
-			continue;
-		}
-
-		if (!strcmp(dep->dlid, dl->dlid)) {
-			log_error("BUG: pre-create loop detected (%s)", dlid);
-			return 0;
-		}
-
-		if (!_resume_with_deps(dm, dep)) {
-			stack;
-			return 0;
-		}
-	}
-
-	if (dl->info.exists & !_get_flag(dl, SUSPENDED) && !_resume(dl)) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-/*
- * Recurses through the tree, ensuring that devices are created
- * in correct order.
- */
-static int _create_rec(struct dev_manager *dm, struct dev_layer *dl)
-{
-	struct str_list *strl;
-	struct dev_layer *dep;
-	const char *dlid;
-	char *newname, *suffix;
-
-	/* Suspend? */
-	if (_get_flag(dl, SUSPENDED) &&
-	    (!_suspend_parents(dm, dl) || !_suspend(dl))) {
-		stack;
-		return 0;
-	}
-
-	list_iterate_items(strl, &dl->pre_create) {
-		dlid = strl->str;
-
-		if (!(dep = hash_lookup(dm->layers, dlid))) {
-			log_error("Couldn't find device layer '%s'.", dlid);
-			return 0;
-		}
-
-		if (!strcmp(dep->dlid, dl->dlid)) {
-			log_error("BUG: pre-create loop detected (%s)", dlid);
-			return 0;
-		}
-
-		if (!_create_rec(dm, dep)) {
-			stack;
-			return 0;
-		}
-	}
+	log_debug("Adding target: 0 %" PRIu64 " snapshot-origin %s",
+		  dl->lv->size, params);
+	log_debug("Adding target: 0 %" PRIu64 " snapshot %s", size, params);
+	log_debug("Getting device info for %s", dl->name);
 
 	/* Rename? */
-	if (dl->info.exists) {
-		if ((suffix = rindex(dl->dlid, '-')))
+		if ((suffix = rindex(dl->dlid + sizeof(UUID_PREFIX) - 1, '-')))
 			suffix++;
 		newname = build_dm_name(dm->mem, dm->vg_name, dl->lv->name,
 					suffix);
-		if (strcmp(newname, dl->name)) {
-			if (!_suspend_parents(dm, dl) ||
-			    !_suspend(dl) || !_rename(dm, dl, newname)) {
-				stack;
-				return 0;
-			}
-		}
-	}
-
-	/* Create? */
-	if (!dl->info.exists) {
-		if (!_suspend_parents(dm, dl) ||
-		    !_load(dm, dl, DM_DEVICE_CREATE)) {
-			stack;
-			return 0;
-		}
-		return 1;
-	}
-
-	/* Reload? */
-	if (_get_flag(dl, RELOAD) &&
-	    (!_suspend_parents(dm, dl) || !_suspend(dl) ||
-	     !_load(dm, dl, DM_DEVICE_RELOAD))) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-static int _build_all_layers(struct dev_manager *dm, struct volume_group *vg)
-{
-	struct lv_list *lvl;
-
-	/*
-	 * Build layers for complete vg.
-	 */
-	list_iterate_items(lvl, &vg->lvs) {
-		if (lvl->lv->status & SNAPSHOT)
-			continue;
-		if (!_expand_lv(dm, lvl->lv)) {
-			stack;
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-static int _fill_in_remove_list(struct dev_manager *dm)
-{
-	struct hash_node *hn;
-	struct dev_layer *dl;
-	struct dl_list *dll;
-
-	hash_iterate(hn, dm->layers) {
-		dl = hash_get_data(dm->layers, hn);
-
-		if (_get_flag(dl, REMOVE))
-			_clear_flag(dl, ACTIVE);
-
-		if (!_get_flag(dl, ACTIVE)) {
-			dll = pool_alloc(dm->mem, sizeof(*dll));
-			if (!dll) {
-				stack;
-				return 0;
-			}
-
-			dll->dl = dl;
-			list_add(&dm->remove_list, &dll->list);
-		}
-	}
-
-	return 1;
-}
-
-static int _populate_pre_suspend_lists(struct dev_manager *dm)
-{
-	struct hash_node *hn;
-	struct dev_layer *dl;
-	struct str_list *strl;
-	const char *dlid;
-	struct dev_layer *dep;
-
-	hash_iterate(hn, dm->layers) {
-		dl = hash_get_data(dm->layers, hn);
-
-		list_iterate_items(strl, &dl->pre_suspend) {
-			dlid = strl->str;
-
-			if (!(dep = hash_lookup(dm->layers, dlid))) {
-				log_debug("_populate_pre_suspend_lists: "
-					  "Couldn't find device layer '%s' - "
-					  "skipping.", dlid);
-				continue;
-			}
-
-			if (!str_list_add(dm->mem, &dep->pre_create, dl->dlid)) {
-				stack;
-				return 0;
-			}
-		}
-
-		list_iterate_items(strl, &dl->pre_create) {
-			dlid = strl->str;
-
-			if (!(dep = hash_lookup(dm->layers, dlid))) {
-				log_debug("_populate_pre_suspend_lists: "
-					  "Couldn't find device layer '%s' - "
-					  "skipping.", dlid);
-				continue;
-			}
-
-			if (!str_list_add(dm->mem, &dep->pre_suspend, dl->dlid)) {
-				stack;
-				return 0;
-			}
-		}
-	}
-
-	return 1;
-}
-
-/*
- * Layers are removed in a top-down manner.
- */
-static int _remove_old_layers(struct dev_manager *dm)
-{
-	int change;
-	struct dl_list *dll;
-	struct list *rh, *n;
-	struct dev_layer *dl;
-
-	do {
-		change = 0;
-		list_iterate_safe(rh, n, &dm->remove_list) {
-			dl = list_item(rh, struct dl_list)->dl;
-
-			if (!dl->info.exists) {
-				list_del(rh);
-				continue;
-			}
 
-			if (_remove(dl)) {
-				change = 1;
-				list_del(rh);
-			}
-		}
-
-	} while (change);
-
-	if (!list_empty(&dm->remove_list)) {
-		list_iterate_items(dll, &dm->remove_list)
-			log_error("Couldn't deactivate device %s", dll->dl->name);
-		return 0;
-	}
-
-	return 1;
-}
-
-/*
- * The guts of the activation unit, this examines the device
- * layers in the manager, and tries to issue the correct
- * instructions to activate them in order.
- */
-static int _execute(struct dev_manager *dm, struct volume_group *vg)
-{
-	struct hash_node *hn;
-	struct dev_layer *dl;
-
-	if (!_build_all_layers(dm, vg)) {
-		stack;
-		return 0;
-	}
-
-	/*
-	 * Mark all layer that need reloading.
-	 */
-	_clear_marks(dm, RELOAD);
-	if (!_mark_lvs(dm, &dm->reload_list, RELOAD)) {
-		stack;
-		return 0;
-	}
-
-	/*
-	 * Mark all layers that should be active.
-	 */
-	_clear_marks(dm, ACTIVE);
-	if (!_mark_lvs(dm, &dm->active_list, ACTIVE)) {
-		stack;
-		return 0;
-	}
-
-	/* 
-	 * Mark all layers that should be left suspended.
-	 */
-	_clear_marks(dm, SUSPENDED);
-	if (!_mark_lvs(dm, &dm->suspend_list, SUSPENDED)) {
-		stack;
-		return 0;
-	}
-
-	if (!_fill_in_remove_list(dm)) {
-		stack;
-		return 0;
-	}
-
-	if (!_populate_pre_suspend_lists(dm)) {
-		stack;
-		return 0;
-	}
-
-	/*
-	 * Now only top level devices will be unmarked.
-	 */
-	hash_iterate(hn, dm->layers) {
-		dl = hash_get_data(dm->layers, hn);
-
-		if (_get_flag(dl, ACTIVE) && _get_flag(dl, TOPLEVEL))
-			if (!_create_rec(dm, dl)) {
-				stack;
-				return 0;
-			}
-	}
-
-	/* Resume devices */
-	hash_iterate(hn, dm->layers) {
-		dl = hash_get_data(dm->layers, hn);
-
-		if (!_resume_with_deps(dm, dl)) {
-			stack;
-			return 0;
-		}
-	}
-
-	if (!_remove_old_layers(dm)) {
-		stack;
-		return 0;
-	}
-
-	return 1;
-}
-
-/*
- * ATM we decide which vg a layer belongs to by
- * looking at the beginning of the device
- * name.
- */
 static int _belong_to_vg(const char *vgname, const char *name)
 {
 	const char *v = vgname, *n = name;
@@ -1890,378 +537,552 @@
 		return 0;
 }
 
-static int _add_existing_layer(struct dev_manager *dm, const char *name)
-{
-	struct dev_layer *dl;
-	char *copy;
+	if (!(snap_seg = find_cow(lv)))
+		return 1;
 
-	log_debug("Found existing layer '%s'", name);
+	old_origin = snap_seg->origin;
 
-	if (!(copy = pool_strdup(dm->mem, name))) {
-		stack;
-		return 0;
+	/* Was this the last active snapshot with this origin? */
+	list_iterate_items(lvl, active_head) {
+		active = lvl->lv;
+		if ((snap_seg = find_cow(active)) &&
+		    snap_seg->origin == old_origin) {
+			return 1;
+		}
 	}
 
-	if (!(dl = _create_dev(dm, copy, ""))) {
-		stack;
-		return 0;
-	}
+#endif
 
-	return 1;
+/*************************/
+/*  NEW CODE STARTS HERE */
+/*************************/
+
+int dev_manager_lv_mknodes(const struct logical_volume *lv)
+{
+	char *name;
+
+	if (!(name = build_dm_name(lv->vg->cmd->mem, lv->vg->name,
+				   lv->name, NULL)))
+		return_0;
+
+	return fs_add_lv(lv, name);
 }
 
-static int _scan_existing_devices(struct dev_manager *dm)
+int dev_manager_lv_rmnodes(const struct logical_volume *lv)
 {
-	int r = 0;
-	struct dm_names *names;
-	unsigned next = 0;
+	return fs_del_lv(lv);
+}
 
-	struct dm_task *dmt;
+static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
+			       struct logical_volume *lv, const char *layer)
+{
+	char *dlid, *name;
+	struct dm_info info;
 
-	if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
+	if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
+		return_0;
+
+	if (!(dlid = build_dlid(dm, lv->lvid.s, layer)))
+		return_0;
+
+        log_debug("Getting device info for %s [%s]", name, dlid);
+        if (!_info(name, dlid, 0, 1, &info, dm->mem, NULL)) {
+                log_error("Failed to get info for %s [%s].", name, dlid);
+                return 0;
+        }
+
+	if (info.exists && !dm_tree_add_dev(dtree, info.major, info.minor)) {
+		log_error("Failed to add device (%" PRIu32 ":%" PRIu32") to dtree",
+			  info.major, info.minor);
 		return 0;
+	}
 
-	if (!dm_task_run(dmt))
-		goto out;
+	return 1;
+}
 
-	if (!(names = dm_task_get_names(dmt)))
-		goto out;
+/*
+ * Add LV and any known dependencies
+ */
+static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, struct logical_volume *lv)
+{
+	if (!_add_dev_to_dtree(dm, dtree, lv, NULL))
+		return_0;
 
-	r = 1;
-	if (!names->dev)
-		goto out;
+	/* FIXME Can we avoid doing this every time? */
+	if (!_add_dev_to_dtree(dm, dtree, lv, "real"))
+		return_0;
 
-	do {
-		names = (void *) names + next;
-		if (_belong_to_vg(dm->vg_name, names->name) &&
-		    !_add_existing_layer(dm, names->name)) {
-			stack;
-			r = 0;
-			break;
-		}
-		next = names->next;
-	} while (next);
+	if (!_add_dev_to_dtree(dm, dtree, lv, "cow"))
+		return_0;
 
-      out:
-	dm_task_destroy(dmt);
-	return r;
+	return 1;
 }
 
-static int _add_lv(struct pool *mem,
-		   struct list *head, struct logical_volume *lv)
+static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, struct logical_volume *lv)
 {
-	struct lv_list *lvl;
+	struct dm_tree *dtree;
+	struct list *snh, *snht;
+	struct lv_segment *seg;
+	uint32_t s;
+
+	if (!(dtree = dm_tree_create())) {
+		log_error("Partial dtree creation failed for %s.", lv->name);
+		return NULL;
+	}
 
-	if (!(lvl = pool_alloc(mem, sizeof(*lvl)))) {
+	if (!_add_lv_to_dtree(dm, dtree, lv)) {
 		stack;
-		return 0;
+		goto fail;
 	}
 
-	lvl->lv = lv;
-	list_add(head, &lvl->list);
+	/* Add any snapshots of this LV */
+	list_iterate_safe(snh, snht, &lv->snapshot_segs)
+		if (!_add_lv_to_dtree(dm, dtree, list_struct_base(snh, struct lv_segment, origin_list)->cow)) {
+			stack;
+			goto fail;
+		}
 
-	return 1;
+	/* Add any LVs used by segments in this LV */
+	list_iterate_items(seg, &lv->segments)
+		for (s = 0; s < seg->area_count; s++)
+			if (seg_type(seg, s) == AREA_LV && seg_lv(seg, s)) {
+				if (!_add_lv_to_dtree(dm, dtree, seg_lv(seg, s))) {
+					stack;
+					goto fail;
+				}
+			}
+
+	return dtree;
+
+fail:
+	dm_tree_free(dtree);
+	return NULL;
 }
 
-static int _add_lvs(struct pool *mem,
-		    struct list *head, struct logical_volume *origin)
+int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
+		   struct dm_tree_node *node, int start_area, int areas)
 {
-	struct lv_segment *snap_seg;
-	struct lv_list *lvl;
+	uint64_t extent_size = seg->lv->vg->extent_size;
+	uint32_t s;
+	char *dlid;
 
-	list_iterate_items(lvl, &origin->vg->lvs) {
-		if (lvl->lv->status & SNAPSHOT)
-			continue;
-		if ((snap_seg = find_cow(lvl->lv)) && snap_seg->origin == origin)
-			if (!_add_lv(mem, head, lvl->lv))
-				return 0;
+	for (s = start_area; s < areas; s++) {
+		if ((seg_type(seg, s) == AREA_PV &&
+		     (!seg_pvseg(seg, s) ||
+		      !seg_pv(seg, s) ||
+		      !seg_dev(seg, s))) ||
+		    (seg_type(seg, s) == AREA_LV && !seg_lv(seg, s)))
+			dm_tree_node_add_target_area(node,
+							dm->stripe_filler,
+							NULL, 0);
+		else if (seg_type(seg, s) == AREA_PV)
+			dm_tree_node_add_target_area(node,
+							dev_name(seg_dev(seg, s)),
+							NULL,
+							(seg_pv(seg, s)->pe_start +
+							 (extent_size * seg_pe(seg, s))));
+		else if (seg_type(seg, s) == AREA_LV) {
+			if (!(dlid = build_dlid(dm,
+						 seg_lv(seg, s)->lvid.s,
+						 NULL)))
+				return_0;
+			dm_tree_node_add_target_area(node, NULL, dlid,
+							extent_size * seg_le(seg, s));
+		} else {
+			log_error("Internal error: Unassigned area found in LV %s.",
+				  seg->lv->name);
+			return 0;
+		}
 	}
 
-	return _add_lv(mem, head, origin);
+	return 1;
 }
 
-static void _remove_lv(struct list *head, struct logical_volume *lv)
+static int _add_origin_target_to_dtree(struct dev_manager *dm,
+					 struct dm_tree *dtree,
+					 struct dm_tree_node *dnode,
+					 struct logical_volume *lv)
 {
-	struct lv_list *lvl;
+	const char *real_dlid;
 
-	list_iterate_items(lvl, head) {
-		if (lvl->lv == lv) {
-			list_del(&lvl->list);
-			break;
-		}
-	}
+	if (!(real_dlid = build_dlid(dm, lv->lvid.s, "real")))
+		return_0;
+
+	if (!dm_tree_node_add_snapshot_origin_target(dnode, lv->size, real_dlid))
+		return_0;
+
+	return 1;
 }
 
-static int _remove_lvs(struct dev_manager *dm, struct logical_volume *lv)
+static int _add_snapshot_target_to_dtree(struct dev_manager *dm,
+					   struct dm_tree *dtree,
+					   struct dm_tree_node *dnode,
+					   struct logical_volume *lv)
 {
-	struct logical_volume *active, *old_origin;
+	const char *origin_dlid;
+	const char *cow_dlid;
 	struct lv_segment *snap_seg;
-	struct list *active_head;
-	struct lv_list *lvl;
-
-	active_head = &dm->active_list;
+	uint64_t size;
 
-	/* Remove any snapshots with given origin */
-	list_iterate_items(lvl, active_head) {
-		active = lvl->lv;
-		if ((snap_seg = find_cow(active)) && snap_seg->origin == lv) {
-			_remove_lv(active_head, active);
-		}
+	if (!(snap_seg = find_cow(lv))) {
+		log_error("Couldn't find snapshot for '%s'.", lv->name);
+		return 0;
 	}
 
-	_remove_lv(active_head, lv);
+	if (!(origin_dlid = build_dlid(dm, snap_seg->origin->lvid.s, "real")))
+		return_0;
 
-	if (!(snap_seg = find_cow(lv)))
-		return 1;
+	if (!(cow_dlid = build_dlid(dm, snap_seg->cow->lvid.s, "cow")))
+		return_0;
 
-	old_origin = snap_seg->origin;
+	size = (uint64_t) snap_seg->len * snap_seg->origin->vg->extent_size;
 
-	/* Was this the last active snapshot with this origin? */
-	list_iterate_items(lvl, active_head) {
-		active = lvl->lv;
-		if ((snap_seg = find_cow(active)) &&
-		    snap_seg->origin == old_origin) {
-			return 1;
-		}
-	}
+	if (!dm_tree_node_add_snapshot_target(dnode, size, origin_dlid, cow_dlid, 1, snap_seg->chunk_size))
+		return_0;
 
-	return _add_lvs(dm->mem, &dm->reload_list, old_origin);
+	return 1;
 }
 
-static int _remove_suspended_lvs(struct dev_manager *dm,
-				 struct logical_volume *lv)
+static int _add_target_to_dtree(struct dev_manager *dm,
+				  struct dm_tree *dtree,
+				  struct dm_tree_node *dnode,
+				  struct lv_segment *seg)
 {
-	struct logical_volume *suspended;
-	struct lv_segment *snap_seg;
-	struct list *suspend_head;
-	struct lv_list *lvl;
+	uint64_t extent_size = seg->lv->vg->extent_size;
 
-	suspend_head = &dm->suspend_list;
+	if (!seg->segtype->ops->add_target_line) {
+		log_error("_emit_target: Internal error: Can't handle "
+			  "segment type %s", seg->segtype->name);
+		return 0;
+	}
 
-	/* Remove from list any snapshots with given origin */
-	list_iterate_items(lvl, suspend_head) {
-		suspended = lvl->lv;
-		if ((snap_seg = find_cow(suspended)) &&
-		    snap_seg->origin == lv) {
-			_remove_lv(suspend_head, suspended);
-		}
+	return seg->segtype->ops->add_target_line(dm, dm->mem, dm->cmd->cft,
+						  &dm->target_state, seg,
+						  dnode,
+						  extent_size * seg->len,
+						  &dm-> pvmove_mirror_count);
+}
+
+static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
+				  struct logical_volume *lv, const char *layer);
+
+static int _add_segment_to_dtree(struct dev_manager *dm,
+				   struct dm_tree *dtree,
+				   struct dm_tree_node *dnode,
+				   struct lv_segment *seg,
+				   const char *layer)
+{
+	uint32_t s;
+	struct list *snh;
+
+	/* Ensure required device-mapper targets are loaded */
+	if (seg->segtype->ops->target_present &&
+	    !seg->segtype->ops->target_present()) {
+		log_error("Can't expand LV %s: %s target support missing "
+			  "from kernel?", seg->lv->name, seg->segtype->name);
+		return 0;
 	}
 
-	_remove_lv(suspend_head, lv);
+	/* Add mirror log */
+	if (seg->log_lv &&
+	    !_add_new_lv_to_dtree(dm, dtree, seg->log_lv, NULL))
+		return_0;
+
+	/* If this is a snapshot origin, add real LV */
+	if (lv_is_origin(seg->lv) && !layer) {
+		if (seg->lv->vg->status & CLUSTERED) {
+			log_error("Clustered snapshots are not yet supported");
+			return 0;
+		}
+		if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, "real"))
+			return_0;
+	} else if (lv_is_cow(seg->lv) && !layer) {
+		if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, "cow"))
+			return_0;
+	} else {
+		/* Add any LVs used by this segment */
+		for (s = 0; s < seg->area_count; s++)
+			if ((seg_type(seg, s) == AREA_LV) &&
+			    (!_add_new_lv_to_dtree(dm, dtree, seg_lv(seg, s), NULL)))
+				return_0;
+	}
+
+	/* Now we've added its dependencies, we can add the target itself */
+	if (lv_is_origin(seg->lv) && !layer) {
+		if (!_add_origin_target_to_dtree(dm, dtree, dnode, seg->lv))
+			return_0;
+	} else if (lv_is_cow(seg->lv) && !layer) {
+		if (!_add_snapshot_target_to_dtree(dm, dtree, dnode, seg->lv))
+			return_0;
+	} else if (!_add_target_to_dtree(dm, dtree, dnode, seg))
+		return_0;
+
+	if (lv_is_origin(seg->lv) && !layer)
+		/* Add any snapshots of this LV */
+		list_iterate(snh, &seg->lv->snapshot_segs)
+			if (!_add_new_lv_to_dtree(dm, dtree, list_struct_base(snh, struct lv_segment, origin_list)->cow, NULL))
+				return_0;
 
 	return 1;
 }
 
-static int _targets_present(struct dev_manager *dm, struct list *lvs)
+static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
+				  struct logical_volume *lv, const char *layer)
 {
-	struct logical_volume *lv;
-	struct lv_list *lvl;
-	struct segment_type *segtype;
 	struct lv_segment *seg;
-	int snapshots = 0, mirrors = 0;
+	struct lv_layer *lvlayer;
+	struct dm_tree_node *dnode;
+	char *name, *dlid;
 
-	list_iterate_items(lvl, lvs) {
-		lv = lvl->lv;
+	if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
+		return_0;
 
-		if (!snapshots)
-			if (lv_is_cow(lv) || lv_is_origin(lv))
-				snapshots = 1;
-
-		if (!mirrors)
-			if (lv->status & PVMOVE)
-				mirrors = 1;
-
-		if (lv->status & VIRTUAL) {
-			list_iterate_items(seg, &lv->segments) {
-				if (seg->segtype->ops->target_present &&
-				    !seg->segtype->ops->target_present()) {
-					log_error("Can't expand LV: %s target "
-						  "support missing "
-						  "from kernel?",
-						  seg->segtype->name);
-					return 0;
-				}
-			}
-		}
-	}
+	if (!(dlid = build_dlid(dm, lv->lvid.s, layer)))
+		return_0;
 
-	if (mirrors) {
-		if (!(segtype = get_segtype_from_string(dm->cmd, "mirror"))) {
-			log_error("Can't expand LV: Mirror support "
-				  "missing from tools?");
-			return 0;
-		}
+	/* We've already processed this node if it already has a context ptr */
+	if ((dnode = dm_tree_find_node_by_uuid(dtree, dlid)) &&
+	    dm_tree_node_get_context(dnode))
+		return 1;
 
-		if (!segtype->ops->target_present ||
-		    !segtype->ops->target_present()) {
-			log_error("Can't expand LV: Mirror support missing "
-				  "from kernel?");
-			return 0;
-		}
+	/* FIXME How do we determine whether a pre-existing node need reloading or not? */
+	if (!(lvlayer = dm_pool_alloc(dm->mem, sizeof(*lvlayer)))) {
+		log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.", lv->name, layer);
+		return 0;
 	}
 
-	if (snapshots) {
-		if (!(segtype = get_segtype_from_string(dm->cmd, "snapshot"))) {
-			log_error("Can't expand LV: Snapshot support "
-				  "missing from tools?");
-			return 0;
-		}
+	lvlayer->lv = lv;
 
-		if (!segtype->ops->target_present ||
-		    !segtype->ops->target_present()) {
-			log_error("Can't expand LV: Snapshot support missing "
-				  "from kernel?");
-			return 0;
-		}
+	/*
+	 * Add LV to dtree.
+	 * If we're working with precommitted metadata, clear any
+	 * existing inactive table left behind.
+	 * Major/minor settings only apply to the visible layer.
+	 */
+	if (!(dnode = dm_tree_add_new_dev(dtree, name, dlid,
+					     layer ? lv->major : 0,
+					     layer ? lv->minor : 0,
+					     _read_only_lv(lv),
+					     lv->vg->status & PRECOMMITTED,
+					     lvlayer)))
+		return_0;
+
+	/* Store existing name so we can do rename later */
+	lvlayer->old_name = dm_tree_node_get_name(dnode);
+
+	/* Create table */
+	dm->pvmove_mirror_count = 0u;
+	list_iterate_items(seg, &lv->segments) {
+		if (!_add_segment_to_dtree(dm, dtree, dnode, seg, layer))
+			return_0;
+		/* These aren't real segments in the LVM2 metadata */
+		if (lv_is_origin(lv) && !layer)
+			break;
+		if (lv_is_cow(lv) && !layer)
+			break;
 	}
 
 	return 1;
 }
 
-static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
+/*
+ * Create LV symlinks for children of supplied root node.
+ */
+static int _create_lv_symlinks(struct dev_manager *dm, struct dm_tree_node *root)
 {
-	char *dlid;
-	struct lv_list *lvl;
-	struct dev_layer *dl;
+	void *handle = NULL;
+	struct dm_tree_node *child;
+	struct lv_layer *lvlayer;
+	char *vgname, *lvname, *layer;
+	const char *name;
+	int r = 1;
 
-	list_iterate_items(lvl, &vg->lvs) {
-		if (lvl->lv->status & SNAPSHOT)
+	while ((child = dm_tree_next_child(&handle, root, 0))) {
+		if (!(lvlayer = (struct lv_layer *) dm_tree_node_get_context(child)))
 			continue;
 
-		if (!(dlid = _build_dlid(dm->mem, lvl->lv->lvid.s, NULL))) {
-			stack;
-			return 0;
-		}
+		/* Detect rename */
+		name = dm_tree_node_get_name(child);
 
-		dl = hash_lookup(dm->layers, dlid);
-		pool_free(dm->mem, dlid);
+		if (name && lvlayer->old_name && *lvlayer->old_name && strcmp(name, lvlayer->old_name)) {
+	        	if (!split_dm_name(dm->mem, lvlayer->old_name, &vgname, &lvname, &layer)) {
+                		log_error("_create_lv_symlinks: Couldn't split up old device name %s", lvlayer->old_name);
+                		return 0;
+        		}
+			fs_rename_lv(lvlayer->lv, name, lvname);
+		} else if (!dev_manager_lv_mknodes(lvlayer->lv))
+			r = 0;
+	}
 
-		if (dl) {
-			log_debug("Found active lv %s%s", lvl->lv->name,
-				  dl->info.suspended ? " (suspended)" : "");
-
-			if (!_add_lv(dm->mem, &dm->active_list, lvl->lv)) {
-				stack;
-				return 0;
-			}
+	return r;
+}
 
-			if (dl->info.suspended) {
-				if (!_add_lv(dm->mem, &dm->suspend_list, lvl->lv)) {
-					stack;
-					return 0;
-				}
-			}
-		}
+static int _clean_tree(struct dev_manager *dm, struct logical_volume *lv, struct dm_tree_node *root)
+{
+	void *handle = NULL;
+	struct dm_tree_node *child;
+	char *vgname, *lvname, *layer;
+	const char *name, *uuid;
+
+	while ((child = dm_tree_next_child(&handle, root, 0))) {
+		if (!(name = dm_tree_node_get_name(child)))
+			continue;
+
+		if (!(uuid = dm_tree_node_get_uuid(child)))
+			continue;
+
+        	if (!split_dm_name(dm->mem, name, &vgname, &lvname, &layer)) {
+                	log_error("_clean_tree: Couldn't split up device name %s.", name);
+                	return 0;
+        	}
+
+		/* Not meant to be top level? */
+		if (!*layer)
+			continue;
+
+		if (!dm_tree_deactivate_children(root, uuid, strlen(uuid)))
+			return_0;
 	}
 
 	return 1;
 }
 
-static int _action(struct dev_manager *dm, struct logical_volume *lv,
-		   action_t action)
+static int _tree_action(struct dev_manager *dm, struct logical_volume *lv, action_t action)
 {
-	if (!_scan_existing_devices(dm)) {
-		stack;
-		return 0;
-	}
-
-	if (!_fill_in_active_list(dm, lv->vg)) {
-		stack;
-		return 0;
-	}
+	struct dm_tree *dtree;
+	struct dm_tree_node *root;
+	char *dlid;
+	int r = 0;
 
-	if (action == ACTIVATE || action == DEACTIVATE)
-		/* Get into known state - remove from active list if present */
-		if (!_remove_lvs(dm, lv)) {
-			stack;
-			return 0;
-		}
+	if (!(dtree = _create_partial_dtree(dm, lv)))
+		return_0;
 
-	if (action == ACTIVATE) {
-		/* Add to active & reload lists */
-		if (!_add_lvs(dm->mem, &dm->reload_list, lv) ||
-		    !_add_lvs(dm->mem, &dm->active_list, lv)) {
-			stack;
-			return 0;
-		}
+	if (!(root = dm_tree_find_node(dtree, 0, 0))) {
+		log_error("Lost dependency tree root node");
+		goto out;
 	}
 
-	if (action == SUSPEND || action == RESUME || action == ACTIVATE)
-		/* Get into known state - remove from suspend list if present */
-		if (!_remove_suspended_lvs(dm, lv)) {
-			stack;
-			return 0;
-		}
+	if (!(dlid = build_dlid(dm, lv->lvid.s, NULL)))
+		goto_out;
 
-	if (action == SUSPEND) {
-		if (!_add_lvs(dm->mem, &dm->suspend_list, lv)) {
-			stack;
-			return 0;
+	/* Only process nodes with uuid of "LVM-" plus VG id. */
+	switch(action) {
+	case CLEAN:
+		/* Deactivate any unused non-toplevel nodes */
+		if (!_clean_tree(dm, lv, root))
+			goto_out;
+		break;
+	case DEACTIVATE:
+ 		/* Deactivate LV and all devices it references that nothing else has open. */
+		if (!dm_tree_deactivate_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1))
+			goto_out;
+		break;
+	case SUSPEND:
+		if (!dm_tree_suspend_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1))
+			goto_out;
+		break;
+	case PRELOAD:
+	case ACTIVATE:
+		/* Add all required new devices to tree */
+		if (!_add_new_lv_to_dtree(dm, dtree, lv, NULL))
+			goto_out;
+
+		/* Preload any devices required before any suspensions */
+		if (!dm_tree_preload_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1))
+			goto_out;
+
+		if ((action == ACTIVATE) &&
+		    !dm_tree_activate_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1))
+			goto_out;
+
+		if (!_create_lv_symlinks(dm, root)) {
+			log_error("Failed to create symlinks for %s.", lv->name);
+			goto out;
 		}
-	}
+		break;
+	default:
+		log_error("_tree_action: Action %u not supported.", action);
+		goto out;
+	}	
 
-	if (!_targets_present(dm, &dm->active_list) ||
-	    !_targets_present(dm, &dm->reload_list)) {
-		stack;
-		return 0;
-	}
+	r = 1;
 
-	if (!_execute(dm, lv->vg)) {
-		stack;
-		return 0;
-	}
+out:
+	dm_tree_free(dtree);
 
-	return 1;
+	return r;
 }
 
 int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
 {
-	return _action(dm, lv, ACTIVATE);
+	if (!_tree_action(dm, lv, ACTIVATE))
+		return_0;
+
+	return _tree_action(dm, lv, CLEAN);
+}
+
+int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv)
+{
+	/* FIXME Update the pvmove implementation! */
+	if ((lv->status & PVMOVE) || (lv->status & LOCKED))
+		return 1;
+
+	return _tree_action(dm, lv, PRELOAD);
 }
 
 int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv)
 {
-	return _action(dm, lv, DEACTIVATE);
+	int r;
+
+	r = _tree_action(dm, lv, DEACTIVATE);
+
+	fs_del_lv(lv);
+
+	return r;
 }
 
 int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
 {
-	return _action(dm, lv, SUSPEND);
+	return _tree_action(dm, lv, SUSPEND);
 }
 
-int dev_manager_lv_mknodes(const struct logical_volume *lv)
+/*
+ * Does device use VG somewhere in its construction?
+ * Returns 1 if uncertain.
+ */
+int dev_manager_device_uses_vg(struct dev_manager *dm, struct device *dev,
+			       struct volume_group *vg)
 {
-	char *name;
+	struct dm_tree *dtree;
+	struct dm_tree_node *root;
+	char dlid[sizeof(UUID_PREFIX) + sizeof(struct id) - 1];
+	int r = 1;
 
-	if (!(name = build_dm_name(lv->vg->cmd->mem, lv->vg->name,
-				   lv->name, NULL))) {
-		stack;
-		return 0;
+	if (!(dtree = dm_tree_create())) {
+		log_error("partial dtree creation failed");
+		return r;
 	}
 
-	return fs_add_lv(lv, name);
-}
+	if (!dm_tree_add_dev(dtree, MAJOR(dev->dev), MINOR(dev->dev))) {
+		log_error("Failed to add device %s (%" PRIu32 ":%" PRIu32") to dtree",
+			  dev_name(dev), (uint32_t) MAJOR(dev->dev), (uint32_t) MINOR(dev->dev));
+		goto out;
+	}
 
-int dev_manager_lv_rmnodes(const struct logical_volume *lv)
-{
-	return fs_del_lv(lv);
-}
+	memcpy(dlid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1);
+	memcpy(dlid + sizeof(UUID_PREFIX) - 1, &vg->id.uuid[0], sizeof(vg->id));
 
-int dev_manager_mknodes(void)
-{
-	struct dm_task *dmt;
-	int r;
+	if (!(root = dm_tree_find_node(dtree, 0, 0))) {
+		log_error("Lost dependency tree root node");
+		goto out;
+	}
 
-	if (!(dmt = dm_task_create(DM_DEVICE_MKNODES)))
-		return 0;
+	if (dm_tree_children_use_uuid(root, dlid, sizeof(UUID_PREFIX) + sizeof(vg->id) - 1))
+		goto_out;
 
-	r = dm_task_run(dmt);
+	r = 0;
 
-	dm_task_destroy(dmt);
+out:
+	dm_tree_free(dtree);
 	return r;
 }
-
-void dev_manager_exit(void)
-{
-	dm_lib_exit();
-}

Modified: lvm2/upstream/current/lib/activate/dev_manager.h
==============================================================================
--- lvm2/upstream/current/lib/activate/dev_manager.h	(original)
+++ lvm2/upstream/current/lib/activate/dev_manager.h	Tue Nov 15 17:45:32 2005
@@ -17,9 +17,11 @@
 #define _LVM_DEV_MANAGER_H
 
 struct logical_volume;
+struct volume_group;
 struct cmd_context;
 struct dev_manager;
 struct dm_info;
+struct device;
 
 /*
  * Constructor and destructor.
@@ -35,7 +37,8 @@
  * (eg, an origin is created before its snapshot, but is not
  * unsuspended until the snapshot is also created.)
  */
-int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
+int dev_manager_info(struct dm_pool *mem, const char *name,
+		     const struct logical_volume *lv,
 		     int mknodes, int with_open_count, struct dm_info *info);
 int dev_manager_snapshot_percent(struct dev_manager *dm,
 				 struct logical_volume *lv, float *percent);
@@ -44,15 +47,18 @@
 			       float *percent, uint32_t *event_nr);
 int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
 int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
+int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv);
 int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
 
 int dev_manager_lv_mknodes(const struct logical_volume *lv);
 int dev_manager_lv_rmnodes(const struct logical_volume *lv);
-int dev_manager_mknodes(void);
 
 /*
  * Put the desired changes into effect.
  */
 int dev_manager_execute(struct dev_manager *dm);
 
+int dev_manager_device_uses_vg(struct dev_manager *dm, struct device *dev,
+			       struct volume_group *vg);
+
 #endif

Modified: lvm2/upstream/current/lib/activate/fs.c
==============================================================================
--- lvm2/upstream/current/lib/activate/fs.c	(original)
+++ lvm2/upstream/current/lib/activate/fs.c	Tue Nov 15 17:45:32 2005
@@ -20,16 +20,11 @@
 #include "lvm-file.h"
 #include "memlock.h"
 
-#ifdef HAVE_SELINUX
-#  include "selinux.h"
-#endif
-
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <limits.h>
 #include <dirent.h>
-#include <libdevmapper.h>
 
 static int _mk_dir(const char *dev_dir, const char *vg_name)
 {
@@ -180,7 +175,7 @@
 	}
 
 #ifdef HAVE_SELINUX
-        if (!set_selinux_context(lv_path, S_IFLNK)) {
+        if (!dm_set_selinux_context(lv_path, S_IFLNK)) {
                 stack;
                 return 0;
         }
@@ -283,7 +278,7 @@
 	    strlen(dev) + strlen(old_lv_name) + 5;
 	char *pos;
 
-	if (!(fsp = dbg_malloc(sizeof(*fsp) + len))) {
+	if (!(fsp = dm_malloc(sizeof(*fsp) + len))) {
 		log_error("No space to stack fs operation");
 		return 0;
 	}
@@ -312,7 +307,7 @@
 		_do_fs_op(fsp->type, fsp->dev_dir, fsp->vg_name, fsp->lv_name,
 			  fsp->dev, fsp->old_lv_name);
 		list_del(&fsp->list);
-		dbg_free(fsp);
+		dm_free(fsp);
 	}
 }
 

Modified: lvm2/upstream/current/lib/activate/targets.h
==============================================================================
--- lvm2/upstream/current/lib/activate/targets.h	(original)
+++ lvm2/upstream/current/lib/activate/targets.h	Tue Nov 15 17:45:32 2005
@@ -23,8 +23,12 @@
 		       char *params, size_t paramsize, int *pos,
 		       int start_area, int areas);
 
-int compose_log_line(struct dev_manager *dm, struct lv_segment *seg,
-		     char *params, size_t paramsize, int *pos, int areas,
-		     uint32_t region_size);
+int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
+                   struct dm_tree_node *node, int start_area, int areas);
+
+int build_dev_string(struct dev_manager *dm, char *dlid, char *devbuf,
+		     size_t bufsize, const char *desc);
+
+char *build_dlid(struct dev_manager *dm, const char *lvid, const char *layer);
 
 #endif

Modified: lvm2/upstream/current/lib/cache/lvmcache.c
==============================================================================
--- lvm2/upstream/current/lib/cache/lvmcache.c	(original)
+++ lvm2/upstream/current/lib/cache/lvmcache.c	Tue Nov 15 17:45:32 2005
@@ -16,7 +16,6 @@
 
 #include "lib.h"
 #include "lvmcache.h"
-#include "hash.h"
 #include "toolcontext.h"
 #include "dev-cache.h"
 #include "metadata.h"
@@ -24,10 +23,10 @@
 #include "memlock.h"
 #include "str_list.h"
 
-static struct hash_table *_pvid_hash = NULL;
-static struct hash_table *_vgid_hash = NULL;
-static struct hash_table *_vgname_hash = NULL;
-static struct hash_table *_lock_hash = NULL;
+static struct dm_hash_table *_pvid_hash = NULL;
+static struct dm_hash_table *_vgid_hash = NULL;
+static struct dm_hash_table *_vgname_hash = NULL;
+static struct dm_hash_table *_lock_hash = NULL;
 static struct list _vginfos;
 static int _has_scanned = 0;
 static int _vgs_locked = 0;
@@ -36,16 +35,16 @@
 {
 	list_init(&_vginfos);
 
-	if (!(_vgname_hash = hash_create(128)))
+	if (!(_vgname_hash = dm_hash_create(128)))
 		return 0;
 
-	if (!(_vgid_hash = hash_create(128)))
+	if (!(_vgid_hash = dm_hash_create(128)))
 		return 0;
 
-	if (!(_pvid_hash = hash_create(128)))
+	if (!(_pvid_hash = dm_hash_create(128)))
 		return 0;
 
-	if (!(_lock_hash = hash_create(128)))
+	if (!(_lock_hash = dm_hash_create(128)))
 		return 0;
 
 	return 1;
@@ -58,25 +57,24 @@
 		return;
 	}
 
-	if (!hash_insert(_lock_hash, vgname, (void *) 1))
+	if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
 		log_error("Cache locking failure for %s", vgname);
 
 	_vgs_locked++;
 }
 
-static int _vgname_is_locked(const char *vgname) __attribute__ ((unused));
-static int _vgname_is_locked(const char *vgname)
+int vgname_is_locked(const char *vgname)
 {
 	if (!_lock_hash)
 		return 0;
 
-	return hash_lookup(_lock_hash, vgname) ? 1 : 0;
+	return dm_hash_lookup(_lock_hash, vgname) ? 1 : 0;
 }
 
 void lvmcache_unlock_vgname(const char *vgname)
 {
 	/* FIXME: Clear all CACHE_LOCKED flags in this vg */
-	hash_remove(_lock_hash, vgname);
+	dm_hash_remove(_lock_hash, vgname);
 
 	/* FIXME Do this per-VG */
 	if (!--_vgs_locked)
@@ -95,7 +93,7 @@
 	if (!_vgname_hash)
 		return NULL;
 
-	if (!(vginfo = hash_lookup(_vgname_hash, vgname)))
+	if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
 		return NULL;
 
 	return vginfo;
@@ -117,7 +115,7 @@
  	 * we check cached labels here. Unfortunately vginfo is volatile. */
 	list_init(&devs);
 	list_iterate_items(info, &vginfo->infos) {
-		devl = dbg_malloc(sizeof(*devl));
+		devl = dm_malloc(sizeof(*devl));
 		devl->dev = info->dev;
 		list_add(&devs, &devl->list);
 	}
@@ -126,7 +124,7 @@
 		devl = list_item(devh, struct device_list);
 		label_read(devl->dev, &label);
 		list_del(&devl->list);
-		dbg_free(devl);
+		dm_free(devl);
 	}
 
 	return vginfo->fmt;
@@ -144,7 +142,7 @@
 	strncpy(&id[0], vgid, ID_LEN);
 	id[ID_LEN] = '\0';
 
-	if (!(vginfo = hash_lookup(_vgid_hash, id)))
+	if (!(vginfo = dm_hash_lookup(_vgid_hash, id)))
 		return NULL;
 
 	return vginfo;
@@ -161,7 +159,7 @@
 	strncpy(&id[0], pvid, ID_LEN);
 	id[ID_LEN] = '\0';
 
-	if (!(info = hash_lookup(_pvid_hash, id)))
+	if (!(info = dm_hash_lookup(_pvid_hash, id)))
 		return NULL;
 
 	return info;
@@ -177,7 +175,7 @@
 
 static int _scan_invalid(void)
 {
-	hash_iter(_pvid_hash, (iterate_fn) _rescan_entry);
+	dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _rescan_entry);
 
 	return 1;
 }
@@ -248,7 +246,7 @@
 
 	list_iterate_items(vgi, &_vginfos) {
 		if (!str_list_add(cmd->mem, vgnames, 
-				  pool_strdup(cmd->mem, vgi->vgname))) {
+				  dm_pool_strdup(cmd->mem, vgi->vgname))) {
 			log_error("strlist allocation failed");
 			return NULL;
 		}
@@ -307,13 +305,13 @@
 	}
 
 	if (info->vginfo && list_empty(&info->vginfo->infos)) {
-		hash_remove(_vgname_hash, info->vginfo->vgname);
+		dm_hash_remove(_vgname_hash, info->vginfo->vgname);
 		if (info->vginfo->vgname)
-			dbg_free(info->vginfo->vgname);
+			dm_free(info->vginfo->vgname);
 		if (*info->vginfo->vgid)
-			hash_remove(_vgid_hash, info->vginfo->vgid);
+			dm_hash_remove(_vgid_hash, info->vginfo->vgid);
 		list_del(&info->vginfo->list);
-		dbg_free(info->vginfo);
+		dm_free(info->vginfo);
 	}
 
 	info->vginfo = NULL;
@@ -323,13 +321,13 @@
 void lvmcache_del(struct lvmcache_info *info)
 {
 	if (info->dev->pvid[0] && _pvid_hash)
-		hash_remove(_pvid_hash, info->dev->pvid);
+		dm_hash_remove(_pvid_hash, info->dev->pvid);
 
 	_drop_vginfo(info);
 
 	info->label->labeller->ops->destroy_label(info->label->labeller,
 						info->label); 
-	dbg_free(info);
+	dm_free(info);
 
 	return;
 } */
@@ -339,10 +337,10 @@
 	if (!strcmp(info->dev->pvid, pvid))
 		return 1;
 	if (*info->dev->pvid) {
-		hash_remove(_pvid_hash, info->dev->pvid);
+		dm_hash_remove(_pvid_hash, info->dev->pvid);
 	}
 	strncpy(info->dev->pvid, pvid, sizeof(info->dev->pvid));
-	if (!hash_insert(_pvid_hash, pvid, info)) {
+	if (!dm_hash_insert(_pvid_hash, pvid, info)) {
 		log_error("_lvmcache_update: pvid insertion failed: %s", pvid);
 		return 0;
 	}
@@ -357,13 +355,13 @@
 		return 1;
 
 	if (info->vginfo && *info->vginfo->vgid)
-		hash_remove(_vgid_hash, info->vginfo->vgid);
+		dm_hash_remove(_vgid_hash, info->vginfo->vgid);
 	if (!vgid)
 		return 1;
 
 	strncpy(info->vginfo->vgid, vgid, sizeof(info->vginfo->vgid));
 	info->vginfo->vgid[sizeof(info->vginfo->vgid) - 1] = '\0';
-	if (!hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
+	if (!dm_hash_insert(_vgid_hash, info->vginfo->vgid, info->vginfo)) {
 		log_error("_lvmcache_update: vgid hash insertion failed: %s",
 			  info->vginfo->vgid);
 		return 0;
@@ -391,22 +389,22 @@
 
 	/* Get existing vginfo or create new one */
 	if (!(vginfo = vginfo_from_vgname(vgname))) {
-		if (!(vginfo = dbg_malloc(sizeof(*vginfo)))) {
+		if (!(vginfo = dm_malloc(sizeof(*vginfo)))) {
 			log_error("lvmcache_update_vgname: list alloc failed");
 			return 0;
 		}
 		memset(vginfo, 0, sizeof(*vginfo));
-		if (!(vginfo->vgname = dbg_strdup(vgname))) {
-			dbg_free(vginfo);
+		if (!(vginfo->vgname = dm_strdup(vgname))) {
+			dm_free(vginfo);
 			log_error("cache vgname alloc failed for %s", vgname);
 			return 0;
 		}
 		list_init(&vginfo->infos);
-		if (!hash_insert(_vgname_hash, vginfo->vgname, vginfo)) {
+		if (!dm_hash_insert(_vgname_hash, vginfo->vgname, vginfo)) {
 			log_error("cache_update: vg hash insertion failed: %s",
 				  vginfo->vgname);
-			dbg_free(vginfo->vgname);
-			dbg_free(vginfo);
+			dm_free(vginfo->vgname);
+			dm_free(vginfo);
 			return 0;
 		}
 		/* Ensure orphans appear last on list_iterate */
@@ -474,7 +472,7 @@
 			stack;
 			return NULL;
 		}
-		if (!(info = dbg_malloc(sizeof(*info)))) {
+		if (!(info = dm_malloc(sizeof(*info)))) {
 			log_error("lvmcache_info allocation failed");
 			label_destroy(label);
 			return NULL;
@@ -495,17 +493,36 @@
 						 pvid, dev_name(dev),
 						 dev_name(existing->dev));
 				return NULL;
+			} else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
+				   !dm_is_dm_major(MAJOR(dev->dev))) {
+				log_very_verbose("Ignoring duplicate PV %s on "
+						 "%s - using dm %s",
+						 pvid, dev_name(dev),
+						 dev_name(existing->dev));
+				return NULL;
 			} else if (MAJOR(existing->dev->dev) != md_major() &&
 				   MAJOR(dev->dev) == md_major())
 				log_very_verbose("Duplicate PV %s on %s - "
 						 "using md %s", pvid,
 						 dev_name(existing->dev),
 						 dev_name(dev));
+			else if (!dm_is_dm_major(MAJOR(existing->dev->dev)) &&
+				 dm_is_dm_major(MAJOR(dev->dev)))
+				log_very_verbose("Duplicate PV %s on %s - "
+						 "using dm %s", pvid,
+						 dev_name(existing->dev),
+						 dev_name(dev));
+			/* FIXME If both dm, check dependencies */
+			//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
+				 //dm_is_dm_major(MAJOR(dev->dev)))
+				 //
 			else
 				log_error("Found duplicate PV %s: using %s not "
 					  "%s", pvid, dev_name(dev),
 					  dev_name(existing->dev));
 		}
+		/* Switch over to new preferred device */
+		existing->dev = dev;
 		info = existing;
 		/* Has labeller changed? */
 		if (info->label->labeller != labeller) {
@@ -525,7 +542,7 @@
 
 	if (!_lvmcache_update_pvid(info, pvid_s)) {
 		if (!existing) {
-			dbg_free(info);
+			dm_free(info);
 			label_destroy(label);
 		}
 		return NULL;
@@ -533,9 +550,9 @@
 
 	if (!lvmcache_update_vgname(info, vgname)) {
 		if (!existing) {
-			hash_remove(_pvid_hash, pvid_s);
+			dm_hash_remove(_pvid_hash, pvid_s);
 			strcpy(info->dev->pvid, "");
-			dbg_free(info);
+			dm_free(info);
 			label_destroy(label);
 		}
 		return NULL;
@@ -554,14 +571,14 @@
 		list_del(&info->list);
 	strcpy(info->dev->pvid, "");
 	label_destroy(info->label);
-	dbg_free(info);
+	dm_free(info);
 }
 
 static void _lvmcache_destroy_vgnamelist(struct lvmcache_vginfo *vginfo)
 {
 	if (vginfo->vgname)
-		dbg_free(vginfo->vgname);
-	dbg_free(vginfo);
+		dm_free(vginfo->vgname);
+	dm_free(vginfo);
 }
 
 static void _lvmcache_destroy_lockname(int present)
@@ -576,26 +593,26 @@
 	_has_scanned = 0;
 
 	if (_vgid_hash) {
-		hash_destroy(_vgid_hash);
+		dm_hash_destroy(_vgid_hash);
 		_vgid_hash = NULL;
 	}
 
 	if (_pvid_hash) {
-		hash_iter(_pvid_hash, (iterate_fn) _lvmcache_destroy_entry);
-		hash_destroy(_pvid_hash);
+		dm_hash_iter(_pvid_hash, (dm_hash_iterate_fn) _lvmcache_destroy_entry);
+		dm_hash_destroy(_pvid_hash);
 		_pvid_hash = NULL;
 	}
 
 	if (_vgname_hash) {
-		hash_iter(_vgname_hash,
-			  (iterate_fn) _lvmcache_destroy_vgnamelist);
-		hash_destroy(_vgname_hash);
+		dm_hash_iter(_vgname_hash,
+			  (dm_hash_iterate_fn) _lvmcache_destroy_vgnamelist);
+		dm_hash_destroy(_vgname_hash);
 		_vgname_hash = NULL;
 	}
 
 	if (_lock_hash) {
-		hash_iter(_lock_hash, (iterate_fn) _lvmcache_destroy_lockname);
-		hash_destroy(_lock_hash);
+		dm_hash_iter(_lock_hash, (dm_hash_iterate_fn) _lvmcache_destroy_lockname);
+		dm_hash_destroy(_lock_hash);
 		_lock_hash = NULL;
 	}
 

Modified: lvm2/upstream/current/lib/cache/lvmcache.h
==============================================================================
--- lvm2/upstream/current/lib/cache/lvmcache.h	(original)
+++ lvm2/upstream/current/lib/cache/lvmcache.h	Tue Nov 15 17:45:32 2005
@@ -81,6 +81,7 @@
 struct lvmcache_info *info_from_pvid(const char *pvid);
 struct device *device_from_pvid(struct cmd_context *cmd, struct id *pvid);
 int vgs_locked(void);
+int vgname_is_locked(const char *vgname);
 
 /* Returns list of struct str_lists containing pool-allocated copy of vgnames */
 /* Set full_scan to 1 to reread every filtered device label */

Modified: lvm2/upstream/current/lib/commands/toolcontext.c
==============================================================================
--- lvm2/upstream/current/lib/commands/toolcontext.c	(original)
+++ lvm2/upstream/current/lib/commands/toolcontext.c	Tue Nov 15 17:45:32 2005
@@ -16,7 +16,6 @@
 
 #include "lib.h"
 #include "toolcontext.h"
-#include "pool.h"
 #include "metadata.h"
 #include "defaults.h"
 #include "lvm-string.h"
@@ -213,7 +212,7 @@
 
 static int _set_tag(struct cmd_context *cmd, const char *tag)
 {
-	log_very_verbose("Setting host tag: %s", pool_strdup(cmd->libmem, tag));
+	log_very_verbose("Setting host tag: %s", dm_pool_strdup(cmd->libmem, tag));
 
 	if (!str_list_add(cmd->libmem, &cmd->tags, tag)) {
 		log_error("_set_tag: str_list_add %s failed", tag);
@@ -323,7 +322,7 @@
 		return 0;
 	}
 
-	if (!(cfl = pool_alloc(cmd->libmem, sizeof(*cfl)))) {
+	if (!(cfl = dm_pool_alloc(cmd->libmem, sizeof(*cfl)))) {
 		log_error("config_tree_list allocation failed");
 		return 0;
 	}
@@ -800,13 +799,13 @@
 		return 0;
 	}
 
-	if (!(cmd->hostname = pool_strdup(cmd->libmem, uts.nodename))) {
-		log_error("_init_hostname: pool_strdup failed");
+	if (!(cmd->hostname = dm_pool_strdup(cmd->libmem, uts.nodename))) {
+		log_error("_init_hostname: dm_pool_strdup failed");
 		return 0;
 	}
 
-	if (!(cmd->kernel_vsn = pool_strdup(cmd->libmem, uts.release))) {
-		log_error("_init_hostname: pool_strdup kernel_vsn failed");
+	if (!(cmd->kernel_vsn = dm_pool_strdup(cmd->libmem, uts.release))) {
+		log_error("_init_hostname: dm_pool_strdup kernel_vsn failed");
 		return 0;
 	}
 
@@ -894,7 +893,7 @@
 
 	init_syslog(DEFAULT_LOG_FACILITY);
 
-	if (!(cmd = dbg_malloc(sizeof(*cmd)))) {
+	if (!(cmd = dm_malloc(sizeof(*cmd)))) {
 		log_error("Failed to allocate command context");
 		return NULL;
 	}
@@ -920,7 +919,7 @@
 		goto error;
 	}
 
-	if (!(cmd->libmem = pool_create("library", 4 * 1024))) {
+	if (!(cmd->libmem = dm_pool_create("library", 4 * 1024))) {
 		log_error("Library memory pool creation failed");
 		return 0;
 	}
@@ -951,7 +950,7 @@
 	if (!_init_filters(cmd))
 		goto error;
 
-	if (!(cmd->mem = pool_create("command", 4 * 1024))) {
+	if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
 		log_error("Command memory pool creation failed");
 		return 0;
 	}
@@ -973,7 +972,7 @@
 	return cmd;
 
       error:
-	dbg_free(cmd);
+	dm_free(cmd);
 	return NULL;
 }
 
@@ -1079,21 +1078,20 @@
 
 	archive_exit(cmd);
 	backup_exit(cmd);
-	activation_exit();
 	lvmcache_destroy();
 	label_exit();
 	_destroy_segtypes(&cmd->segtypes);
 	_destroy_formats(&cmd->formats);
 	cmd->filter->destroy(cmd->filter);
-	pool_destroy(cmd->mem);
+	dm_pool_destroy(cmd->mem);
 	dev_cache_exit();
 	_destroy_tags(cmd);
 	_destroy_tag_configs(cmd);
-	pool_destroy(cmd->libmem);
-	dbg_free(cmd);
+	dm_pool_destroy(cmd->libmem);
+	dm_free(cmd);
 
 	release_log_memory();
-	dump_memory();
+	activation_exit();
 	fin_log();
 	fin_syslog();
 

Modified: lvm2/upstream/current/lib/commands/toolcontext.h
==============================================================================
--- lvm2/upstream/current/lib/commands/toolcontext.h	(original)
+++ lvm2/upstream/current/lib/commands/toolcontext.h	Tue Nov 15 17:45:32 2005
@@ -17,7 +17,6 @@
 #define _LVM_TOOLCONTEXT_H
 
 #include "dev-cache.h"
-#include "pool.h"
 
 #include <stdio.h>
 #include <limits.h>
@@ -50,8 +49,8 @@
 /* FIXME Split into tool & library contexts */
 /* command-instance-related variables needed by library */
 struct cmd_context {
-	struct pool *libmem;	/* For permanent config data */
-	struct pool *mem;	/* Transient: Cleared between each command */
+	struct dm_pool *libmem;	/* For permanent config data */
+	struct dm_pool *mem;	/* Transient: Cleared between each command */
 
 	const struct format_type *fmt;	/* Current format to use by default */
 	struct format_type *fmt_backup;	/* Format to use for backups */

Modified: lvm2/upstream/current/lib/config/config.c
==============================================================================
--- lvm2/upstream/current/lib/config/config.c	(original)
+++ lvm2/upstream/current/lib/config/config.c	Tue Nov 15 17:45:32 2005
@@ -16,7 +16,6 @@
 #include "lib.h"
 #include "config.h"
 #include "crc.h"
-#include "pool.h"
 #include "device.h"
 #include "str_list.h"
 #include "toolcontext.h"
@@ -50,12 +49,12 @@
 	int fd;			/* descriptor for file being parsed */
 	int line;		/* line number we are on */
 
-	struct pool *mem;
+	struct dm_pool *mem;
 };
 
 struct cs {
 	struct config_tree cft;
-	struct pool *mem;
+	struct dm_pool *mem;
 	time_t timestamp;
 	char *filename;
 	int exists;
@@ -99,16 +98,16 @@
 struct config_tree *create_config_tree(const char *filename)
 {
 	struct cs *c;
-	struct pool *mem = pool_create("config", 10 * 1024);
+	struct dm_pool *mem = dm_pool_create("config", 10 * 1024);
 
 	if (!mem) {
 		stack;
 		return 0;
 	}
 
-	if (!(c = pool_zalloc(mem, sizeof(*c)))) {
+	if (!(c = dm_pool_zalloc(mem, sizeof(*c)))) {
 		stack;
-		pool_destroy(mem);
+		dm_pool_destroy(mem);
 		return 0;
 	}
 
@@ -117,13 +116,13 @@
 	c->timestamp = 0;
 	c->exists = 0;
 	if (filename)
-		c->filename = pool_strdup(c->mem, filename);
+		c->filename = dm_pool_strdup(c->mem, filename);
 	return &c->cft;
 }
 
 void destroy_config_tree(struct config_tree *cft)
 {
-	pool_destroy(((struct cs *) cft)->mem);
+	dm_pool_destroy(((struct cs *) cft)->mem);
 }
 
 int read_config_fd(struct config_tree *cft, struct device *dev,
@@ -136,7 +135,7 @@
 	int use_mmap = 1;
 	off_t mmap_offset = 0;
 
-	if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
+	if (!(p = dm_pool_alloc(c->mem, sizeof(*p)))) {
 		stack;
 		return 0;
 	}
@@ -157,7 +156,7 @@
 		}
 		p->fb = p->fb + mmap_offset;
 	} else {
-		if (!(p->fb = dbg_malloc(size + size2))) {
+		if (!(p->fb = dm_malloc(size + size2))) {
 			stack;
 			return 0;
 		}
@@ -197,7 +196,7 @@
 
       out:
 	if (!use_mmap)
-		dbg_free(p->fb);
+		dm_free(p->fb);
 	else {
 		/* unmap the file */
 		if (munmap((char *) (p->fb - mmap_offset), size + mmap_offset)) {
@@ -688,14 +687,14 @@
  */
 static struct config_value *_create_value(struct parser *p)
 {
-	struct config_value *v = pool_alloc(p->mem, sizeof(*v));
+	struct config_value *v = dm_pool_alloc(p->mem, sizeof(*v));
 	memset(v, 0, sizeof(*v));
 	return v;
 }
 
 static struct config_node *_create_node(struct parser *p)
 {
-	struct config_node *n = pool_alloc(p->mem, sizeof(*n));
+	struct config_node *n = dm_pool_alloc(p->mem, sizeof(*n));
 	memset(n, 0, sizeof(*n));
 	return n;
 }
@@ -703,7 +702,7 @@
 static char *_dup_tok(struct parser *p)
 {
 	size_t len = p->te - p->tb;
-	char *str = pool_alloc(p->mem, len + 1);
+	char *str = dm_pool_alloc(p->mem, len + 1);
 	if (!str) {
 		stack;
 		return 0;

Modified: lvm2/upstream/current/lib/config/config.h
==============================================================================
--- lvm2/upstream/current/lib/config/config.h	(original)
+++ lvm2/upstream/current/lib/config/config.h	Tue Nov 15 17:45:32 2005
@@ -16,6 +16,8 @@
 #ifndef _LVM_CONFIG_H
 #define _LVM_CONFIG_H
 
+#include "lvm-types.h"
+
 struct device;
 struct cmd_context;
 

Modified: lvm2/upstream/current/lib/datastruct/btree.c
==============================================================================
--- lvm2/upstream/current/lib/datastruct/btree.c	(original)
+++ lvm2/upstream/current/lib/datastruct/btree.c	Tue Nov 15 17:45:32 2005
@@ -24,13 +24,13 @@
 };
 
 struct btree {
-	struct pool *mem;
+	struct dm_pool *mem;
 	struct node *root;
 };
 
-struct btree *btree_create(struct pool *mem)
+struct btree *btree_create(struct dm_pool *mem)
 {
-	struct btree *t = pool_alloc(mem, sizeof(*t));
+	struct btree *t = dm_pool_alloc(mem, sizeof(*t));
 
 	if (t) {
 		t->mem = mem;
@@ -86,7 +86,7 @@
 	struct node *p, **c = _lookup(&t->root, key, &p), *n;
 
 	if (!*c) {
-		if (!(n = pool_alloc(t->mem, sizeof(*n)))) {
+		if (!(n = dm_pool_alloc(t->mem, sizeof(*n)))) {
 			stack;
 			return 0;
 		}

Modified: lvm2/upstream/current/lib/datastruct/btree.h
==============================================================================
--- lvm2/upstream/current/lib/datastruct/btree.h	(original)
+++ lvm2/upstream/current/lib/datastruct/btree.h	Tue Nov 15 17:45:32 2005
@@ -16,11 +16,9 @@
 #ifndef _LVM_BTREE_H
 #define _LVM_BTREE_H
 
-#include "pool.h"
-
 struct btree;
 
-struct btree *btree_create(struct pool *mem);
+struct btree *btree_create(struct dm_pool *mem);
 
 void *btree_lookup(struct btree *t, uint32_t k);
 int btree_insert(struct btree *t, uint32_t k, void *data);

Modified: lvm2/upstream/current/lib/datastruct/list.h
==============================================================================
--- lvm2/upstream/current/lib/datastruct/list.h	(original)
+++ lvm2/upstream/current/lib/datastruct/list.h	Tue Nov 15 17:45:32 2005
@@ -203,6 +203,26 @@
 #define list_iterate_items(v, head) list_iterate_items_gen(v, (head), list)
 
 /*
+ * Walk a list, setting 'v' in turn to the containing structure of each item.
+ * The containing structure should be the same type as 'v'.
+ * The 'struct list' variable within the containing structure is 'field'.
+ * t must be defined as a temporary variable of the same type as v.
+ */
+#define list_iterate_items_gen_safe(v, t, head, field) \
+	for (v = list_struct_base((head)->n, typeof(*v), field), \
+	     t = list_struct_base(v->field.n, typeof(*v), field); \
+	     &v->field != (head); \
+	     v = t, t = list_struct_base(v->field.n, typeof(*v), field))
+/*
+ * Walk a list, setting 'v' in turn to the containing structure of each item.
+ * The containing structure should be the same type as 'v'.
+ * The list should be 'struct list list' within the containing structure.
+ * t must be defined as a temporary variable of the same type as v.
+ */
+#define list_iterate_items_safe(v, t, head) \
+	list_iterate_items_gen_safe(v, t, (head), list)
+
+/*
  * Walk a list backwards, setting 'v' in turn to the containing structure 
  * of each item.
  * The containing structure should be the same type as 'v'.

Modified: lvm2/upstream/current/lib/datastruct/str_list.c
==============================================================================
--- lvm2/upstream/current/lib/datastruct/str_list.c	(original)
+++ lvm2/upstream/current/lib/datastruct/str_list.c	Tue Nov 15 17:45:32 2005
@@ -16,11 +16,11 @@
 #include "lib.h"
 #include "str_list.h"
 
-struct list *str_list_create(struct pool *mem)
+struct list *str_list_create(struct dm_pool *mem)
 {
 	struct list *sl;
 
-	if (!(sl = pool_alloc(mem, sizeof(struct list)))) {
+	if (!(sl = dm_pool_alloc(mem, sizeof(struct list)))) {
 		stack;
 		return NULL;
 	}
@@ -30,7 +30,7 @@
 	return sl;
 }
 
-int str_list_add(struct pool *mem, struct list *sll, const char *str)
+int str_list_add(struct dm_pool *mem, struct list *sll, const char *str)
 {
 	struct str_list *sln;
 
@@ -43,7 +43,7 @@
 	if (str_list_match_item(sll, str))
 		return 1;
 
-	if (!(sln = pool_alloc(mem, sizeof(*sln)))) {
+	if (!(sln = dm_pool_alloc(mem, sizeof(*sln)))) {
 		stack;
 		return 0;
 	}
@@ -66,7 +66,7 @@
 	return 1;
 }
 
-int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold)
+int str_list_dup(struct dm_pool *mem, struct list *sllnew, struct list *sllold)
 {
 	struct str_list *sl;
 

Modified: lvm2/upstream/current/lib/datastruct/str_list.h
==============================================================================
--- lvm2/upstream/current/lib/datastruct/str_list.h	(original)
+++ lvm2/upstream/current/lib/datastruct/str_list.h	Tue Nov 15 17:45:32 2005
@@ -16,14 +16,12 @@
 #ifndef _LVM_STR_LIST_H
 #define _LVM_STR_LIST_H
 
-#include "pool.h"
-
-struct list *str_list_create(struct pool *mem);
-int str_list_add(struct pool *mem, struct list *sll, const char *str);
+struct list *str_list_create(struct dm_pool *mem);
+int str_list_add(struct dm_pool *mem, struct list *sll, const char *str);
 int str_list_del(struct list *sll, const char *str);
 int str_list_match_item(struct list *sll, const char *str);
 int str_list_match_list(struct list *sll, struct list *sll2);
 int str_list_lists_equal(struct list *sll, struct list *sll2);
-int str_list_dup(struct pool *mem, struct list *sllnew, struct list *sllold);
+int str_list_dup(struct dm_pool *mem, struct list *sllnew, struct list *sllold);
 
 #endif

Modified: lvm2/upstream/current/lib/device/dev-cache.c
==============================================================================
--- lvm2/upstream/current/lib/device/dev-cache.c	(original)
+++ lvm2/upstream/current/lib/device/dev-cache.c	Tue Nov 15 17:45:32 2005
@@ -15,9 +15,6 @@
 
 #include "lib.h"
 #include "dev-cache.h"
-#include "pool.h"
-#include "hash.h"
-#include "list.h"
 #include "lvm-types.h"
 #include "btree.h"
 #include "filter.h"
@@ -38,8 +35,8 @@
 };
 
 static struct {
-	struct pool *mem;
-	struct hash_table *names;
+	struct dm_pool *mem;
+	struct dm_hash_table *names;
 	struct btree *devices;
 
 	int has_scanned;
@@ -48,9 +45,9 @@
 
 } _cache;
 
-#define _alloc(x) pool_zalloc(_cache.mem, (x))
-#define _free(x) pool_free(_cache.mem, (x))
-#define _strdup(x) pool_strdup(_cache.mem, (x))
+#define _alloc(x) dm_pool_zalloc(_cache.mem, (x))
+#define _free(x) dm_pool_free(_cache.mem, (x))
+#define _strdup(x) dm_pool_strdup(_cache.mem, (x))
 
 static int _insert(const char *path, int rec);
 
@@ -61,19 +58,19 @@
 
 	if (allocate) {
 		if (use_malloc) {
-			if (!(dev = dbg_malloc(sizeof(*dev)))) {
+			if (!(dev = dm_malloc(sizeof(*dev)))) {
 				log_error("struct device allocation failed");
 				return NULL;
 			}
-			if (!(alias = dbg_malloc(sizeof(*alias)))) {
+			if (!(alias = dm_malloc(sizeof(*alias)))) {
 				log_error("struct str_list allocation failed");
-				dbg_free(dev);
+				dm_free(dev);
 				return NULL;
 			}
-			if (!(alias->str = dbg_strdup(filename))) {
+			if (!(alias->str = dm_strdup(filename))) {
 				log_error("filename strdup failed");
-				dbg_free(dev);
-				dbg_free(alias);
+				dm_free(dev);
+				dm_free(alias);
 				return NULL;
 			}
 			dev->flags = DEV_ALLOCED;
@@ -92,7 +89,7 @@
 				return NULL;
 			}
 		}
-	} else if (!(alias->str = dbg_strdup(filename))) {
+	} else if (!(alias->str = dm_strdup(filename))) {
 		log_error("filename strdup failed");
 		return NULL;
 	}
@@ -213,7 +210,7 @@
 		}
 	}
 
-	if (!(sl->str = pool_strdup(_cache.mem, path))) {
+	if (!(sl->str = dm_pool_strdup(_cache.mem, path))) {
 		stack;
 		return 0;
 	}
@@ -247,7 +244,7 @@
 
 	/* Generate pretend device numbers for loopfiles */
 	if (!d) {
-		if (hash_lookup(_cache.names, path))
+		if (dm_hash_lookup(_cache.names, path))
 			return 1;
 		d = ++loopfile_count;
 		loopfile = 1;
@@ -279,7 +276,7 @@
 		return 0;
 	}
 
-	if (!hash_insert(_cache.names, path, dev)) {
+	if (!dm_hash_insert(_cache.names, path, dev)) {
 		log_err("Couldn't add name to hash in dev cache.");
 		return 0;
 	}
@@ -290,7 +287,7 @@
 static char *_join(const char *dir, const char *name)
 {
 	size_t len = strlen(dir) + strlen(name) + 2;
-	char *r = dbg_malloc(len);
+	char *r = dm_malloc(len);
 	if (r)
 		snprintf(r, len, "%s/%s", dir, name);
 
@@ -340,7 +337,7 @@
 
 			_collapse_slashes(path);
 			r &= _insert(path, 1);
-			dbg_free(path);
+			dm_free(path);
 
 			free(dirent[n]);
 		}
@@ -449,14 +446,14 @@
 	_cache.names = NULL;
 	_cache.has_scanned = 0;
 
-	if (!(_cache.mem = pool_create("dev_cache", 10 * 1024))) {
+	if (!(_cache.mem = dm_pool_create("dev_cache", 10 * 1024))) {
 		stack;
 		return 0;
 	}
 
-	if (!(_cache.names = hash_create(128))) {
+	if (!(_cache.names = dm_hash_create(128))) {
 		stack;
-		pool_destroy(_cache.mem);
+		dm_pool_destroy(_cache.mem);
 		_cache.mem = 0;
 		return 0;
 	}
@@ -484,7 +481,7 @@
 
 static inline void _check_for_open_devices(void)
 {
-	hash_iter(_cache.names, (iterate_fn) _check_closed);
+	dm_hash_iter(_cache.names, (dm_hash_iterate_fn) _check_closed);
 }
 
 void dev_cache_exit(void)
@@ -493,12 +490,12 @@
 		_check_for_open_devices();
 
 	if (_cache.mem) {
-		pool_destroy(_cache.mem);
+		dm_pool_destroy(_cache.mem);
 		_cache.mem = NULL;
 	}
 
 	if (_cache.names) {
-		hash_destroy(_cache.names);
+		dm_hash_destroy(_cache.names);
 		_cache.names = NULL;
 	}
 
@@ -592,7 +589,7 @@
 				  (int) MINOR(dev->dev));
 
 		/* Remove the incorrect hash entry */
-		hash_remove(_cache.names, name);
+		dm_hash_remove(_cache.names, name);
 
 		/* Leave list alone if there isn't an alternative name */
 		/* so dev_name will always find something to return. */
@@ -615,23 +612,23 @@
 struct device *dev_cache_get(const char *name, struct dev_filter *f)
 {
 	struct stat buf;
-	struct device *d = (struct device *) hash_lookup(_cache.names, name);
+	struct device *d = (struct device *) dm_hash_lookup(_cache.names, name);
 
 	if (d && (d->flags & DEV_REGULAR))
 		return d;
 
 	/* If the entry's wrong, remove it */
 	if (d && (stat(name, &buf) || (buf.st_rdev != d->dev))) {
-		hash_remove(_cache.names, name);
+		dm_hash_remove(_cache.names, name);
 		d = NULL;
 	}
 
 	if (!d) {
 		_insert(name, 0);
-		d = (struct device *) hash_lookup(_cache.names, name);
+		d = (struct device *) dm_hash_lookup(_cache.names, name);
 		if (!d) {
 			_full_scan(0);
-			d = (struct device *) hash_lookup(_cache.names, name);
+			d = (struct device *) dm_hash_lookup(_cache.names, name);
 		}
 	}
 
@@ -641,7 +638,7 @@
 
 struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
 {
-	struct dev_iter *di = dbg_malloc(sizeof(*di));
+	struct dev_iter *di = dm_malloc(sizeof(*di));
 
 	if (!di) {
 		log_error("dev_iter allocation failed");
@@ -664,7 +661,7 @@
 
 void dev_iter_destroy(struct dev_iter *iter)
 {
-	dbg_free(iter);
+	dm_free(iter);
 }
 
 static inline struct device *_iter_next(struct dev_iter *iter)

Modified: lvm2/upstream/current/lib/device/dev-cache.h
==============================================================================
--- lvm2/upstream/current/lib/device/dev-cache.h	(original)
+++ lvm2/upstream/current/lib/device/dev-cache.h	Tue Nov 15 17:45:32 2005
@@ -16,7 +16,6 @@
 #ifndef _LVM_DEV_CACHE_H
 #define _LVM_DEV_CACHE_H
 
-#include "lvm-types.h"
 #include "device.h"
 
 /*

Modified: lvm2/upstream/current/lib/device/dev-io.c
==============================================================================
--- lvm2/upstream/current/lib/device/dev-io.c	(original)
+++ lvm2/upstream/current/lib/device/dev-io.c	Tue Nov 15 17:45:32 2005
@@ -320,15 +320,22 @@
 {
 	struct stat buf;
 	const char *name;
+	int need_excl = 0, need_rw = 0;
+
+	if ((flags & O_ACCMODE) == O_RDWR)
+		need_rw = 1;
+
+	if ((flags & O_EXCL))
+		need_excl = 1;
 
 	if (dev->fd >= 0) {
-		if ((dev->flags & DEV_OPENED_RW) ||
-		    ((flags & O_ACCMODE) != O_RDWR)) {
+		if (((dev->flags & DEV_OPENED_RW) || !need_rw) &&
+		    ((dev->flags & DEV_OPENED_EXCL) || !need_excl)) {
 			dev->open_count++;
 			return 1;
 		}
 
-		if (dev->open_count) {
+		if (dev->open_count && !need_excl) {
 			/* FIXME Ensure we never get here */
 			log_debug("WARNING: %s already opened read-only", 
 				  dev_name(dev));
@@ -397,11 +404,16 @@
 	dev->open_count++;
 	dev->flags &= ~DEV_ACCESSED_W;
 
-	if ((flags & O_ACCMODE) == O_RDWR)
+	if (need_rw)
 		dev->flags |= DEV_OPENED_RW;
 	else
 		dev->flags &= ~DEV_OPENED_RW;
 
+	if (need_excl)
+		dev->flags |= DEV_OPENED_EXCL;
+	else
+		dev->flags &= ~DEV_OPENED_EXCL;
+
 	if (!(dev->flags & DEV_REGULAR) &&
 	    ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
 		log_error("%s: fstat failed: Has device name changed?", name);
@@ -420,8 +432,9 @@
 
 	list_add(&_open_devices, &dev->open_list);
 
-	log_debug("Opened %s %s%s", dev_name(dev),
+	log_debug("Opened %s %s%s%s", dev_name(dev),
 		  dev->flags & DEV_OPENED_RW ? "RW" : "RO",
+		  dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "",
 		  dev->flags & DEV_O_DIRECT ? " O_DIRECT" : "");
 
 	return 1;
@@ -445,6 +458,21 @@
 	return dev_open_flags(dev, flags, 1, 0);
 }
 
+int dev_test_excl(struct device *dev)
+{
+	int flags;
+	int r;
+
+	flags = vg_write_lock_held() ? O_RDWR : O_RDONLY;
+	flags |= O_EXCL;
+
+	r = dev_open_flags(dev, flags, 1, 1);
+	if (r)
+		dev_close_immediate(dev);
+
+	return r;
+}
+
 static void _close(struct device *dev)
 {
 	if (close(dev->fd))
@@ -456,15 +484,17 @@
 	log_debug("Closed %s", dev_name(dev));
 
 	if (dev->flags & DEV_ALLOCED) {
-		dbg_free((void *) list_item(dev->aliases.n, struct str_list)->
+		dm_free((void *) list_item(dev->aliases.n, struct str_list)->
 			 str);
-		dbg_free(dev->aliases.n);
-		dbg_free(dev);
+		dm_free(dev->aliases.n);
+		dm_free(dev);
 	}
 }
 
 static int _dev_close(struct device *dev, int immediate)
 {
+	struct lvmcache_info *info;
+
 	if (dev->fd < 0) {
 		log_error("Attempt to close device '%s' "
 			  "which is not open.", dev_name(dev));
@@ -479,8 +509,18 @@
 	if (dev->open_count > 0)
 		dev->open_count--;
 
-	/* FIXME lookup device in cache to get vgname and see if it's locked? */
-	if (immediate || (dev->open_count < 1 && !vgs_locked()))
+	if (immediate && dev->open_count) {
+		log_debug("%s: Immediate close attempt while still referenced",
+			  dev_name(dev));
+		dev->open_count = 0;
+	}
+
+	/* Close unless device is known to belong to a locked VG */
+	if (immediate ||
+	    (dev->open_count < 1 && 
+	     (!(info = info_from_pvid(dev->pvid)) ||
+	      !info->vginfo ||
+	      !vgname_is_locked(info->vginfo->vgname))))
 		_close(dev);
 
 	return 1;

Modified: lvm2/upstream/current/lib/device/device.c
==============================================================================
--- lvm2/upstream/current/lib/device/device.c	(original)
+++ lvm2/upstream/current/lib/device/device.c	Tue Nov 15 17:45:32 2005
@@ -202,7 +202,7 @@
 		return 0;
 	}
 
-	if (!(buffer = dbg_malloc(SECTOR_SIZE))) {
+	if (!(buffer = dm_malloc(SECTOR_SIZE))) {
 		log_error("Failed to allocate partition table buffer");
 		return 0;
 	}

Modified: lvm2/upstream/current/lib/device/device.h
==============================================================================
--- lvm2/upstream/current/lib/device/device.h	(original)
+++ lvm2/upstream/current/lib/device/device.h	Tue Nov 15 17:45:32 2005
@@ -17,14 +17,16 @@
 #define _LVM_DEVICE_H
 
 #include "uuid.h"
+
 #include <fcntl.h>
 
 #define DEV_ACCESSED_W		0x00000001	/* Device written to? */
 #define DEV_REGULAR		0x00000002	/* Regular file? */
-#define DEV_ALLOCED		0x00000004	/* dbg_malloc used */
+#define DEV_ALLOCED		0x00000004	/* dm_malloc used */
 #define DEV_OPENED_RW		0x00000008	/* Opened RW */
-#define DEV_O_DIRECT		0x00000010	/* Use O_DIRECT */
-#define DEV_O_DIRECT_TESTED	0x00000020	/* DEV_O_DIRECT is reliable */
+#define DEV_OPENED_EXCL		0x00000010	/* Opened EXCL */
+#define DEV_O_DIRECT		0x00000020	/* Use O_DIRECT */
+#define DEV_O_DIRECT_TESTED	0x00000040	/* DEV_O_DIRECT is reliable */
 
 /*
  * All devices in LVM will be represented by one of these.
@@ -70,6 +72,7 @@
 int dev_close(struct device *dev);
 int dev_close_immediate(struct device *dev);
 void dev_close_all(void);
+int dev_test_excl(struct device *dev);
 
 static inline int dev_fd(struct device *dev)
 {

Modified: lvm2/upstream/current/lib/display/display.c
==============================================================================
--- lvm2/upstream/current/lib/display/display.c	(original)
+++ lvm2/upstream/current/lib/display/display.c	Tue Nov 15 17:45:32 2005
@@ -151,7 +151,7 @@
 		{"         ", "   ", " "},
 	};
 
-	if (!(size_buf = pool_alloc(cmd->mem, SIZE_BUF))) {
+	if (!(size_buf = dm_pool_alloc(cmd->mem, SIZE_BUF))) {
 		log_error("no memory for size display buffer");
 		return "";
 	}
@@ -317,7 +317,7 @@
 {
 	int inkernel;
 	struct lvinfo info;
-	inkernel = lv_info(lv, &info, 1) && info.exists;
+	inkernel = lv_info(lv->vg->cmd, lv, &info, 1) && info.exists;
 
 	log_print("%s%s/%s:%s:%d:%d:-1:%d:%" PRIu64 ":%d:-1:%d:%d:%d:%d",
 		  lv->vg->cmd->dev_dir,
@@ -347,7 +347,7 @@
 		return 0;
 	}
 
-	inkernel = lv_info(lv, &info, 1) && info.exists;
+	inkernel = lv_info(cmd, lv, &info, 1) && info.exists;
 
 	log_print("--- Logical volume ---");
 

Modified: lvm2/upstream/current/lib/error/errseg.c
==============================================================================
--- lvm2/upstream/current/lib/error/errseg.c	(original)
+++ lvm2/upstream/current/lib/error/errseg.c	Tue Nov 15 17:45:32 2005
@@ -13,8 +13,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
-#include "list.h"
 #include "toolcontext.h"
 #include "segtype.h"
 #include "display.h"
@@ -40,18 +38,13 @@
 }
 
 #ifdef DEVMAPPER_SUPPORT
-static int _compose_target_line(struct dev_manager *dm, struct pool *mem,
+static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
 				struct config_tree *cft, void **target_state,
-				struct lv_segment *seg, char *params,
-				size_t paramsize, const char **target, int *pos,
+				struct lv_segment *seg,
+				struct dm_tree_node *node, uint64_t len,
 				uint32_t *pvmove_mirror_count)
 {
-	/*   error */
-
-	*target = "error";
-	*params = '\0';
-
-	return 1;
+	return dm_tree_node_add_error_target(node, len);
 }
 
 static int _target_present(void)
@@ -59,8 +52,10 @@
 	static int checked = 0;
 	static int present = 0;
 
-	if (!checked)
-		present = target_present("error");
+	/* Reported truncated in older kernels */
+	if (!checked &&
+	    (target_present("error", 0) || target_present("erro", 0)))
+		present = 1;
 
 	checked = 1;
 	return present;
@@ -69,14 +64,14 @@
 
 static void _destroy(const struct segment_type *segtype)
 {
-	dbg_free((void *) segtype);
+	dm_free((void *) segtype);
 }
 
 static struct segtype_handler _error_ops = {
 	name:_name,
 	merge_segments:_merge_segments,
 #ifdef DEVMAPPER_SUPPORT
-	compose_target_line:_compose_target_line,
+	add_target_line:_add_target_line,
 	target_present:_target_present,
 #endif
 	destroy:_destroy,
@@ -84,18 +79,16 @@
 
 struct segment_type *init_error_segtype(struct cmd_context *cmd)
 {
-	struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
+	struct segment_type *segtype = dm_malloc(sizeof(*segtype));
 
-	if (!segtype) {
-		stack;
-		return NULL;
-	}
+	if (!segtype)
+		return_NULL;
 
 	segtype->cmd = cmd;
 	segtype->ops = &_error_ops;
 	segtype->name = "error";
 	segtype->private = NULL;
-	segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL;
+	segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
 
 	log_very_verbose("Initialised segtype: %s", segtype->name);
 

Modified: lvm2/upstream/current/lib/filters/filter-composite.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-composite.c	(original)
+++ lvm2/upstream/current/lib/filters/filter-composite.c	Tue Nov 15 17:45:32 2005
@@ -42,8 +42,8 @@
 		filters++;
 	}
 
-	dbg_free(f->private);
-	dbg_free(f);
+	dm_free(f->private);
+	dm_free(f);
 }
 
 struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
@@ -55,7 +55,7 @@
 		return NULL;
 	}
 
-	if (!(filters_copy = dbg_malloc(sizeof(*filters) * (n + 1)))) {
+	if (!(filters_copy = dm_malloc(sizeof(*filters) * (n + 1)))) {
 		log_error("composite filters allocation failed");
 		return NULL;
 	}
@@ -63,9 +63,9 @@
 	memcpy(filters_copy, filters, sizeof(*filters) * n);
 	filters_copy[n] = NULL;
 
-	if (!(cft = dbg_malloc(sizeof(*cft)))) {
+	if (!(cft = dm_malloc(sizeof(*cft)))) {
 		log_error("compsoite filters allocation failed");
-		dbg_free(filters_copy);
+		dm_free(filters_copy);
 		return NULL;
 	}
 

Modified: lvm2/upstream/current/lib/filters/filter-md.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-md.c	(original)
+++ lvm2/upstream/current/lib/filters/filter-md.c	Tue Nov 15 17:45:32 2005
@@ -51,14 +51,14 @@
 
 static void _destroy(struct dev_filter *f)
 {
-	dbg_free(f);
+	dm_free(f);
 }
 
 struct dev_filter *md_filter_create(void)
 {
 	struct dev_filter *f;
 
-	if (!(f = dbg_malloc(sizeof(*f)))) {
+	if (!(f = dm_malloc(sizeof(*f)))) {
 		log_error("md filter allocation failed");
 		return NULL;
 	}

Modified: lvm2/upstream/current/lib/filters/filter-persistent.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-persistent.c	(original)
+++ lvm2/upstream/current/lib/filters/filter-persistent.c	Tue Nov 15 17:45:32 2005
@@ -16,7 +16,6 @@
 #include "lib.h"
 #include "config.h"
 #include "dev-cache.h"
-#include "hash.h"
 #include "filter-persistent.h"
 
 #include <sys/stat.h>
@@ -25,7 +24,7 @@
 
 struct pfilter {
 	char *file;
-	struct hash_table *devices;
+	struct dm_hash_table *devices;
 	struct dev_filter *real;
 };
 
@@ -39,9 +38,9 @@
 static int _init_hash(struct pfilter *pf)
 {
 	if (pf->devices)
-		hash_destroy(pf->devices);
+		dm_hash_destroy(pf->devices);
 
-	if (!(pf->devices = hash_create(128))) {
+	if (!(pf->devices = dm_hash_create(128))) {
 		stack;
 		return 0;
 	}
@@ -54,7 +53,7 @@
 	struct pfilter *pf = (struct pfilter *) f->private;
 
 	log_verbose("Wiping cache of LVM-capable devices");
-	hash_wipe(pf->devices);
+	dm_hash_wipe(pf->devices);
 
 	/* Trigger complete device scan */
 	dev_cache_scan(1);
@@ -85,7 +84,7 @@
 			continue;
 		}
 
-		if (!hash_insert(pf->devices, cv->v.str, data))
+		if (!dm_hash_insert(pf->devices, cv->v.str, data))
 			log_verbose("Couldn't add '%s' to filter ... ignoring",
 				    cv->v.str);
 		/* Populate dev_cache ourselves */
@@ -118,7 +117,7 @@
 	   PF_BAD_DEVICE); */
 
 	/* Did we find anything? */
-	if (hash_get_num_entries(pf->devices)) {
+	if (dm_hash_get_num_entries(pf->devices)) {
 		/* We populated dev_cache ourselves */
 		dev_cache_scan(0);
 		r = 1;
@@ -136,11 +135,11 @@
 {
 	void *d;
 	int first = 1;
-	struct hash_node *n;
+	struct dm_hash_node *n;
 
-	for (n = hash_get_first(pf->devices); n;
-	     n = hash_get_next(pf->devices, n)) {
-		d = hash_get_data(pf->devices, n);
+	for (n = dm_hash_get_first(pf->devices); n;
+	     n = dm_hash_get_next(pf->devices, n)) {
+		d = dm_hash_get_data(pf->devices, n);
 
 		if (d != data)
 			continue;
@@ -152,7 +151,7 @@
 			first = 0;
 		}
 
-		fprintf(fp, "\t\t\"%s\"", hash_get_key(pf->devices, n));
+		fprintf(fp, "\t\t\"%s\"", dm_hash_get_key(pf->devices, n));
 	}
 
 	if (!first)
@@ -167,7 +166,7 @@
 
 	FILE *fp;
 
-	if (!hash_get_num_entries(pf->devices)) {
+	if (!dm_hash_get_num_entries(pf->devices)) {
 		log_very_verbose("Internal persistent device cache empty "
 				 "- not writing to %s", pf->file);
 		return 0;
@@ -202,7 +201,7 @@
 static int _lookup_p(struct dev_filter *f, struct device *dev)
 {
 	struct pfilter *pf = (struct pfilter *) f->private;
-	void *l = hash_lookup(pf->devices, dev_name(dev));
+	void *l = dm_hash_lookup(pf->devices, dev_name(dev));
 	struct str_list *sl;
 
 	if (!l) {
@@ -210,7 +209,7 @@
 		    PF_GOOD_DEVICE : PF_BAD_DEVICE;
 
 		list_iterate_items(sl, &dev->aliases)
-			hash_insert(pf->devices, sl->str, l);
+			dm_hash_insert(pf->devices, sl->str, l);
 
 	} else if (l == PF_BAD_DEVICE)
 			log_debug("%s: Skipping (cached)", dev_name(dev));
@@ -222,11 +221,11 @@
 {
 	struct pfilter *pf = (struct pfilter *) f->private;
 
-	hash_destroy(pf->devices);
-	dbg_free(pf->file);
+	dm_hash_destroy(pf->devices);
+	dm_free(pf->file);
 	pf->real->destroy(pf->real);
-	dbg_free(pf);
-	dbg_free(f);
+	dm_free(pf);
+	dm_free(f);
 }
 
 struct dev_filter *persistent_filter_create(struct dev_filter *real,
@@ -235,13 +234,13 @@
 	struct pfilter *pf;
 	struct dev_filter *f = NULL;
 
-	if (!(pf = dbg_malloc(sizeof(*pf)))) {
+	if (!(pf = dm_malloc(sizeof(*pf)))) {
 		stack;
 		return NULL;
 	}
 	memset(pf, 0, sizeof(*pf));
 
-	if (!(pf->file = dbg_malloc(strlen(file) + 1))) {
+	if (!(pf->file = dm_malloc(strlen(file) + 1))) {
 		stack;
 		goto bad;
 	}
@@ -253,7 +252,7 @@
 		goto bad;
 	}
 
-	if (!(f = dbg_malloc(sizeof(*f)))) {
+	if (!(f = dm_malloc(sizeof(*f)))) {
 		stack;
 		goto bad;
 	}
@@ -265,10 +264,10 @@
 	return f;
 
       bad:
-	dbg_free(pf->file);
+	dm_free(pf->file);
 	if (pf->devices)
-		hash_destroy(pf->devices);
-	dbg_free(pf);
-	dbg_free(f);
+		dm_hash_destroy(pf->devices);
+	dm_free(pf);
+	dm_free(f);
 	return NULL;
 }

Modified: lvm2/upstream/current/lib/filters/filter-regex.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-regex.c	(original)
+++ lvm2/upstream/current/lib/filters/filter-regex.c	Tue Nov 15 17:45:32 2005
@@ -14,21 +14,18 @@
  */
 
 #include "lib.h"
-#include "pool.h"
 #include "filter-regex.h"
 #include "matcher.h"
 #include "device.h"
-#include "bitset.h"
-#include "list.h"
 
 struct rfilter {
-	struct pool *mem;
-	bitset_t accept;
+	struct dm_pool *mem;
+	dm_bitset_t accept;
 	struct matcher *engine;
 };
 
-static int _extract_pattern(struct pool *mem, const char *pat,
-			    char **regex, bitset_t accept, int ix)
+static int _extract_pattern(struct dm_pool *mem, const char *pat,
+			    char **regex, dm_bitset_t accept, int ix)
 {
 	char sep, *r, *ptr;
 
@@ -37,11 +34,11 @@
 	 */
 	switch (*pat) {
 	case 'a':
-		bit_set(accept, ix);
+		dm_bit_set(accept, ix);
 		break;
 
 	case 'r':
-		bit_clear(accept, ix);
+		dm_bit_clear(accept, ix);
 		break;
 
 	default:
@@ -74,7 +71,7 @@
 	/*
 	 * copy the regex
 	 */
-	if (!(r = pool_strdup(mem, pat))) {
+	if (!(r = dm_pool_strdup(mem, pat))) {
 		stack;
 		return 0;
 	}
@@ -95,13 +92,13 @@
 
 static int _build_matcher(struct rfilter *rf, struct config_value *val)
 {
-	struct pool *scratch;
+	struct dm_pool *scratch;
 	struct config_value *v;
 	char **regex;
 	unsigned count = 0;
 	int i, r = 0;
 
-	if (!(scratch = pool_create("filter matcher", 1024))) {
+	if (!(scratch = dm_pool_create("filter matcher", 1024))) {
 		stack;
 		return 0;
 	}
@@ -122,7 +119,7 @@
 	/*
 	 * allocate space for them
 	 */
-	if (!(regex = pool_alloc(scratch, sizeof(*regex) * count))) {
+	if (!(regex = dm_pool_alloc(scratch, sizeof(*regex) * count))) {
 		stack;
 		goto out;
 	}
@@ -130,7 +127,7 @@
 	/*
 	 * create the accept/reject bitset
 	 */
-	rf->accept = bitset_create(rf->mem, count);
+	rf->accept = dm_bitset_create(rf->mem, count);
 
 	/*
 	 * fill the array back to front because we
@@ -152,7 +149,7 @@
 	r = 1;
 
       out:
-	pool_destroy(scratch);
+	dm_pool_destroy(scratch);
 	return r;
 }
 
@@ -166,7 +163,7 @@
 		m = matcher_run(rf->engine, sl->str);
 
 		if (m >= 0) {
-			if (bit(rf->accept, m)) {
+			if (dm_bit(rf->accept, m)) {
 
 				if (!first) {
 					log_debug("%s: New preferred name",
@@ -197,12 +194,12 @@
 static void _destroy(struct dev_filter *f)
 {
 	struct rfilter *rf = (struct rfilter *) f->private;
-	pool_destroy(rf->mem);
+	dm_pool_destroy(rf->mem);
 }
 
 struct dev_filter *regex_filter_create(struct config_value *patterns)
 {
-	struct pool *mem = pool_create("filter regex", 10 * 1024);
+	struct dm_pool *mem = dm_pool_create("filter regex", 10 * 1024);
 	struct rfilter *rf;
 	struct dev_filter *f;
 
@@ -211,7 +208,7 @@
 		return NULL;
 	}
 
-	if (!(rf = pool_alloc(mem, sizeof(*rf)))) {
+	if (!(rf = dm_pool_alloc(mem, sizeof(*rf)))) {
 		stack;
 		goto bad;
 	}
@@ -223,7 +220,7 @@
 		goto bad;
 	}
 
-	if (!(f = pool_zalloc(mem, sizeof(*f)))) {
+	if (!(f = dm_pool_zalloc(mem, sizeof(*f)))) {
 		stack;
 		goto bad;
 	}
@@ -234,6 +231,6 @@
 	return f;
 
       bad:
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return NULL;
 }

Modified: lvm2/upstream/current/lib/filters/filter-sysfs.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter-sysfs.c	(original)
+++ lvm2/upstream/current/lib/filters/filter-sysfs.c	Tue Nov 15 17:45:32 2005
@@ -15,7 +15,6 @@
 #include "lib.h"
 #include "filter-sysfs.h"
 #include "lvm-string.h"
-#include "pool.h"
 
 #ifdef linux
 
@@ -69,21 +68,21 @@
 
 #define SET_BUCKETS 64
 struct dev_set {
-	struct pool *mem;
+	struct dm_pool *mem;
 	const char *sys_block;
 	int initialised;
 	struct entry *slots[SET_BUCKETS];
 };
 
-static struct dev_set *_dev_set_create(struct pool *mem, const char *sys_block)
+static struct dev_set *_dev_set_create(struct dm_pool *mem, const char *sys_block)
 {
 	struct dev_set *ds;
 
-	if (!(ds = pool_zalloc(mem, sizeof(*ds))))
+	if (!(ds = dm_pool_zalloc(mem, sizeof(*ds))))
 		return NULL;
 
 	ds->mem = mem;
-	ds->sys_block = pool_strdup(mem, sys_block);
+	ds->sys_block = dm_pool_strdup(mem, sys_block);
 	ds->initialised = 0;
 
 	return ds;
@@ -102,7 +101,7 @@
 	struct entry *e;
 	unsigned h = _hash_dev(dev);
 
-	if (!(e = pool_alloc(ds->mem, sizeof(*e))))
+	if (!(e = dm_pool_alloc(ds->mem, sizeof(*e))))
 		return 0;
 
 	e->next = ds->slots[h];
@@ -258,20 +257,20 @@
 static void _destroy(struct dev_filter *f)
 {
 	struct dev_set *ds = (struct dev_set *) f->private;
-	pool_destroy(ds->mem);
+	dm_pool_destroy(ds->mem);
 }
 
 struct dev_filter *sysfs_filter_create(const char *proc)
 {
 	char sys_block[PATH_MAX];
-	struct pool *mem;
+	struct dm_pool *mem;
 	struct dev_set *ds;
 	struct dev_filter *f;
 
 	if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block)))
 		return NULL;
 
-	if (!(mem = pool_create("sysfs", 256))) {
+	if (!(mem = dm_pool_create("sysfs", 256))) {
 		log_error("sysfs pool creation failed");
 		return NULL;
 	}
@@ -281,7 +280,7 @@
 		goto bad;
 	}
 
-	if (!(f = pool_zalloc(mem, sizeof(*f)))) {
+	if (!(f = dm_pool_zalloc(mem, sizeof(*f)))) {
 		stack;
 		goto bad;
 	}
@@ -292,7 +291,7 @@
 	return f;
 
  bad:
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return NULL;
 }
 

Modified: lvm2/upstream/current/lib/filters/filter.c
==============================================================================
--- lvm2/upstream/current/lib/filters/filter.c	(original)
+++ lvm2/upstream/current/lib/filters/filter.c	Tue Nov 15 17:45:32 2005
@@ -28,7 +28,6 @@
 
 #define NUMBER_OF_MAJORS 4096
 
-/* FIXME Make this sparse */
 /* 0 means LVM won't use this major number. */
 static int _max_partitions_by_major[NUMBER_OF_MAJORS];
 
@@ -71,6 +70,9 @@
 	{"iseries/vd", 8},	/* iSeries disks */
 	{"gnbd", 1},		/* Network block device */
 	{"ramdisk", 1},		/* RAM disk */
+	{"aoe", 16},		/* ATA over Ethernet */
+	{"device-mapper", 1},	/* Other mapped devices */
+	{"xvd", 16},		/* Xen virtual block device */
 	{NULL, 0}
 };
 
@@ -241,7 +243,7 @@
 {
 	struct dev_filter *f;
 
-	if (!(f = dbg_malloc(sizeof(struct dev_filter)))) {
+	if (!(f = dm_malloc(sizeof(struct dev_filter)))) {
 		log_error("LVM type filter allocation failed");
 		return NULL;
 	}
@@ -260,6 +262,6 @@
 
 void lvm_type_filter_destroy(struct dev_filter *f)
 {
-	dbg_free(f);
+	dm_free(f);
 	return;
 }

Modified: lvm2/upstream/current/lib/filters/filter.h
==============================================================================
--- lvm2/upstream/current/lib/filters/filter.h	(original)
+++ lvm2/upstream/current/lib/filters/filter.h	Tue Nov 15 17:45:32 2005
@@ -36,7 +36,6 @@
 void lvm_type_filter_destroy(struct dev_filter *f);
 
 int md_major(void);
-
 int max_partitions(int major);
 
 #endif

Modified: lvm2/upstream/current/lib/format1/disk-rep.c
==============================================================================
--- lvm2/upstream/current/lib/format1/disk-rep.c	(original)
+++ lvm2/upstream/current/lib/format1/disk-rep.c	Tue Nov 15 17:45:32 2005
@@ -15,7 +15,6 @@
 
 #include "lib.h"
 #include "disk-rep.h"
-#include "pool.h"
 #include "xlate.h"
 #include "filter.h"
 #include "lvmcache.h"
@@ -255,7 +254,7 @@
 		if (!dev_read(data->dev, pos, sizeof(buffer), buffer))
 			fail;
 
-		if (!(ul = pool_alloc(data->mem, sizeof(*ul))))
+		if (!(ul = dm_pool_alloc(data->mem, sizeof(*ul))))
 			fail;
 
 		memcpy(ul->uuid, buffer, NAME_LEN);
@@ -284,7 +283,7 @@
 
 	for (i = 0; (i < vgd->lv_max) && (read < vgd->lv_cur); i++) {
 		pos = data->pvd.lv_on_disk.base + (i * sizeof(struct lv_disk));
-		ll = pool_alloc(data->mem, sizeof(*ll));
+		ll = dm_pool_alloc(data->mem, sizeof(*ll));
 
 		if (!ll)
 			fail;
@@ -305,7 +304,7 @@
 static int _read_extents(struct disk_list *data)
 {
 	size_t len = sizeof(struct pe_disk) * data->pvd.pe_total;
-	struct pe_disk *extents = pool_alloc(data->mem, len);
+	struct pe_disk *extents = dm_pool_alloc(data->mem, len);
 	uint64_t pos = data->pvd.pe_on_disk.base;
 
 	if (!extents)
@@ -321,10 +320,10 @@
 }
 
 static struct disk_list *__read_disk(const struct format_type *fmt,
-				     struct device *dev, struct pool *mem,
+				     struct device *dev, struct dm_pool *mem,
 				     const char *vg_name)
 {
-	struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
+	struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
 	const char *name = dev_name(dev);
 	struct lvmcache_info *info;
 
@@ -400,12 +399,12 @@
 	return dl;
 
       bad:
-	pool_free(dl->mem, dl);
+	dm_pool_free(dl->mem, dl);
 	return NULL;
 }
 
 struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
-			    struct pool *mem, const char *vg_name)
+			    struct dm_pool *mem, const char *vg_name)
 {
 	struct disk_list *r;
 
@@ -452,7 +451,7 @@
  * so we can free off all the memory if something goes wrong.
  */
 int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
-		   struct dev_filter *filter, struct pool *mem,
+		   struct dev_filter *filter, struct dm_pool *mem,
 		   struct list *head)
 {
 	struct dev_iter *iter;
@@ -506,6 +505,9 @@
 	struct vg_disk *vgd = &data->vgd;
 	uint64_t pos = data->pvd.vg_on_disk.base;
 
+	log_debug("Writing %s VG metadata to %s at %" PRIu64 " len %" PRIsize_t,
+		  data->pvd.vg_name, dev_name(data->dev), pos, sizeof(*vgd));
+
 	_xlate_vgd(vgd);
 	if (!dev_write(data->dev, pos, sizeof(*vgd), vgd))
 		fail;
@@ -528,6 +530,10 @@
 			return 0;
 		}
 
+		log_debug("Writing %s uuidlist to %s at %" PRIu64 " len %d",
+			  data->pvd.vg_name, dev_name(data->dev),
+			  pos, NAME_LEN);
+
 		if (!dev_write(data->dev, pos, NAME_LEN, ul->uuid))
 			fail;
 
@@ -539,6 +545,10 @@
 
 static int _write_lvd(struct device *dev, uint64_t pos, struct lv_disk *disk)
 {
+	log_debug("Writing %s LV %s metadata to %s at %" PRIu64 " len %"
+		  PRIsize_t, disk->vg_name, disk->lv_name, dev_name(dev),
+		  pos, sizeof(*disk));
+
 	_xlate_lvd(disk);
 	if (!dev_write(dev, pos, sizeof(*disk), disk))
 		fail;
@@ -581,6 +591,10 @@
 	struct pe_disk *extents = data->extents;
 	uint64_t pos = data->pvd.pe_on_disk.base;
 
+	log_debug("Writing %s extents metadata to %s at %" PRIu64 " len %"
+		  PRIsize_t, data->pvd.vg_name, dev_name(data->dev),
+		  pos, len);
+
 	_xlate_extents(extents, data->pvd.pe_total);
 	if (!dev_write(data->dev, pos, len, extents))
 		fail;
@@ -604,7 +618,7 @@
 	/* Make sure that the gap between the PV structure and
 	   the next one is zeroed in order to make non LVM tools
 	   happy (idea from AED) */
-	buf = dbg_malloc(size);
+	buf = dm_malloc(size);
 	if (!buf) {
 		log_err("Couldn't allocate temporary PV buffer.");
 		return 0;
@@ -613,13 +627,17 @@
 	memset(buf, 0, size);
 	memcpy(buf, &data->pvd, sizeof(struct pv_disk));
 
+	log_debug("Writing %s PV metadata to %s at %" PRIu64 " len %"
+		  PRIsize_t, data->pvd.vg_name, dev_name(data->dev),
+		  pos, size);
+
 	_xlate_pvd((struct pv_disk *) buf);
 	if (!dev_write(data->dev, pos, size, buf)) {
-		dbg_free(buf);
+		dm_free(buf);
 		fail;
 	}
 
-	dbg_free(buf);
+	dm_free(buf);
 	return 1;
 }
 

Modified: lvm2/upstream/current/lib/format1/disk-rep.h
==============================================================================
--- lvm2/upstream/current/lib/format1/disk-rep.h	(original)
+++ lvm2/upstream/current/lib/format1/disk-rep.h	Tue Nov 15 17:45:32 2005
@@ -18,7 +18,6 @@
 
 #include "lvm-types.h"
 #include "metadata.h"
-#include "pool.h"
 #include "toolcontext.h"
 
 #define MAX_PV 256
@@ -159,7 +158,7 @@
 
 struct disk_list {
 	struct list list;
-	struct pool *mem;
+	struct dm_pool *mem;
 	struct device *dev;
 
 	struct pv_disk pvd;
@@ -191,11 +190,11 @@
  */
 
 struct disk_list *read_disk(const struct format_type *fmt, struct device *dev,
-			    struct pool *mem, const char *vg_name);
+			    struct dm_pool *mem, const char *vg_name);
 
 int read_pvs_in_vg(const struct format_type *fmt, const char *vg_name,
 		   struct dev_filter *filter,
-		   struct pool *mem, struct list *results);
+		   struct dm_pool *mem, struct list *results);
 
 int write_disks(const struct format_type *fmt, struct list *pvds);
 
@@ -203,33 +202,33 @@
  * Functions to translate to between disk and in
  * core structures.
  */
-int import_pv(struct pool *mem, struct device *dev,
+int import_pv(struct dm_pool *mem, struct device *dev,
 	      struct volume_group *vg,
 	      struct physical_volume *pv, struct pv_disk *pvd);
-int export_pv(struct cmd_context *cmd, struct pool *mem,
+int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
 	      struct volume_group *vg,
 	      struct pv_disk *pvd, struct physical_volume *pv);
 
-int import_vg(struct pool *mem,
+int import_vg(struct dm_pool *mem,
 	      struct volume_group *vg, struct disk_list *dl, int partial);
 int export_vg(struct vg_disk *vgd, struct volume_group *vg);
 
-int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
+int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
 
 int import_extents(struct cmd_context *cmd, struct volume_group *vg,
 		   struct list *pvds);
 int export_extents(struct disk_list *dl, uint32_t lv_num,
 		   struct logical_volume *lv, struct physical_volume *pv);
 
-int import_pvs(const struct format_type *fmt, struct pool *mem,
+int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
 	       struct volume_group *vg,
 	       struct list *pvds, struct list *results, int *count);
 
-int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds);
+int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds);
 int export_lvs(struct disk_list *dl, struct volume_group *vg,
 	       struct physical_volume *pv, const char *dev_dir);
 
-int import_snapshots(struct pool *mem, struct volume_group *vg,
+int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
 		     struct list *pvds);
 
 int export_uuids(struct disk_list *dl, struct volume_group *vg);

Modified: lvm2/upstream/current/lib/format1/format1.c
==============================================================================
--- lvm2/upstream/current/lib/format1/format1.c	(original)
+++ lvm2/upstream/current/lib/format1/format1.c	Tue Nov 15 17:45:32 2005
@@ -15,10 +15,7 @@
 
 #include "lib.h"
 #include "disk-rep.h"
-#include "pool.h"
-#include "hash.h"
 #include "limits.h"
-#include "list.h"
 #include "display.h"
 #include "toolcontext.h"
 #include "lvmcache.h"
@@ -128,8 +125,8 @@
 static struct volume_group *_build_vg(struct format_instance *fid,
 				      struct list *pvs)
 {
-	struct pool *mem = fid->fmt->cmd->mem;
-	struct volume_group *vg = pool_alloc(mem, sizeof(*vg));
+	struct dm_pool *mem = fid->fmt->cmd->mem;
+	struct volume_group *vg = dm_pool_alloc(mem, sizeof(*vg));
 	struct disk_list *dl;
 	int partial;
 
@@ -172,7 +169,7 @@
 
       bad:
 	stack;
-	pool_free(mem, vg);
+	dm_pool_free(mem, vg);
 	return NULL;
 }
 
@@ -180,7 +177,7 @@
 				     const char *vg_name,
 				     struct metadata_area *mda)
 {
-	struct pool *mem = pool_create("lvm1 vg_read", 1024 * 10);
+	struct dm_pool *mem = dm_pool_create("lvm1 vg_read", 1024 * 10);
 	struct list pvs;
 	struct volume_group *vg = NULL;
 	list_init(&pvs);
@@ -205,16 +202,16 @@
 	}
 
       bad:
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return vg;
 }
 
 static struct disk_list *_flatten_pv(struct format_instance *fid,
-				     struct pool *mem, struct volume_group *vg,
+				     struct dm_pool *mem, struct volume_group *vg,
 				     struct physical_volume *pv,
 				     const char *dev_dir)
 {
-	struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
+	struct disk_list *dl = dm_pool_alloc(mem, sizeof(*dl));
 
 	if (!dl) {
 		stack;
@@ -232,14 +229,14 @@
 	    !export_uuids(dl, vg) ||
 	    !export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) {
 		stack;
-		pool_free(mem, dl);
+		dm_pool_free(mem, dl);
 		return NULL;
 	}
 
 	return dl;
 }
 
-static int _flatten_vg(struct format_instance *fid, struct pool *mem,
+static int _flatten_vg(struct format_instance *fid, struct dm_pool *mem,
 		       struct volume_group *vg,
 		       struct list *pvds, const char *dev_dir,
 		       struct dev_filter *filter)
@@ -270,7 +267,7 @@
 static int _vg_write(struct format_instance *fid, struct volume_group *vg,
 		     struct metadata_area *mda)
 {
-	struct pool *mem = pool_create("lvm1 vg_write", 1024 * 10);
+	struct dm_pool *mem = dm_pool_create("lvm1 vg_write", 1024 * 10);
 	struct list pvds;
 	int r = 0;
 
@@ -286,14 +283,14 @@
 	     write_disks(fid->fmt, &pvds));
 
 	lvmcache_update_vg(vg);
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return r;
 }
 
 static int _pv_read(const struct format_type *fmt, const char *pv_name,
 		    struct physical_volume *pv, struct list *mdas)
 {
-	struct pool *mem = pool_create("lvm1 pv_read", 1024);
+	struct dm_pool *mem = dm_pool_create("lvm1 pv_read", 1024);
 	struct disk_list *dl;
 	struct device *dev;
 	int r = 0;
@@ -325,7 +322,7 @@
 	r = 1;
 
       out:
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return r;
 }
 
@@ -392,7 +389,7 @@
 static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
 		     struct list *mdas, int64_t sector)
 {
-	struct pool *mem;
+	struct dm_pool *mem;
 	struct disk_list *dl;
 	struct list pvs;
 	struct label *label;
@@ -415,12 +412,12 @@
 	pv->pe_size = pv->pe_count = 0;
 	pv->pe_start = PE_ALIGN;
 
-	if (!(mem = pool_create("lvm1 pv_write", 1024))) {
+	if (!(mem = dm_pool_create("lvm1 pv_write", 1024))) {
 		stack;
 		return 0;
 	}
 
-	if (!(dl = pool_alloc(mem, sizeof(*dl)))) {
+	if (!(dl = dm_pool_alloc(mem, sizeof(*dl)))) {
 		stack;
 		goto bad;
 	}
@@ -444,11 +441,11 @@
 		goto bad;
 	}
 
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return 1;
 
       bad:
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return 0;
 }
 
@@ -510,7 +507,7 @@
 	struct format_instance *fid;
 	struct metadata_area *mda;
 
-	if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
+	if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
 		stack;
 		return NULL;
 	}
@@ -519,9 +516,9 @@
 	list_init(&fid->metadata_areas);
 
 	/* Define a NULL metadata area */
-	if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
+	if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
 		stack;
-		pool_free(fmt->cmd->mem, fid);
+		dm_pool_free(fmt->cmd->mem, fid);
 		return NULL;
 	}
 
@@ -539,7 +536,7 @@
 
 static void _destroy(const struct format_type *fmt)
 {
-	dbg_free((void *) fmt);
+	dm_free((void *) fmt);
 }
 
 static struct format_handler _format1_ops = {
@@ -561,7 +558,7 @@
 struct format_type *init_format(struct cmd_context *cmd)
 #endif
 {
-	struct format_type *fmt = dbg_malloc(sizeof(*fmt));
+	struct format_type *fmt = dm_malloc(sizeof(*fmt));
 
 	if (!fmt) {
 		stack;

Modified: lvm2/upstream/current/lib/format1/import-export.c
==============================================================================
--- lvm2/upstream/current/lib/format1/import-export.c	(original)
+++ lvm2/upstream/current/lib/format1/import-export.c	Tue Nov 15 17:45:32 2005
@@ -19,9 +19,6 @@
 
 #include "lib.h"
 #include "disk-rep.h"
-#include "pool.h"
-#include "hash.h"
-#include "list.h"
 #include "lvm-string.h"
 #include "filter.h"
 #include "toolcontext.h"
@@ -38,7 +35,7 @@
 /*
  * Extracts the last part of a path.
  */
-static char *_create_lv_name(struct pool *mem, const char *full_name)
+static char *_create_lv_name(struct dm_pool *mem, const char *full_name)
 {
 	const char *ptr = strrchr(full_name, '/');
 
@@ -47,10 +44,10 @@
 	else
 		ptr++;
 
-	return pool_strdup(mem, ptr);
+	return dm_pool_strdup(mem, ptr);
 }
 
-int import_pv(struct pool *mem, struct device *dev,
+int import_pv(struct dm_pool *mem, struct device *dev,
 	      struct volume_group *vg,
 	      struct physical_volume *pv, struct pv_disk *pvd)
 {
@@ -58,7 +55,7 @@
 	memcpy(&pv->id, pvd->pv_uuid, ID_LEN);
 
 	pv->dev = dev;
-	if (!(pv->vg_name = pool_strdup(mem, pvd->vg_name))) {
+	if (!(pv->vg_name = dm_pool_strdup(mem, pvd->vg_name))) {
 		stack;
 		return 0;
 	}
@@ -112,7 +109,7 @@
 	return 1;
 }
 
-int export_pv(struct cmd_context *cmd, struct pool *mem,
+int export_pv(struct cmd_context *cmd, struct dm_pool *mem,
 	      struct volume_group *vg,
 	      struct pv_disk *pvd, struct physical_volume *pv)
 {
@@ -198,7 +195,7 @@
 	return 1;
 }
 
-int import_vg(struct pool *mem,
+int import_vg(struct dm_pool *mem,
 	      struct volume_group *vg, struct disk_list *dl, int partial)
 {
 	struct vg_disk *vgd = &dl->vgd;
@@ -209,12 +206,12 @@
 		return 0;
 	}
 
-	if (!(vg->name = pool_strdup(mem, dl->pvd.vg_name))) {
+	if (!(vg->name = dm_pool_strdup(mem, dl->pvd.vg_name))) {
 		stack;
 		return 0;
 	}
 
-	if (!(vg->system_id = pool_alloc(mem, NAME_LEN))) {
+	if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN))) {
 		stack;
 		return 0;
 	}
@@ -288,7 +285,7 @@
 	return 1;
 }
 
-int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
+int import_lv(struct dm_pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
 {
 	lvid_from_lvnum(&lv->lvid, &lv->vg->id, lvd->lv_number);
 
@@ -414,7 +411,7 @@
 	return 1;
 }
 
-int import_pvs(const struct format_type *fmt, struct pool *mem,
+int import_pvs(const struct format_type *fmt, struct dm_pool *mem,
 	       struct volume_group *vg,
 	       struct list *pvds, struct list *results, int *count)
 {
@@ -423,8 +420,8 @@
 
 	*count = 0;
 	list_iterate_items(dl, pvds) {
-		if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
-		    !(pvl->pv = pool_alloc(mem, sizeof(*pvl->pv)))) {
+		if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
+		    !(pvl->pv = dm_pool_alloc(mem, sizeof(*pvl->pv)))) {
 			stack;
 			return 0;
 		}
@@ -442,15 +439,15 @@
 	return 1;
 }
 
-static struct logical_volume *_add_lv(struct pool *mem,
+static struct logical_volume *_add_lv(struct dm_pool *mem,
 				      struct volume_group *vg,
 				      struct lv_disk *lvd)
 {
 	struct lv_list *ll;
 	struct logical_volume *lv;
 
-	if (!(ll = pool_zalloc(mem, sizeof(*ll))) ||
-	    !(ll->lv = pool_zalloc(mem, sizeof(*ll->lv)))) {
+	if (!(ll = dm_pool_zalloc(mem, sizeof(*ll))) ||
+	    !(ll->lv = dm_pool_zalloc(mem, sizeof(*ll->lv)))) {
 		stack;
 		return NULL;
 	}
@@ -468,7 +465,7 @@
 	return lv;
 }
 
-int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds)
+int import_lvs(struct dm_pool *mem, struct volume_group *vg, struct list *pvds)
 {
 	struct disk_list *dl;
 	struct lvd_list *ll;
@@ -498,14 +495,14 @@
 	struct lvd_list *lvdl;
 	size_t len;
 	uint32_t lv_num;
-	struct hash_table *lvd_hash;
+	struct dm_hash_table *lvd_hash;
 
 	if (!_check_vg_name(vg->name)) {
 		stack;
 		return 0;
 	}
 
-	if (!(lvd_hash = hash_create(32))) {
+	if (!(lvd_hash = dm_hash_create(32))) {
 		stack;
 		return 0;
 	}
@@ -514,7 +511,7 @@
 	 * setup the pv's extents array
 	 */
 	len = sizeof(struct pe_disk) * dl->pvd.pe_total;
-	if (!(dl->extents = pool_alloc(dl->mem, len))) {
+	if (!(dl->extents = dm_pool_alloc(dl->mem, len))) {
 		stack;
 		goto out;
 	}
@@ -524,7 +521,7 @@
 		if (ll->lv->status & SNAPSHOT)
 			continue;
 
-		if (!(lvdl = pool_alloc(dl->mem, sizeof(*lvdl)))) {
+		if (!(lvdl = dm_pool_alloc(dl->mem, sizeof(*lvdl)))) {
 			stack;
 			goto out;
 		}
@@ -534,7 +531,7 @@
 		lv_num = lvnum_from_lvid(&ll->lv->lvid);
 		lvdl->lvd.lv_number = lv_num;
 
-		if (!hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
+		if (!dm_hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) {
 			stack;
 			goto out;
 		}
@@ -561,14 +558,14 @@
 	r = 1;
 
       out:
-	hash_destroy(lvd_hash);
+	dm_hash_destroy(lvd_hash);
 	return r;
 }
 
 /*
  * FIXME: More inefficient code.
  */
-int import_snapshots(struct pool *mem, struct volume_group *vg,
+int import_snapshots(struct dm_pool *mem, struct volume_group *vg,
 		     struct list *pvds)
 {
 	struct logical_volume *lvs[MAX_LV];
@@ -642,7 +639,7 @@
 	struct pv_list *pvl;
 
 	list_iterate_items(pvl, &vg->pvs) {
-		if (!(ul = pool_alloc(dl->mem, sizeof(*ul)))) {
+		if (!(ul = dm_pool_alloc(dl->mem, sizeof(*ul)))) {
 			stack;
 			return 0;
 		}

Modified: lvm2/upstream/current/lib/format1/import-extents.c
==============================================================================
--- lvm2/upstream/current/lib/format1/import-extents.c	(original)
+++ lvm2/upstream/current/lib/format1/import-extents.c	Tue Nov 15 17:45:32 2005
@@ -15,8 +15,6 @@
 
 #include "lib.h"
 #include "metadata.h"
-#include "hash.h"
-#include "pool.h"
 #include "disk-rep.h"
 #include "lv_alloc.h"
 #include "display.h"
@@ -44,10 +42,10 @@
 	struct pe_specifier *map;
 };
 
-static struct hash_table *_create_lv_maps(struct pool *mem,
+static struct dm_hash_table *_create_lv_maps(struct dm_pool *mem,
 					  struct volume_group *vg)
 {
-	struct hash_table *maps = hash_create(32);
+	struct dm_hash_table *maps = dm_hash_create(32);
 	struct lv_list *ll;
 	struct lv_map *lvm;
 
@@ -61,19 +59,19 @@
 		if (ll->lv->status & SNAPSHOT)
 			continue;
 
-		if (!(lvm = pool_alloc(mem, sizeof(*lvm)))) {
+		if (!(lvm = dm_pool_alloc(mem, sizeof(*lvm)))) {
 			stack;
 			goto bad;
 		}
 
 		lvm->lv = ll->lv;
-		if (!(lvm->map = pool_zalloc(mem, sizeof(*lvm->map)
+		if (!(lvm->map = dm_pool_zalloc(mem, sizeof(*lvm->map)
 					     * ll->lv->le_count))) {
 			stack;
 			goto bad;
 		}
 
-		if (!hash_insert(maps, ll->lv->name, lvm)) {
+		if (!dm_hash_insert(maps, ll->lv->name, lvm)) {
 			stack;
 			goto bad;
 		}
@@ -82,12 +80,12 @@
 	return maps;
 
       bad:
-	hash_destroy(maps);
+	dm_hash_destroy(maps);
 	return NULL;
 }
 
 static int _fill_lv_array(struct lv_map **lvs,
-			  struct hash_table *maps, struct disk_list *dl)
+			  struct dm_hash_table *maps, struct disk_list *dl)
 {
 	struct lvd_list *ll;
 	struct lv_map *lvm;
@@ -95,7 +93,7 @@
 	memset(lvs, 0, sizeof(*lvs) * MAX_LV);
 
 	list_iterate_items(ll, &dl->lvds) {
-		if (!(lvm = hash_lookup(maps, strrchr(ll->lvd.lv_name, '/')
+		if (!(lvm = dm_hash_lookup(maps, strrchr(ll->lvd.lv_name, '/')
 					+ 1))) {
 			log_err("Physical volume (%s) contains an "
 				"unknown logical volume (%s).",
@@ -112,7 +110,7 @@
 	return 1;
 }
 
-static int _fill_maps(struct hash_table *maps, struct volume_group *vg,
+static int _fill_maps(struct dm_hash_table *maps, struct volume_group *vg,
 		      struct list *pvds)
 {
 	struct disk_list *dl;
@@ -184,13 +182,13 @@
 	return 1;
 }
 
-static int _check_maps_are_complete(struct hash_table *maps)
+static int _check_maps_are_complete(struct dm_hash_table *maps)
 {
-	struct hash_node *n;
+	struct dm_hash_node *n;
 	struct lv_map *lvm;
 
-	for (n = hash_get_first(maps); n; n = hash_get_next(maps, n)) {
-		lvm = (struct lv_map *) hash_get_data(maps, n);
+	for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
+		lvm = (struct lv_map *) dm_hash_get_data(maps, n);
 
 		if (!_check_single_map(lvm)) {
 			stack;
@@ -327,13 +325,13 @@
 		_read_linear(cmd, lvm));
 }
 
-static int _build_all_segments(struct cmd_context *cmd, struct hash_table *maps)
+static int _build_all_segments(struct cmd_context *cmd, struct dm_hash_table *maps)
 {
-	struct hash_node *n;
+	struct dm_hash_node *n;
 	struct lv_map *lvm;
 
-	for (n = hash_get_first(maps); n; n = hash_get_next(maps, n)) {
-		lvm = (struct lv_map *) hash_get_data(maps, n);
+	for (n = dm_hash_get_first(maps); n; n = dm_hash_get_next(maps, n)) {
+		lvm = (struct lv_map *) dm_hash_get_data(maps, n);
 		if (!_build_segments(cmd, lvm)) {
 			stack;
 			return 0;
@@ -347,8 +345,8 @@
 		   struct list *pvds)
 {
 	int r = 0;
-	struct pool *scratch = pool_create("lvm1 import_extents", 10 * 1024);
-	struct hash_table *maps;
+	struct dm_pool *scratch = dm_pool_create("lvm1 import_extents", 10 * 1024);
+	struct dm_hash_table *maps;
 
 	if (!scratch) {
 		stack;
@@ -378,7 +376,7 @@
 
       out:
 	if (maps)
-		hash_destroy(maps);
-	pool_destroy(scratch);
+		dm_hash_destroy(maps);
+	dm_pool_destroy(scratch);
 	return r;
 }

Modified: lvm2/upstream/current/lib/format1/layout.c
==============================================================================
--- lvm2/upstream/current/lib/format1/layout.c	(original)
+++ lvm2/upstream/current/lib/format1/layout.c	Tue Nov 15 17:45:32 2005
@@ -117,7 +117,7 @@
 int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
 			   uint32_t max_extent_count, uint64_t pe_start)
 {
-	struct pv_disk *pvd = dbg_malloc(sizeof(*pvd));
+	struct pv_disk *pvd = dm_malloc(sizeof(*pvd));
 	uint32_t end;
 
 	if (!pvd) {
@@ -138,7 +138,7 @@
 	if (pvd->pe_total < PE_SIZE_PV_SIZE_REL) {
 		log_error("Too few extents on %s.  Try smaller extent size.",
 			  dev_name(pv->dev));
-		dbg_free(pvd);
+		dm_free(pvd);
 		return 0;
 	}
 
@@ -160,13 +160,13 @@
 		log_error("Metadata extent limit (%u) exceeded for %s - "
 			  "%u required", MAX_PE_TOTAL, dev_name(pv->dev),
 			  pvd->pe_total);
-		dbg_free(pvd);
+		dm_free(pvd);
 		return 0;
 	}
 
 	pv->pe_count = pvd->pe_total;
 	pv->pe_start = pvd->pe_start;
 	/* We can't set pe_size here without breaking LVM1 compatibility */
-	dbg_free(pvd);
+	dm_free(pvd);
 	return 1;
 }

Modified: lvm2/upstream/current/lib/format1/lvm1-label.c
==============================================================================
--- lvm2/upstream/current/lib/format1/lvm1-label.c	(original)
+++ lvm2/upstream/current/lib/format1/lvm1-label.c	Tue Nov 15 17:45:32 2005
@@ -90,7 +90,7 @@
 
 static void _destroy(struct labeller *l)
 {
-	dbg_free(l);
+	dm_free(l);
 }
 
 struct label_ops _lvm1_ops = {
@@ -107,7 +107,7 @@
 {
 	struct labeller *l;
 
-	if (!(l = dbg_malloc(sizeof(*l)))) {
+	if (!(l = dm_malloc(sizeof(*l)))) {
 		log_err("Couldn't allocate labeller object.");
 		return NULL;
 	}

Modified: lvm2/upstream/current/lib/format1/vg_number.c
==============================================================================
--- lvm2/upstream/current/lib/format1/vg_number.c	(original)
+++ lvm2/upstream/current/lib/format1/vg_number.c	Tue Nov 15 17:45:32 2005
@@ -14,7 +14,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
 #include "disk-rep.h"
 
 /*
@@ -29,7 +28,7 @@
 {
 	struct list all_pvs;
 	struct disk_list *dl;
-	struct pool *mem = pool_create("lvm1 vg_number", 10 * 1024);
+	struct dm_pool *mem = dm_pool_create("lvm1 vg_number", 10 * 1024);
 	int numbers[MAX_VG], i, r = 0;
 
 	list_init(&all_pvs);
@@ -62,6 +61,6 @@
 	}
 
       out:
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return r;
 }

Modified: lvm2/upstream/current/lib/format_pool/disk_rep.c
==============================================================================
--- lvm2/upstream/current/lib/format_pool/disk_rep.c	(original)
+++ lvm2/upstream/current/lib/format_pool/disk_rep.c	Tue Nov 15 17:45:32 2005
@@ -14,12 +14,10 @@
  */
 
 #include "lib.h"
-#include "pool.h"
 #include "label.h"
 #include "metadata.h"
 #include "lvmcache.h"
 #include "filter.h"
-#include "list.h"
 #include "xlate.h"
 
 #include "disk_rep.h"
@@ -35,7 +33,7 @@
 #define CPOUT_64(x, y) {(y) = xlate64_be((x));}
 
 static int __read_pool_disk(const struct format_type *fmt, struct device *dev,
-			    struct pool *mem, struct pool_list *pl,
+			    struct dm_pool *mem, struct pool_list *pl,
 			    const char *vg_name)
 {
 	char buf[512];
@@ -240,13 +238,13 @@
 
 }
 
-static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
+static int _read_vg_pds(const struct format_type *fmt, struct dm_pool *mem,
 			struct lvmcache_vginfo *vginfo, struct list *head,
 			uint32_t *devcount)
 {
 	struct lvmcache_info *info;
 	struct pool_list *pl = NULL;
-	struct pool *tmpmem;
+	struct dm_pool *tmpmem;
 
 	uint32_t sp_count = 0;
 	uint32_t *sp_devs = NULL;
@@ -254,7 +252,7 @@
 
 	/* FIXME: maybe should return a different error in memory
 	 * allocation failure */
-	if (!(tmpmem = pool_create("pool read_vg", 512))) {
+	if (!(tmpmem = dm_pool_create("pool read_vg", 512))) {
 		stack;
 		return 0;
 	}
@@ -271,11 +269,11 @@
 			/* FIXME pl left uninitialised if !info->dev */
 			sp_count = pl->pd.pl_subpools;
 			if (!(sp_devs =
-			      pool_zalloc(tmpmem,
+			      dm_pool_zalloc(tmpmem,
 					  sizeof(uint32_t) * sp_count))) {
 				log_error("Unable to allocate %d 32-bit uints",
 					  sp_count);
-				pool_destroy(tmpmem);
+				dm_pool_destroy(tmpmem);
 				return 0;
 			}
 		}
@@ -296,7 +294,7 @@
 	for (i = 0; i < sp_count; i++)
 		*devcount += sp_devs[i];
 
-	pool_destroy(tmpmem);
+	dm_pool_destroy(tmpmem);
 
 	if (pl && *pl->pd.pl_pool_name)
 		return 1;
@@ -306,7 +304,7 @@
 }
 
 int read_pool_pds(const struct format_type *fmt, const char *vg_name,
-		  struct pool *mem, struct list *pdhead)
+		  struct dm_pool *mem, struct list *pdhead)
 {
 	struct lvmcache_vginfo *vginfo;
 	uint32_t totaldevs;
@@ -351,7 +349,7 @@
 }
 
 struct pool_list *read_pool_disk(const struct format_type *fmt,
-				 struct device *dev, struct pool *mem,
+				 struct device *dev, struct dm_pool *mem,
 				 const char *vg_name)
 {
 	struct pool_list *pl;
@@ -361,7 +359,7 @@
 		return NULL;
 	}
 
-	if (!(pl = pool_zalloc(mem, sizeof(*pl)))) {
+	if (!(pl = dm_pool_zalloc(mem, sizeof(*pl)))) {
 		log_error("Unable to allocate pool list structure");
 		return 0;
 	}

Modified: lvm2/upstream/current/lib/format_pool/disk_rep.h
==============================================================================
--- lvm2/upstream/current/lib/format_pool/disk_rep.h	(original)
+++ lvm2/upstream/current/lib/format_pool/disk_rep.h	Tue Nov 15 17:45:32 2005
@@ -18,7 +18,6 @@
 
 #include "label.h"
 #include "metadata.h"
-#include "pool.h"
 
 #define MINOR_OFFSET 65536
 
@@ -138,20 +137,20 @@
 void pool_label_out(struct pool_disk *pl, char *buf);
 void pool_label_in(struct pool_disk *pl, char *buf);
 void get_pool_uuid(char *uuid, uint64_t poolid, uint32_t spid, uint32_t devid);
-int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls);
-int import_pool_lvs(struct volume_group *vg, struct pool *mem,
+int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pls);
+int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem,
 		    struct list *pls);
 int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
-		    struct list *pvs, struct pool *mem, struct list *pls);
-int import_pool_pv(const struct format_type *fmt, struct pool *mem,
+		    struct list *pvs, struct dm_pool *mem, struct list *pls);
+int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
 		   struct volume_group *vg, struct physical_volume *pv,
 		   struct pool_list *pl);
-int import_pool_segments(struct list *lvs, struct pool *mem,
+int import_pool_segments(struct list *lvs, struct dm_pool *mem,
 			 struct user_subpool *usp, int sp_count);
 int read_pool_pds(const struct format_type *fmt, const char *vgname,
-		  struct pool *mem, struct list *head);
+		  struct dm_pool *mem, struct list *head);
 struct pool_list *read_pool_disk(const struct format_type *fmt,
-				 struct device *dev, struct pool *mem,
+				 struct device *dev, struct dm_pool *mem,
 				 const char *vg_name);
 
 #endif				/* DISK_REP_POOL_FORMAT_H */

Modified: lvm2/upstream/current/lib/format_pool/format_pool.c
==============================================================================
--- lvm2/upstream/current/lib/format_pool/format_pool.c	(original)
+++ lvm2/upstream/current/lib/format_pool/format_pool.c	Tue Nov 15 17:45:32 2005
@@ -14,12 +14,9 @@
  */
 
 #include "lib.h"
-#include "pool.h"
 #include "label.h"
 #include "metadata.h"
-#include "hash.h"
 #include "limits.h"
-#include "list.h"
 #include "display.h"
 #include "toolcontext.h"
 #include "lvmcache.h"
@@ -30,7 +27,7 @@
 #define FMT_POOL_NAME "pool"
 
 /* Must be called after pvs are imported */
-static struct user_subpool *_build_usp(struct list *pls, struct pool *mem,
+static struct user_subpool *_build_usp(struct list *pls, struct dm_pool *mem,
 				       int *sps)
 {
 	struct pool_list *pl;
@@ -43,7 +40,7 @@
 	 */
 	list_iterate_items(pl, pls) {
 		*sps = pl->pd.pl_subpools;
-		if (!usp && (!(usp = pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
+		if (!usp && (!(usp = dm_pool_zalloc(mem, sizeof(*usp) * (*sps))))) {
 			log_error("Unable to allocate %d subpool structures",
 				  *sps);
 			return 0;
@@ -61,7 +58,7 @@
 
 		if (!cur_sp->devs &&
 		    (!(cur_sp->devs =
-		       pool_zalloc(mem,
+		       dm_pool_zalloc(mem,
 				   sizeof(*usp->devs) * pl->pd.pl_sp_devs)))) {
 
 			log_error("Unable to allocate %d pool_device "
@@ -103,15 +100,15 @@
 }
 
 static struct volume_group *_build_vg_from_pds(struct format_instance
-					       *fid, struct pool *mem,
+					       *fid, struct dm_pool *mem,
 					       struct list *pds)
 {
-	struct pool *smem = fid->fmt->cmd->mem;
+	struct dm_pool *smem = fid->fmt->cmd->mem;
 	struct volume_group *vg = NULL;
 	struct user_subpool *usp = NULL;
 	int sp_count;
 
-	if (!(vg = pool_zalloc(smem, sizeof(*vg)))) {
+	if (!(vg = dm_pool_zalloc(smem, sizeof(*vg)))) {
 		log_error("Unable to allocate volume group structure");
 		return NULL;
 	}
@@ -176,7 +173,7 @@
 				     const char *vg_name,
 				     struct metadata_area *mda)
 {
-	struct pool *mem = pool_create("pool vg_read", 1024);
+	struct dm_pool *mem = dm_pool_create("pool vg_read", 1024);
 	struct list pds;
 	struct volume_group *vg = NULL;
 
@@ -205,7 +202,7 @@
 	}
 
       out:
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return vg;
 }
 
@@ -222,7 +219,7 @@
 static int _pv_read(const struct format_type *fmt, const char *pv_name,
 		    struct physical_volume *pv, struct list *mdas)
 {
-	struct pool *mem = pool_create("pool pv_read", 1024);
+	struct dm_pool *mem = dm_pool_create("pool pv_read", 1024);
 	struct pool_list *pl;
 	struct device *dev;
 	int r = 0;
@@ -259,7 +256,7 @@
 	r = 1;
 
       out:
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	return r;
 }
 
@@ -276,7 +273,7 @@
 	struct format_instance *fid;
 	struct metadata_area *mda;
 
-	if (!(fid = pool_zalloc(fmt->cmd->mem, sizeof(*fid)))) {
+	if (!(fid = dm_pool_zalloc(fmt->cmd->mem, sizeof(*fid)))) {
 		log_error("Unable to allocate format instance structure for "
 			  "pool format");
 		return NULL;
@@ -286,10 +283,10 @@
 	list_init(&fid->metadata_areas);
 
 	/* Define a NULL metadata area */
-	if (!(mda = pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
+	if (!(mda = dm_pool_zalloc(fmt->cmd->mem, sizeof(*mda)))) {
 		log_error("Unable to allocate metadata area structure "
 			  "for pool format");
-		pool_free(fmt->cmd->mem, fid);
+		dm_pool_free(fmt->cmd->mem, fid);
 		return NULL;
 	}
 
@@ -307,7 +304,7 @@
 
 static void _destroy(const struct format_type *fmt)
 {
-	dbg_free((void *) fmt);
+	dm_free((void *) fmt);
 }
 
 /* *INDENT-OFF* */
@@ -327,7 +324,7 @@
 struct format_type *init_format(struct cmd_context *cmd)
 #endif
 {
-	struct format_type *fmt = dbg_malloc(sizeof(*fmt));
+	struct format_type *fmt = dm_malloc(sizeof(*fmt));
 
 	if (!fmt) {
 		log_error("Unable to allocate format type structure for pool "

Modified: lvm2/upstream/current/lib/format_pool/import_export.c
==============================================================================
--- lvm2/upstream/current/lib/format_pool/import_export.c	(original)
+++ lvm2/upstream/current/lib/format_pool/import_export.c	Tue Nov 15 17:45:32 2005
@@ -14,7 +14,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
 #include "label.h"
 #include "metadata.h"
 #include "lvmcache.h"
@@ -28,7 +27,7 @@
 
 /* This file contains only imports at the moment... */
 
-int import_pool_vg(struct volume_group *vg, struct pool *mem, struct list *pls)
+int import_pool_vg(struct volume_group *vg, struct dm_pool *mem, struct list *pls)
 {
 	struct pool_list *pl;
 
@@ -41,7 +40,7 @@
 		if (vg->name)
 			continue;
 
-		vg->name = pool_strdup(mem, pl->pd.pl_pool_name);
+		vg->name = dm_pool_strdup(mem, pl->pd.pl_pool_name);
 		get_pool_vg_uuid(&vg->id, &pl->pd);
 		vg->extent_size = POOL_PE_SIZE;
 		vg->status |= LVM_READ | LVM_WRITE | CLUSTERED | SHARED;
@@ -55,10 +54,10 @@
 	return 1;
 }
 
-int import_pool_lvs(struct volume_group *vg, struct pool *mem, struct list *pls)
+int import_pool_lvs(struct volume_group *vg, struct dm_pool *mem, struct list *pls)
 {
 	struct pool_list *pl;
-	struct lv_list *lvl = pool_zalloc(mem, sizeof(*lvl));
+	struct lv_list *lvl = dm_pool_zalloc(mem, sizeof(*lvl));
 	struct logical_volume *lv;
 
 	if (!lvl) {
@@ -66,7 +65,7 @@
 		return 0;
 	}
 
-	if (!(lvl->lv = pool_zalloc(mem, sizeof(*lvl->lv)))) {
+	if (!(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) {
 		log_error("Unable to allocate logical volume structure");
 		return 0;
 	}
@@ -90,7 +89,7 @@
 		if (lv->name)
 			continue;
 
-		if (!(lv->name = pool_strdup(mem, pl->pd.pl_pool_name))) {
+		if (!(lv->name = dm_pool_strdup(mem, pl->pd.pl_pool_name))) {
 			stack;
 			return 0;
 		}
@@ -124,17 +123,17 @@
 }
 
 int import_pool_pvs(const struct format_type *fmt, struct volume_group *vg,
-		    struct list *pvs, struct pool *mem, struct list *pls)
+		    struct list *pvs, struct dm_pool *mem, struct list *pls)
 {
 	struct pv_list *pvl;
 	struct pool_list *pl;
 
 	list_iterate_items(pl, pls) {
-		if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) {
+		if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) {
 			log_error("Unable to allocate pv list structure");
 			return 0;
 		}
-		if (!(pvl->pv = pool_zalloc(mem, sizeof(*pvl->pv)))) {
+		if (!(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) {
 			log_error("Unable to allocate pv structure");
 			return 0;
 		}
@@ -150,7 +149,7 @@
 	return 1;
 }
 
-int import_pool_pv(const struct format_type *fmt, struct pool *mem,
+int import_pool_pv(const struct format_type *fmt, struct dm_pool *mem,
 		   struct volume_group *vg, struct physical_volume *pv,
 		   struct pool_list *pl)
 {
@@ -162,7 +161,7 @@
 	pv->fmt = fmt;
 
 	pv->dev = pl->dev;
-	if (!(pv->vg_name = pool_strdup(mem, pd->pl_pool_name))) {
+	if (!(pv->vg_name = dm_pool_strdup(mem, pd->pl_pool_name))) {
 		log_error("Unable to duplicate vg_name string");
 		return 0;
 	}
@@ -197,7 +196,7 @@
 	return sptype_names[i].name;
 }
 
-static int _add_stripe_seg(struct pool *mem,
+static int _add_stripe_seg(struct dm_pool *mem,
 			   struct user_subpool *usp, struct logical_volume *lv,
 			   uint32_t *le_cur)
 {
@@ -243,7 +242,7 @@
 	return 1;
 }
 
-static int _add_linear_seg(struct pool *mem,
+static int _add_linear_seg(struct dm_pool *mem,
 			   struct user_subpool *usp, struct logical_volume *lv,
 			   uint32_t *le_cur)
 {
@@ -284,7 +283,7 @@
 	return 1;
 }
 
-int import_pool_segments(struct list *lvs, struct pool *mem,
+int import_pool_segments(struct list *lvs, struct dm_pool *mem,
 			 struct user_subpool *usp, int subpools)
 {
 	struct lv_list *lvl;

Modified: lvm2/upstream/current/lib/format_pool/pool_label.c
==============================================================================
--- lvm2/upstream/current/lib/format_pool/pool_label.c	(original)
+++ lvm2/upstream/current/lib/format_pool/pool_label.c	Tue Nov 15 17:45:32 2005
@@ -14,7 +14,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
 #include "label.h"
 #include "metadata.h"
 #include "xlate.h"
@@ -79,7 +78,7 @@
 
 static void _destroy(struct labeller *l)
 {
-	dbg_free(l);
+	dm_free(l);
 }
 
 struct label_ops _pool_ops = {
@@ -96,7 +95,7 @@
 {
 	struct labeller *l;
 
-	if (!(l = dbg_malloc(sizeof(*l)))) {
+	if (!(l = dm_malloc(sizeof(*l)))) {
 		log_error("Couldn't allocate labeller object.");
 		return NULL;
 	}

Modified: lvm2/upstream/current/lib/format_text/archive.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/archive.c	(original)
+++ lvm2/upstream/current/lib/format_text/archive.c	Tue Nov 15 17:45:32 2005
@@ -16,9 +16,7 @@
 #include "lib.h"
 #include "format-text.h"
 
-#include "pool.h"
 #include "config.h"
-#include "hash.h"
 #include "import-export.h"
 #include "lvm-string.h"
 #include "lvm-file.h"
@@ -109,24 +107,24 @@
 	list_add_h(&bf->list, &b->list);
 }
 
-static char *_join(struct pool *mem, const char *dir, const char *name)
+static char *_join(struct dm_pool *mem, const char *dir, const char *name)
 {
-	if (!pool_begin_object(mem, 32) ||
-	    !pool_grow_object(mem, dir, strlen(dir)) ||
-	    !pool_grow_object(mem, "/", 1) ||
-	    !pool_grow_object(mem, name, strlen(name)) ||
-	    !pool_grow_object(mem, "\0", 1)) {
+	if (!dm_pool_begin_object(mem, 32) ||
+	    !dm_pool_grow_object(mem, dir, strlen(dir)) ||
+	    !dm_pool_grow_object(mem, "/", 1) ||
+	    !dm_pool_grow_object(mem, name, strlen(name)) ||
+	    !dm_pool_grow_object(mem, "\0", 1)) {
 		stack;
 		return NULL;
 	}
 
-	return pool_end_object(mem);
+	return dm_pool_end_object(mem);
 }
 
 /*
  * Returns a list of archive_files.
  */
-static struct list *_scan_archive(struct pool *mem,
+static struct list *_scan_archive(struct dm_pool *mem,
 				  const char *vgname, const char *dir)
 {
 	int i, count;
@@ -136,7 +134,7 @@
 	struct archive_file *af;
 	struct list *results;
 
-	if (!(results = pool_alloc(mem, sizeof(*results)))) {
+	if (!(results = dm_pool_alloc(mem, sizeof(*results)))) {
 		stack;
 		return NULL;
 	}
@@ -171,7 +169,7 @@
 		/*
 		 * Create a new archive_file.
 		 */
-		if (!(af = pool_alloc(mem, sizeof(*af)))) {
+		if (!(af = dm_pool_alloc(mem, sizeof(*af)))) {
 			log_err("Couldn't create new archive file.");
 			results = NULL;
 			goto out;
@@ -333,7 +331,7 @@
 	log_print("Description:\t%s", desc ? desc : "<No description>");
 	log_print("Backup Time:\t%s", ctime(&when));
 
-	pool_free(cmd->mem, vg);
+	dm_pool_free(cmd->mem, vg);
 	tf->fmt->ops->destroy_instance(tf);
 }
 
@@ -353,7 +351,7 @@
 	list_iterate_back_items(af, archives)
 		_display_archive(cmd, af);
 
-	pool_free(cmd->mem, archives);
+	dm_pool_free(cmd->mem, archives);
 
 	return 1;
 }

Modified: lvm2/upstream/current/lib/format_text/archiver.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/archiver.c	(original)
+++ lvm2/upstream/current/lib/format_text/archiver.c	Tue Nov 15 17:45:32 2005
@@ -38,7 +38,7 @@
 int archive_init(struct cmd_context *cmd, const char *dir,
 		 unsigned int keep_days, unsigned int keep_min)
 {
-	if (!(cmd->archive_params = pool_zalloc(cmd->libmem,
+	if (!(cmd->archive_params = dm_pool_zalloc(cmd->libmem,
 						sizeof(*cmd->archive_params)))) {
 		log_error("archive_params alloc failed");
 		return 0;
@@ -49,7 +49,7 @@
 	if (!*dir)
 		return 1;
 
-	if (!(cmd->archive_params->dir = dbg_strdup(dir))) {
+	if (!(cmd->archive_params->dir = dm_strdup(dir))) {
 		log_error("Couldn't copy archive directory name.");
 		return 0;
 	}
@@ -64,7 +64,7 @@
 void archive_exit(struct cmd_context *cmd)
 {
 	if (cmd->archive_params->dir)
-		dbg_free(cmd->archive_params->dir);
+		dm_free(cmd->archive_params->dir);
 	memset(cmd->archive_params, 0, sizeof(*cmd->archive_params));
 }
 
@@ -73,12 +73,12 @@
 	cmd->archive_params->enabled = flag;
 }
 
-static char *_build_desc(struct pool *mem, const char *line, int before)
+static char *_build_desc(struct dm_pool *mem, const char *line, int before)
 {
 	size_t len = strlen(line) + 32;
 	char *buffer;
 
-	if (!(buffer = pool_zalloc(mem, strlen(line) + 32))) {
+	if (!(buffer = dm_pool_zalloc(mem, strlen(line) + 32))) {
 		stack;
 		return NULL;
 	}
@@ -150,7 +150,7 @@
 
 int backup_init(struct cmd_context *cmd, const char *dir)
 {
-	if (!(cmd->backup_params = pool_zalloc(cmd->libmem,
+	if (!(cmd->backup_params = dm_pool_zalloc(cmd->libmem,
 					       sizeof(*cmd->archive_params)))) {
 		log_error("archive_params alloc failed");
 		return 0;
@@ -160,7 +160,7 @@
 	if (!*dir)
 		return 1;
 
-	if (!(cmd->backup_params->dir = dbg_strdup(dir))) {
+	if (!(cmd->backup_params->dir = dm_strdup(dir))) {
 		log_error("Couldn't copy backup directory name.");
 		return 0;
 	}
@@ -171,7 +171,7 @@
 void backup_exit(struct cmd_context *cmd)
 {
 	if (cmd->backup_params->dir)
-		dbg_free(cmd->backup_params->dir);
+		dm_free(cmd->backup_params->dir);
 	memset(cmd->backup_params, 0, sizeof(*cmd->backup_params));
 }
 

Modified: lvm2/upstream/current/lib/format_text/export.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/export.c	(original)
+++ lvm2/upstream/current/lib/format_text/export.c	Tue Nov 15 17:45:32 2005
@@ -16,8 +16,6 @@
 #include "lib.h"
 #include "import-export.h"
 #include "metadata.h"
-#include "hash.h"
-#include "pool.h"
 #include "display.h"
 #include "lvm-string.h"
 #include "segtype.h"
@@ -31,13 +29,26 @@
 typedef int (*out_with_comment_fn) (struct formatter * f, const char *comment,
 				    const char *fmt, va_list ap);
 typedef int (*nl_fn) (struct formatter * f);
+
+/*
+ * Macro for formatted output.
+ * out_with_comment_fn returns -1 if data didn't fit and buffer was expanded.
+ * Then argument list is reset and out_with_comment_fn is called again.
+ */
+#define _out_with_comment(f, buffer, fmt, ap) \
+        do { \
+		va_start(ap, fmt); \
+		r = f->out_with_comment(f, buffer, fmt, ap); \
+		va_end(ap); \
+	} while (r == -1)
+
 /*
  * The first half of this file deals with
  * exporting the vg, ie. writing it to a file.
  */
 struct formatter {
-	struct pool *mem;	/* pv names allocated from here */
-	struct hash_table *pv_names;	/* dev_name -> pv_name (eg, pv1) */
+	struct dm_pool *mem;	/* pv names allocated from here */
+	struct dm_hash_table *pv_names;	/* dev_name -> pv_name (eg, pv1) */
 
 	union {
 		FILE *fp;	/* where we're writing to */
@@ -102,19 +113,30 @@
 	return 1;
 }
 
-static int _nl_raw(struct formatter *f)
+static int _extend_buffer(struct formatter *f)
 {
 	char *newbuf;
 
-	/* If metadata doesn't fit, double the buffer size */
-	if (f->data.buf.used + 2 > f->data.buf.size) {
-		if (!(newbuf = dbg_realloc(f->data.buf.start,
-					   f->data.buf.size * 2))) {
-			stack;
-			return 0;
-		}
-		f->data.buf.start = newbuf;
-		f->data.buf.size *= 2;
+	log_debug("Doubling metadata output buffer to %" PRIu32,
+		  f->data.buf.size * 2);
+	if (!(newbuf = dm_realloc(f->data.buf.start,
+				   f->data.buf.size * 2))) {
+		log_error("Buffer reallocation failed.");
+		return 0;
+	}
+	f->data.buf.start = newbuf;
+	f->data.buf.size *= 2;
+
+	return 1;
+}
+
+static int _nl_raw(struct formatter *f)
+{
+	/* If metadata doesn't fit, extend buffer */
+	if ((f->data.buf.used + 2 > f->data.buf.size) &&
+	    (!_extend_buffer(f))) {
+		stack;
+		return 0;
 	}
 
 	*(f->data.buf.start + f->data.buf.used) = '\n';
@@ -165,22 +187,17 @@
 				 const char *fmt, va_list ap)
 {
 	int n;
-	char *newbuf;
 
-      retry:
 	n = vsnprintf(f->data.buf.start + f->data.buf.used,
 		      f->data.buf.size - f->data.buf.used, fmt, ap);
 
-	/* If metadata doesn't fit, double the buffer size */
+	/* If metadata doesn't fit, extend buffer */
 	if (n < 0 || (n + f->data.buf.used + 2 > f->data.buf.size)) {
-		if (!(newbuf = dbg_realloc(f->data.buf.start,
-					   f->data.buf.size * 2))) {
+		if (!_extend_buffer(f)) {
 			stack;
 			return 0;
 		}
-		f->data.buf.start = newbuf;
-		f->data.buf.size *= 2;
-		goto retry;
+		return -1; /* Retry */
 	}
 
 	f->data.buf.used += n;
@@ -231,9 +248,7 @@
 	if (!_sectors_to_units(size, buffer, sizeof(buffer)))
 		return 0;
 
-	va_start(ap, fmt);
-	r = f->out_with_comment(f, buffer, fmt, ap);
-	va_end(ap);
+	_out_with_comment(f, buffer, fmt, ap);
 
 	return r;
 }
@@ -247,9 +262,7 @@
 	va_list ap;
 	int r;
 
-	va_start(ap, fmt);
-	r = f->out_with_comment(f, "# Hint only", fmt, ap);
-	va_end(ap);
+	_out_with_comment(f, "# Hint only", fmt, ap);
 
 	return r;
 }
@@ -262,9 +275,7 @@
 	va_list ap;
 	int r;
 
-	va_start(ap, fmt);
-	r = f->out_with_comment(f, NULL, fmt, ap);
-	va_end(ap);
+	_out_with_comment(f, NULL, fmt, ap);
 
 	return r;
 }
@@ -347,7 +358,7 @@
 				       struct physical_volume *pv)
 {
 	return (pv) ? (const char *)
-	    hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";
+	    dm_hash_lookup(f->pv_names, dev_name(pv->dev)) : "Missing";
 }
 
 static int _print_pvs(struct formatter *f, struct volume_group *vg)
@@ -602,12 +613,12 @@
 	struct physical_volume *pv;
 	char buffer[32], *name;
 
-	if (!(f->mem = pool_create("text pv_names", 512))) {
+	if (!(f->mem = dm_pool_create("text pv_names", 512))) {
 		stack;
 		goto bad;
 	}
 
-	if (!(f->pv_names = hash_create(128))) {
+	if (!(f->pv_names = dm_hash_create(128))) {
 		stack;
 		goto bad;
 	}
@@ -621,12 +632,12 @@
 			goto bad;
 		}
 
-		if (!(name = pool_strdup(f->mem, buffer))) {
+		if (!(name = dm_pool_strdup(f->mem, buffer))) {
 			stack;
 			goto bad;
 		}
 
-		if (!hash_insert(f->pv_names, dev_name(pv->dev), name)) {
+		if (!dm_hash_insert(f->pv_names, dev_name(pv->dev), name)) {
 			stack;
 			goto bad;
 		}
@@ -636,10 +647,10 @@
 
       bad:
 	if (f->mem)
-		pool_destroy(f->mem);
+		dm_pool_destroy(f->mem);
 
 	if (f->pv_names)
-		hash_destroy(f->pv_names);
+		dm_hash_destroy(f->pv_names);
 
 	return 0;
 }
@@ -686,10 +697,10 @@
 
       out:
 	if (f->mem)
-		pool_destroy(f->mem);
+		dm_pool_destroy(f->mem);
 
 	if (f->pv_names)
-		hash_destroy(f->pv_names);
+		dm_hash_destroy(f->pv_names);
 
 	return r;
 }
@@ -701,7 +712,7 @@
 
 	_init();
 
-	if (!(f = dbg_malloc(sizeof(*f)))) {
+	if (!(f = dm_malloc(sizeof(*f)))) {
 		stack;
 		return 0;
 	}
@@ -716,7 +727,7 @@
 	r = _text_vg_export(f, vg, desc);
 	if (r)
 		r = !ferror(f->data.fp);
-	dbg_free(f);
+	dm_free(f);
 	return r;
 }
 
@@ -728,7 +739,7 @@
 
 	_init();
 
-	if (!(f = dbg_malloc(sizeof(*f)))) {
+	if (!(f = dm_malloc(sizeof(*f)))) {
 		stack;
 		return 0;
 	}
@@ -736,7 +747,7 @@
 	memset(f, 0, sizeof(*f));
 
 	f->data.buf.size = 65536;	/* Initial metadata limit */
-	if (!(f->data.buf.start = dbg_malloc(f->data.buf.size))) {
+	if (!(f->data.buf.start = dm_malloc(f->data.buf.size))) {
 		log_error("text_export buffer allocation failed");
 		goto out;
 	}
@@ -748,7 +759,7 @@
 
 	if (!_text_vg_export(f, vg, desc)) {
 		stack;
-		dbg_free(f->data.buf.start);
+		dm_free(f->data.buf.start);
 		goto out;
 	}
 
@@ -756,7 +767,7 @@
 	*buf = f->data.buf.start;
 
       out:
-	dbg_free(f);
+	dm_free(f);
 	return r;
 }
 

Modified: lvm2/upstream/current/lib/format_text/flags.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/flags.c	(original)
+++ lvm2/upstream/current/lib/format_text/flags.c	Tue Nov 15 17:45:32 2005
@@ -36,6 +36,7 @@
 	{LVM_WRITE, "WRITE"},
 	{CLUSTERED, "CLUSTERED"},
 	{SHARED, "SHARED"},
+	{PRECOMMITTED, NULL},
 	{0, NULL}
 };
 
@@ -57,6 +58,7 @@
 	{MIRRORED, NULL},
 	{VIRTUAL, NULL},
 	{SNAPSHOT, NULL},
+	{ACTIVATE_EXCL, NULL},
 	{0, NULL}
 };
 

Modified: lvm2/upstream/current/lib/format_text/format-text.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/format-text.c	(original)
+++ lvm2/upstream/current/lib/format_text/format-text.c	Tue Nov 15 17:45:32 2005
@@ -18,9 +18,7 @@
 #include "import-export.h"
 #include "device.h"
 #include "lvm-file.h"
-#include "pool.h"
 #include "config.h"
-#include "hash.h"
 #include "display.h"
 #include "toolcontext.h"
 #include "lvm-string.h"
@@ -45,6 +43,11 @@
 						     *fmt, const char *vgname,
 						     void *context);
 
+struct text_fid_context {
+	char *raw_metadata_buf;
+	uint32_t raw_metadata_buf_size;
+};
+
 struct dir_list {
 	struct list list;
 	char dir[0];
@@ -83,7 +86,7 @@
 	if (lv->size > max_size) {
 		char *dummy = display_size(max_size, SIZE_SHORT);
 		log_error("logical volumes cannot be larger than %s", dummy);
-		dbg_free(dummy);
+		dm_free(dummy);
 		return 0;
 	}
 */
@@ -119,14 +122,14 @@
 {
 	struct mda_header *mdah;
 
-	if (!(mdah = pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
+	if (!(mdah = dm_pool_alloc(fmt->cmd->mem, MDA_HEADER_SIZE))) {
 		log_error("struct mda_header allocation failed");
 		return NULL;
 	}
 
 	if (!dev_read(dev_area->dev, dev_area->start, MDA_HEADER_SIZE, mdah)) {
 		stack;
-		pool_free(fmt->cmd->mem, mdah);
+		dm_pool_free(fmt->cmd->mem, mdah);
 		return NULL;
 	}
 
@@ -174,7 +177,7 @@
 
 	if (!dev_write(dev, start_byte, MDA_HEADER_SIZE, mdah)) {
 		stack;
-		pool_free(fmt->cmd->mem, mdah);
+		dm_pool_free(fmt->cmd->mem, mdah);
 		return 0;
 	}
 
@@ -184,17 +187,22 @@
 static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
 				       struct mda_header *mdah,
 				       const char *vgname,
-				       int precommit)
+				       int *precommitted)
 {
 	size_t len;
 	char vgnamebuf[NAME_LEN + 2];
-	struct raw_locn *rlocn;
+	struct raw_locn *rlocn, *rlocn_precommitted;
 	struct lvmcache_info *info;
 
 	rlocn = mdah->raw_locns;	/* Slot 0 */
+	rlocn_precommitted = rlocn + 1;	/* Slot 1 */
 
-	if (precommit)
-		rlocn++;		/* Slot 1 */
+	/* Should we use precommitted metadata? */
+	if (*precommitted && rlocn_precommitted->size &&
+	    (rlocn_precommitted->offset != rlocn->offset)) {
+		rlocn = rlocn_precommitted;
+	} else
+		*precommitted = 0;
 
 	/* FIXME Loop through rlocns two-at-a-time.  List null-terminated. */
 	/* FIXME Ignore if checksum incorrect!!! */
@@ -238,6 +246,7 @@
 			     struct device_area *dev_area, const char *vgname)
 {
 	int r = 0;
+	int noprecommit = 0;
 	struct mda_header *mdah;
 
 	if (!dev_open(dev_area->dev)) {
@@ -250,7 +259,7 @@
 		return 0;
 	}
 
-	if (_find_vg_rlocn(dev_area, mdah, vgname, 0))
+	if (_find_vg_rlocn(dev_area, mdah, vgname, &noprecommit))
 		r = 1;
 
 	if (!dev_close(dev_area->dev))
@@ -262,7 +271,7 @@
 static struct volume_group *_vg_read_raw_area(struct format_instance *fid,
 					      const char *vgname,
 					      struct device_area *area,
-					      int precommit)
+					      int precommitted)
 {
 	struct volume_group *vg = NULL;
 	struct raw_locn *rlocn;
@@ -281,7 +290,7 @@
 		goto out;
 	}
 
-	if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, precommit))) {
+	if (!(rlocn = _find_vg_rlocn(area, mdah, vgname, &precommitted))) {
 		log_debug("VG %s not found on %s", vgname, dev_name(area->dev));
 		goto out;
 	}
@@ -306,10 +315,13 @@
 		goto out;
 	}
 	log_debug("Read %s %smetadata (%u) from %s at %" PRIu64 " size %"
-		  PRIu64, vg->name, precommit ? "pre-commit " : "",
+		  PRIu64, vg->name, precommitted ? "pre-commit " : "",
 		  vg->seqno, dev_name(area->dev),
 		  area->start + rlocn->offset, rlocn->size);
 
+	if (precommitted)
+		vg->status |= PRECOMMITTED;
+
       out:
 	if (!dev_close(area->dev))
 		stack;
@@ -339,13 +351,14 @@
 			 struct metadata_area *mda)
 {
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
+	struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
 	struct raw_locn *rlocn;
 	struct mda_header *mdah;
 	struct pv_list *pvl;
 	int r = 0;
 	uint32_t new_wrap = 0, old_wrap = 0;
-	char *buf = NULL;
 	int found = 0;
+	int noprecommit = 0;
 
 	/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
 	list_iterate_items(pvl, &vg->pvs) {
@@ -368,14 +381,18 @@
 		goto out;
 	}
 
-	rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0);
+	rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit);
 	mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
 
-	if (!(mdac->rlocn.size = text_vg_export_raw(vg, "", &buf))) {
+	if (!fidtc->raw_metadata_buf &&
+	    !(fidtc->raw_metadata_buf_size =
+			text_vg_export_raw(vg, "", &fidtc->raw_metadata_buf))) {
 		log_error("VG %s metadata writing failed", vg->name);
 		goto out;
 	}
 
+	mdac->rlocn.size = fidtc->raw_metadata_buf_size;
+
 	if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
 		new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
 
@@ -398,7 +415,8 @@
 
 	/* Write text out, circularly */
 	if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
-		       (size_t) (mdac->rlocn.size - new_wrap), buf)) {
+		       (size_t) (mdac->rlocn.size - new_wrap),
+		       fidtc->raw_metadata_buf)) {
 		stack;
 		goto out;
 	}
@@ -411,18 +429,20 @@
 		if (!dev_write(mdac->area.dev,
 			       mdac->area.start + MDA_HEADER_SIZE,
 			       (size_t) new_wrap,
-			       buf + mdac->rlocn.size - new_wrap)) {
+			       fidtc->raw_metadata_buf + 
+			       mdac->rlocn.size - new_wrap)) {
 			stack;
 			goto out;
 		}
 	}
 
-	mdac->rlocn.checksum = calc_crc(INITIAL_CRC, buf,
+	mdac->rlocn.checksum = calc_crc(INITIAL_CRC, fidtc->raw_metadata_buf,
 					(uint32_t) (mdac->rlocn.size -
 						    new_wrap));
 	if (new_wrap)
 		mdac->rlocn.checksum = calc_crc(mdac->rlocn.checksum,
-						buf + mdac->rlocn.size -
+						fidtc->raw_metadata_buf +
+						mdac->rlocn.size -
 						new_wrap, new_wrap);
 
 	r = 1;
@@ -431,8 +451,6 @@
 	if (!r && !dev_close(mdac->area.dev))
 		stack;
 
-	if (buf)
-		dbg_free(buf);
 	return r;
 }
 
@@ -442,11 +460,13 @@
 				int precommit)
 {
 	struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
+	struct text_fid_context *fidtc = (struct text_fid_context *) fid->private;
 	struct mda_header *mdah;
 	struct raw_locn *rlocn;
 	struct pv_list *pvl;
 	int r = 0;
 	int found = 0;
+	int noprecommit = 0;
 
 	/* Ignore any mda on a PV outside the VG. vgsplit relies on this */
 	list_iterate_items(pvl, &vg->pvs) {
@@ -464,23 +484,41 @@
 		goto out;
 	}
 
-	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0))) {
+	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
 		mdah->raw_locns[0].offset = 0;
+		mdah->raw_locns[0].size = 0;
+		mdah->raw_locns[0].checksum = 0;
 		mdah->raw_locns[1].offset = 0;
+		mdah->raw_locns[1].size = 0;
+		mdah->raw_locns[1].checksum = 0;
 		mdah->raw_locns[2].offset = 0;
+		mdah->raw_locns[2].size = 0;
+		mdah->raw_locns[2].checksum = 0;
 		rlocn = &mdah->raw_locns[0];
 	}
 
 	if (precommit)
 		rlocn++;
+	else {
+		/* If not precommitting, wipe the precommitted rlocn */
+		mdah->raw_locns[1].offset = 0;
+		mdah->raw_locns[1].size = 0;
+		mdah->raw_locns[1].checksum = 0;
+	}
+
+	/* Is there new metadata to commit? */
+	if (mdac->rlocn.size) {
+		rlocn->offset = mdac->rlocn.offset;
+		rlocn->size = mdac->rlocn.size;
+		rlocn->checksum = mdac->rlocn.checksum;
+		log_debug("%sCommitting %s metadata (%u) to %s header at %"
+			  PRIu64, precommit ? "Pre-" : "", vg->name, vg->seqno,
+			  dev_name(mdac->area.dev), mdac->area.start);
+	} else
+		log_debug("Wiping pre-committed %s metadata from %s "
+			  "header at %" PRIu64, vg->name,
+			  dev_name(mdac->area.dev), mdac->area.start);
 
-	rlocn->offset = mdac->rlocn.offset;
-	rlocn->size = mdac->rlocn.size;
-	rlocn->checksum = mdac->rlocn.checksum;
-
-	log_debug("%sCommitting %s metadata (%u) to %s header at %" PRIu64,
-		  precommit ? "Pre-" : "", vg->name, vg->seqno,
-		  dev_name(mdac->area.dev), mdac->area.start);
 	if (!_raw_write_mda_header(fid->fmt, mdac->area.dev, mdac->area.start,
 				   mdah)) {
 		log_error("Failed to write metadata area header");
@@ -490,8 +528,14 @@
 	r = 1;
 
       out:
-	if (!precommit && !dev_close(mdac->area.dev))
-		stack;
+	if (!precommit) {
+		if (!dev_close(mdac->area.dev))
+			stack;
+		if (fidtc->raw_metadata_buf) {
+			dm_free(fidtc->raw_metadata_buf);
+			fidtc->raw_metadata_buf = NULL;
+		}
+	}
 
 	return r;
 }
@@ -528,10 +572,9 @@
 	if (!found)
 		return 1;
 
-	if (!dev_close(mdac->area.dev))
-		stack;
-
-	return 1;
+	/* Wipe pre-committed metadata */
+	mdac->rlocn.size = 0;
+	return _vg_commit_raw_rlocn(fid, vg, mda, 0);
 }
 
 static int _vg_remove_raw(struct format_instance *fid, struct volume_group *vg,
@@ -541,6 +584,7 @@
 	struct mda_header *mdah;
 	struct raw_locn *rlocn;
 	int r = 0;
+	int noprecommit = 0;
 
 	if (!dev_open(mdac->area.dev)) {
 		stack;
@@ -552,7 +596,7 @@
 		goto out;
 	}
 
-	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, 0))) {
+	if (!(rlocn = _find_vg_rlocn(&mdac->area, mdah, vg->name, &noprecommit))) {
 		rlocn = &mdah->raw_locns[0];
 		mdah->raw_locns[1].offset = 0;
 	}
@@ -595,7 +639,7 @@
 	 * check that it contains the correct volume group.
 	 */
 	if (vgname && strcmp(vgname, vg->name)) {
-		pool_free(fid->fmt->cmd->mem, vg);
+		dm_pool_free(fid->fmt->cmd->mem, vg);
 		log_err("'%s' does not contain volume group '%s'.",
 			read_path, vgname);
 		return NULL;
@@ -619,8 +663,14 @@
 						    struct metadata_area *mda)
 {
 	struct text_context *tc = (struct text_context *) mda->metadata_locn;
+	struct volume_group *vg;
+
+	if ((vg = _vg_read_file_name(fid, vgname, tc->path_edit)))
+		vg->status |= PRECOMMITTED;
+	else
+		vg = _vg_read_file_name(fid, vgname, tc->path_live);
 
-	return _vg_read_file_name(fid, vgname, tc->path_edit);
+	return vg;
 }
 
 static int _vg_write_file(struct format_instance *fid, struct volume_group *vg,
@@ -666,7 +716,7 @@
 		return 0;
 	}
 
-	if (fsync(fd)) {
+	if (fsync(fd) && (errno != EROFS) && (errno != EINVAL)) {
 		log_sys_error("fsync", tc->path_edit);
 		fclose(fp);
 		return 0;
@@ -1160,7 +1210,7 @@
 			return 1;
 	}
 
-	if (!(rl = dbg_malloc(sizeof(struct raw_list)))) {
+	if (!(rl = dm_malloc(sizeof(struct raw_list)))) {
 		log_error("_add_raw allocation failed");
 		return 0;
 	}
@@ -1234,11 +1284,11 @@
 	/* Add copy of mdas to supplied list */
 	list_iterate_items(mda, &info->mdas) {
 		mdac = (struct mda_context *) mda->metadata_locn;
-		if (!(mda_new = pool_alloc(fmt->cmd->mem, sizeof(*mda_new)))) {
+		if (!(mda_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda_new)))) {
 			log_error("metadata_area allocation failed");
 			return 0;
 		}
-		if (!(mdac_new = pool_alloc(fmt->cmd->mem, sizeof(*mdac_new)))) {
+		if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac_new)))) {
 			log_error("metadata_area allocation failed");
 			return 0;
 		}
@@ -1262,7 +1312,7 @@
 
 	list_iterate_safe(dl, tmp, dir_list) {
 		list_del(dl);
-		dbg_free(dl);
+		dm_free(dl);
 	}
 }
 
@@ -1272,7 +1322,7 @@
 
 	list_iterate_safe(rl, tmp, raw_list) {
 		list_del(rl);
-		dbg_free(rl);
+		dm_free(rl);
 	}
 }
 
@@ -1281,10 +1331,10 @@
 	if (fmt->private) {
 		_free_dirs(&((struct mda_lists *) fmt->private)->dirs);
 		_free_raws(&((struct mda_lists *) fmt->private)->raws);
-		dbg_free(fmt->private);
+		dm_free(fmt->private);
 	}
 
-	dbg_free((void *) fmt);
+	dm_free((void *) fmt);
 }
 
 static struct metadata_area_ops _metadata_text_file_ops = {
@@ -1361,13 +1411,13 @@
 				if (found)
 					continue;
 
-				if (!(mda_new = pool_alloc(fmt->cmd->mem,
+				if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
 							   sizeof(*mda_new)))) {
 					stack;
 					return 0;
 				}
 
-				if (!(mdac_new = pool_alloc(fmt->cmd->mem,
+				if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
 							    sizeof(*mdac_new)))) {
 					stack;
 					return 0;
@@ -1403,6 +1453,7 @@
 						     void *context)
 {
 	struct format_instance *fid;
+	struct text_fid_context *fidtc;
 	struct metadata_area *mda, *mda_new;
 	struct mda_context *mdac, *mdac_new;
 	struct dir_list *dl;
@@ -1412,17 +1463,25 @@
 	struct lvmcache_vginfo *vginfo;
 	struct lvmcache_info *info;
 
-	if (!(fid = pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
+	if (!(fid = dm_pool_alloc(fmt->cmd->mem, sizeof(*fid)))) {
 		log_error("Couldn't allocate format instance object.");
 		return NULL;
 	}
 
-	fid->fmt = fmt;
+	if (!(fidtc = (struct text_fid_context *)
+			dm_pool_zalloc(fmt->cmd->mem,sizeof(*fidtc)))) {
+		log_error("Couldn't allocate text_fid_context.");
+		return NULL;
+	}
+
+	fidtc->raw_metadata_buf = NULL;
+	fid->private = (void *) fidtc;
 
+	fid->fmt = fmt;
 	list_init(&fid->metadata_areas);
 
 	if (!vgname) {
-		if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
+		if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
 			stack;
 			return NULL;
 		}
@@ -1441,7 +1500,7 @@
 			}
 
 			context = create_text_context(fmt->cmd, path, NULL);
-			if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
+			if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
 				stack;
 				return NULL;
 			}
@@ -1457,12 +1516,12 @@
 			if (!_raw_holds_vgname(fid, &rl->dev_area, vgname))
 				continue;
 
-			if (!(mda = pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
+			if (!(mda = dm_pool_alloc(fmt->cmd->mem, sizeof(*mda)))) {
 				stack;
 				return NULL;
 			}
 
-			if (!(mdac = pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) {
+			if (!(mdac = dm_pool_alloc(fmt->cmd->mem, sizeof(*mdac)))) {
 				stack;
 				return NULL;
 			}
@@ -1487,13 +1546,13 @@
 				    (struct mda_context *) mda->metadata_locn;
 
 				/* FIXME Check it holds this VG */
-				if (!(mda_new = pool_alloc(fmt->cmd->mem,
+				if (!(mda_new = dm_pool_alloc(fmt->cmd->mem,
 							   sizeof(*mda_new)))) {
 					stack;
 					return NULL;
 				}
 
-				if (!(mdac_new = pool_alloc(fmt->cmd->mem,
+				if (!(mdac_new = dm_pool_alloc(fmt->cmd->mem,
 							    sizeof(*mdac_new)))) {
 					stack;
 					return NULL;
@@ -1525,17 +1584,17 @@
 		return NULL;
 	}
 
-	if (!(tc = pool_alloc(cmd->mem, sizeof(*tc)))) {
+	if (!(tc = dm_pool_alloc(cmd->mem, sizeof(*tc)))) {
 		stack;
 		return NULL;
 	}
 
-	if (!(tc->path_live = pool_strdup(cmd->mem, path))) {
+	if (!(tc->path_live = dm_pool_strdup(cmd->mem, path))) {
 		stack;
 		goto no_mem;
 	}
 
-	if (!(tc->path_edit = pool_alloc(cmd->mem, strlen(path) + 5))) {
+	if (!(tc->path_edit = dm_pool_alloc(cmd->mem, strlen(path) + 5))) {
 		stack;
 		goto no_mem;
 	}
@@ -1544,7 +1603,7 @@
 	if (!desc)
 		desc = "";
 
-	if (!(tc->desc = pool_strdup(cmd->mem, desc))) {
+	if (!(tc->desc = dm_pool_strdup(cmd->mem, desc))) {
 		stack;
 		goto no_mem;
 	}
@@ -1552,7 +1611,7 @@
 	return (void *) tc;
 
       no_mem:
-	pool_free(cmd->mem, tc);
+	dm_pool_free(cmd->mem, tc);
 
 	log_err("Couldn't allocate text format context object.");
 	return NULL;
@@ -1575,7 +1634,7 @@
 	struct dir_list *dl;
 
 	if (create_dir(dir)) {
-		if (!(dl = dbg_malloc(sizeof(struct list) + strlen(dir) + 1))) {
+		if (!(dl = dm_malloc(sizeof(struct list) + strlen(dir) + 1))) {
 			log_error("_add_dir allocation failed");
 			return 0;
 		}
@@ -1647,7 +1706,7 @@
 	struct config_value *cv;
 	struct mda_lists *mda_lists;
 
-	if (!(fmt = dbg_malloc(sizeof(*fmt)))) {
+	if (!(fmt = dm_malloc(sizeof(*fmt)))) {
 		stack;
 		return NULL;
 	}
@@ -1657,9 +1716,9 @@
 	fmt->name = FMT_TEXT_NAME;
 	fmt->alias = FMT_TEXT_ALIAS;
 	fmt->features = FMT_SEGMENTS | FMT_MDAS | FMT_TAGS | FMT_PRECOMMIT |
-			FMT_UNLIMITED_VOLS;
+			FMT_UNLIMITED_VOLS | FMT_RESIZE_PV;
 
-	if (!(mda_lists = dbg_malloc(sizeof(struct mda_lists)))) {
+	if (!(mda_lists = dm_malloc(sizeof(struct mda_lists)))) {
 		log_error("Failed to allocate dir_list");
 		return NULL;
 	}
@@ -1710,6 +1769,6 @@
       err:
 	_free_dirs(&mda_lists->dirs);
 
-	dbg_free(fmt);
+	dm_free(fmt);
 	return NULL;
 }

Modified: lvm2/upstream/current/lib/format_text/format-text.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/format-text.h	(original)
+++ lvm2/upstream/current/lib/format_text/format-text.h	Tue Nov 15 17:45:32 2005
@@ -18,7 +18,6 @@
 
 #include "lvm-types.h"
 #include "metadata.h"
-#include "pool.h"
 
 /*
  * Archives a vg config.  'retain_days' is the minimum number of
@@ -47,11 +46,11 @@
 
 int pvhdr_read(struct device *dev, char *buf);
 
-int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
+int add_da(const struct format_type *fmt, struct dm_pool *mem, struct list *das,
 	   uint64_t start, uint64_t size);
 void del_das(struct list *das);
 
-int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
+int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mdas,
 	    struct device *dev, uint64_t start, uint64_t size);
 void del_mdas(struct list *mdas);
 

Modified: lvm2/upstream/current/lib/format_text/import-export.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/import-export.h	(original)
+++ lvm2/upstream/current/lib/format_text/import-export.h	Tue Nov 15 17:45:32 2005
@@ -19,7 +19,6 @@
 #include "config.h"
 #include "lvm-types.h"
 #include "metadata.h"
-#include "pool.h"
 
 #include <stdio.h>
 
@@ -46,7 +45,7 @@
 	int (*check_version) (struct config_tree * cf);
 	struct volume_group *(*read_vg) (struct format_instance * fid,
 					 struct config_tree * cf);
-	void (*read_desc) (struct pool * mem, struct config_tree * cf,
+	void (*read_desc) (struct dm_pool * mem, struct config_tree * cf,
 			   time_t *when, char **desc);
 };
 
@@ -56,7 +55,7 @@
 int read_flags(uint32_t *status, int type, struct config_value *cv);
 
 int print_tags(struct list *tags, char *buffer, size_t size);
-int read_tags(struct pool *mem, struct list *tags, struct config_value *cv);
+int read_tags(struct dm_pool *mem, struct list *tags, struct config_value *cv);
 
 int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp);
 int text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf);

Modified: lvm2/upstream/current/lib/format_text/import.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/import.c	(original)
+++ lvm2/upstream/current/lib/format_text/import.c	Tue Nov 15 17:45:32 2005
@@ -16,9 +16,7 @@
 #include "lib.h"
 #include "metadata.h"
 #include "import-export.h"
-#include "pool.h"
 #include "display.h"
-#include "hash.h"
 #include "toolcontext.h"
 #include "lvmcache.h"
 

Modified: lvm2/upstream/current/lib/format_text/import_vsn1.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/import_vsn1.c	(original)
+++ lvm2/upstream/current/lib/format_text/import_vsn1.c	Tue Nov 15 17:45:32 2005
@@ -16,9 +16,7 @@
 #include "lib.h"
 #include "metadata.h"
 #include "import-export.h"
-#include "pool.h"
 #include "display.h"
-#include "hash.h"
 #include "toolcontext.h"
 #include "lvmcache.h"
 #include "lv_alloc.h"
@@ -26,10 +24,10 @@
 #include "segtype.h"
 #include "text_import.h"
 
-typedef int (*section_fn) (struct format_instance * fid, struct pool * mem,
+typedef int (*section_fn) (struct format_instance * fid, struct dm_pool * mem,
 			   struct volume_group * vg, struct config_node * pvn,
 			   struct config_node * vgn,
-			   struct hash_table * pv_hash);
+			   struct dm_hash_table * pv_hash);
 
 #define _read_int32(root, path, result) \
 	get_config_uint32(root, path, (uint32_t *) result)
@@ -111,16 +109,16 @@
 	return 1;
 }
 
-static int _read_pv(struct format_instance *fid, struct pool *mem,
+static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
 		    struct volume_group *vg, struct config_node *pvn,
-		    struct config_node *vgn, struct hash_table *pv_hash)
+		    struct config_node *vgn, struct dm_hash_table *pv_hash)
 {
 	struct physical_volume *pv;
 	struct pv_list *pvl;
 	struct config_node *cn;
 
-	if (!(pvl = pool_zalloc(mem, sizeof(*pvl))) ||
-	    !(pvl->pv = pool_zalloc(mem, sizeof(*pvl->pv)))) {
+	if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl))) ||
+	    !(pvl->pv = dm_pool_zalloc(mem, sizeof(*pvl->pv)))) {
 		stack;
 		return 0;
 	}
@@ -131,7 +129,7 @@
 	 * Add the pv to the pv hash for quick lookup when we read
 	 * the lv segments.
 	 */
-	if (!hash_insert(pv_hash, pvn->key, pv)) {
+	if (!dm_hash_insert(pv_hash, pvn->key, pv)) {
 		stack;
 		return 0;
 	}
@@ -164,7 +162,7 @@
 			return 0;
 	}
 
-	if (!(pv->vg_name = pool_strdup(mem, vg->name))) {
+	if (!(pv->vg_name = dm_pool_strdup(mem, vg->name))) {
 		stack;
 		return 0;
 	}
@@ -236,9 +234,9 @@
 	list_add(&lv->segments, &seg->list);
 }
 
-static int _read_segment(struct pool *mem, struct volume_group *vg,
+static int _read_segment(struct dm_pool *mem, struct volume_group *vg,
 			 struct logical_volume *lv, struct config_node *sn,
-			 struct hash_table *pv_hash)
+			 struct dm_hash_table *pv_hash)
 {
 	uint32_t area_count = 0u;
 	struct lv_segment *seg;
@@ -323,7 +321,7 @@
 }
 
 int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
-		      const struct config_node *cn, struct hash_table *pv_hash,
+		      const struct config_node *cn, struct dm_hash_table *pv_hash,
 		      uint32_t flags)
 {
 	unsigned int s;
@@ -359,7 +357,7 @@
 		}
 
 		/* FIXME Cope if LV not yet read in */
-		if ((pv = hash_lookup(pv_hash, cv->v.str))) {
+		if ((pv = dm_hash_lookup(pv_hash, cv->v.str))) {
 			if (!set_lv_segment_area_pv(seg, s, pv, cv->next->v.i)) {
 				stack;
 				return 0;
@@ -389,9 +387,9 @@
 	return 1;
 }
 
-static int _read_segments(struct pool *mem, struct volume_group *vg,
+static int _read_segments(struct dm_pool *mem, struct volume_group *vg,
 			  struct logical_volume *lv, struct config_node *lvn,
-			  struct hash_table *pv_hash)
+			  struct dm_hash_table *pv_hash)
 {
 	struct config_node *sn;
 	int count = 0, seg_count;
@@ -430,7 +428,7 @@
 	/*
 	 * Check there are no gaps or overlaps in the lv.
 	 */
-	if (!check_lv_segments(lv)) {
+	if (!check_lv_segments(lv, 0)) {
 		stack;
 		return 0;
 	}
@@ -446,23 +444,23 @@
 	return 1;
 }
 
-static int _read_lvnames(struct format_instance *fid, struct pool *mem,
+static int _read_lvnames(struct format_instance *fid, struct dm_pool *mem,
 			 struct volume_group *vg, struct config_node *lvn,
-			 struct config_node *vgn, struct hash_table *pv_hash)
+			 struct config_node *vgn, struct dm_hash_table *pv_hash)
 {
 	struct logical_volume *lv;
 	struct lv_list *lvl;
 	struct config_node *cn;
 
-	if (!(lvl = pool_zalloc(mem, sizeof(*lvl))) ||
-	    !(lvl->lv = pool_zalloc(mem, sizeof(*lvl->lv)))) {
+	if (!(lvl = dm_pool_zalloc(mem, sizeof(*lvl))) ||
+	    !(lvl->lv = dm_pool_zalloc(mem, sizeof(*lvl->lv)))) {
 		stack;
 		return 0;
 	}
 
 	lv = lvl->lv;
 
-	if (!(lv->name = pool_strdup(mem, lvn->key))) {
+	if (!(lv->name = dm_pool_strdup(mem, lvn->key))) {
 		stack;
 		return 0;
 	}
@@ -521,9 +519,9 @@
 	return 1;
 }
 
-static int _read_lvsegs(struct format_instance *fid, struct pool *mem,
+static int _read_lvsegs(struct format_instance *fid, struct dm_pool *mem,
 			struct volume_group *vg, struct config_node *lvn,
-			struct config_node *vgn, struct hash_table *pv_hash)
+			struct config_node *vgn, struct dm_hash_table *pv_hash)
 {
 	struct logical_volume *lv;
 	struct lv_list *lvl;
@@ -586,9 +584,9 @@
 
 static int _read_sections(struct format_instance *fid,
 			  const char *section, section_fn fn,
-			  struct pool *mem,
+			  struct dm_pool *mem,
 			  struct volume_group *vg, struct config_node *vgn,
-			  struct hash_table *pv_hash, int optional)
+			  struct dm_hash_table *pv_hash, int optional)
 {
 	struct config_node *n;
 
@@ -616,8 +614,8 @@
 {
 	struct config_node *vgn, *cn;
 	struct volume_group *vg;
-	struct hash_table *pv_hash = NULL;
-	struct pool *mem = fid->fmt->cmd->mem;
+	struct dm_hash_table *pv_hash = NULL;
+	struct dm_pool *mem = fid->fmt->cmd->mem;
 
 	/* skip any top-level values */
 	for (vgn = cft->root; (vgn && vgn->v); vgn = vgn->sib) ;
@@ -627,7 +625,7 @@
 		return NULL;
 	}
 
-	if (!(vg = pool_zalloc(mem, sizeof(*vg)))) {
+	if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
 		stack;
 		return NULL;
 	}
@@ -637,12 +635,12 @@
 	/* eg Set to instance of fmt1 here if reading a format1 backup? */
 	vg->fid = fid;
 
-	if (!(vg->name = pool_strdup(mem, vgn->key))) {
+	if (!(vg->name = dm_pool_strdup(mem, vgn->key))) {
 		stack;
 		goto bad;
 	}
 
-	if (!(vg->system_id = pool_zalloc(mem, NAME_LEN))) {
+	if (!(vg->system_id = dm_pool_zalloc(mem, NAME_LEN))) {
 		stack;
 		goto bad;
 	}
@@ -722,7 +720,7 @@
 	 * The pv hash memoises the pv section names -> pv
 	 * structures.
 	 */
-	if (!(pv_hash = hash_create(32))) {
+	if (!(pv_hash = dm_hash_create(32))) {
 		log_error("Couldn't create hash table.");
 		goto bad;
 	}
@@ -759,7 +757,13 @@
 		goto bad;
 	}
 
-	hash_destroy(pv_hash);
+	if (!fixup_imported_mirrors(vg)) {
+		log_error("Failed to fixup mirror pointers after import for "
+			  "volume group %s.", vg->name);
+		goto bad;
+	}
+
+	dm_hash_destroy(pv_hash);
 
 	if (vg->status & PARTIAL_VG) {
 		vg->status &= ~LVM_WRITE;
@@ -773,13 +777,13 @@
 
       bad:
 	if (pv_hash)
-		hash_destroy(pv_hash);
+		dm_hash_destroy(pv_hash);
 
-	pool_free(mem, vg);
+	dm_pool_free(mem, vg);
 	return NULL;
 }
 
-static void _read_desc(struct pool *mem,
+static void _read_desc(struct dm_pool *mem,
 		       struct config_tree *cft, time_t *when, char **desc)
 {
 	const char *d;
@@ -788,7 +792,7 @@
 	log_suppress(1);
 	d = find_config_str(cft->root, "description", "");
 	log_suppress(0);
-	*desc = pool_strdup(mem, d);
+	*desc = dm_pool_strdup(mem, d);
 
 	get_config_uint32(cft->root, "creation_time", &u);
 	*when = u;

Modified: lvm2/upstream/current/lib/format_text/layout.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/layout.h	(original)
+++ lvm2/upstream/current/lib/format_text/layout.h	Tue Nov 15 17:45:32 2005
@@ -37,6 +37,8 @@
 /* On disk */
 struct pv_header {
 	uint8_t pv_uuid[ID_LEN];
+
+	/* This size can be overridden if PV belongs to a VG */
 	uint64_t device_size_xl;	/* Bytes */
 
 	/* NULL-terminated list of data areas followed by */

Modified: lvm2/upstream/current/lib/format_text/tags.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/tags.c	(original)
+++ lvm2/upstream/current/lib/format_text/tags.c	Tue Nov 15 17:45:32 2005
@@ -16,7 +16,6 @@
 #include "lib.h"
 #include "metadata.h"
 #include "import-export.h"
-#include "pool.h"
 #include "str_list.h"
 #include "lvm-string.h"
 
@@ -53,7 +52,7 @@
 	return 1;
 }
 
-int read_tags(struct pool *mem, struct list *tags, struct config_value *cv)
+int read_tags(struct dm_pool *mem, struct list *tags, struct config_value *cv)
 {
 	if (cv->type == CFG_EMPTY_ARRAY)
 		return 1;
@@ -64,7 +63,7 @@
 			return 0;
 		}
 
-		if (!str_list_add(mem, tags, pool_strdup(mem, cv->v.str))) {
+		if (!str_list_add(mem, tags, dm_pool_strdup(mem, cv->v.str))) {
 			stack;
 			return 0;
 		}

Modified: lvm2/upstream/current/lib/format_text/text_import.h
==============================================================================
--- lvm2/upstream/current/lib/format_text/text_import.h	(original)
+++ lvm2/upstream/current/lib/format_text/text_import.h	Tue Nov 15 17:45:32 2005
@@ -20,7 +20,7 @@
 struct config_node;
 
 int text_import_areas(struct lv_segment *seg, const struct config_node *sn,
-		      const struct config_node *cn, struct hash_table *pv_hash,
+		      const struct config_node *cn, struct dm_hash_table *pv_hash,
 		      uint32_t flags);
 
 #endif

Modified: lvm2/upstream/current/lib/format_text/text_label.c
==============================================================================
--- lvm2/upstream/current/lib/format_text/text_label.c	(original)
+++ lvm2/upstream/current/lib/format_text/text_label.c	Tue Nov 15 17:45:32 2005
@@ -86,18 +86,18 @@
 	return 1;
 }
 
-int add_da(const struct format_type *fmt, struct pool *mem, struct list *das,
+int add_da(const struct format_type *fmt, struct dm_pool *mem, struct list *das,
 	   uint64_t start, uint64_t size)
 {
 	struct data_area_list *dal;
 
 	if (!mem) {
-		if (!(dal = dbg_malloc(sizeof(*dal)))) {
+		if (!(dal = dm_malloc(sizeof(*dal)))) {
 			log_error("struct data_area_list allocation failed");
 			return 0;
 		}
 	} else {
-		if (!(dal = pool_alloc(mem, sizeof(*dal)))) {
+		if (!(dal = dm_pool_alloc(mem, sizeof(*dal)))) {
 			log_error("struct data_area_list allocation failed");
 			return 0;
 		}
@@ -119,11 +119,11 @@
 	list_iterate_safe(dah, tmp, das) {
 		da = list_item(dah, struct data_area_list);
 		list_del(&da->list);
-		dbg_free(da);
+		dm_free(da);
 	}
 }
 
-int add_mda(const struct format_type *fmt, struct pool *mem, struct list *mdas,
+int add_mda(const struct format_type *fmt, struct dm_pool *mem, struct list *mdas,
 	    struct device *dev, uint64_t start, uint64_t size)
 {
 /* FIXME List size restricted by pv_header SECTOR_SIZE */
@@ -132,23 +132,23 @@
 	struct mda_context *mdac;
 
 	if (!mem) {
-		if (!(mdal = dbg_malloc(sizeof(struct metadata_area)))) {
+		if (!(mdal = dm_malloc(sizeof(struct metadata_area)))) {
 			log_error("struct mda_list allocation failed");
 			return 0;
 		}
 
-		if (!(mdac = dbg_malloc(sizeof(struct mda_context)))) {
+		if (!(mdac = dm_malloc(sizeof(struct mda_context)))) {
 			log_error("struct mda_context allocation failed");
-			dbg_free(mdal);
+			dm_free(mdal);
 			return 0;
 		}
 	} else {
-		if (!(mdal = pool_alloc(mem, sizeof(struct metadata_area)))) {
+		if (!(mdal = dm_pool_alloc(mem, sizeof(struct metadata_area)))) {
 			log_error("struct mda_list allocation failed");
 			return 0;
 		}
 
-		if (!(mdac = pool_alloc(mem, sizeof(struct mda_context)))) {
+		if (!(mdac = dm_pool_alloc(mem, sizeof(struct mda_context)))) {
 			log_error("struct mda_context allocation failed");
 			return 0;
 		}
@@ -173,9 +173,9 @@
 
 	list_iterate_safe(mdah, tmp, mdas) {
 		mda = list_item(mdah, struct metadata_area);
-		dbg_free(mda->metadata_locn);
+		dm_free(mda->metadata_locn);
 		list_del(&mda->list);
-		dbg_free(mda);
+		dm_free(mda);
 	}
 }
 
@@ -255,7 +255,7 @@
 
 static void _destroy(struct labeller *l)
 {
-	dbg_free(l);
+	dm_free(l);
 }
 
 struct label_ops _text_ops = {
@@ -272,7 +272,7 @@
 {
 	struct labeller *l;
 
-	if (!(l = dbg_malloc(sizeof(*l)))) {
+	if (!(l = dm_malloc(sizeof(*l)))) {
 		log_err("Couldn't allocate labeller object.");
 		return NULL;
 	}

Modified: lvm2/upstream/current/lib/label/label.c
==============================================================================
--- lvm2/upstream/current/lib/label/label.c	(original)
+++ lvm2/upstream/current/lib/label/label.c	Tue Nov 15 17:45:32 2005
@@ -15,7 +15,6 @@
 
 #include "lib.h"
 #include "label.h"
-#include "list.h"
 #include "crc.h"
 #include "xlate.h"
 #include "lvmcache.h"
@@ -46,7 +45,7 @@
 
 	len = sizeof(*li) + strlen(name) + 1;
 
-	if (!(li = dbg_malloc(len))) {
+	if (!(li = dm_malloc(len))) {
 		log_error("Couldn't allocate memory for labeller list object.");
 		return NULL;
 	}
@@ -59,7 +58,7 @@
 
 static void _free_li(struct labeller_i *li)
 {
-	dbg_free(li);
+	dm_free(li);
 }
 
 int label_init(void)
@@ -353,14 +352,14 @@
 void label_destroy(struct label *label)
 {
 	label->labeller->ops->destroy_label(label->labeller, label);
-	dbg_free(label);
+	dm_free(label);
 }
 
 struct label *label_create(struct labeller *labeller)
 {
 	struct label *label;
 
-	if (!(label = dbg_malloc(sizeof(*label)))) {
+	if (!(label = dm_malloc(sizeof(*label)))) {
 		log_error("label allocaction failed");
 		return NULL;
 	}

Modified: lvm2/upstream/current/lib/locking/cluster_locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/cluster_locking.c	(original)
+++ lvm2/upstream/current/lib/locking/cluster_locking.c	Tue Nov 15 17:45:32 2005
@@ -127,7 +127,7 @@
 
 	/* Allocate buffer */
 	buflen = len + outheader->arglen;
-	*retbuf = dbg_malloc(buflen);
+	*retbuf = dm_malloc(buflen);
 	if (!*retbuf) {
 		errno = ENOMEM;
 		return 0;
@@ -236,7 +236,7 @@
 	 * With an extra pair of INTs on the front to sanity
 	 * check the pointer when we are given it back to free
 	 */
-	outptr = dbg_malloc(sizeof(lvm_response_t) * num_responses +
+	outptr = dm_malloc(sizeof(lvm_response_t) * num_responses +
 			    sizeof(int) * 2);
 	if (!outptr) {
 		errno = ENOMEM;
@@ -259,12 +259,12 @@
 		rarray[i].status = *(int *) inptr;
 		inptr += sizeof(int);
 
-		rarray[i].response = dbg_malloc(strlen(inptr) + 1);
+		rarray[i].response = dm_malloc(strlen(inptr) + 1);
 		if (rarray[i].response == NULL) {
 			/* Free up everything else and return error */
 			int j;
 			for (j = 0; j < i; j++)
-				dbg_free(rarray[i].response);
+				dm_free(rarray[i].response);
 			free(outptr);
 			errno = ENOMEM;
 			status = -1;
@@ -281,7 +281,7 @@
 
       out:
 	if (retbuf)
-		dbg_free(retbuf);
+		dm_free(retbuf);
 
 	return status;
 }
@@ -302,10 +302,10 @@
 	num = ptr[1];
 
 	for (i = 0; i < num; i++) {
-		dbg_free(response[i].response);
+		dm_free(response[i].response);
 	}
 
-	dbg_free(ptr);
+	dm_free(ptr);
 
 	return 1;
 }
@@ -327,8 +327,8 @@
 	args = alloca(len);
 	strcpy(args + 2, name);
 
-	args[0] = flags & 0xBF; /* Maskoff LOCAL flag */
-	args[1] = 0;		/* Not used now */
+	args[0] = flags & 0x7F; /* Maskoff lock flags */
+	args[1] = flags & 0xC0; /* Bitmap flags */
 
 	/*
 	 * VG locks are just that: locks, and have no side effects
@@ -339,7 +339,8 @@
 	 */
 	if (cmd == CLVMD_CMD_LOCK_VG ||
 	    (flags & LCK_TYPE_MASK) == LCK_EXCL ||
-	    (flags & LCK_LOCAL))
+	    (flags & LCK_LOCAL) ||
+	    !(flags & LCK_CLUSTER_VG))
 		node = ".";
 
 	status = _cluster_request(cmd, node, args, len,

Modified: lvm2/upstream/current/lib/locking/file_locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/file_locking.c	(original)
+++ lvm2/upstream/current/lib/locking/file_locking.c	Tue Nov 15 17:45:32 2005
@@ -71,8 +71,8 @@
 			if (close(ll->lf) < 0)
 				log_sys_error("close", ll->res);
 
-			dbg_free(ll->res);
-			dbg_free(llh);
+			dm_free(ll->res);
+			dm_free(llh);
 
 			if (file)
 				return 1;
@@ -150,11 +150,11 @@
 		return 0;
 	}
 
-	if (!(ll = dbg_malloc(sizeof(struct lock_list))))
+	if (!(ll = dm_malloc(sizeof(struct lock_list))))
 		return 0;
 
-	if (!(ll->res = dbg_strdup(file))) {
-		dbg_free(ll);
+	if (!(ll->res = dm_strdup(file))) {
+		dm_free(ll);
 		return 0;
 	}
 
@@ -197,8 +197,8 @@
 	return 1;
 
       err:
-	dbg_free(ll->res);
-	dbg_free(ll);
+	dm_free(ll->res);
+	dm_free(ll);
 	return 0;
 }
 
@@ -243,7 +243,7 @@
 			break;
 		case LCK_READ:
 			log_debug("Locking LV %s (R)", resource);
-			if (!lv_activate_with_filter(cmd, resource))
+			if (!lv_activate_with_filter(cmd, resource, 0))
 				return 0;
 			break;
 		case LCK_WRITE:
@@ -253,7 +253,7 @@
 			break;
 		case LCK_EXCL:
 			log_debug("Locking LV %s (EX)", resource);
-			if (!lv_activate_with_filter(cmd, resource))
+			if (!lv_activate_with_filter(cmd, resource, 1))
 				return 0;
 			break;
 		default:

Modified: lvm2/upstream/current/lib/locking/locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/locking.c	(original)
+++ lvm2/upstream/current/lib/locking/locking.c	Tue Nov 15 17:45:32 2005
@@ -268,7 +268,7 @@
 	struct lv_list *lvl;
 
 	list_iterate_items(lvl, lvs)
-		resume_lv(cmd, lvl->lv->lvid.s);
+		resume_lv(cmd, lvl->lv);
 
 	return 1;
 }
@@ -280,11 +280,11 @@
 	struct lv_list *lvl;
 
 	list_iterate_items(lvl, lvs) {
-		if (!suspend_lv(cmd, lvl->lv->lvid.s)) {
+		if (!suspend_lv(cmd, lvl->lv)) {
 			log_error("Failed to suspend %s", lvl->lv->name);
 			list_uniterate(lvh, lvs, &lvl->list) {
 				lvl = list_item(lvh, struct lv_list);
-				resume_lv(cmd, lvl->lv->lvid.s);
+				resume_lv(cmd, lvl->lv);
 			}
 
 			return 0;
@@ -301,11 +301,11 @@
 	struct lv_list *lvl;
 
 	list_iterate_items(lvl, lvs) {
-		if (!activate_lv_excl(cmd, lvl->lv->lvid.s)) {
+		if (!activate_lv_excl(cmd, lvl->lv)) {
 			log_error("Failed to activate %s", lvl->lv->name);
 			list_uniterate(lvh, lvs, &lvl->list) {
 				lvl = list_item(lvh, struct lv_list);
-				activate_lv(cmd, lvl->lv->lvid.s);
+				activate_lv(cmd, lvl->lv);
 			}
 
 			return 0;

Modified: lvm2/upstream/current/lib/locking/locking.h
==============================================================================
--- lvm2/upstream/current/lib/locking/locking.h	(original)
+++ lvm2/upstream/current/lib/locking/locking.h	Tue Nov 15 17:45:32 2005
@@ -65,6 +65,7 @@
 #define LCK_NONBLOCK	0x00000010	/* Don't block waiting for lock? */
 #define LCK_HOLD	0x00000020	/* Hold lock when lock_vol returns? */
 #define LCK_LOCAL	0x00000040	/* Don't propagate to other nodes */
+#define LCK_CLUSTER_VG	0x00000080	/* VG is clustered */
 
 /*
  * Common combinations
@@ -79,22 +80,27 @@
 #define LCK_LV_ACTIVATE		(LCK_LV | LCK_READ | LCK_NONBLOCK)
 #define LCK_LV_DEACTIVATE	(LCK_LV | LCK_NULL | LCK_NONBLOCK)
 
+#define LCK_LV_CLUSTERED(lv)	\
+	(((lv)->vg->status & CLUSTERED) ? LCK_CLUSTER_VG : 0)
+
+#define lock_lv_vol(cmd, lv, flags)	\
+	lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv))
+
 #define unlock_vg(cmd, vol)	lock_vol(cmd, vol, LCK_VG_UNLOCK)
 
-#define resume_lv(cmd, vol)	lock_vol(cmd, vol, LCK_LV_RESUME)
-#define suspend_lv(cmd, vol)	lock_vol(cmd, vol, LCK_LV_SUSPEND | LCK_HOLD)
-#define deactivate_lv(cmd, vol)	lock_vol(cmd, vol, LCK_LV_DEACTIVATE)
-#define activate_lv(cmd, vol)	lock_vol(cmd, vol, LCK_LV_ACTIVATE | LCK_HOLD)
-#define activate_lv_excl(cmd, vol)	\
-				lock_vol(cmd, vol, LCK_LV_EXCLUSIVE | LCK_HOLD)
-#define activate_lv_local(cmd, vol)	\
-	lock_vol(cmd, vol, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
-#define deactivate_lv_local(cmd, vol)	\
-	lock_vol(cmd, vol, LCK_LV_DEACTIVATE | LCK_LOCAL)
+#define resume_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_RESUME)
+#define suspend_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD)
+#define deactivate_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE)
+#define activate_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
+#define activate_lv_excl(cmd, lv)	\
+				lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD)
+#define activate_lv_local(cmd, lv)	\
+	lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
+#define deactivate_lv_local(cmd, lv)	\
+	lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
 
 /* Process list of LVs */
 int suspend_lvs(struct cmd_context *cmd, struct list *lvs);
 int resume_lvs(struct cmd_context *cmd, struct list *lvs);
 int activate_lvs_excl(struct cmd_context *cmd, struct list *lvs);
 
-

Modified: lvm2/upstream/current/lib/locking/no_locking.c
==============================================================================
--- lvm2/upstream/current/lib/locking/no_locking.c	(original)
+++ lvm2/upstream/current/lib/locking/no_locking.c	Tue Nov 15 17:45:32 2005
@@ -58,11 +58,11 @@
 		case LCK_UNLOCK:
 			return lv_resume_if_active(cmd, resource);
 		case LCK_READ:
-			return lv_activate_with_filter(cmd, resource);
+			return lv_activate_with_filter(cmd, resource, 0);
 		case LCK_WRITE:
 			return lv_suspend_if_active(cmd, resource);
 		case LCK_EXCL:
-			return lv_activate_with_filter(cmd, resource);
+			return lv_activate_with_filter(cmd, resource, 1);
 		default:
 			break;
 		}

Modified: lvm2/upstream/current/lib/log/log.c
==============================================================================
--- lvm2/upstream/current/lib/log/log.c	(original)
+++ lvm2/upstream/current/lib/log/log.c	Tue Nov 15 17:45:32 2005
@@ -100,7 +100,7 @@
 	if (!_log_direct)
 		return;
 
-	dbg_free((char *) _log_dev_alias.str);
+	dm_free((char *) _log_dev_alias.str);
 	_log_dev_alias.str = "activate_log file";
 }
 

Modified: lvm2/upstream/current/lib/log/log.h
==============================================================================
--- lvm2/upstream/current/lib/log/log.h	(original)
+++ lvm2/upstream/current/lib/log/log.h	Tue Nov 15 17:45:32 2005
@@ -124,4 +124,8 @@
 #define log_sys_debug(x, y) \
 		log_debug("%s: %s failed: %s", y, x, strerror(errno))
 
+#define return_0	do { stack; return 0; } while (0)
+#define return_NULL	do { stack; return NULL; } while (0)
+#define goto_out	do { stack; goto out; } while (0)
+
 #endif

Modified: lvm2/upstream/current/lib/metadata/lv_alloc.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/lv_alloc.h	(original)
+++ lvm2/upstream/current/lib/metadata/lv_alloc.h	Tue Nov 15 17:45:32 2005
@@ -14,9 +14,8 @@
  */
 
 #ifndef _LVM_LV_ALLOC_H
-#include "pool.h"
 
-struct lv_segment *alloc_lv_segment(struct pool *mem,
+struct lv_segment *alloc_lv_segment(struct dm_pool *mem,
 				    struct segment_type *segtype,
 				    struct logical_volume *lv,
 				    uint32_t le, uint32_t len,
@@ -77,6 +76,10 @@
 			  uint32_t status,
 			  uint32_t region_size,
 			  struct logical_volume *log_lv);
+int lv_add_more_mirrored_areas(struct logical_volume *lv,
+                               struct logical_volume **sub_lvs,
+                               uint32_t new_area_count,
+                               uint32_t status);
 
 void alloc_destroy(struct alloc_handle *ah);
 

Modified: lvm2/upstream/current/lib/metadata/lv_manip.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/lv_manip.c	(original)
+++ lvm2/upstream/current/lib/metadata/lv_manip.c	Tue Nov 15 17:45:32 2005
@@ -53,7 +53,7 @@
 /*
  * All lv_segments get created here.
  */
-struct lv_segment *alloc_lv_segment(struct pool *mem,
+struct lv_segment *alloc_lv_segment(struct dm_pool *mem,
 				    struct segment_type *segtype,
 				    struct logical_volume *lv,
 				    uint32_t le, uint32_t len,
@@ -67,9 +67,15 @@
 				    uint32_t extents_copied)
 {
 	struct lv_segment *seg;
-	uint32_t sz = sizeof(*seg) + (area_count * sizeof(seg->area[0]));
+	uint32_t areas_sz = area_count * sizeof(*seg->areas);
 
-	if (!(seg = pool_zalloc(mem, sz))) {
+	if (!(seg = dm_pool_zalloc(mem, sizeof(*seg)))) {
+		stack;
+		return NULL;
+	}
+
+	if (!(seg->areas = dm_pool_zalloc(mem, areas_sz))) {
+		dm_pool_free(mem, seg);
 		stack;
 		return NULL;
 	}
@@ -91,10 +97,13 @@
 	seg->region_size = region_size;
 	seg->extents_copied = extents_copied;
 	seg->log_lv = log_lv;
+	seg->mirror_seg = NULL;
 	list_init(&seg->tags);
 
-	if (log_lv)
+	if (log_lv) {
 		log_lv->status |= MIRROR_LOG;
+		first_seg(log_lv)->mirror_seg = seg;
+	}
 
 	return seg;
 }
@@ -199,7 +208,7 @@
 int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
 			   struct physical_volume *pv, uint32_t pe)
 {
-	seg->area[area_num].type = AREA_PV;
+	seg->areas[area_num].type = AREA_PV;
 
 	if (!(seg_pvseg(seg, area_num) =
 	      assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num))) {
@@ -217,13 +226,36 @@
 			    struct logical_volume *lv, uint32_t le,
 			    uint32_t flags)
 {
-	seg->area[area_num].type = AREA_LV;
+	seg->areas[area_num].type = AREA_LV;
 	seg_lv(seg, area_num) = lv;
 	seg_le(seg, area_num) = le;
 	lv->status |= flags;
 }
 
 /*
+ * Prepare for adding parallel areas to an existing segment.
+ */
+static int _lv_segment_add_areas(struct logical_volume *lv,
+				 struct lv_segment *seg,
+				 uint32_t new_area_count)
+{
+	struct lv_segment_area *newareas;
+	uint32_t areas_sz = new_area_count * sizeof(*newareas);
+
+	if (!(newareas = dm_pool_zalloc(lv->vg->cmd->mem, areas_sz))) {
+		stack;
+		return 0;
+	}
+
+	memcpy(newareas, seg->areas, seg->area_count * sizeof(*seg->areas));
+
+	seg->areas = newareas;
+	seg->area_count = new_area_count;
+
+	return 1;
+}
+
+/*
  * Reduce the size of an lv_segment.  New size can be zero.
  */
 static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
@@ -351,7 +383,7 @@
  * Details of an allocation attempt
  */
 struct alloc_handle {
-	struct pool *mem;
+	struct dm_pool *mem;
 
 	alloc_policy_t alloc;		/* Overall policy */
 	uint32_t area_count;		/* Number of parallel areas */
@@ -366,7 +398,7 @@
 /*
  * Preparation for a specific allocation attempt
  */
-static struct alloc_handle *_alloc_init(struct pool *mem,
+static struct alloc_handle *_alloc_init(struct dm_pool *mem,
 					struct segment_type *segtype,
 					alloc_policy_t alloc,
 					uint32_t mirrors,
@@ -403,7 +435,7 @@
 	else
 		area_count = stripes;
 
-	if (!(ah = pool_zalloc(mem, sizeof(*ah) + sizeof(ah->alloced_areas[0]) * area_count))) {
+	if (!(ah = dm_pool_zalloc(mem, sizeof(*ah) + sizeof(ah->alloced_areas[0]) * area_count))) {
 		log_error("allocation handle allocation failed");
 		return NULL;
 	}
@@ -411,7 +443,7 @@
 	if (segtype_is_virtual(segtype))
 		return ah;
 
-	if (!(ah->mem = pool_create("allocation", 1024))) {
+	if (!(ah->mem = dm_pool_create("allocation", 1024))) {
 		log_error("allocation pool creation failed");
 		return NULL;
 	}
@@ -432,7 +464,7 @@
 void alloc_destroy(struct alloc_handle *ah)
 {
 	if (ah->mem)
-		pool_destroy(ah->mem);
+		dm_pool_destroy(ah->mem);
 }
 
 static int _setup_alloced_segment(struct logical_volume *lv, uint32_t status,
@@ -453,10 +485,11 @@
 
 	area_multiple = segtype_is_striped(segtype) ? area_count : 1;
 
+	/* log_lv gets set up elsehere */
 	if (!(seg = alloc_lv_segment(lv->vg->cmd->mem, segtype, lv,
 				     lv->le_count,
 				     aa[0].len * area_multiple,
-				     status, stripe_size, log_lv,
+				     status, stripe_size, NULL,
 				     area_count + extra_areas,
 				     aa[0].len, 0u, region_size, 0u))) {
 		log_error("Couldn't allocate new LV segment.");
@@ -537,7 +570,7 @@
 	if (area_len > smallest)
 		area_len = smallest;
 
-	if (!(aa = pool_alloc(ah->mem, sizeof(*aa) *
+	if (!(aa = dm_pool_alloc(ah->mem, sizeof(*aa) *
 			      (ah->area_count + (log_area ? 1 : 0))))) {
 		log_error("alloced_area allocation failed");
 		return 0;
@@ -630,12 +663,10 @@
 	/* FIXME Do calculations on free extent counts before selecting space */
 	/* FIXME Select log PV appropriately if there isn't one yet */
 
-	if ((alloc == ALLOC_CONTIGUOUS)) {
+	/* Are there any preceding segments we must follow on from? */
+	if ((alloc == ALLOC_CONTIGUOUS) && prev_lvseg) {
 		contiguous = 1;
-		if (prev_lvseg)
-			ix_offset = prev_lvseg->area_count;
-		else
-			ix_offset = ah->area_count;
+		ix_offset = prev_lvseg->area_count;
 	}
 
 	/* FIXME This algorithm needs a lot of cleaning up! */
@@ -687,7 +718,7 @@
 					already_found_one = 1;
 				}
 
-				areas[ix + ix_offset -1] = pva;
+				areas[ix + ix_offset - 1] = pva;
 
 				break;	/* Next PV */
 			}
@@ -780,8 +811,13 @@
 		areas_size = ah->area_count + ah->log_count;
 	}
 
+	/* Upper bound if none of the PVs in prev_lvseg is in pvms */
+	/* FIXME Work size out properly */
+	if (prev_lvseg)
+		areas_size += prev_lvseg->area_count;
+
 	/* Allocate an array of pv_areas to hold the largest space on each PV */
-	if (!(areas = dbg_malloc(sizeof(*areas) * areas_size))) {
+	if (!(areas = dm_malloc(sizeof(*areas) * areas_size))) {
 		log_err("Couldn't allocate areas array.");
 		return 0;
 	}
@@ -831,7 +867,7 @@
 	r = 1;
 
       out:
-	dbg_free(areas);
+	dm_free(areas);
 	return r;
 }
 
@@ -1027,8 +1063,10 @@
 		return 0;
 	}
 
-	for (m = 0; m < mirrors; m++)
+	for (m = 0; m < mirrors; m++) {
 		set_lv_segment_area_lv(seg, m, sub_lvs[m], 0, MIRROR_IMAGE);
+		first_seg(sub_lvs[m])->mirror_seg = seg;
+	}
 
 	list_add(&lv->segments, &seg->list);
 	lv->le_count += ah->total_area_len;
@@ -1043,6 +1081,42 @@
 	return 1;
 }
 
+/*
+ * Add parallel areas to an existing mirror
+ */
+int lv_add_more_mirrored_areas(struct logical_volume *lv,
+			       struct logical_volume **sub_lvs,
+			       uint32_t num_extra_areas,
+			       uint32_t status)
+{
+	struct lv_segment *seg;
+	uint32_t old_area_count, new_area_count;
+	uint32_t m;
+
+	if (list_size(&lv->segments) != 1) {
+		log_error("Mirrored LV must only have one segment.");
+		return 0;
+	}
+
+	list_iterate_items(seg, &lv->segments)
+		break;
+
+	old_area_count = seg->area_count;
+	new_area_count = old_area_count + num_extra_areas;
+
+	if (!_lv_segment_add_areas(lv, seg, new_area_count)) {
+		log_error("Failed to allocate widened LV segment for %s.",
+			  lv->name);
+		return 0;
+	}
+
+	for (m = old_area_count; m < new_area_count; m++) {
+		set_lv_segment_area_lv(seg, m, sub_lvs[m - old_area_count], 0, status);
+		first_seg(sub_lvs[m - old_area_count])->mirror_seg = seg;
+	}
+
+	return 1;
+}
 
 /*
  * Entry point for single-step LV allocation + extension.
@@ -1058,7 +1132,7 @@
 	int r = 1;
 	uint32_t m;
 	struct alloc_handle *ah;
-	struct lv_segment *first_seg;
+	struct lv_segment *seg;
 
 	if (segtype_is_virtual(segtype))
 		return lv_add_virtual_segment(lv, status, extents, segtype);
@@ -1077,20 +1151,19 @@
 			goto out;
 		}
 	} else {
-		list_iterate_items(first_seg, &lv->segments)
-			break;
+		seg = first_seg(lv);
 		for (m = 0; m < mirrors; m++) {
-			if (!lv_add_segment(ah, m, 1, seg_lv(first_seg, m),
+			if (!lv_add_segment(ah, m, 1, seg_lv(seg, m),
 					    get_segtype_from_string(lv->vg->cmd,
 								    "striped"),
 					    0, NULL, 0, 0, 0, NULL)) {
 				log_error("Aborting. Failed to extend %s.",
-					  seg_lv(first_seg, m)->name);
+					  seg_lv(seg, m)->name);
 				return 0;
                 	}
 		}
-		first_seg->area_len += extents;
-		first_seg->len += extents;
+		seg->area_len += extents;
+		seg->len += extents;
 		lv->le_count += extents;
 		lv->size += (uint64_t) extents *lv->vg->extent_size;
 	}
@@ -1152,21 +1225,21 @@
 	if (!import)
 		log_verbose("Creating logical volume %s", name);
 
-	if (!(ll = pool_zalloc(cmd->mem, sizeof(*ll))) ||
-	    !(ll->lv = pool_zalloc(cmd->mem, sizeof(*ll->lv)))) {
+	if (!(ll = dm_pool_zalloc(cmd->mem, sizeof(*ll))) ||
+	    !(ll->lv = dm_pool_zalloc(cmd->mem, sizeof(*ll->lv)))) {
 		log_error("lv_list allocation failed");
 		if (ll)
-			pool_free(cmd->mem, ll);
+			dm_pool_free(cmd->mem, ll);
 		return NULL;
 	}
 
 	lv = ll->lv;
 	lv->vg = vg;
 
-	if (!(lv->name = pool_strdup(cmd->mem, name))) {
+	if (!(lv->name = dm_pool_strdup(cmd->mem, name))) {
 		log_error("lv name strdup failed");
 		if (ll)
-			pool_free(cmd->mem, ll);
+			dm_pool_free(cmd->mem, ll);
 		return NULL;
 	}
 
@@ -1188,7 +1261,7 @@
 	if (fi->fmt->ops->lv_setup && !fi->fmt->ops->lv_setup(fi, lv)) {
 		stack;
 		if (ll)
-			pool_free(cmd->mem, ll);
+			dm_pool_free(cmd->mem, ll);
 		return NULL;
 	}
 

Modified: lvm2/upstream/current/lib/metadata/merge.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/merge.c	(original)
+++ lvm2/upstream/current/lib/metadata/merge.c	Tue Nov 15 17:45:32 2005
@@ -58,9 +58,9 @@
 /*
  * Verify that an LV's segments are consecutive, complete and don't overlap.
  */
-int check_lv_segments(struct logical_volume *lv)
+int check_lv_segments(struct logical_volume *lv, int complete_vg)
 {
-	struct lv_segment *seg;
+	struct lv_segment *seg, *seg2;
 	uint32_t le = 0;
 	unsigned seg_count = 0;
 	int r = 1;
@@ -85,6 +85,40 @@
 			r = 0;
 		}
 
+		if (complete_vg && seg->log_lv) {
+			if (!seg_is_mirrored(seg)) {
+				log_error("LV %s: segment %u has log LV but "
+					  "is not mirrored",
+					  lv->name, seg_count);
+				r = 0;
+			}
+
+			if (!(seg->log_lv->status & MIRROR_LOG)) {
+				log_error("LV %s: segment %u log LV %s is not "
+					  "a mirror log",
+					   lv->name, seg_count, seg->log_lv->name);
+				r = 0;
+			}
+
+			if (!(seg2 = first_seg(seg->log_lv)) ||
+			    seg2->mirror_seg != seg) {
+				log_error("LV %s: segment %u log LV does not "
+					  "point back to mirror segment",
+					   lv->name, seg_count);
+				r = 0;
+			}
+		}
+
+		if (complete_vg && seg->status & MIRROR_IMAGE) {
+			if (!seg->mirror_seg ||
+			    !seg_is_mirrored(seg->mirror_seg)) {
+				log_error("LV %s: segment %u mirror image "
+					  "is not mirrored",
+					  lv->name, seg_count);
+				r = 0;
+			}
+		}
+
 		for (s = 0; s < seg->area_count; s++) {
 			if (seg_type(seg, s) == AREA_UNASSIGNED) {
 				log_error("LV %s: segment %u has unassigned "
@@ -109,6 +143,18 @@
 						  lv->name, seg_count, s);
 					r = 0;
 				}
+
+				if (complete_vg && seg_lv(seg, s) &&
+				    (seg_lv(seg, s)->status & MIRROR_IMAGE) &&
+				    (find_seg_by_le(seg_lv(seg, s),
+						    seg_le(seg, s))->mirror_seg
+							!= seg)) {
+					log_error("LV %s: segment %u mirror "
+						  "image %u missing mirror ptr",
+						  lv->name, seg_count, s);
+					r = 0;
+				}
+
 /* FIXME I don't think this ever holds?
 				if (seg_le(seg, s) != le) {
 					log_error("LV %s: segment %u has "

Modified: lvm2/upstream/current/lib/metadata/metadata.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/metadata.c	(original)
+++ lvm2/upstream/current/lib/metadata/metadata.c	Tue Nov 15 17:45:32 2005
@@ -14,7 +14,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
 #include "device.h"
 #include "metadata.h"
 #include "toolcontext.h"
@@ -23,19 +22,20 @@
 #include "memlock.h"
 #include "str_list.h"
 #include "pv_alloc.h"
+#include "activate.h"
 
 static int _add_pv_to_vg(struct format_instance *fid, struct volume_group *vg,
 			 const char *pv_name)
 {
 	struct pv_list *pvl;
 	struct physical_volume *pv;
-	struct pool *mem = fid->fmt->cmd->mem;
+	struct dm_pool *mem = fid->fmt->cmd->mem;
 	struct list mdas;
 
 	log_verbose("Adding physical volume '%s' to volume group '%s'",
 		    pv_name, vg->name);
 
-	if (!(pvl = pool_zalloc(mem, sizeof(*pvl)))) {
+	if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) {
 		log_error("pv_list allocation for '%s' failed", pv_name);
 		return 0;
 	}
@@ -59,7 +59,14 @@
 		return 0;
 	}
 
-	if (!(pv->vg_name = pool_strdup(mem, vg->name))) {
+	/* Ensure PV doesn't depend on another PV already in the VG */
+	if (pv_uses_vg(fid->fmt->cmd, pv, vg)) {
+		log_error("Physical volume %s might be constructed from same "
+			  "volume group %s", pv_name, vg->name);
+		return 0;
+	}
+
+	if (!(pv->vg_name = dm_pool_strdup(mem, vg->name))) {
 		log_error("vg->name allocation failed for '%s'", pv_name);
 		return 0;
 	}
@@ -168,16 +175,16 @@
 int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
 	      const char *new_name)
 {
-	struct pool *mem = cmd->mem;
+	struct dm_pool *mem = cmd->mem;
 	struct pv_list *pvl;
 
-	if (!(vg->name = pool_strdup(mem, new_name))) {
+	if (!(vg->name = dm_pool_strdup(mem, new_name))) {
 		log_error("vg->name allocation failed for '%s'", new_name);
 		return 0;
 	}
 
 	list_iterate_items(pvl, &vg->pvs) {
-		if (!(pvl->pv->vg_name = pool_strdup(mem, new_name))) {
+		if (!(pvl->pv->vg_name = dm_pool_strdup(mem, new_name))) {
 			log_error("pv->vg_name allocation failed for '%s'",
 				  dev_name(pvl->pv->dev));
 			return 0;
@@ -220,11 +227,11 @@
 			       int pv_count, char **pv_names)
 {
 	struct volume_group *vg;
-	struct pool *mem = cmd->mem;
+	struct dm_pool *mem = cmd->mem;
 	int consistent = 0;
 	int old_partial;
 
-	if (!(vg = pool_zalloc(mem, sizeof(*vg)))) {
+	if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
 		stack;
 		return NULL;
 	}
@@ -248,7 +255,7 @@
 
 	vg->cmd = cmd;
 
-	if (!(vg->name = pool_strdup(mem, vg_name))) {
+	if (!(vg->name = dm_pool_strdup(mem, vg_name))) {
 		stack;
 		goto bad;
 	}
@@ -256,7 +263,7 @@
 	vg->seqno = 0;
 
 	vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE);
-	vg->system_id = pool_alloc(mem, NAME_LEN);
+	vg->system_id = dm_pool_alloc(mem, NAME_LEN);
 	*vg->system_id = '\0';
 
 	vg->extent_size = extent_size;
@@ -298,7 +305,7 @@
 	return vg;
 
       bad:
-	pool_free(mem, vg);
+	dm_pool_free(mem, vg);
 	return NULL;
 }
 
@@ -488,8 +495,8 @@
 				  int pvmetadatacopies,
 				  uint64_t pvmetadatasize, struct list *mdas)
 {
-	struct pool *mem = fmt->cmd->mem;
-	struct physical_volume *pv = pool_alloc(mem, sizeof(*pv));
+	struct dm_pool *mem = fmt->cmd->mem;
+	struct physical_volume *pv = dm_pool_alloc(mem, sizeof(*pv));
 
 	if (!pv) {
 		stack;
@@ -506,7 +513,7 @@
 
 	pv->dev = dev;
 
-	if (!(pv->vg_name = pool_zalloc(mem, NAME_LEN))) {
+	if (!(pv->vg_name = dm_pool_zalloc(mem, NAME_LEN))) {
 		stack;
 		goto bad;
 	}
@@ -553,7 +560,7 @@
 	return pv;
 
       bad:
-	pool_free(mem, pv);
+	dm_pool_free(mem, pv);
 	return NULL;
 }
 
@@ -668,6 +675,16 @@
 	return NULL;
 }
 
+struct lv_segment *first_seg(struct logical_volume *lv)
+{
+	struct lv_segment *seg = NULL;
+
+	list_iterate_items(seg, &lv->segments)
+		break;
+
+	return seg;
+}
+
 /* Find segment at a given physical extent in a PV */
 struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe)
 {
@@ -708,7 +725,7 @@
 	}
 
 	list_iterate_items(lvl, &vg->lvs) {
-		if (!check_lv_segments(lvl->lv)) {
+		if (!check_lv_segments(lvl->lv, 1)) {
 			log_error("Internal error: LV segments corrupted in %s.",
 				  lvl->lv->name);
 			return 0;
@@ -850,7 +867,7 @@
 		return NULL;
 	}
 
-	if (!(vg = pool_zalloc(cmd->mem, sizeof(*vg)))) {
+	if (!(vg = dm_pool_zalloc(cmd->mem, sizeof(*vg)))) {
 		log_error("vg allocation failed");
 		return NULL;
 	}
@@ -858,7 +875,7 @@
 	list_init(&vg->lvs);
 	list_init(&vg->tags);
 	vg->cmd = cmd;
-	if (!(vg->name = pool_strdup(cmd->mem, ORPHAN))) {
+	if (!(vg->name = dm_pool_strdup(cmd->mem, ORPHAN))) {
 		log_error("vg name allocation failed");
 		return NULL;
 	}
@@ -867,7 +884,7 @@
 		if (!(pv = pv_read(cmd, dev_name(info->dev), NULL, NULL, 1))) {
 			continue;
 		}
-		if (!(pvl = pool_zalloc(cmd->mem, sizeof(*pvl)))) {
+		if (!(pvl = dm_pool_zalloc(cmd->mem, sizeof(*pvl)))) {
 			log_error("pv_list allocation failed");
 			return NULL;
 		}
@@ -885,6 +902,8 @@
  * If consistent is 0, caller must check whether consistent == 1 on return
  * and take appropriate action if it isn't (e.g. abort; get write lock 
  * and call vg_read again).
+ *
+ * If precommitted is set, use precommitted metadata if present.
  */
 static struct volume_group *_vg_read(struct cmd_context *cmd,
 				     const char *vgname,
@@ -895,9 +914,10 @@
 	struct volume_group *vg, *correct_vg = NULL;
 	struct metadata_area *mda;
 	int inconsistent = 0;
+	int use_precommitted = precommitted;
 
 	if (!*vgname) {
-		if (precommitted) {
+		if (use_precommitted) {
 			log_error("Internal error: vg_read requires vgname "
 				  "with pre-commit.");
 			return NULL;
@@ -923,11 +943,8 @@
 		}
 	}
 
-	if (precommitted && !(fmt->features & FMT_PRECOMMIT)) {
-		log_error("Internal error: %s doesn't support "
-			  "pre-commit", fmt->name);
-		return NULL;
-	}
+	if (use_precommitted && !(fmt->features & FMT_PRECOMMIT))
+		use_precommitted = 0;
 
 	/* create format instance with appropriate metadata area */
 	if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
@@ -937,9 +954,9 @@
 
 	/* Ensure contents of all metadata areas match - else do recovery */
 	list_iterate_items(mda, &fid->metadata_areas) {
-		if ((precommitted &&
+		if ((use_precommitted &&
 		     !(vg = mda->ops->vg_read_precommit(fid, vgname, mda))) ||
-		    (!precommitted &&
+		    (!use_precommitted &&
 		     !(vg = mda->ops->vg_read(fid, vgname, mda)))) {
 			inconsistent = 1;
 			continue;
@@ -966,11 +983,8 @@
 			return NULL;
 		}
 
-		if (precommitted && !(fmt->features & FMT_PRECOMMIT)) {
-			log_error("Internal error: %s doesn't support "
-				  "pre-commit", fmt->name);
-			return NULL;
-		}
+		if (precommitted && !(fmt->features & FMT_PRECOMMIT))
+			use_precommitted = 0;
 
 		/* create format instance with appropriate metadata area */
 		if (!(fid = fmt->ops->create_instance(fmt, vgname, NULL))) {
@@ -980,10 +994,10 @@
 
 		/* Ensure contents of all metadata areas match - else recover */
 		list_iterate_items(mda, &fid->metadata_areas) {
-			if ((precommitted &&
+			if ((use_precommitted &&
 			     !(vg = mda->ops->vg_read_precommit(fid, vgname,
 								mda))) ||
-			    (!precommitted &&
+			    (!use_precommitted &&
 			     !(vg = mda->ops->vg_read(fid, vgname, mda)))) {
 				inconsistent = 1;
 				continue;
@@ -1010,7 +1024,8 @@
 	lvmcache_update_vg(correct_vg);
 
 	if (inconsistent) {
-		if (precommitted) {
+		/* FIXME Test should be if we're *using* precommitted metadata not if we were searching for it */
+		if (use_precommitted) {
 			log_error("Inconsistent pre-commit metadata copies "
 				  "for volume group %s", vgname);
 			return NULL;
@@ -1069,7 +1084,7 @@
 	}
 
 	list_iterate_items(lvl, &vg->lvs) {
-		if (!check_lv_segments(lvl->lv)) {
+		if (!check_lv_segments(lvl->lv, 1)) {
 			log_error("Internal error: LV segments corrupted in %s.",
 				  lvl->lv->name);
 			return NULL;
@@ -1079,18 +1094,13 @@
 	return vg;
 }
 
-struct volume_group *vg_read_precommitted(struct cmd_context *cmd,
-					  const char *vgname,
-					  int *consistent)
-{
-	return _vg_read(cmd, vgname, consistent, 1);
-}
-
 /* This is only called by lv_from_lvid, which is only called from 
  * activate.c so we know the appropriate VG lock is already held and 
  * the vg_read is therefore safe.
  */
-struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid)
+static struct volume_group *_vg_read_by_vgid(struct cmd_context *cmd,
+					    const char *vgid,
+					    int precommitted)
 {
 	const char *vgname;
 	struct list *vgnames;
@@ -1102,7 +1112,8 @@
 	/* Is corresponding vgname already cached? */
 	if ((vginfo = vginfo_from_vgid(vgid)) &&
 	    vginfo->vgname && *vginfo->vgname) {
-		if ((vg = vg_read(cmd, vginfo->vgname, &consistent)) &&
+		if ((vg = _vg_read(cmd, vginfo->vgname,
+				   &consistent, precommitted)) &&
 		    !strncmp(vg->id.uuid, vgid, ID_LEN)) {
 			if (!consistent) {
 				log_error("Volume group %s metadata is "
@@ -1132,7 +1143,8 @@
 		if (!vgname || !*vgname)
 			continue;	// FIXME Unnecessary? 
 		consistent = 0;
-		if ((vg = vg_read(cmd, vgname, &consistent)) &&
+		if ((vg = _vg_read(cmd, vgname, &consistent,
+				   precommitted)) &&
 		    !strncmp(vg->id.uuid, vgid, ID_LEN)) {
 			if (!consistent) {
 				log_error("Volume group %s metadata is "
@@ -1147,7 +1159,8 @@
 }
 
 /* Only called by activate.c */
-struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s)
+struct logical_volume *lv_from_lvid(struct cmd_context *cmd, const char *lvid_s,
+				    int precommitted)
 {
 	struct lv_list *lvl;
 	struct volume_group *vg;
@@ -1156,7 +1169,7 @@
 	lvid = (const union lvid *) lvid_s;
 
 	log_very_verbose("Finding volume group for uuid %s", lvid_s);
-	if (!(vg = vg_read_by_vgid(cmd, lvid->id[0].uuid))) {
+	if (!(vg = _vg_read_by_vgid(cmd, lvid->id[0].uuid, precommitted))) {
 		log_error("Volume group for uuid not found: %s", lvid_s);
 		return NULL;
 	}
@@ -1200,7 +1213,7 @@
 	if (label_sector && *label_sector)
 		*label_sector = label->sector;
 
-	if (!(pv = pool_zalloc(cmd->mem, sizeof(*pv)))) {
+	if (!(pv = dm_pool_zalloc(cmd->mem, sizeof(*pv)))) {
 		log_error("pv allocation for '%s' failed", pv_name);
 		return NULL;
 	}
@@ -1246,7 +1259,7 @@
 
 	lvmcache_label_scan(cmd, 0);
 
-	if (!(results = pool_alloc(cmd->mem, sizeof(*results)))) {
+	if (!(results = dm_pool_alloc(cmd->mem, sizeof(*results)))) {
 		log_error("PV list allocation failed");
 		return NULL;
 	}

Modified: lvm2/upstream/current/lib/metadata/metadata.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/metadata.h	(original)
+++ lvm2/upstream/current/lib/metadata/metadata.h	Tue Nov 15 17:45:32 2005
@@ -57,6 +57,8 @@
 #define VIRTUAL			0x00010000	/* LV - internal use only */
 #define MIRROR_LOG		0x00020000	/* LV */
 #define MIRROR_IMAGE		0x00040000	/* LV */
+#define ACTIVATE_EXCL		0x00080000	/* LV - internal use only */
+#define PRECOMMITTED		0x00100000	/* VG - internal use only */
 
 #define LVM_READ              	0x00000100	/* LV VG */
 #define LVM_WRITE             	0x00000200	/* LV VG */
@@ -71,6 +73,7 @@
 #define FMT_RESTRICTED_LVIDS	0x00000010	/* LVID <= 255 */
 #define FMT_ORPHAN_ALLOCATABLE	0x00000020	/* Orphan PV allocatable? */
 #define FMT_PRECOMMIT		0x00000040	/* Supports pre-commit? */
+#define FMT_RESIZE_PV		0x00000080	/* Supports pvresize? */
 
 typedef enum {
 	ALLOC_INVALID,
@@ -180,6 +183,7 @@
 struct format_instance {
 	const struct format_type *fmt;
 	struct list metadata_areas;	/* e.g. metadata locations */
+	void *private;
 };
 
 struct volume_group {
@@ -213,6 +217,20 @@
 	struct list tags;
 };
 
+/* There will be one area for each stripe */
+struct lv_segment_area {
+	area_type_t type;
+	union {
+		struct {
+			struct pv_segment *pvseg;
+		} pv;
+		struct {
+			struct logical_volume *lv;
+			uint32_t le;
+		} lv;
+	} u;
+};
+
 struct segment_type;
 struct lv_segment {
 	struct list list;
@@ -235,31 +253,20 @@
 	uint32_t region_size;	/* For mirrors - in sectors */
 	uint32_t extents_copied;
 	struct logical_volume *log_lv;
+	struct lv_segment *mirror_seg;
 
 	struct list tags;
 
-	/* There will be one area for each stripe */
-	struct {
-		area_type_t type;
-		union {
-			struct {
-				struct pv_segment *pvseg;
-			} pv;
-			struct {
-				struct logical_volume *lv;
-				uint32_t le;
-			} lv;
-		} u;
-	} area[0];
-};
-
-#define seg_type(seg, s)	(seg)->area[(s)].type
-#define seg_pvseg(seg, s)	(seg)->area[(s)].u.pv.pvseg
-#define seg_pv(seg, s)		(seg)->area[(s)].u.pv.pvseg->pv
-#define seg_dev(seg, s)		(seg)->area[(s)].u.pv.pvseg->pv->dev
-#define seg_pe(seg, s)		(seg)->area[(s)].u.pv.pvseg->pe
-#define seg_lv(seg, s)		(seg)->area[(s)].u.lv.lv
-#define seg_le(seg, s)		(seg)->area[(s)].u.lv.le
+	struct lv_segment_area *areas;
+};
+
+#define seg_type(seg, s)	(seg)->areas[(s)].type
+#define seg_pvseg(seg, s)	(seg)->areas[(s)].u.pv.pvseg
+#define seg_pv(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pv
+#define seg_dev(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pv->dev
+#define seg_pe(seg, s)		(seg)->areas[(s)].u.pv.pvseg->pe
+#define seg_lv(seg, s)		(seg)->areas[(s)].u.lv.lv
+#define seg_le(seg, s)		(seg)->areas[(s)].u.lv.le
 
 struct logical_volume {
 	union lvid lvid;
@@ -397,10 +404,6 @@
 int vg_revert(struct volume_group *vg);
 struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name,
 			     int *consistent);
-struct volume_group *vg_read_precommitted(struct cmd_context *cmd,
-					  const char *vg_name,
-					  int *consistent);
-struct volume_group *vg_read_by_vgid(struct cmd_context *cmd, const char *vgid);
 struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
 				struct list *mdas, uint64_t *label_sector,
 				int warnings);
@@ -423,6 +426,8 @@
 				  uint32_t existing_extent_size,
 				  int pvmetadatacopies,
 				  uint64_t pvmetadatasize, struct list *mdas);
+int pv_resize(struct physical_volume *pv, struct volume_group *vg,
+              uint32_t new_pe_count);
 
 struct volume_group *vg_create(struct cmd_context *cmd, const char *name,
 			       uint32_t extent_size, uint32_t max_pv,
@@ -486,7 +491,8 @@
 
 /* Find LV with given lvid (used during activation) */
 struct logical_volume *lv_from_lvid(struct cmd_context *cmd,
-				    const char *lvid_s);
+				    const char *lvid_s,
+				    int precommitted);
 
 /* FIXME Merge these functions with ones above */
 struct physical_volume *find_pv(struct volume_group *vg, struct device *dev);
@@ -496,6 +502,7 @@
 
 /* Find LV segment containing given LE */
 struct lv_segment *find_seg_by_le(struct logical_volume *lv, uint32_t le);
+struct lv_segment *first_seg(struct logical_volume *lv);
 
 /* Find PV segment containing given LE */
 struct pv_segment *find_peg_by_pe(struct physical_volume *pv, uint32_t pe);
@@ -507,8 +514,9 @@
 
 /*
  * Checks that an lv has no gaps or overlapping segments.
+ * Set complete_vg to perform additional VG level checks.
  */
-int check_lv_segments(struct logical_volume *lv);
+int check_lv_segments(struct logical_volume *lv, int complete_vg);
 
 /*
  * Sometimes (eg, after an lvextend), it is possible to merge two
@@ -543,6 +551,8 @@
  * Mirroring functions
  */
 struct alloc_handle;
+uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
+                                     uint32_t region_size);
 int create_mirror_layers(struct alloc_handle *ah,
 			 uint32_t first_area,
 			 uint32_t num_mirrors,
@@ -553,6 +563,11 @@
 			 struct logical_volume *log_lv);
 int remove_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors);
 int remove_all_mirror_images(struct logical_volume *lv);
+/*
+ * Given mirror image or mirror log segment, find corresponding mirror segment 
+ */
+struct lv_segment *find_mirror_seg(struct lv_segment *seg);
+int fixup_imported_mirrors(struct volume_group *vg);
 
 int insert_pvmove_mirrors(struct cmd_context *cmd,
 			  struct logical_volume *lv_mirr,

Modified: lvm2/upstream/current/lib/metadata/mirror.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/mirror.c	(original)
+++ lvm2/upstream/current/lib/metadata/mirror.c	Tue Nov 15 17:45:32 2005
@@ -22,6 +22,50 @@
 #include "lv_alloc.h"
 #include "lvm-string.h"
 
+struct lv_segment *find_mirror_seg(struct lv_segment *seg)
+{
+	return seg->mirror_seg;
+}
+
+/*
+ * Ensure region size is compatible with volume size.
+ */
+uint32_t adjusted_mirror_region_size(uint32_t extent_size, uint32_t extents,
+				     uint32_t region_size)
+{
+	uint32_t region_max;
+
+	region_max = (1 << (ffs(extents) - 1)) * extent_size;
+
+	if (region_max < region_size) {
+		region_size = region_max;
+		log_print("Using reduced mirror region size of %" PRIu32
+			  " sectors", region_max);
+		return region_max;
+	}
+
+	return region_size;
+}
+
+static void _move_lv_segments(struct logical_volume *lv_to, struct logical_volume *lv_from)
+{
+	struct lv_segment *seg;
+
+	lv_to->segments = lv_from->segments;
+	lv_to->segments.n->p = &lv_to->segments;
+	lv_to->segments.p->n = &lv_to->segments;
+
+	list_iterate_items(seg, &lv_to->segments)
+		seg->lv = lv_to;
+
+/* FIXME set or reset seg->mirror_seg (according to status)? */
+
+	list_init(&lv_from->segments);
+
+	lv_from->le_count = 0;
+	lv_from->size = 0;
+}
+
 /*
  * Reduce mirrored_seg to num_mirrors images.
  */
@@ -43,31 +87,25 @@
 
 int remove_all_mirror_images(struct logical_volume *lv)
 {
-	struct lv_segment *first_seg, *seg;
+	struct lv_segment *seg;
 	struct logical_volume *lv1;
 
-	list_iterate_items(first_seg, &lv->segments)
-		break;
+	seg = first_seg(lv);
 
-	if (!remove_mirror_images(first_seg, 1)) {
+	if (!remove_mirror_images(seg, 1)) {
 		stack;
 		return 0;
 	}
 
-	if (!lv_remove(first_seg->log_lv)) {
+	if (seg->log_lv && !lv_remove(seg->log_lv)) {
 		stack;
 		return 0;
 	}
 
-	lv1 = seg_lv(first_seg, 0);
+	lv1 = seg_lv(seg, 0);
+
+	_move_lv_segments(lv, lv1);
 
-	lv->segments = lv1->segments;
-	lv->segments.n->p = &lv->segments;
-	lv->segments.p->n = &lv->segments;
-
-	list_init(&lv1->segments);
-	lv1->le_count = 0;
-	lv1->size = 0;
 	if (!lv_remove(lv1)) {
 		stack;
 		return 0;
@@ -75,9 +113,6 @@
 
 	lv->status &= ~MIRRORED;
 
-	list_iterate_items(seg, &lv->segments)
-		seg->lv = lv;
-
 	return 1;
 }
 
@@ -93,26 +128,17 @@
 }
 */
 
-int create_mirror_layers(struct alloc_handle *ah,
-			 uint32_t first_area,
-			 uint32_t num_mirrors,
-			 struct logical_volume *lv,
-			 struct segment_type *segtype,
-			 uint32_t status,
-			 uint32_t region_size,
-			 struct logical_volume *log_lv)
+static int _create_layers_for_mirror(struct alloc_handle *ah,
+				     uint32_t first_area,
+				     uint32_t num_mirrors,
+				     struct logical_volume *lv,
+				     struct segment_type *segtype,
+				     struct logical_volume **img_lvs)
 {
 	uint32_t m;
-	struct logical_volume **img_lvs;
 	char *img_name;
 	size_t len;
 	
-	if (!(img_lvs = alloca(sizeof(*img_lvs) * num_mirrors))) {
-		log_error("img_lvs allocation failed. "
-			  "Remove new LV and retry.");
-		return 0;
-	}
-
 	len = strlen(lv->name) + 32;
 	if (!(img_name = alloca(len))) {
 		log_error("img_name allocation failed. "
@@ -129,8 +155,8 @@
 	for (m = 0; m < num_mirrors; m++) {
 		if (!(img_lvs[m] = lv_create_empty(lv->vg->fid, img_name,
 					     NULL, LVM_READ | LVM_WRITE,
-					     ALLOC_INHERIT, 0, lv->vg))) {\
-			log_error("Aborting. Failed to create submirror LV. "
+					     ALLOC_INHERIT, 0, lv->vg))) {
+			log_error("Aborting. Failed to create mirror image LV. "
 				  "Remove new LV and retry.");
 			return 0;
 		}
@@ -139,13 +165,48 @@
 				    get_segtype_from_string(lv->vg->cmd,
 							    "striped"),
 				    0, NULL, 0, 0, 0, NULL)) {
-			log_error("Aborting. Failed to add submirror segment "
+			log_error("Aborting. Failed to add mirror image segment "
 				  "to %s. Remove new LV and retry.",
 				  img_lvs[m]->name);
 			return 0;
 		}
 	}
 
+	return 1;
+}
+
+int create_mirror_layers(struct alloc_handle *ah,
+			 uint32_t first_area,
+			 uint32_t num_mirrors,
+			 struct logical_volume *lv,
+			 struct segment_type *segtype,
+			 uint32_t status,
+			 uint32_t region_size,
+			 struct logical_volume *log_lv)
+{
+	struct logical_volume **img_lvs;
+	
+	if (!(img_lvs = alloca(sizeof(*img_lvs) * num_mirrors))) {
+		log_error("img_lvs allocation failed. "
+			  "Remove new LV and retry.");
+		return 0;
+	}
+
+	if (!_create_layers_for_mirror(ah, first_area, num_mirrors, lv,
+				       segtype, img_lvs)) {
+		stack;
+		return 0;
+	}
+
+	/* Already got the parent mirror segment? */
+	if (lv->status & MIRRORED)
+		return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors,
+						  MIRROR_IMAGE);
+
+	/* Already got a non-mirrored area to be converted? */
+	if (first_area)
+		_move_lv_segments(img_lvs[0], lv);
+
 	if (!lv_add_mirror_segment(ah, lv, img_lvs, num_mirrors, segtype,
 				   0, region_size, log_lv)) {
 		log_error("Aborting. Failed to add mirror segment. "
@@ -153,6 +214,8 @@
 		return 0;
 	}
 
+	lv->status |= MIRRORED;
+
 	return 1;
 }
 
@@ -263,7 +326,7 @@
 
 				/* First time, add LV to list of LVs affected */
 				if (!lv_used) {
-					if (!(lvl = pool_alloc(cmd->mem, sizeof(*lvl)))) {
+					if (!(lvl = dm_pool_alloc(cmd->mem, sizeof(*lvl)))) {
 						log_error("lv_list alloc failed");
 						return 0;
 					}
@@ -475,7 +538,7 @@
 	struct lv_segment *seg;
 	uint32_t s;
 
-	if (!(lvs = pool_alloc(cmd->mem, sizeof(*lvs)))) {
+	if (!(lvs = dm_pool_alloc(cmd->mem, sizeof(*lvs)))) {
 		log_error("lvs list alloc failed");
 		return NULL;
 	}
@@ -494,7 +557,7 @@
 				if (seg_type(seg, s) != AREA_LV ||
 				    seg_lv(seg, s) != lv)
 					continue;
-				if (!(lvl = pool_alloc(cmd->mem, sizeof(*lvl)))) {
+				if (!(lvl = dm_pool_alloc(cmd->mem, sizeof(*lvl)))) {
 					log_error("lv_list alloc failed");
 					return NULL;
 				}
@@ -526,3 +589,31 @@
 
 	return denominator ? (float) numerator *100 / denominator : 100.0;
 }
+
+/*
+ * Fixup mirror pointers after single-pass segment import
+ */
+int fixup_imported_mirrors(struct volume_group *vg)
+{
+	struct lv_list *lvl;
+	struct lv_segment *seg;
+	uint32_t s;
+
+	list_iterate_items(lvl, &vg->lvs) {
+		list_iterate_items(seg, &lvl->lv->segments) {
+			if (seg->segtype !=
+			    get_segtype_from_string(vg->cmd, "mirror"))
+				continue;
+
+			if (seg->log_lv)
+				first_seg(seg->log_lv)->mirror_seg = seg;
+			for (s = 0; s < seg->area_count; s++)
+				if (seg_type(seg, s) == AREA_LV)
+					first_seg(seg_lv(seg, s))->mirror_seg
+					    = seg;
+		}
+	}
+
+	return 1;
+}
+

Modified: lvm2/upstream/current/lib/metadata/pv_alloc.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/pv_alloc.h	(original)
+++ lvm2/upstream/current/lib/metadata/pv_alloc.h	Tue Nov 15 17:45:32 2005
@@ -13,10 +13,9 @@
  */
 
 #ifndef _LVM_PV_ALLOC_H
-#include "pool.h"
 
-int alloc_pv_segment_whole_pv(struct pool *mem, struct physical_volume *pv);
-int peg_dup(struct pool *mem, struct list *peg_new, struct list *peg_old);
+int alloc_pv_segment_whole_pv(struct dm_pool *mem, struct physical_volume *pv);
+int peg_dup(struct dm_pool *mem, struct list *peg_new, struct list *peg_old);
 struct pv_segment *assign_peg_to_lvseg(struct physical_volume *pv, uint32_t pe,
 				       uint32_t area_len,
 				       struct lv_segment *seg,

Modified: lvm2/upstream/current/lib/metadata/pv_manip.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/pv_manip.c	(original)
+++ lvm2/upstream/current/lib/metadata/pv_manip.c	Tue Nov 15 17:45:32 2005
@@ -14,12 +14,11 @@
  */
 
 #include "lib.h"
-#include "pool.h"
 #include "metadata.h"
 #include "pv_alloc.h"
 #include "toolcontext.h"
 
-static struct pv_segment *_alloc_pv_segment(struct pool *mem,
+static struct pv_segment *_alloc_pv_segment(struct dm_pool *mem,
 					    struct physical_volume *pv,
 					    uint32_t pe, uint32_t len,
 					    struct lv_segment *lvseg,
@@ -27,7 +26,7 @@
 {
 	struct pv_segment *peg;
 
-	if (!(peg = pool_zalloc(mem, sizeof(*peg)))) {
+	if (!(peg = dm_pool_zalloc(mem, sizeof(*peg)))) {
 		log_error("pv_segment allocation failed");
 		return NULL;
 	}
@@ -43,7 +42,7 @@
 	return peg;
 }
 
-int alloc_pv_segment_whole_pv(struct pool *mem, struct physical_volume *pv)
+int alloc_pv_segment_whole_pv(struct dm_pool *mem, struct physical_volume *pv)
 {
 	struct pv_segment *peg;
 
@@ -61,7 +60,7 @@
 	return 1;
 }
 
-int peg_dup(struct pool *mem, struct list *peg_new, struct list *peg_old)
+int peg_dup(struct dm_pool *mem, struct list *peg_new, struct list *peg_old)
 {
 	struct pv_segment *peg, *pego;
 
@@ -302,3 +301,98 @@
 
 	return ret;
 }
+
+static int _reduce_pv(struct physical_volume *pv, struct volume_group *vg, uint32_t new_pe_count)
+{
+	struct pv_segment *peg, *pegt;
+	uint32_t old_pe_count = pv->pe_count;
+
+	if (new_pe_count < pv->pe_alloc_count) {
+		log_error("%s: cannot resize to %" PRIu32 " extents "
+			  "as %" PRIu32 " are allocated.",
+			  dev_name(pv->dev), new_pe_count,
+			  pv->pe_alloc_count);
+		return 0;
+	}
+
+	/* Check PEs to be removed are not already allocated */
+	list_iterate_items(peg, &pv->segments) {
+ 		if (peg->pe + peg->len <= new_pe_count)
+			continue;
+
+		if (peg->lvseg) {
+			log_error("%s: cannot resize to %" PRIu32 " extents as "
+				  "later ones are allocated.",
+				  dev_name(pv->dev), new_pe_count);
+			return 0;
+		}
+	}
+
+	if (!pv_split_segment(pv, new_pe_count)) {
+		stack;
+		return 0;
+	}
+
+	list_iterate_items_safe(peg, pegt, &pv->segments) {
+ 		if (peg->pe + peg->len > new_pe_count)
+			list_del(&peg->list);
+	}
+
+	pv->pe_count = new_pe_count;
+
+	vg->extent_count -= (old_pe_count - new_pe_count);
+	vg->free_count -= (old_pe_count - new_pe_count);
+
+	return 1;
+}
+
+static int _extend_pv(struct physical_volume *pv, struct volume_group *vg,
+		      uint32_t new_pe_count)
+{
+	struct pv_segment *peg;
+	uint32_t old_pe_count = pv->pe_count;
+
+	if ((uint64_t) new_pe_count * pv->pe_size > pv->size ) {
+		log_error("%s: cannot resize to %" PRIu32 " extents as there "
+			  "is only room for %" PRIu64 ".", dev_name(pv->dev),
+			  new_pe_count, pv->size / pv->pe_size);
+		return 0;
+	}
+
+	peg = _alloc_pv_segment(pv->fmt->cmd->mem, pv,
+				old_pe_count,
+				new_pe_count - old_pe_count,
+				NULL, 0);
+	list_add(&pv->segments, &peg->list);
+
+	pv->pe_count = new_pe_count;
+
+	vg->extent_count += (new_pe_count - old_pe_count);
+	vg->free_count += (new_pe_count - old_pe_count);
+
+	return 1;
+}
+
+/*
+ * Resize a PV in a VG, adding or removing segments as needed.
+ * New size must fit within pv->size.
+ */
+int pv_resize(struct physical_volume *pv,
+	      struct volume_group *vg,
+	      uint32_t new_pe_count)
+{
+	if ((new_pe_count == pv->pe_count)) {
+		log_verbose("No change to size of physical volume %s.",
+			    dev_name(pv->dev));
+		return 1;
+	}
+
+	log_verbose("Resizing physical volume %s from %" PRIu32
+		    " to %" PRIu32 " extents.",
+		    dev_name(pv->dev), pv->pe_count, new_pe_count);
+
+	if (new_pe_count > pv->pe_count)
+		return _extend_pv(pv, vg, new_pe_count);
+	else
+		return _reduce_pv(pv, vg, new_pe_count);
+}

Modified: lvm2/upstream/current/lib/metadata/pv_map.c
==============================================================================
--- lvm2/upstream/current/lib/metadata/pv_map.c	(original)
+++ lvm2/upstream/current/lib/metadata/pv_map.c	Tue Nov 15 17:45:32 2005
@@ -15,7 +15,6 @@
 
 #include "lib.h"
 #include "pv_map.h"
-#include "hash.h"
 #include "pv_alloc.h"
 
 /*
@@ -33,12 +32,12 @@
 	list_add(&pva->list, &a->list);
 }
 
-static int _create_single_area(struct pool *mem, struct pv_map *pvm,
+static int _create_single_area(struct dm_pool *mem, struct pv_map *pvm,
 			       uint32_t start, uint32_t length)
 {
 	struct pv_area *pva;
 
-	if (!(pva = pool_zalloc(mem, sizeof(*pva)))) {
+	if (!(pva = dm_pool_zalloc(mem, sizeof(*pva)))) {
 		stack;
 		return 0;
 	}
@@ -53,7 +52,7 @@
 	return 1;
 }
 
-static int _create_alloc_areas_for_pv(struct pool *mem, struct pv_map *pvm,
+static int _create_alloc_areas_for_pv(struct dm_pool *mem, struct pv_map *pvm,
 				      uint32_t start, uint32_t count)
 {
         struct pv_segment *peg;
@@ -98,7 +97,7 @@
 	return 1;
 }
 
-static int _create_all_areas_for_pv(struct pool *mem, struct pv_map *pvm,
+static int _create_all_areas_for_pv(struct dm_pool *mem, struct pv_map *pvm,
 				    struct list *pe_ranges)
 {
 	struct pe_range *aa;
@@ -125,7 +124,7 @@
 	return 1;
 }
 
-static int _create_maps(struct pool *mem, struct list *pvs, struct list *pvms)
+static int _create_maps(struct dm_pool *mem, struct list *pvs, struct list *pvms)
 {
 	struct pv_map *pvm;
 	struct pv_list *pvl;
@@ -134,7 +133,7 @@
 		if (!(pvl->pv->status & ALLOCATABLE_PV))
 			continue;
 
-		if (!(pvm = pool_zalloc(mem, sizeof(*pvm)))) {
+		if (!(pvm = dm_pool_zalloc(mem, sizeof(*pvm)))) {
 			stack;
 			return 0;
 		}
@@ -156,12 +155,12 @@
 /*
  * Create list of PV areas available for this particular allocation
  */
-struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
+struct list *create_pv_maps(struct dm_pool *mem, struct volume_group *vg,
 			    struct list *allocatable_pvs)
 {
 	struct list *pvms;
 
-	if (!(pvms = pool_zalloc(mem, sizeof(*pvms)))) {
+	if (!(pvms = dm_pool_zalloc(mem, sizeof(*pvms)))) {
 		log_error("create_pv_maps alloc failed");
 		return NULL;
 	}
@@ -171,7 +170,7 @@
 	if (!_create_maps(mem, allocatable_pvs, pvms)) {
 		log_error("Couldn't create physical volume maps in %s",
 			  vg->name);
-		pool_free(mem, pvms);
+		dm_pool_free(mem, pvms);
 		return NULL;
 	}
 

Modified: lvm2/upstream/current/lib/metadata/pv_map.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/pv_map.h	(original)
+++ lvm2/upstream/current/lib/metadata/pv_map.h	Tue Nov 15 17:45:32 2005
@@ -17,8 +17,6 @@
 #define _LVM_PV_MAP_H
 
 #include "metadata.h"
-#include "bitset.h"
-#include "pool.h"
 
 /*
  * The in core rep. only stores a mapping from
@@ -46,7 +44,7 @@
 /*
  * Find intersection between available_pvs and free space in VG
  */
-struct list *create_pv_maps(struct pool *mem, struct volume_group *vg,
+struct list *create_pv_maps(struct dm_pool *mem, struct volume_group *vg,
 			    struct list *allocatable_pvs);
 
 void consume_pv_area(struct pv_area *area, uint32_t to_go);

Modified: lvm2/upstream/current/lib/metadata/segtype.h
==============================================================================
--- lvm2/upstream/current/lib/metadata/segtype.h	(original)
+++ lvm2/upstream/current/lib/metadata/segtype.h	Tue Nov 15 17:45:32 2005
@@ -22,7 +22,6 @@
 struct lv_segment;
 struct formatter;
 struct config_node;
-struct hash_table;
 struct dev_manager;
 
 /* Feature flags */
@@ -32,12 +31,14 @@
 #define SEG_SNAPSHOT		0x00000008
 #define SEG_FORMAT1_SUPPORT	0x00000010
 #define SEG_VIRTUAL		0x00000020
+#define SEG_CANNOT_BE_ZEROED	0x00000040
 
 #define seg_is_mirrored(seg)	((seg)->segtype->flags & SEG_AREAS_MIRRORED ? 1 : 0)
 #define seg_is_striped(seg)	((seg)->segtype->flags & SEG_AREAS_STRIPED ? 1 : 0)
 #define seg_is_snapshot(seg)	((seg)->segtype->flags & SEG_SNAPSHOT ? 1 : 0)
 #define seg_is_virtual(seg)	((seg)->segtype->flags & SEG_VIRTUAL ? 1 : 0)
 #define seg_can_split(seg)	((seg)->segtype->flags & SEG_CAN_SPLIT ? 1 : 0)
+#define seg_cannot_be_zeroed(seg) ((seg)->segtype->flags & SEG_CANNOT_BE_ZEROED ? 1 : 0)
 
 #define segtype_is_striped(segtype)	((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0)
 #define segtype_is_mirrored(segtype)	((segtype)->flags & SEG_AREAS_MIRRORED ? 1 : 0)
@@ -62,16 +63,15 @@
 				       uint32_t *area_count);
 	int (*text_import) (struct lv_segment * seg,
 			    const struct config_node * sn,
-			    struct hash_table * pv_hash);
+			    struct dm_hash_table * pv_hash);
 	int (*merge_segments) (struct lv_segment * seg1,
 			       struct lv_segment * seg2);
-	int (*compose_target_line) (struct dev_manager * dm, struct pool * mem,
-				    struct config_tree * cft,
-				    void **target_state,
-				    struct lv_segment * seg, char *params,
-				    size_t paramsize, const char **target,
-				    int *pos, uint32_t *pvmove_mirror_count);
-	int (*target_percent) (void **target_state, struct pool * mem,
+	int (*add_target_line) (struct dev_manager *dm, struct dm_pool *mem,
+                                struct config_tree *cft, void **target_state,
+                                struct lv_segment *seg,
+                                struct dm_tree_node *node, uint64_t len,
+                                uint32_t *pvmove_mirror_count);
+	int (*target_percent) (void **target_state, struct dm_pool * mem,
 			       struct config_tree * cft,
 			       struct lv_segment * seg, char *params,
 			       uint64_t *total_numerator,

Modified: lvm2/upstream/current/lib/mirror/mirrored.c
==============================================================================
--- lvm2/upstream/current/lib/mirror/mirrored.c	(original)
+++ lvm2/upstream/current/lib/mirror/mirrored.c	Tue Nov 15 17:45:32 2005
@@ -14,8 +14,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
-#include "list.h"
 #include "toolcontext.h"
 #include "metadata.h"
 #include "segtype.h"
@@ -46,6 +44,7 @@
 static void _display(const struct lv_segment *seg)
 {
 	const char *size;
+	uint32_t s;
 
 	log_print("  Mirrors\t\t%u", seg->area_count);
 	log_print("  Mirror size\t\t%u", seg->area_len);
@@ -61,8 +60,9 @@
 
 	log_print("  Mirror original:");
 	display_stripe(seg, 0, "    ");
-	log_print("  Mirror destination:");
-	display_stripe(seg, 1, "    ");
+	log_print("  Mirror destinations:");
+	for (s = 1; s < seg->area_count; s++)
+		display_stripe(seg, s, "    ");
 	log_print(" ");
 }
 
@@ -78,7 +78,7 @@
 }
 
 static int _text_import(struct lv_segment *seg, const struct config_node *sn,
-			struct hash_table *pv_hash)
+			struct dm_hash_table *pv_hash)
 {
 	const struct config_node *cn;
 	char *logname = NULL;
@@ -147,12 +147,12 @@
 }
 
 #ifdef DEVMAPPER_SUPPORT
-static struct mirror_state *_init_target(struct pool *mem,
+static struct mirror_state *_init_target(struct dm_pool *mem,
 					 struct config_tree *cft)
 {
 	struct mirror_state *mirr_state;
 
-	if (!(mirr_state = pool_alloc(mem, sizeof(*mirr_state)))) {
+	if (!(mirr_state = dm_pool_alloc(mem, sizeof(*mirr_state)))) {
 		log_error("struct mirr_state allocation failed");
 		return NULL;
 	}
@@ -165,26 +165,104 @@
 	return mirr_state;
 }
 
-static int _compose_target_line(struct dev_manager *dm, struct pool *mem,
-				struct config_tree *cft, void **target_state,
-				struct lv_segment *seg, char *params,
-				size_t paramsize, const char **target, int *pos,
-				uint32_t *pvmove_mirror_count)
+static int _target_percent(void **target_state, struct dm_pool *mem,
+			   struct config_tree *cft, struct lv_segment *seg,
+			   char *params, uint64_t *total_numerator,
+			   uint64_t *total_denominator, float *percent)
 {
 	struct mirror_state *mirr_state;
-	int mirror_status = MIRR_RUNNING;
-	int areas = seg->area_count;
+	uint64_t numerator, denominator;
+	unsigned mirror_count, m;
+	int used;
+	char *pos = params;
+
+	if (!*target_state)
+		*target_state = _init_target(mem, cft);
+
+	mirr_state = *target_state;
+
+	/* Status line: <#mirrors> (maj:min)+ <synced>/<total_regions> */
+	log_debug("Mirror status: %s", params);
+
+	if (sscanf(pos, "%u %n", &mirror_count, &used) != 1) {
+		log_error("Failure parsing mirror status mirror count: %s",
+			  params);
+		return 0;
+	}
+	pos += used;
+
+	for (m = 0; m < mirror_count; m++) {
+		if (sscanf(pos, "%*x:%*x %n", &used) != 0) {
+			log_error("Failure parsing mirror status devices: %s",
+				  params);
+			return 0;
+		}
+		pos += used;
+	}
+
+	if (sscanf(pos, "%" PRIu64 "/%" PRIu64 "%n", &numerator, &denominator,
+		   &used) != 2) {
+		log_error("Failure parsing mirror status fraction: %s", params);
+		return 0;
+	}
+	pos += used;
+
+	*total_numerator += numerator;
+	*total_denominator += denominator;
+
+	if (seg)
+		seg->extents_copied = seg->area_len * numerator / denominator;
+
+	return 1;
+}
+
+static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
+		    struct dm_tree_node *node, uint32_t area_count, uint32_t region_size)
+{
+	unsigned clustered = 0;
+	char *log_dlid = NULL;
+
+	/*
+	 * Use clustered mirror log for non-exclusive activation 
+	 * in clustered VG.
+	 */
+	if ((!(seg->lv->status & ACTIVATE_EXCL) &&
+	      (seg->lv->vg->status & CLUSTERED)))
+		clustered = 1;
+
+	if (seg->log_lv &&
+	    !(log_dlid = build_dlid(dm, seg->log_lv->lvid.s, NULL))) {
+		log_error("Failed to build uuid for log LV %s.",
+			  seg->log_lv->name);
+		return 0;
+	}
+
+	/* FIXME Add sync parm? */
+	return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count);
+}
+
+static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
+                                struct config_tree *cft, void **target_state,
+                                struct lv_segment *seg,
+                                struct dm_tree_node *node, uint64_t len,
+                                uint32_t *pvmove_mirror_count)
+{
+	struct mirror_state *mirr_state;
+	uint32_t area_count = seg->area_count;
 	int start_area = 0u;
+	int mirror_status = MIRR_RUNNING;
 	uint32_t region_size, region_max;
-	int ret;
+	int r;
 
 	if (!*target_state)
 		*target_state = _init_target(mem, cft);
 
 	mirr_state = *target_state;
 
-	/*   mirror  log_type #log_params [log_params]* 
-	 *           #mirrors [device offset]+
+	/*
+	 * For pvmove, only have one mirror segment RUNNING at once.
+	 * Segments before this are COMPLETED and use 2nd area.
+	 * Segments after this are DISABLED and use 1st area.
 	 */
 	if (seg->status & PVMOVE) {
 		if (seg->extents_copied == seg->area_len) {
@@ -192,71 +270,46 @@
 			start_area = 1;
 		} else if ((*pvmove_mirror_count)++) {
 			mirror_status = MIRR_DISABLED;
-			areas = 1;
+			area_count = 1;
 		}
+		/* else MIRR_RUNNING */
 	}
 
 	if (mirror_status != MIRR_RUNNING) {
-		*target = "linear";
-	} else {
-		*target = "mirror";
+		if (!dm_tree_node_add_linear_target(node, len))
+			return_0;
+		goto done;
+	}
 
-		if (!(seg->status & PVMOVE)) {
-			if (!seg->region_size) {
-				log_error("Missing region size for mirror segment.");
-				return 0;
-			}
-			region_size = seg->region_size;
-		} else {
-			/* Find largest power of 2 region size unit we can use */
-			region_max = (1 << (ffs(seg->area_len) - 1)) *
-			      seg->lv->vg->extent_size;
-
-			region_size = mirr_state->default_region_size;
-			if (region_max < region_size) {
-				region_size = region_max;
-				log_verbose("Using reduced mirror region size of %u sectors",
-					    region_size);
-			}
+	if (!(seg->status & PVMOVE)) {
+		if (!seg->region_size) {
+			log_error("Missing region size for mirror segment.");
+			return 0;
 		}
-
-		if ((ret = compose_log_line(dm, seg, params, paramsize, pos,
-					    areas, region_size)) <= 0) {
-			stack;
-			return ret;
+		region_size = seg->region_size;
+	} else {
+		/* Find largest power of 2 region size unit we can use */
+		region_max = (1 << (ffs(seg->area_len) - 1)) *
+		      seg->lv->vg->extent_size;
+
+		region_size = mirr_state->default_region_size;
+		if (region_max < region_size) {
+			region_size = region_max;
+			log_verbose("Using reduced mirror region size of %u sectors",
+				    region_size);
 		}
 	}
 
-	return compose_areas_line(dm, seg, params, paramsize, pos, start_area,
-				  areas);
-}
+	if (!dm_tree_node_add_mirror_target(node, len))
+		return_0;
 
-static int _target_percent(void **target_state, struct pool *mem,
-			   struct config_tree *cft, struct lv_segment *seg,
-			   char *params, uint64_t *total_numerator,
-			   uint64_t *total_denominator, float *percent)
-{
-	struct mirror_state *mirr_state;
-	uint64_t numerator, denominator;
-
-	if (!*target_state)
-		*target_state = _init_target(mem, cft);
-
-	mirr_state = *target_state;
-
-	log_debug("Mirror status: %s", params);
-	if (sscanf(params, "%*d %*x:%*x %*x:%*x %" PRIu64
-		   "/%" PRIu64, &numerator, &denominator) != 2) {
-		log_error("Failure parsing mirror status: %s", params);
-		return 0;
+	if ((r = _add_log(dm, seg, node, area_count, region_size)) <= 0) {
+		stack;
+		return r;
 	}
-	*total_numerator += numerator;
-	*total_denominator += denominator;
 
-	if (seg)
-		seg->extents_copied = seg->area_len * numerator / denominator;
-
-	return 1;
+      done:
+	return add_areas_line(dm, seg, node, start_area, area_count);
 }
 
 static int _target_present(void)
@@ -265,7 +318,7 @@
 	static int present = 0;
 
 	if (!checked)
-		present = target_present("mirror");
+		present = target_present("mirror", 1);
 
 	checked = 1;
 
@@ -275,7 +328,7 @@
 
 static void _destroy(const struct segment_type *segtype)
 {
-	dbg_free((void *) segtype);
+	dm_free((void *) segtype);
 }
 
 static struct segtype_handler _mirrored_ops = {
@@ -285,7 +338,7 @@
 	text_import:_text_import,
 	text_export:_text_export,
 #ifdef DEVMAPPER_SUPPORT
-	compose_target_line:_compose_target_line,
+	add_target_line:_add_target_line,
 	target_percent:_target_percent,
 	target_present:_target_present,
 #endif
@@ -299,7 +352,7 @@
 struct segment_type *init_segtype(struct cmd_context *cmd)
 #endif
 {
-	struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
+	struct segment_type *segtype = dm_malloc(sizeof(*segtype));
 
 	if (!segtype) {
 		stack;

Modified: lvm2/upstream/current/lib/misc/lib.h
==============================================================================
--- lvm2/upstream/current/lib/misc/lib.h	(original)
+++ lvm2/upstream/current/lib/misc/lib.h	Tue Nov 15 17:45:32 2005
@@ -24,7 +24,9 @@
 #define _FILE_OFFSET_BITS 64
 
 #include "log.h"
-#include "dbg_malloc.h"
 #include "intl.h"
+#include "lvm-types.h"
+
+#include <libdevmapper.h>
 
 #endif

Added: lvm2/upstream/current/lib/misc/lvm-exec.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/misc/lvm-exec.c	Tue Nov 15 17:45:32 2005
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "lib.h"
+#include "lvm-exec.h"
+
+#include <unistd.h>
+#include <sys/wait.h>
+
+/*
+ * Execute and wait for external command
+ */
+int exec_cmd(const char *command, const char *fscmd, const char *lv_path,
+	     const char *size)
+{
+	pid_t pid;
+	int status;
+
+	log_verbose("Executing: %s %s %s %s", command, fscmd, lv_path, size);
+
+	if ((pid = fork()) == -1) {
+		log_error("fork failed: %s", strerror(errno));
+		return 0;
+	}
+
+	if (!pid) {
+		/* Child */
+		/* FIXME Use execve directly */
+		execlp(command, command, fscmd, lv_path, size, NULL);
+		log_sys_error("execlp", command);
+		exit(errno);
+	}
+
+	/* Parent */
+	if (wait4(pid, &status, 0, NULL) != pid) {
+		log_error("wait4 child process %u failed: %s", pid,
+			  strerror(errno));
+		return 0;
+	}
+
+	if (!WIFEXITED(status)) {
+		log_error("Child %u exited abnormally", pid);
+		return 0;
+	}
+
+	if (WEXITSTATUS(status)) {
+		log_error("%s failed: %u", command, WEXITSTATUS(status));
+		return 0;
+	}
+
+	return 1;
+}

Added: lvm2/upstream/current/lib/misc/lvm-exec.h
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/lib/misc/lvm-exec.h	Tue Nov 15 17:45:32 2005
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "lib.h"
+
+int exec_cmd(const char *command, const char *fscmd, const char *lv_path,
+	     const char *size);

Modified: lvm2/upstream/current/lib/misc/lvm-file.c
==============================================================================
--- lvm2/upstream/current/lib/misc/lvm-file.c	(original)
+++ lvm2/upstream/current/lib/misc/lvm-file.c	Tue Nov 15 17:45:32 2005
@@ -146,7 +146,7 @@
 
 	log_verbose("Creating directory \"%s\"", dir);
 	/* Create parent directories */
-	orig = s = dbg_strdup(dir);
+	orig = s = dm_strdup(dir);
 	while ((s = strchr(s, '/')) != NULL) {
 		*s = '\0';
 		if (*orig) {
@@ -154,13 +154,13 @@
 			if (rc < 0 && errno != EEXIST) {
 				if (errno != EROFS)
 					log_sys_error("mkdir", orig);
-				dbg_free(orig);
+				dm_free(orig);
 				return 0;
 			}
 		}
 		*s++ = '/';
 	}
-	dbg_free(orig);
+	dm_free(orig);
 
 	/* Create final directory */
 	rc = mkdir(dir, 0777);
@@ -215,7 +215,7 @@
 	int fd;
 	char *dir, *c;
 
-	if (!(dir = dbg_strdup(file))) {
+	if (!(dir = dm_strdup(file))) {
 		log_error("sync_dir failed in strdup");
 		return;
 	}
@@ -236,11 +236,11 @@
 		goto out;
 	}
 
-	if (fsync(fd) == -1)
+	if (fsync(fd) && (errno != EROFS) && (errno != EINVAL))
 		log_sys_error("fsync", dir);
 
 	close(fd);
 
       out:
-	dbg_free(dir);
+	dm_free(dir);
 }

Modified: lvm2/upstream/current/lib/misc/lvm-string.c
==============================================================================
--- lvm2/upstream/current/lib/misc/lvm-string.c	(original)
+++ lvm2/upstream/current/lib/misc/lvm-string.c	Tue Nov 15 17:45:32 2005
@@ -16,7 +16,6 @@
 #include "lib.h"
 #include "lvm-types.h"
 #include "lvm-string.h"
-#include "pool.h"
 
 #include <ctype.h>
 
@@ -131,15 +130,15 @@
 /*
  * <vg>-<lv>-<layer> or if !layer just <vg>-<lv>.
  */
-char *build_dm_name(struct pool *mem, const char *vg,
-		    const char *lv, const char *layer)
+char *build_dm_name(struct dm_pool *mem, const char *vgname,
+		    const char *lvname, const char *layer)
 {
 	size_t len = 1;
 	int hyphens = 1;
 	char *r, *out;
 
-	_count_hyphens(vg, &len, &hyphens);
-	_count_hyphens(lv, &len, &hyphens);
+	_count_hyphens(vgname, &len, &hyphens);
+	_count_hyphens(lvname, &len, &hyphens);
 
 	if (layer && *layer) {
 		_count_hyphens(layer, &len, &hyphens);
@@ -148,15 +147,16 @@
 
 	len += hyphens;
 
-	if (!(r = pool_alloc(mem, len))) {
-		stack;
+	if (!(r = dm_pool_alloc(mem, len))) {
+		log_error("build_dm_name: Allocation failed for %" PRIsize_t
+			  " for %s %s %s.", len, vgname, lvname, layer);
 		return NULL;
 	}
 
 	out = r;
-	_quote_hyphens(&out, vg);
+	_quote_hyphens(&out, vgname);
 	*out++ = '-';
-	_quote_hyphens(&out, lv);
+	_quote_hyphens(&out, lvname);
 
 	if (layer && *layer) {
 		*out++ = '-';
@@ -175,6 +175,7 @@
 {
 	char *c = component;
 	char *o = c;
+	char *r;
 
 	while (*c) {
 		if (*(c + 1)) {
@@ -190,14 +191,16 @@
 		c++;
 	}
 
+	r = (*c) ? c + 1 : c;
 	*o = '\0';
-	return (c + 1);
+
+	return r;
 }
 
-int split_dm_name(struct pool *mem, const char *dmname,
+int split_dm_name(struct dm_pool *mem, const char *dmname,
 		  char **vgname, char **lvname, char **layer)
 {
-	if (!(*vgname = pool_strdup(mem, dmname)))
+	if (!(*vgname = dm_pool_strdup(mem, dmname)))
 		return 0;
 
 	_unquote(*layer = _unquote(*lvname = _unquote(*vgname)));

Modified: lvm2/upstream/current/lib/misc/lvm-string.h
==============================================================================
--- lvm2/upstream/current/lib/misc/lvm-string.h	(original)
+++ lvm2/upstream/current/lib/misc/lvm-string.h	Tue Nov 15 17:45:32 2005
@@ -34,10 +34,10 @@
 
 int split_words(char *buffer, unsigned max, char **argv);
 
-char *build_dm_name(struct pool *mem, const char *vg,
+char *build_dm_name(struct dm_pool *mem, const char *vg,
                     const char *lv, const char *layer);
 
-int split_dm_name(struct pool *mem, const char *dmname,
+int split_dm_name(struct dm_pool *mem, const char *dmname,
                   char **vgname, char **lvname, char **layer);
 
 #endif

Modified: lvm2/upstream/current/lib/misc/sharedlib.c
==============================================================================
--- lvm2/upstream/current/lib/misc/sharedlib.c	(original)
+++ lvm2/upstream/current/lib/misc/sharedlib.c	Tue Nov 15 17:45:32 2005
@@ -22,21 +22,28 @@
 #include <sys/stat.h>
 #include <dlfcn.h>
 
-void *load_shared_library(struct config_tree *cft, const char *libname,
-			  const char *desc)
+static void _get_library_path(struct config_tree *cft, const char *libname,
+			      char *path, int path_len)
 {
-	char path[PATH_MAX];
 	struct stat info;
 	const char *lib_dir;
-	void *library;
 
 	/* If libname doesn't begin with '/' then use lib_dir/libname,
 	 * if present */
 	if (libname[0] == '/' ||
 	    !(lib_dir = find_config_str(cft->root, "global/library_dir", 0)) ||
-	    (lvm_snprintf(path, sizeof(path), "%s/%s", lib_dir,
+	    (lvm_snprintf(path, path_len, "%s/%s", lib_dir,
 			  libname) == -1) || stat(path, &info) == -1)
-		strncpy(path, libname, sizeof(path));
+		strncpy(path, libname, path_len);
+}
+
+void *load_shared_library(struct config_tree *cft, const char *libname,
+			  const char *desc)
+{
+	char path[PATH_MAX];
+	void *library;
+
+	_get_library_path(cft, libname, path, sizeof(path));
 
 	log_very_verbose("Opening shared %s library %s", desc, path);
 

Modified: lvm2/upstream/current/lib/mm/memlock.c
==============================================================================
--- lvm2/upstream/current/lib/mm/memlock.c	(original)
+++ lvm2/upstream/current/lib/mm/memlock.c	Tue Nov 15 17:45:32 2005
@@ -15,7 +15,6 @@
 
 #include "lib.h"
 #include "memlock.h"
-#include "pool.h"
 #include "defaults.h"
 #include "config.h"
 #include "toolcontext.h"

Modified: lvm2/upstream/current/lib/regex/matcher.c
==============================================================================
--- lvm2/upstream/current/lib/regex/matcher.c	(original)
+++ lvm2/upstream/current/lib/regex/matcher.c	Tue Nov 15 17:45:32 2005
@@ -17,7 +17,6 @@
 #include "matcher.h"
 #include "parse_rx.h"
 #include "ttree.h"
-#include "bitset.h"
 
 struct dfa_state {
 	int final;
@@ -26,7 +25,7 @@
 
 struct state_queue {
 	struct dfa_state *s;
-	bitset_t bits;
+	dm_bitset_t bits;
 	struct state_queue *next;
 };
 
@@ -35,7 +34,7 @@
 	unsigned num_nodes;
 	int nodes_entered;
 	struct rx_node **nodes;
-	struct pool *scratch, *mem;
+	struct dm_pool *scratch, *mem;
 };
 
 #define TARGET_TRANS '\0'
@@ -72,9 +71,9 @@
 
 	for (i = 0; i < m->num_nodes; i++) {
 		struct rx_node *n = m->nodes[i];
-		n->firstpos = bitset_create(m->scratch, m->num_nodes);
-		n->lastpos = bitset_create(m->scratch, m->num_nodes);
-		n->followpos = bitset_create(m->scratch, m->num_nodes);
+		n->firstpos = dm_bitset_create(m->scratch, m->num_nodes);
+		n->lastpos = dm_bitset_create(m->scratch, m->num_nodes);
+		n->followpos = dm_bitset_create(m->scratch, m->num_nodes);
 	}
 }
 
@@ -88,48 +87,48 @@
 		c1 = rx->left;
 		c2 = rx->right;
 
-		if (bit(rx->charset, TARGET_TRANS))
+		if (dm_bit(rx->charset, TARGET_TRANS))
 			rx->final = final++;
 
 		switch (rx->type) {
 		case CAT:
 			if (c1->nullable)
-				bit_union(rx->firstpos,
+				dm_bit_union(rx->firstpos,
 					  c1->firstpos, c2->firstpos);
 			else
-				bit_copy(rx->firstpos, c1->firstpos);
+				dm_bit_copy(rx->firstpos, c1->firstpos);
 
 			if (c2->nullable)
-				bit_union(rx->lastpos,
+				dm_bit_union(rx->lastpos,
 					  c1->lastpos, c2->lastpos);
 			else
-				bit_copy(rx->lastpos, c2->lastpos);
+				dm_bit_copy(rx->lastpos, c2->lastpos);
 
 			rx->nullable = c1->nullable && c2->nullable;
 			break;
 
 		case PLUS:
-			bit_copy(rx->firstpos, c1->firstpos);
-			bit_copy(rx->lastpos, c1->lastpos);
+			dm_bit_copy(rx->firstpos, c1->firstpos);
+			dm_bit_copy(rx->lastpos, c1->lastpos);
 			rx->nullable = c1->nullable;
 			break;
 
 		case OR:
-			bit_union(rx->firstpos, c1->firstpos, c2->firstpos);
-			bit_union(rx->lastpos, c1->lastpos, c2->lastpos);
+			dm_bit_union(rx->firstpos, c1->firstpos, c2->firstpos);
+			dm_bit_union(rx->lastpos, c1->lastpos, c2->lastpos);
 			rx->nullable = c1->nullable || c2->nullable;
 			break;
 
 		case QUEST:
 		case STAR:
-			bit_copy(rx->firstpos, c1->firstpos);
-			bit_copy(rx->lastpos, c1->lastpos);
+			dm_bit_copy(rx->firstpos, c1->firstpos);
+			dm_bit_copy(rx->lastpos, c1->lastpos);
 			rx->nullable = 1;
 			break;
 
 		case CHARSET:
-			bit_set(rx->firstpos, i);
-			bit_set(rx->lastpos, i);
+			dm_bit_set(rx->firstpos, i);
+			dm_bit_set(rx->lastpos, i);
 			rx->nullable = 0;
 			break;
 
@@ -145,9 +144,9 @@
 		switch (rx->type) {
 		case CAT:
 			for (j = 0; j < m->num_nodes; j++) {
-				if (bit(c1->lastpos, j)) {
+				if (dm_bit(c1->lastpos, j)) {
 					struct rx_node *n = m->nodes[j];
-					bit_union(n->followpos,
+					dm_bit_union(n->followpos,
 						  n->followpos, c2->firstpos);
 				}
 			}
@@ -156,9 +155,9 @@
 		case PLUS:
 		case STAR:
 			for (j = 0; j < m->num_nodes; j++) {
-				if (bit(rx->lastpos, j)) {
+				if (dm_bit(rx->lastpos, j)) {
 					struct rx_node *n = m->nodes[j];
-					bit_union(n->followpos,
+					dm_bit_union(n->followpos,
 						  n->followpos, rx->firstpos);
 				}
 			}
@@ -167,16 +166,16 @@
 	}
 }
 
-static inline struct dfa_state *_create_dfa_state(struct pool *mem)
+static inline struct dfa_state *_create_dfa_state(struct dm_pool *mem)
 {
-	return pool_zalloc(mem, sizeof(struct dfa_state));
+	return dm_pool_zalloc(mem, sizeof(struct dfa_state));
 }
 
-static struct state_queue *_create_state_queue(struct pool *mem,
+static struct state_queue *_create_state_queue(struct dm_pool *mem,
 					       struct dfa_state *dfa,
-					       bitset_t bits)
+					       dm_bitset_t bits)
 {
-	struct state_queue *r = pool_alloc(mem, sizeof(*r));
+	struct state_queue *r = dm_pool_alloc(mem, sizeof(*r));
 
 	if (!r) {
 		stack;
@@ -184,20 +183,20 @@
 	}
 
 	r->s = dfa;
-	r->bits = bitset_create(mem, bits[0]);	/* first element is the size */
-	bit_copy(r->bits, bits);
+	r->bits = dm_bitset_create(mem, bits[0]);	/* first element is the size */
+	dm_bit_copy(r->bits, bits);
 	r->next = 0;
 	return r;
 }
 
 static int _calc_states(struct matcher *m, struct rx_node *rx)
 {
-	unsigned iwidth = (m->num_nodes / BITS_PER_INT) + 1;
+	unsigned iwidth = (m->num_nodes / DM_BITS_PER_INT) + 1;
 	struct ttree *tt = ttree_create(m->scratch, iwidth);
 	struct state_queue *h, *t, *tmp;
 	struct dfa_state *dfa, *ldfa;
 	int i, a, set_bits = 0, count = 0;
-	bitset_t bs = bitset_create(m->scratch, m->num_nodes), dfa_bits;
+	dm_bitset_t bs = dm_bitset_create(m->scratch, m->num_nodes), dfa_bits;
 
 	if (!tt) {
 		stack;
@@ -223,16 +222,16 @@
 		h = h->next;
 
 		/* iterate through all the inputs for this state */
-		bit_clear_all(bs);
+		dm_bit_clear_all(bs);
 		for (a = 0; a < 256; a++) {
 			/* iterate through all the states in firstpos */
-			for (i = bit_get_first(dfa_bits);
-			     i >= 0; i = bit_get_next(dfa_bits, i)) {
-				if (bit(m->nodes[i]->charset, a)) {
+			for (i = dm_bit_get_first(dfa_bits);
+			     i >= 0; i = dm_bit_get_next(dfa_bits, i)) {
+				if (dm_bit(m->nodes[i]->charset, a)) {
 					if (a == TARGET_TRANS)
 						dfa->final = m->nodes[i]->final;
 
-					bit_union(bs, bs,
+					dm_bit_union(bs, bs,
 						  m->nodes[i]->followpos);
 					set_bits = 1;
 				}
@@ -259,7 +258,7 @@
 
 				dfa->lookup[a] = ldfa;
 				set_bits = 0;
-				bit_clear_all(bs);
+				dm_bit_clear_all(bs);
 			}
 		}
 	}
@@ -268,14 +267,14 @@
 	return 1;
 }
 
-struct matcher *matcher_create(struct pool *mem, const char **patterns,
+struct matcher *matcher_create(struct dm_pool *mem, const char **patterns,
 			       unsigned num)
 {
 	char *all, *ptr;
 	int i;
 	size_t len = 0;
 	struct rx_node *rx;
-	struct pool *scratch = pool_create("regex matcher", 10 * 1024);
+	struct dm_pool *scratch = dm_pool_create("regex matcher", 10 * 1024);
 	struct matcher *m;
 
 	if (!scratch) {
@@ -283,7 +282,7 @@
 		return NULL;
 	}
 
-	if (!(m = pool_alloc(mem, sizeof(*m)))) {
+	if (!(m = dm_pool_alloc(mem, sizeof(*m)))) {
 		stack;
 		return NULL;
 	}
@@ -294,7 +293,7 @@
 	for (i = 0; i < num; i++)
 		len += strlen(patterns[i]) + 8;
 
-	ptr = all = pool_alloc(scratch, len + 1);
+	ptr = all = dm_pool_alloc(scratch, len + 1);
 
 	if (!all) {
 		stack;
@@ -316,7 +315,7 @@
 	m->mem = mem;
 	m->scratch = scratch;
 	m->num_nodes = _count_nodes(rx);
-	m->nodes = pool_alloc(scratch, sizeof(*m->nodes) * m->num_nodes);
+	m->nodes = dm_pool_alloc(scratch, sizeof(*m->nodes) * m->num_nodes);
 
 	if (!m->nodes) {
 		stack;
@@ -327,14 +326,14 @@
 	_create_bitsets(m);
 	_calc_functions(m);
 	_calc_states(m, rx);
-	pool_destroy(scratch);
+	dm_pool_destroy(scratch);
 	m->scratch = NULL;
 
 	return m;
 
       bad:
-	pool_destroy(scratch);
-	pool_destroy(mem);
+	dm_pool_destroy(scratch);
+	dm_pool_destroy(mem);
 	return NULL;
 }
 

Modified: lvm2/upstream/current/lib/regex/matcher.h
==============================================================================
--- lvm2/upstream/current/lib/regex/matcher.h	(original)
+++ lvm2/upstream/current/lib/regex/matcher.h	Tue Nov 15 17:45:32 2005
@@ -16,10 +16,8 @@
 #ifndef _LVM_MATCHER_H
 #define _LVM_MATCHER_H
 
-#include "pool.h"
-
 struct matcher;
-struct matcher *matcher_create(struct pool *mem, const char **patterns,
+struct matcher *matcher_create(struct dm_pool *mem, const char **patterns,
 			       unsigned num);
 
 int matcher_run(struct matcher *m, const char *begin);

Modified: lvm2/upstream/current/lib/regex/parse_rx.c
==============================================================================
--- lvm2/upstream/current/lib/regex/parse_rx.c	(original)
+++ lvm2/upstream/current/lib/regex/parse_rx.c	Tue Nov 15 17:45:32 2005
@@ -15,12 +15,11 @@
 
 #include "lib.h"
 #include "parse_rx.h"
-#include "bitset.h"
 
 struct parse_sp {		/* scratch pad for the parsing process */
-	struct pool *mem;
+	struct dm_pool *mem;
 	int type;		/* token type, 0 indicates a charset */
-	bitset_t charset;	/* The current charset */
+	dm_bitset_t charset;	/* The current charset */
 	const char *cursor;	/* where we are in the regex */
 	const char *rx_end;	/* 1pte for the expression being parsed */
 };
@@ -31,8 +30,8 @@
 {
 	ps->type = 0;
 	ps->cursor = ptr + 1;
-	bit_clear_all(ps->charset);
-	bit_set(ps->charset, c);
+	dm_bit_clear_all(ps->charset);
+	dm_bit_set(ps->charset, c);
 }
 
 /*
@@ -54,15 +53,15 @@
 	case '[':
 		ptr++;
 		if (*ptr == '^') {
-			bit_set_all(ps->charset);
+			dm_bit_set_all(ps->charset);
 
 			/* never transition on zero */
-			bit_clear(ps->charset, 0);
+			dm_bit_clear(ps->charset, 0);
 			neg = 1;
 			ptr++;
 
 		} else
-			bit_clear_all(ps->charset);
+			dm_bit_clear_all(ps->charset);
 
 		while ((ptr < ps->rx_end) && (*ptr != ']')) {
 			if (*ptr == '\\') {
@@ -104,17 +103,17 @@
 
 				for (; lc <= c; lc++) {
 					if (neg)
-						bit_clear(ps->charset, lc);
+						dm_bit_clear(ps->charset, lc);
 					else
-						bit_set(ps->charset, lc);
+						dm_bit_set(ps->charset, lc);
 				}
 				range = 0;
 			} else {
 				/* add c into the bitset */
 				if (neg)
-					bit_clear(ps->charset, c);
+					dm_bit_clear(ps->charset, c);
 				else
-					bit_set(ps->charset, c);
+					dm_bit_set(ps->charset, c);
 			}
 			ptr++;
 			lc = c;
@@ -154,10 +153,10 @@
 		/* The 'all but newline' character set */
 		ps->type = 0;
 		ps->cursor = ptr + 1;
-		bit_set_all(ps->charset);
-		bit_clear(ps->charset, (int) '\n');
-		bit_clear(ps->charset, (int) '\r');
-		bit_clear(ps->charset, 0);
+		dm_bit_set_all(ps->charset);
+		dm_bit_clear(ps->charset, (int) '\n');
+		dm_bit_clear(ps->charset, (int) '\r');
+		dm_bit_clear(ps->charset, 0);
 		break;
 
 	case '\\':
@@ -172,19 +171,19 @@
 
 		ps->type = 0;
 		ps->cursor = ptr + 1;
-		bit_clear_all(ps->charset);
+		dm_bit_clear_all(ps->charset);
 		switch (*ptr) {
 		case 'n':
-			bit_set(ps->charset, (int) '\n');
+			dm_bit_set(ps->charset, (int) '\n');
 			break;
 		case 'r':
-			bit_set(ps->charset, (int) '\r');
+			dm_bit_set(ps->charset, (int) '\r');
 			break;
 		case 't':
-			bit_set(ps->charset, (int) '\t');
+			dm_bit_set(ps->charset, (int) '\t');
 			break;
 		default:
-			bit_set(ps->charset, (int) *ptr);
+			dm_bit_set(ps->charset, (int) *ptr);
 		}
 		break;
 
@@ -192,22 +191,22 @@
 		/* add a single character to the bitset */
 		ps->type = 0;
 		ps->cursor = ptr + 1;
-		bit_clear_all(ps->charset);
-		bit_set(ps->charset, (int) *ptr);
+		dm_bit_clear_all(ps->charset);
+		dm_bit_set(ps->charset, (int) *ptr);
 		break;
 	}
 
 	return 1;
 }
 
-static struct rx_node *_node(struct pool *mem, int type,
+static struct rx_node *_node(struct dm_pool *mem, int type,
 			     struct rx_node *l, struct rx_node *r)
 {
-	struct rx_node *n = pool_zalloc(mem, sizeof(*n));
+	struct rx_node *n = dm_pool_zalloc(mem, sizeof(*n));
 
 	if (n) {
-		if (!(n->charset = bitset_create(mem, 256))) {
-			pool_free(mem, n);
+		if (!(n->charset = dm_bitset_create(mem, 256))) {
+			dm_pool_free(mem, n);
 			return NULL;
 		}
 
@@ -230,7 +229,7 @@
 			return NULL;
 		}
 
-		bit_copy(n->charset, ps->charset);
+		dm_bit_copy(n->charset, ps->charset);
 		_get_token(ps);	/* match charset */
 		break;
 
@@ -330,11 +329,11 @@
 	return n;
 }
 
-struct rx_node *rx_parse_tok(struct pool *mem,
+struct rx_node *rx_parse_tok(struct dm_pool *mem,
 			     const char *begin, const char *end)
 {
 	struct rx_node *r;
-	struct parse_sp *ps = pool_zalloc(mem, sizeof(*ps));
+	struct parse_sp *ps = dm_pool_zalloc(mem, sizeof(*ps));
 
 	if (!ps) {
 		stack;
@@ -342,20 +341,20 @@
 	}
 
 	ps->mem = mem;
-	ps->charset = bitset_create(mem, 256);
+	ps->charset = dm_bitset_create(mem, 256);
 	ps->cursor = begin;
 	ps->rx_end = end;
 	_get_token(ps);		/* load the first token */
 
 	if (!(r = _or_term(ps))) {
 		log_error("Parse error in regex");
-		pool_free(mem, ps);
+		dm_pool_free(mem, ps);
 	}
 
 	return r;
 }
 
-struct rx_node *rx_parse_str(struct pool *mem, const char *str)
+struct rx_node *rx_parse_str(struct dm_pool *mem, const char *str)
 {
 	return rx_parse_tok(mem, str, str + strlen(str));
 }

Modified: lvm2/upstream/current/lib/regex/parse_rx.h
==============================================================================
--- lvm2/upstream/current/lib/regex/parse_rx.h	(original)
+++ lvm2/upstream/current/lib/regex/parse_rx.h	Tue Nov 15 17:45:32 2005
@@ -16,8 +16,6 @@
 #ifndef _LVM_PARSE_REGEX_H
 #define _LVM_PARSE_REGEX_H
 
-#include "bitset.h"
-
 enum {
 	CAT,
 	STAR,
@@ -37,18 +35,18 @@
 
 struct rx_node {
 	int type;
-	bitset_t charset;
+	dm_bitset_t charset;
 	struct rx_node *left, *right;
 
 	/* used to build the dfa for the toker */
 	int nullable, final;
-	bitset_t firstpos;
-	bitset_t lastpos;
-	bitset_t followpos;
+	dm_bitset_t firstpos;
+	dm_bitset_t lastpos;
+	dm_bitset_t followpos;
 };
 
-struct rx_node *rx_parse_str(struct pool *mem, const char *str);
-struct rx_node *rx_parse_tok(struct pool *mem,
+struct rx_node *rx_parse_str(struct dm_pool *mem, const char *str);
+struct rx_node *rx_parse_tok(struct dm_pool *mem,
 			     const char *begin, const char *end);
 
 #endif

Modified: lvm2/upstream/current/lib/regex/ttree.c
==============================================================================
--- lvm2/upstream/current/lib/regex/ttree.c	(original)
+++ lvm2/upstream/current/lib/regex/ttree.c	Tue Nov 15 17:45:32 2005
@@ -15,7 +15,6 @@
 
 #include "lib.h"
 #include "ttree.h"
-#include "pool.h"
 
 struct node {
 	unsigned k;
@@ -25,7 +24,7 @@
 
 struct ttree {
 	int klen;
-	struct pool *mem;
+	struct dm_pool *mem;
 	struct node *root;
 };
 
@@ -60,9 +59,9 @@
 	return *c ? (*c)->data : NULL;
 }
 
-static struct node *_node(struct pool *mem, unsigned int k)
+static struct node *_node(struct dm_pool *mem, unsigned int k)
 {
-	struct node *n = pool_zalloc(mem, sizeof(*n));
+	struct node *n = dm_pool_zalloc(mem, sizeof(*n));
 
 	if (n)
 		n->k = k;
@@ -103,11 +102,11 @@
 	return 1;
 }
 
-struct ttree *ttree_create(struct pool *mem, unsigned int klen)
+struct ttree *ttree_create(struct dm_pool *mem, unsigned int klen)
 {
 	struct ttree *tt;
 
-	if (!(tt = pool_zalloc(mem, sizeof(*tt)))) {
+	if (!(tt = dm_pool_zalloc(mem, sizeof(*tt)))) {
 		stack;
 		return NULL;
 	}

Modified: lvm2/upstream/current/lib/regex/ttree.h
==============================================================================
--- lvm2/upstream/current/lib/regex/ttree.h	(original)
+++ lvm2/upstream/current/lib/regex/ttree.h	Tue Nov 15 17:45:32 2005
@@ -16,11 +16,9 @@
 #ifndef _LVM_TTREE_H
 #define _LVM_TTREE_H
 
-#include "pool.h"
-
 struct ttree;
 
-struct ttree *ttree_create(struct pool *mem, unsigned int klen);
+struct ttree *ttree_create(struct dm_pool *mem, unsigned int klen);
 
 void *ttree_lookup(struct ttree *tt, unsigned *key);
 int ttree_insert(struct ttree *tt, unsigned *key, void *data);

Modified: lvm2/upstream/current/lib/report/columns.h
==============================================================================
--- lvm2/upstream/current/lib/report/columns.h	(original)
+++ lvm2/upstream/current/lib/report/columns.h	Tue Nov 15 17:45:32 2005
@@ -38,6 +38,7 @@
 FIELD(PVS, pv, STR, "PV UUID", id, 38, uuid, "pv_uuid")
 FIELD(PVS, pv, NUM, "PSize", id, 5, pvsize, "pv_size")
 FIELD(PVS, pv, NUM, "DevSize", dev, 7, devsize, "dev_size")
+FIELD(PVS, pv, NUM, "1st PE", pe_start, 7, size64, "pe_start")
 FIELD(PVS, pv, NUM, "PFree", id, 5, pvfree, "pv_free")
 FIELD(PVS, pv, NUM, "Used", id, 4, pvused, "pv_used")
 FIELD(PVS, pv, STR, "PV", dev, 10, dev_name, "pv_name")
@@ -67,7 +68,7 @@
 FIELD(SEGS, seg, STR, "Type", list, 4, segtype, "segtype")
 FIELD(SEGS, seg, NUM, "#Str", area_count, 4, uint32, "stripes")
 FIELD(SEGS, seg, NUM, "Stripe", stripe_size, 6, size32, "stripesize")
-FIELD(SEGS, seg, NUM, "Chunk", chunk_size, 5, size32, "chunksize")
+FIELD(SEGS, seg, NUM, "Chunk", list, 5, chunksize, "chunksize")
 FIELD(SEGS, seg, NUM, "Region", region_size, 6, size32, "regionsize")
 FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, "seg_start")
 FIELD(SEGS, seg, NUM, "SSize", list, 5, segsize, "seg_size")

Modified: lvm2/upstream/current/lib/report/report.c
==============================================================================
--- lvm2/upstream/current/lib/report/report.c	(original)
+++ lvm2/upstream/current/lib/report/report.c	Tue Nov 15 17:45:32 2005
@@ -17,7 +17,6 @@
 #include "metadata.h"
 #include "report.h"
 #include "toolcontext.h"
-#include "pool.h"
 #include "lvm-string.h"
 #include "display.h"
 #include "activate.h"
@@ -45,7 +44,7 @@
 
 struct report_handle {
 	struct cmd_context *cmd;
-	struct pool *mem;
+	struct dm_pool *mem;
 
 	report_type_t type;
 	const char *field_prefix;
@@ -121,8 +120,8 @@
 {
 	if (!
 	    (field->report_string =
-	     pool_strdup(rh->mem, *(const char **) data))) {
-		log_error("pool_strdup failed");
+	     dm_pool_strdup(rh->mem, *(const char **) data))) {
+		log_error("dm_pool_strdup failed");
 		return 0;
 	}
 
@@ -144,12 +143,12 @@
 {
 	const struct lv_segment *seg = (const struct lv_segment *) data;
 	unsigned int s;
-	const char *name;
-	uint32_t extent;
+	const char *name = NULL;
+	uint32_t extent = 0;
 	char extent_str[32];
 
-	if (!pool_begin_object(rh->mem, 256)) {
-		log_error("pool_begin_object failed");
+	if (!dm_pool_begin_object(rh->mem, 256)) {
+		log_error("dm_pool_begin_object failed");
 		return 0;
 	}
 
@@ -168,8 +167,8 @@
 			extent = 0;
 		}
 
-		if (!pool_grow_object(rh->mem, name, strlen(name))) {
-			log_error("pool_grow_object failed");
+		if (!dm_pool_grow_object(rh->mem, name, strlen(name))) {
+			log_error("dm_pool_grow_object failed");
 			return 0;
 		}
 
@@ -179,24 +178,24 @@
 			return 0;
 		}
 
-		if (!pool_grow_object(rh->mem, extent_str, strlen(extent_str))) {
-			log_error("pool_grow_object failed");
+		if (!dm_pool_grow_object(rh->mem, extent_str, strlen(extent_str))) {
+			log_error("dm_pool_grow_object failed");
 			return 0;
 		}
 
 		if ((s != seg->area_count - 1) &&
-		    !pool_grow_object(rh->mem, ",", 1)) {
-			log_error("pool_grow_object failed");
+		    !dm_pool_grow_object(rh->mem, ",", 1)) {
+			log_error("dm_pool_grow_object failed");
 			return 0;
 		}
 	}
 
-	if (!pool_grow_object(rh->mem, "\0", 1)) {
-		log_error("pool_grow_object failed");
+	if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
+		log_error("dm_pool_grow_object failed");
 		return 0;
 	}
 
-	field->report_string = pool_end_object(rh->mem);
+	field->report_string = dm_pool_end_object(rh->mem);
 	field->sort_value = (const void *) field->report_string;
 
 	return 1;
@@ -207,25 +206,25 @@
 	const struct list *tags = (const struct list *) data;
 	struct str_list *sl;
 
-	if (!pool_begin_object(rh->mem, 256)) {
-		log_error("pool_begin_object failed");
+	if (!dm_pool_begin_object(rh->mem, 256)) {
+		log_error("dm_pool_begin_object failed");
 		return 0;
 	}
 
 	list_iterate_items(sl, tags) {
-		if (!pool_grow_object(rh->mem, sl->str, strlen(sl->str)) ||
-		    (sl->list.n != tags && !pool_grow_object(rh->mem, ",", 1))) {
-			log_error("pool_grow_object failed");
+		if (!dm_pool_grow_object(rh->mem, sl->str, strlen(sl->str)) ||
+		    (sl->list.n != tags && !dm_pool_grow_object(rh->mem, ",", 1))) {
+			log_error("dm_pool_grow_object failed");
 			return 0;
 		}
 	}
 
-	if (!pool_grow_object(rh->mem, "\0", 1)) {
-		log_error("pool_grow_object failed");
+	if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
+		log_error("dm_pool_grow_object failed");
 		return 0;
 	}
 
-	field->report_string = pool_end_object(rh->mem);
+	field->report_string = dm_pool_end_object(rh->mem);
 	field->sort_value = (const void *) field->report_string;
 
 	return 1;
@@ -267,13 +266,13 @@
 	uint64_t *sortval;
 	char *repstr;
 
-	if (!(repstr = pool_zalloc(rh->mem, 13))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, 13))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
-	if (!(sortval = pool_alloc(rh->mem, sizeof(int64_t)))) {
-		log_error("pool_alloc failed");
+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(int64_t)))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -296,7 +295,7 @@
 	struct lvinfo info;
 	uint64_t minusone = UINT64_C(-1);
 
-	if (lv_info(lv, &info, 0) && info.exists)
+	if (lv_info(lv->vg->cmd, lv, &info, 0) && info.exists)
 		return _int_disp(rh, field, &info.major);
 	else
 		return _int_disp(rh, field, &minusone);
@@ -311,7 +310,7 @@
 	struct lvinfo info;
 	uint64_t minusone = UINT64_C(-1);
 
-	if (lv_info(lv, &info, 0) && info.exists)
+	if (lv_info(lv->vg->cmd, lv, &info, 0) && info.exists)
 		return _int_disp(rh, field, &info.minor);
 	else
 		return _int_disp(rh, field, &minusone);
@@ -328,8 +327,8 @@
 	struct lv_segment *snap_seg;
 	float snap_percent;
 
-	if (!(repstr = pool_zalloc(rh->mem, 7))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, 7))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -367,27 +366,31 @@
 	else
 		repstr[3] = '-';
 
-	if (lv_info(lv, &info, 1) && info.exists) {
+	if (lv_info(lv->vg->cmd, lv, &info, 1) && info.exists) {
 		if (info.suspended)
 			repstr[4] = 's';	/* Suspended */
-		else
+		else if (info.live_table)
 			repstr[4] = 'a';	/* Active */
-		if (info.open_count)
-			repstr[5] = 'o';	/* Open */
+		else if (info.inactive_table)
+			repstr[4] = 'i';	/* Inactive with table */
 		else
-			repstr[5] = '-';
+			repstr[4] = 'd';	/* Inactive without table */
 
 		/* Snapshot dropped? */
-		if ((snap_seg = find_cow(lv)) &&
+		if (info.live_table && (snap_seg = find_cow(lv)) &&
 		    (!lv_snapshot_percent(snap_seg->cow, &snap_percent) ||
 		     snap_percent < 0 || snap_percent >= 100)) {
 			repstr[0] = toupper(repstr[0]);
 			if (info.suspended)
-				repstr[4] = 'S';
+				repstr[4] = 'S'; /* Susp Inv snapshot */
 			else
-				repstr[4] = 'I';
+				repstr[4] = 'I'; /* Invalid snapshot */
 		}
 
+		if (info.open_count)
+			repstr[5] = 'o';	/* Open */
+		else
+			repstr[5] = '-';
 	} else {
 		repstr[4] = '-';
 		repstr[5] = '-';
@@ -405,8 +408,8 @@
 	const uint32_t status = *(const uint32_t *) data;
 	char *repstr;
 
-	if (!(repstr = pool_zalloc(rh->mem, 4))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, 4))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -432,8 +435,8 @@
 	const struct volume_group *vg = (const struct volume_group *) data;
 	char *repstr;
 
-	if (!(repstr = pool_zalloc(rh->mem, 6))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, 7))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -459,6 +462,11 @@
 
 	repstr[4] = _alloc_policy_char(vg->alloc);
 
+	if (vg->status & CLUSTERED)
+		repstr[5] = 'c';
+	else
+		repstr[5] = '-';
+
 	field->report_string = repstr;
 	field->sort_value = (const void *) field->report_string;
 
@@ -519,14 +527,15 @@
 	char *repstr;
 	size_t len;
 
-	if (lv->status & VISIBLE_LV) {
+	/* FIXME Remove need for snapshot special case */
+	if (lv->status & VISIBLE_LV || lv_is_cow(lv)) {
 		repstr = lv->name;
 		return _string_disp(rh, field, &repstr);
 	}
 
 	len = strlen(lv->name) + 3;
-	if (!(repstr = pool_zalloc(rh->mem, len))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, len))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -537,8 +546,8 @@
 
 	field->report_string = repstr;
 
-	if (!(field->sort_value = pool_strdup(rh->mem, lv->name))) {
-		log_error("pool_strdup failed");
+	if (!(field->sort_value = dm_pool_strdup(rh->mem, lv->name))) {
+		log_error("dm_pool_strdup failed");
 		return 0;
 	}
 
@@ -577,13 +586,13 @@
 		return 0;
 	}
 
-	if (!(field->report_string = pool_strdup(rh->mem, disp))) {
-		log_error("pool_strdup failed");
+	if (!(field->report_string = dm_pool_strdup(rh->mem, disp))) {
+		log_error("dm_pool_strdup failed");
 		return 0;
 	}
 
-	if (!(sortval = pool_alloc(rh->mem, sizeof(uint64_t)))) {
-		log_error("pool_alloc failed");
+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -605,13 +614,13 @@
 		return 0;
 	}
 
-	if (!(field->report_string = pool_strdup(rh->mem, disp))) {
-		log_error("pool_strdup failed");
+	if (!(field->report_string = dm_pool_strdup(rh->mem, disp))) {
+		log_error("dm_pool_strdup failed");
 		return 0;
 	}
 
-	if (!(sortval = pool_alloc(rh->mem, sizeof(uint64_t)))) {
-		log_error("pool_alloc failed");
+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -654,6 +663,21 @@
 	return _size64_disp(rh, field, &size);
 }
 
+static int _chunksize_disp(struct report_handle *rh, struct field *field,
+			   const void *data)
+{
+	const struct lv_segment *seg = (const struct lv_segment *) data;
+	struct lv_segment *snap_seg;
+	uint64_t size;
+
+	if ((snap_seg = find_cow(seg->lv)))
+		size = (uint64_t) snap_seg->chunk_size;
+	else
+		size = 0;
+
+	return _size64_disp(rh, field, &size);
+}
+
 static int _pvused_disp(struct report_handle *rh, struct field *field,
 			const void *data)
 {
@@ -727,8 +751,8 @@
 {
 	char *repstr = NULL;
 
-	if (!(repstr = pool_alloc(rh->mem, 40))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_alloc(rh->mem, 40))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -750,13 +774,13 @@
 	uint64_t *sortval;
 	char *repstr;
 
-	if (!(repstr = pool_zalloc(rh->mem, 12))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, 12))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
-	if (!(sortval = pool_alloc(rh->mem, sizeof(uint64_t)))) {
-		log_error("pool_alloc failed");
+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -779,13 +803,13 @@
 	uint64_t *sortval;
 	char *repstr;
 
-	if (!(repstr = pool_zalloc(rh->mem, 13))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, 13))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
-	if (!(sortval = pool_alloc(rh->mem, sizeof(int64_t)))) {
-		log_error("pool_alloc failed");
+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(int64_t)))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -822,13 +846,13 @@
 	uint64_t *sortval;
 	char *repstr;
 
-	if (!(sortval = pool_alloc(rh->mem, sizeof(uint64_t)))) {
-		log_error("pool_alloc failed");
+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
 	if (!(snap_seg = find_cow(lv)) ||
-	    (lv_info(snap_seg->cow, &info, 0) && !info.exists)) {
+	    (lv_info(lv->vg->cmd, snap_seg->cow, &info, 0) && !info.exists)) {
 		field->report_string = "";
 		*sortval = UINT64_C(0);
 		field->sort_value = sortval;
@@ -843,8 +867,8 @@
 		return 1;
 	}
 
-	if (!(repstr = pool_zalloc(rh->mem, 8))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, 8))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -868,13 +892,13 @@
 	uint64_t *sortval;
 	char *repstr;
 
-	if (!(sortval = pool_alloc(rh->mem, sizeof(uint64_t)))) {
-		log_error("pool_alloc failed");
+	if (!(sortval = dm_pool_alloc(rh->mem, sizeof(uint64_t)))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
 	if ((!(lv->status & PVMOVE) && !(lv->status & MIRRORED)) ||
-	    !lv_mirror_percent(lv, 0, &percent, NULL)) {
+	    !lv_mirror_percent(lv->vg->cmd, lv, 0, &percent, NULL)) {
 		field->report_string = "";
 		*sortval = UINT64_C(0);
 		field->sort_value = sortval;
@@ -883,8 +907,8 @@
 
 	percent = copy_percent(lv);
 
-	if (!(repstr = pool_zalloc(rh->mem, 8))) {
-		log_error("pool_alloc failed");
+	if (!(repstr = dm_pool_zalloc(rh->mem, 8))) {
+		log_error("dm_pool_alloc failed");
 		return 0;
 	}
 
@@ -945,7 +969,7 @@
 		     !strncasecmp(_fields[f].id + l, field, len) &&
 		     strlen(_fields[f].id) == l + len)) {
 			rh->type |= _fields[f].type;
-			if (!(fp = pool_zalloc(rh->mem, sizeof(*fp)))) {
+			if (!(fp = dm_pool_zalloc(rh->mem, sizeof(*fp)))) {
 				log_error("struct field_properties allocation "
 					  "failed");
 				return 0;
@@ -981,7 +1005,7 @@
 
 	if (!found) {
 		/* Add as a non-display field */
-		if (!(found = pool_zalloc(rh->mem, sizeof(*found)))) {
+		if (!(found = dm_pool_zalloc(rh->mem, sizeof(*found)))) {
 			log_error("struct field_properties allocation failed");
 			return 0;
 		}
@@ -1095,8 +1119,8 @@
 {
 	struct report_handle *rh;
 
-	if (!(rh = pool_zalloc(cmd->mem, sizeof(*rh)))) {
-		log_error("report_handle pool_zalloc failed");
+	if (!(rh = dm_pool_zalloc(cmd->mem, sizeof(*rh)))) {
+		log_error("report_handle dm_pool_zalloc failed");
 		return 0;
 	}
 
@@ -1136,7 +1160,7 @@
 		rh->field_prefix = "";
 	}
 
-	if (!(rh->mem = pool_create("report", 10 * 1024))) {
+	if (!(rh->mem = dm_pool_create("report", 10 * 1024))) {
 		log_error("Allocation of memory pool for report failed");
 		return NULL;
 	}
@@ -1175,7 +1199,7 @@
 {
 	struct report_handle *rh = handle;
 
-	pool_destroy(rh->mem);
+	dm_pool_destroy(rh->mem);
 
 	return;
 }
@@ -1199,7 +1223,7 @@
 		return 0;
 	}
 
-	if (!(row = pool_zalloc(rh->mem, sizeof(*row)))) {
+	if (!(row = dm_pool_zalloc(rh->mem, sizeof(*row)))) {
 		log_error("struct row allocation failed");
 		return 0;
 	}
@@ -1207,7 +1231,7 @@
 	row->rh = rh;
 
 	if ((rh->flags & RH_SORT_REQUIRED) &&
-	    !(row->sort_fields = pool_zalloc(rh->mem, sizeof(struct field *) *
+	    !(row->sort_fields = dm_pool_zalloc(rh->mem, sizeof(struct field *) *
 					     rh->keys_count))) {
 		log_error("row sort value structure allocation failed");
 		return 0;
@@ -1220,7 +1244,7 @@
 	list_iterate_items(fp, &rh->field_props) {
 		skip = 0;
 
-		if (!(field = pool_zalloc(rh->mem, sizeof(*field)))) {
+		if (!(field = dm_pool_zalloc(rh->mem, sizeof(*field)))) {
 			log_error("struct field allocation failed");
 			return 0;
 		}
@@ -1290,8 +1314,8 @@
 	if (!(rh->flags & RH_HEADINGS))
 		return 1;
 
-	if (!pool_begin_object(rh->mem, 128)) {
-		log_error("pool_begin_object failed for headings");
+	if (!dm_pool_begin_object(rh->mem, 128)) {
+		log_error("dm_pool_begin_object failed for headings");
 		return 0;
 	}
 
@@ -1305,24 +1329,24 @@
 			if (lvm_snprintf(buf, sizeof(buf), "%-*.*s",
 					 fp->width, fp->width, heading) < 0) {
 				log_error("snprintf heading failed");
-				pool_end_object(rh->mem);
+				dm_pool_end_object(rh->mem);
 				return 0;
 			}
-			if (!pool_grow_object(rh->mem, buf, fp->width))
+			if (!dm_pool_grow_object(rh->mem, buf, fp->width))
 				goto bad;
-		} else if (!pool_grow_object(rh->mem, heading, strlen(heading)))
+		} else if (!dm_pool_grow_object(rh->mem, heading, strlen(heading)))
 			goto bad;
 
 		if (!list_end(&rh->field_props, &fp->list))
-			if (!pool_grow_object(rh->mem, rh->separator,
+			if (!dm_pool_grow_object(rh->mem, rh->separator,
 					      strlen(rh->separator)))
 				goto bad;
 	}
-	if (!pool_grow_object(rh->mem, "\0", 1)) {
-		log_error("pool_grow_object failed");
+	if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
+		log_error("dm_pool_grow_object failed");
 		goto bad;
 	}
-	log_print("%s", (char *) pool_end_object(rh->mem));
+	log_print("%s", (char *) dm_pool_end_object(rh->mem));
 
 	return 1;
 
@@ -1384,7 +1408,7 @@
 	uint32_t count = 0;
 	struct row *row;
 
-	if (!(rows = pool_alloc(rh->mem, sizeof(**rows) *
+	if (!(rows = dm_pool_alloc(rh->mem, sizeof(**rows) *
 				list_size(&rh->rows)))) {
 		log_error("sort array allocation failed");
 		return 0;
@@ -1428,8 +1452,8 @@
 
 	/* Print and clear buffer */
 	list_iterate_safe(rowh, rtmp, &rh->rows) {
-		if (!pool_begin_object(rh->mem, 512)) {
-			log_error("pool_begin_object failed for row");
+		if (!dm_pool_begin_object(rh->mem, 512)) {
+			log_error("dm_pool_begin_object failed for row");
 			return 0;
 		}
 		row = list_item(rowh, struct row);
@@ -1441,45 +1465,45 @@
 			repstr = field->report_string;
 			width = field->props->width;
 			if (!(rh->flags & RH_ALIGNED)) {
-				if (!pool_grow_object(rh->mem, repstr,
+				if (!dm_pool_grow_object(rh->mem, repstr,
 						      strlen(repstr)))
 					goto bad;
 			} else if (field->props->flags & FLD_ALIGN_LEFT) {
 				if (lvm_snprintf(buf, sizeof(buf), "%-*.*s",
 						 width, width, repstr) < 0) {
 					log_error("snprintf repstr failed");
-					pool_end_object(rh->mem);
+					dm_pool_end_object(rh->mem);
 					return 0;
 				}
-				if (!pool_grow_object(rh->mem, buf, width))
+				if (!dm_pool_grow_object(rh->mem, buf, width))
 					goto bad;
 			} else if (field->props->flags & FLD_ALIGN_RIGHT) {
 				if (lvm_snprintf(buf, sizeof(buf), "%*.*s",
 						 width, width, repstr) < 0) {
 					log_error("snprintf repstr failed");
-					pool_end_object(rh->mem);
+					dm_pool_end_object(rh->mem);
 					return 0;
 				}
-				if (!pool_grow_object(rh->mem, buf, width))
+				if (!dm_pool_grow_object(rh->mem, buf, width))
 					goto bad;
 			}
 
 			if (!list_end(&row->fields, fh))
-				if (!pool_grow_object(rh->mem, rh->separator,
+				if (!dm_pool_grow_object(rh->mem, rh->separator,
 						      strlen(rh->separator)))
 					goto bad;
 			list_del(&field->list);
 		}
-		if (!pool_grow_object(rh->mem, "\0", 1)) {
-			log_error("pool_grow_object failed for row");
+		if (!dm_pool_grow_object(rh->mem, "\0", 1)) {
+			log_error("dm_pool_grow_object failed for row");
 			return 0;
 		}
-		log_print("%s", (char *) pool_end_object(rh->mem));
+		log_print("%s", (char *) dm_pool_end_object(rh->mem));
 		list_del(&row->list);
 	}
 
 	if (row)
-		pool_free(rh->mem, row);
+		dm_pool_free(rh->mem, row);
 
 	return 1;
 

Modified: lvm2/upstream/current/lib/snapshot/snapshot.c
==============================================================================
--- lvm2/upstream/current/lib/snapshot/snapshot.c	(original)
+++ lvm2/upstream/current/lib/snapshot/snapshot.c	Tue Nov 15 17:45:32 2005
@@ -14,8 +14,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
-#include "list.h"
 #include "toolcontext.h"
 #include "metadata.h"
 #include "segtype.h"
@@ -29,7 +27,7 @@
 }
 
 static int _text_import(struct lv_segment *seg, const struct config_node *sn,
-			struct hash_table *pv_hash)
+			struct dm_hash_table *pv_hash)
 {
 	uint32_t chunk_size;
 	const char *org_name, *cow_name;
@@ -89,7 +87,7 @@
 }
 
 #ifdef DEVMAPPER_SUPPORT
-static int _target_percent(void **target_state, struct pool *mem,
+static int _target_percent(void **target_state, struct dm_pool *mem,
 			   struct config_tree *cft, struct lv_segment *seg,
 			   char *params, uint64_t *total_numerator,
 			   uint64_t *total_denominator, float *percent)
@@ -117,8 +115,8 @@
 	static int present = 0;
 
 	if (!checked)
-		present = target_present("snapshot") &&
-		    target_present("snapshot-origin");
+		present = target_present("snapshot", 1) &&
+		    target_present("snapshot-origin", 0);
 
 	checked = 1;
 
@@ -128,7 +126,7 @@
 
 static void _destroy(const struct segment_type *segtype)
 {
-	dbg_free((void *) segtype);
+	dm_free((void *) segtype);
 }
 
 static struct segtype_handler _snapshot_ops = {
@@ -149,7 +147,7 @@
 struct segment_type *init_segtype(struct cmd_context *cmd)
 #endif
 {
-	struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
+	struct segment_type *segtype = dm_malloc(sizeof(*segtype));
 
 	if (!segtype) {
 		stack;

Modified: lvm2/upstream/current/lib/striped/striped.c
==============================================================================
--- lvm2/upstream/current/lib/striped/striped.c	(original)
+++ lvm2/upstream/current/lib/striped/striped.c	Tue Nov 15 17:45:32 2005
@@ -14,8 +14,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
-#include "list.h"
 #include "toolcontext.h"
 #include "segtype.h"
 #include "display.h"
@@ -63,7 +61,7 @@
 }
 
 static int _text_import(struct lv_segment *seg, const struct config_node *sn,
-			struct hash_table *pv_hash)
+			struct dm_hash_table *pv_hash)
 {
 	struct config_node *cn;
 
@@ -108,14 +106,15 @@
 	unsigned s;
 
 	if ((first->area_count != second->area_count) ||
-	    (first->stripe_size != second->stripe_size)) return 0;
+	    (first->stripe_size != second->stripe_size))
+		return 0;
 
 	for (s = 0; s < first->area_count; s++) {
 
 		/* FIXME Relax this to first area type != second area type */
 		/*       plus the additional AREA_LV checks needed */
-		if ((first->area[s].type != AREA_PV) ||
-		    (second->area[s].type != AREA_PV))
+		if ((seg_type(first, s) != AREA_PV) ||
+		    (seg_type(second, s) != AREA_PV))
 			return 0;
 
 		width = first->area_len;
@@ -144,7 +143,7 @@
 	seg1->area_len += seg2->area_len;
 
 	for (s = 0; s < seg1->area_count; s++)
-		if (seg1->area[s].type == AREA_PV)
+		if (seg_type(seg1, s) == AREA_PV)
 			merge_pv_segments(seg_pvseg(seg1, s),
 					  seg_pvseg(seg2, s));
 
@@ -152,32 +151,25 @@
 }
 
 #ifdef DEVMAPPER_SUPPORT
-static int _compose_target_line(struct dev_manager *dm, struct pool *mem,
-				struct config_tree *cft, void **target_state,
-				struct lv_segment *seg, char *params,
-				size_t paramsize, const char **target, int *pos,
-				uint32_t *pvmove_mirror_count)
-{
-	/*   linear [device offset]+
-	 *   striped #stripes stripe_size [device offset]+   */
-
-	if (seg->area_count == 1)
-		*target = "linear";
-	else if (seg->area_count > 1) {
-		*target = "striped";
-		if ((*pos = lvm_snprintf(params, paramsize, "%u %u ",
-					 seg->area_count,
-					 seg->stripe_size)) < 0) {
-			stack;
-			return -1;
-		}
-	} else {
-		log_error("Internal error: striped target with no stripes");
-		return 0;
-	}
+static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
+                                struct config_tree *cft, void **target_state,
+                                struct lv_segment *seg,
+                                struct dm_tree_node *node, uint64_t len,
+                                uint32_t *pvmove_mirror_count)
+{
+	if (!seg->area_count) {
+		log_error("Internal error: striped add_target_line called "
+			  "with no areas for %s.", seg->lv->name);
+		return 0;
+	}
+	if (seg->area_count == 1) {
+		if (!dm_tree_node_add_linear_target(node, len))
+			return_0;
+	} else if (!dm_tree_node_add_striped_target(node, len,
+						  seg->stripe_size))
+		return_0;
 
-	return compose_areas_line(dm, seg, params, paramsize, pos, 0u,
-				  seg->area_count);
+	return add_areas_line(dm, seg, node, 0u, seg->area_count);
 }
 
 static int _target_present(void)
@@ -186,7 +178,8 @@
 	static int present = 0;
 
 	if (!checked)
-		present = target_present("linear") && target_present("striped");
+		present = target_present("linear", 0) &&
+			  target_present("striped", 0);
 
 	checked = 1;
 	return present;
@@ -195,7 +188,7 @@
 
 static void _destroy(const struct segment_type *segtype)
 {
-	dbg_free((void *) segtype);
+	dm_free((void *) segtype);
 }
 
 static struct segtype_handler _striped_ops = {
@@ -206,7 +199,7 @@
 	text_export:_text_export,
 	merge_segments:_merge_segments,
 #ifdef DEVMAPPER_SUPPORT
-	compose_target_line:_compose_target_line,
+	add_target_line:_add_target_line,
 	target_present:_target_present,
 #endif
 	destroy:_destroy,
@@ -214,7 +207,7 @@
 
 struct segment_type *init_striped_segtype(struct cmd_context *cmd)
 {
-	struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
+	struct segment_type *segtype = dm_malloc(sizeof(*segtype));
 
 	if (!segtype) {
 		stack;

Modified: lvm2/upstream/current/lib/zero/zero.c
==============================================================================
--- lvm2/upstream/current/lib/zero/zero.c	(original)
+++ lvm2/upstream/current/lib/zero/zero.c	Tue Nov 15 17:45:32 2005
@@ -13,8 +13,6 @@
  */
 
 #include "lib.h"
-#include "pool.h"
-#include "list.h"
 #include "toolcontext.h"
 #include "segtype.h"
 #include "display.h"
@@ -40,18 +38,13 @@
 }
 
 #ifdef DEVMAPPER_SUPPORT
-static int _compose_target_line(struct dev_manager *dm, struct pool *mem,
-				struct config_tree *cft, void **target_state,
-				struct lv_segment *seg, char *params,
-				size_t paramsize, const char **target, int *pos,
-				uint32_t *pvmove_mirror_count)
+static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
+                                struct config_tree *cft, void **target_state,
+                                struct lv_segment *seg,
+                                struct dm_tree_node *node, uint64_t len,
+                                uint32_t *pvmove_mirror_count)
 {
-	/*   zero */
-
-	*target = "zero";
-	*params = '\0';
-
-	return 1;
+	return dm_tree_node_add_zero_target(node, len);
 }
 
 static int _target_present(void)
@@ -60,7 +53,7 @@
 	static int present = 0;
 
 	if (!checked)
-		present = target_present("zero");
+		present = target_present("zero", 0);
 
 	checked = 1;
 	return present;
@@ -69,14 +62,14 @@
 
 static void _destroy(const struct segment_type *segtype)
 {
-	dbg_free((void *) segtype);
+	dm_free((void *) segtype);
 }
 
 static struct segtype_handler _zero_ops = {
 	name:_name,
 	merge_segments:_merge_segments,
 #ifdef DEVMAPPER_SUPPORT
-	compose_target_line:_compose_target_line,
+	add_target_line:_add_target_line,
 	target_present:_target_present,
 #endif
 	destroy:_destroy,
@@ -84,7 +77,7 @@
 
 struct segment_type *init_zero_segtype(struct cmd_context *cmd)
 {
-	struct segment_type *segtype = dbg_malloc(sizeof(*segtype));
+	struct segment_type *segtype = dm_malloc(sizeof(*segtype));
 
 	if (!segtype) {
 		stack;
@@ -95,7 +88,7 @@
 	segtype->ops = &_zero_ops;
 	segtype->name = "zero";
 	segtype->private = NULL;
-	segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL;
+	segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
 
 	log_very_verbose("Initialised segtype: %s", segtype->name);
 

Modified: lvm2/upstream/current/make.tmpl.in
==============================================================================
--- lvm2/upstream/current/make.tmpl.in	(original)
+++ lvm2/upstream/current/make.tmpl.in	Tue Nov 15 17:45:32 2005
@@ -24,6 +24,7 @@
 MSGFMT = @MSGFMT@
 LN_S = @LN_S@
 LIBS = @LIBS@
+CFLAGS += @DEFS@
 CFLAGS += @CFLAGS@
 CLDFLAGS += @CLDFLAGS@
 CLDWHOLEARCHIVE += @CLDWHOLEARCHIVE@

Modified: lvm2/upstream/current/man/Makefile.in
==============================================================================
--- lvm2/upstream/current/man/Makefile.in	(original)
+++ lvm2/upstream/current/man/Makefile.in	Tue Nov 15 17:45:32 2005
@@ -19,10 +19,10 @@
 MAN5=lvm.conf.5
 MAN8=lvchange.8 lvcreate.8 lvdisplay.8 lvextend.8 lvm.8 lvmchange.8 \
 	lvmdiskscan.8 lvreduce.8 lvremove.8 lvrename.8 lvresize.8 lvs.8 \
-	lvscan.8 pvchange.8 pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 pvs.8 \
-	pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 vgck.8 vgcreate.8 \
-	vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 vgimport.8 \
-	vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 vgrename.8 \
+	lvscan.8 pvchange.8 pvcreate.8 pvdisplay.8 pvmove.8 pvremove.8 \
+	pvresize.8 pvs.8 pvscan.8 vgcfgbackup.8 vgcfgrestore.8 vgchange.8 \
+	vgck.8 vgcreate.8 vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 \
+	vgimport.8 vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 vgrename.8 \
 	vgs.8 vgscan.8 vgsplit.8
 MAN8CLUSTER=clvmd.8
 MAN5DIR=${mandir}/man5

Modified: lvm2/upstream/current/man/lvcreate.8
==============================================================================
--- lvm2/upstream/current/man/lvcreate.8	(original)
+++ lvm2/upstream/current/man/lvcreate.8	Tue Nov 15 17:45:32 2005
@@ -42,7 +42,7 @@
 See \fBlvm\fP for common options.
 .TP
 .I \-c, \-\-chunksize ChunkSize
-Power of 2 chunk size for the snapshot logical volume between 4k and 1024k.
+Power of 2 chunk size for the snapshot logical volume between 4k and 512k.
 .TP
 .I \-C, \-\-contiguous y/n
 Sets or resets the contiguous allocation policy for

Modified: lvm2/upstream/current/man/lvs.8
==============================================================================
--- lvm2/upstream/current/man/lvs.8	(original)
+++ lvm2/upstream/current/man/lvs.8	Tue Nov 15 17:45:32 2005
@@ -55,7 +55,8 @@
 .IP 4 3
 fixed (m)inor
 .IP 5 3
-State: (a)ctive, (s)uspended, (I)nvalid snapshot, invalid (S)uspended snapshot 
+State: (a)ctive, (s)uspended, (I)nvalid snapshot, invalid (S)uspended snapshot,
+mapped (d)evice present without tables, mapped device present with (i)nactive table
 .IP 6 3
 device (o)pen
 .RE

Added: lvm2/upstream/current/man/pvresize.8
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/man/pvresize.8	Tue Nov 15 17:45:32 2005
@@ -0,0 +1,49 @@
+.TH PVRESIZE 8 "LVM TOOLS" "Sistina Software UK" \" -*- nroff -*-
+.SH NAME
+pvresize \- resize a disk or partition in use by LVM2
+.SH SYNOPSIS
+.B pvresize
+.RB [ \-d | \-\-debug ]
+.RB [ \-h | \-\-help ]
+.RB [ \-t | \-\-test ]
+.RB [ \-v | \-\-verbose ]
+.RB [ \-\-setphysicalvolumesize size ]
+.IR PhysicalVolume " [" PhysicalVolume ...]
+.SH DESCRIPTION
+.B pvresize
+resizes
+.I PhysicalVolume
+which may already be in a volume group and have active logical volumes
+allocated on it.
+.SH OPTIONS
+See \fBlvm\fP(8) for common options.
+.TP
+.BR \-\-setphysicalvolumesize " size"
+Overrides the automatically-detected size of the PV.  Use with care, or
+prior to reducing the physical size of the device.
+.SH EXAMPLES
+Expand the PV on /dev/sda1 after enlarging the partition with fdisk:
+.sp
+.B pvresize /dev/sda1
+.sp
+Shrink the PV on /dev/sda1 prior to shrinking the partition with fdisk
+(ensure that the PV size is appropriate for your intended new partition
+size):
+.sp
+.B pvresize --setphysicalvolumesize 40G /dev/sda1
+.sp
+.SH RESTRICTIONS
+.B pvresize
+will refuse to shrink
+.I PhysicalVolume
+if it has allocated extents after where its new end would be. In the future,
+it should relocate these elsewhere in the volume group if there is sufficient
+free space, like
+.B pvmove
+does.
+.sp
+.B pvresize
+won't currently work correctly on LVM1 volumes or PVs with extra
+metadata areas.
+.SH SEE ALSO
+.BR lvm "(8), " pvmove "(8), " lvresize "(8), " fdisk "(8)"

Modified: lvm2/upstream/current/man/vgs.8
==============================================================================
--- lvm2/upstream/current/man/vgs.8	(original)
+++ lvm2/upstream/current/man/vgs.8	Tue Nov 15 17:45:32 2005
@@ -37,7 +37,7 @@
 Any "vg_" prefixes are optional.  Columns mentioned in either \fBpvs (8)\fP 
 or \fBlvs (8)\fP can also be chosen, but columns cannot be taken from both
 at the same time.  The vg_attr bits are: (w)riteable, (r)eadonly, 
-resi(z)eable, e(x)ported, (p)artial.
+resi(z)eable, e(x)ported, (p)artial and (c)lustered.
 .TP
 .I \-O, \-\-sort
 Comma-separated ordered list of columns to sort by.  Replaces the default

Modified: lvm2/upstream/current/scripts/lvmconf.sh
==============================================================================
--- lvm2/upstream/current/scripts/lvmconf.sh	(original)
+++ lvm2/upstream/current/scripts/lvmconf.sh	Tue Nov 15 17:45:32 2005
@@ -1,8 +1,19 @@
 #!/bin/sh
 #
-# Edit an lvm.conf file to adjust various properties
+# Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+#
+# This file is part of the lvm2-cluster package.
 #
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
 #
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+#
+# Edit an lvm.conf file to adjust various properties
 #
 
 function usage
@@ -138,7 +149,7 @@
     if [ "$have_global" = "1" ] 
 	then
 	echo "global keys but no 'global {' found, can't edit file"
-	exit 12
+	exit 13
     fi
 fi
 
@@ -161,7 +172,7 @@
     if [ $? != 0 ]
     then
 	echo "failed to create temporary config file, $CONFIGFILE not updated"
-	exit 1
+	exit 14
     fi
 else
     #
@@ -208,7 +219,7 @@
     if [ $? != 0 ]
     then
 	echo "sed failed, $CONFIGFILE not updated"
-	exit 1
+	exit 15
     fi
 fi
 

Modified: lvm2/upstream/current/test/config/config_t.c
==============================================================================
--- lvm2/upstream/current/test/config/config_t.c	(original)
+++ lvm2/upstream/current/test/config/config_t.c	Tue Nov 15 17:45:32 2005
@@ -3,7 +3,6 @@
  */
 #include <stdio.h>
 
-#include "dbg_malloc.h"
 #include "config.h"
 
 int main(int argc, char **argv)

Modified: lvm2/upstream/current/test/datastruct/hash_t.c
==============================================================================
--- lvm2/upstream/current/test/datastruct/hash_t.c	(original)
+++ lvm2/upstream/current/test/datastruct/hash_t.c	Tue Nov 15 17:45:32 2005
@@ -13,9 +13,6 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "hash.h"
-#include "dbg_malloc.h"
-
 #include <stdio.h>
 
 static void _help(FILE *fp, const char *prog)

Modified: lvm2/upstream/current/test/device/dev_cache_t.c
==============================================================================
--- lvm2/upstream/current/test/device/dev_cache_t.c	(original)
+++ lvm2/upstream/current/test/device/dev_cache_t.c	Tue Nov 15 17:45:32 2005
@@ -13,7 +13,6 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "dbg_malloc.h"
 #include "dev-cache.h"
 #include "log.h"
 

Modified: lvm2/upstream/current/test/filters/pfilter_t.c
==============================================================================
--- lvm2/upstream/current/test/filters/pfilter_t.c	(original)
+++ lvm2/upstream/current/test/filters/pfilter_t.c	Tue Nov 15 17:45:32 2005
@@ -15,7 +15,6 @@
 
 #include "filter-persistent.h"
 #include "log.h"
-#include "dbg_malloc.h"
 #include "config.h"
 #include "filter-regex.h"
 

Modified: lvm2/upstream/current/test/filters/rfilter_t.c
==============================================================================
--- lvm2/upstream/current/test/filters/rfilter_t.c	(original)
+++ lvm2/upstream/current/test/filters/rfilter_t.c	Tue Nov 15 17:45:32 2005
@@ -16,7 +16,6 @@
 #include "filter-regex.h"
 #include "config.h"
 #include "log.h"
-#include "dbg_malloc.h"
 
 #include <stdio.h>
 #include <ctype.h>

Modified: lvm2/upstream/current/test/format1/get_pvs_t.c
==============================================================================
--- lvm2/upstream/current/test/format1/get_pvs_t.c	(original)
+++ lvm2/upstream/current/test/format1/get_pvs_t.c	Tue Nov 15 17:45:32 2005
@@ -15,8 +15,6 @@
 
 #include "log.h"
 #include "format1.h"
-#include "dbg_malloc.h"
-#include "pool.h"
 #include "pretty_print.h"
 #include "list.h"
 
@@ -26,7 +24,7 @@
 {
 	struct io_space *ios;
 	struct list_head *pvs, *tmp;
-	struct pool *mem;
+	struct dm_pool *mem;
 
 	init_log(stderr);
 	init_debug(_LOG_INFO);
@@ -41,7 +39,7 @@
 		exit(1);
 	}
 
-	if (!(mem = pool_create(10 * 1024))) {
+	if (!(mem = dm_pool_create(10 * 1024))) {
 		fprintf(stderr, "couldn't create pool\n");
 		exit(1);
 	}
@@ -67,7 +65,7 @@
 
 	ios->destroy(ios);
 
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	dev_cache_exit();
 	dump_memory();
 	fin_log();

Modified: lvm2/upstream/current/test/format1/get_vgs_t.c
==============================================================================
--- lvm2/upstream/current/test/format1/get_vgs_t.c	(original)
+++ lvm2/upstream/current/test/format1/get_vgs_t.c	Tue Nov 15 17:45:32 2005
@@ -15,8 +15,6 @@
 
 #include "log.h"
 #include "format1.h"
-#include "dbg_malloc.h"
-#include "pool.h"
 #include "pretty_print.h"
 #include "list.h"
 
@@ -26,7 +24,7 @@
 {
 	struct io_space *ios;
 	struct list_head *vgs;
-	struct pool *mem;
+	struct dm_pool *mem;
 
 	init_log(stderr);
 	init_debug(_LOG_INFO);
@@ -41,7 +39,7 @@
 		exit(1);
 	}
 
-	if (!(mem = pool_create(10 * 1024))) {
+	if (!(mem = dm_pool_create(10 * 1024))) {
 		fprintf(stderr, "couldn't create pool\n");
 		exit(1);
 	}
@@ -63,7 +61,7 @@
 	dump_vg_names(vgs, stdout);
 	ios->destroy(ios);
 
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	dev_cache_exit();
 	dump_memory();
 	fin_log();

Modified: lvm2/upstream/current/test/format1/read_pv_t.c
==============================================================================
--- lvm2/upstream/current/test/format1/read_pv_t.c	(original)
+++ lvm2/upstream/current/test/format1/read_pv_t.c	Tue Nov 15 17:45:32 2005
@@ -15,8 +15,6 @@
 
 #include "log.h"
 #include "format1.h"
-#include "dbg_malloc.h"
-#include "pool.h"
 #include "pretty_print.h"
 #include "list.h"
 
@@ -26,7 +24,7 @@
 {
 	struct io_space *ios;
 	struct physical_volume *pv;
-	struct pool *mem;
+	struct dm_pool *mem;
 	struct device *dev;
 
 	if (argc != 2) {
@@ -47,7 +45,7 @@
 		exit(1);
 	}
 
-	if (!(mem = pool_create(10 * 1024))) {
+	if (!(mem = dm_pool_create(10 * 1024))) {
 		fprintf(stderr, "couldn't create pool\n");
 		exit(1);
 	}
@@ -69,7 +67,7 @@
 	dump_pv(pv, stdout);
 	ios->destroy(ios);
 
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	dev_cache_exit();
 	dump_memory();
 	fin_log();

Modified: lvm2/upstream/current/test/format1/read_vg_t.c
==============================================================================
--- lvm2/upstream/current/test/format1/read_vg_t.c	(original)
+++ lvm2/upstream/current/test/format1/read_vg_t.c	Tue Nov 15 17:45:32 2005
@@ -15,8 +15,6 @@
 
 #include "log.h"
 #include "format1.h"
-#include "dbg_malloc.h"
-#include "pool.h"
 #include "pretty_print.h"
 
 #include <stdio.h>
@@ -25,7 +23,7 @@
 {
 	struct io_space *ios;
 	struct volume_group *vg;
-	struct pool *mem;
+	struct dm_pool *mem;
 
 	if (argc != 2) {
 		fprintf(stderr, "usage: read_vg_t <vg_name>\n");
@@ -45,7 +43,7 @@
 		exit(1);
 	}
 
-	if (!(mem = pool_create(10 * 1024))) {
+	if (!(mem = dm_pool_create(10 * 1024))) {
 		fprintf(stderr, "couldn't create pool\n");
 		exit(1);
 	}
@@ -68,7 +66,7 @@
 
 	ios->destroy(ios);
 
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	dev_cache_exit();
 	dump_memory();
 	fin_log();

Modified: lvm2/upstream/current/test/format1/write_vg_t.c
==============================================================================
--- lvm2/upstream/current/test/format1/write_vg_t.c	(original)
+++ lvm2/upstream/current/test/format1/write_vg_t.c	Tue Nov 15 17:45:32 2005
@@ -15,8 +15,6 @@
 
 #include "log.h"
 #include "format1.h"
-#include "dbg_malloc.h"
-#include "pool.h"
 #include "pretty_print.h"
 
 #include <stdio.h>
@@ -25,7 +23,7 @@
 {
 	struct io_space *ios;
 	struct volume_group *vg;
-	struct pool *mem;
+	struct dm_pool *mem;
 
 	if (argc != 2) {
 		fprintf(stderr, "usage: read_vg_t <vg_name>\n");
@@ -45,7 +43,7 @@
 		exit(1);
 	}
 
-	if (!(mem = pool_create(10 * 1024))) {
+	if (!(mem = dm_pool_create(10 * 1024))) {
 		fprintf(stderr, "couldn't create pool\n");
 		exit(1);
 	}
@@ -71,7 +69,7 @@
 
 	ios->destroy(ios);
 
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 	dev_cache_exit();
 	dump_memory();
 	fin_log();

Modified: lvm2/upstream/current/test/mm/dbg_malloc_t.c
==============================================================================
--- lvm2/upstream/current/test/mm/dbg_malloc_t.c	(original)
+++ lvm2/upstream/current/test/mm/dbg_malloc_t.c	Tue Nov 15 17:45:32 2005
@@ -13,7 +13,6 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "dbg_malloc.h"
 #include "log.h"
 
 #include <stdio.h>

Modified: lvm2/upstream/current/test/regex/matcher_t.c
==============================================================================
--- lvm2/upstream/current/test/regex/matcher_t.c	(original)
+++ lvm2/upstream/current/test/regex/matcher_t.c	Tue Nov 15 17:45:32 2005
@@ -14,7 +14,6 @@
  */
 
 #include "matcher.h"
-#include "dbg_malloc.h"
 #include "log.h"
 
 #include <stdio.h>
@@ -105,7 +104,7 @@
 
 int main(int argc, char **argv)
 {
-	struct pool *mem;
+	struct dm_pool *mem;
 	struct matcher *scanner;
 	char **regex;
 	int nregex;
@@ -118,7 +117,7 @@
 	init_log(stderr);
 	init_debug(_LOG_DEBUG);
 
-	if (!(mem = pool_create(10 * 1024))) {
+	if (!(mem = dm_pool_create(10 * 1024))) {
 		fprintf(stderr, "Couldn't create pool\n");
 		exit(2);
 	}
@@ -135,7 +134,7 @@
 
 	_scan_input(scanner, regex);
 	_free_regex(regex, nregex);
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 
 	dump_memory();
 	fin_log();

Modified: lvm2/upstream/current/test/regex/parse_t.c
==============================================================================
--- lvm2/upstream/current/test/regex/parse_t.c	(original)
+++ lvm2/upstream/current/test/regex/parse_t.c	Tue Nov 15 17:45:32 2005
@@ -13,10 +13,8 @@
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include "dbg_malloc.h"
 #include "log.h"
 #include "../../lib/regex/parse_rx.h"
-#include "bitset.h"
 
 #include <stdio.h>
 #include <ctype.h>
@@ -72,7 +70,7 @@
 
 int main(int argc, char **argv)
 {
-	struct pool *mem;
+	struct dm_pool *mem;
 	struct rx_node *rx;
 
 	if (argc != 2) {
@@ -83,7 +81,7 @@
 	init_log(stderr);
 	init_debug(_LOG_INFO);
 
-	if (!(mem = pool_create(1024))) {
+	if (!(mem = dm_pool_create(1024))) {
 		fprintf(stderr, "Couldn't create pool\n");
 		exit(1);
 	}
@@ -94,7 +92,7 @@
 	}
 
 	_pretty_print(rx, 0);
-	pool_destroy(mem);
+	dm_pool_destroy(mem);
 
 	dump_memory();
 	fin_log();

Modified: lvm2/upstream/current/tools/Makefile.in
==============================================================================
--- lvm2/upstream/current/tools/Makefile.in	(original)
+++ lvm2/upstream/current/tools/Makefile.in	Tue Nov 15 17:45:32 2005
@@ -42,6 +42,7 @@
 	pvdisplay.c \
 	pvmove.c \
 	pvremove.c \
+	pvresize.c \
 	pvscan.c \
 	reporter.c \
 	segtypes.c \

Modified: lvm2/upstream/current/tools/commands.h
==============================================================================
--- lvm2/upstream/current/tools/commands.h	(original)
+++ lvm2/upstream/current/tools/commands.h	Tue Nov 15 17:45:32 2005
@@ -343,6 +343,7 @@
 xx(lvscan,
    "List all logical volumes in all volume groups",
    "lvscan " "\n"
+   "\t[-a|--all]\n"
    "\t[-b|--blockdevice] " "\n"
    "\t[-d|--debug] " "\n"
    "\t[-h|-?|--help] " "\n"
@@ -351,7 +352,7 @@
    "\t[-v|--verbose] " "\n"
    "\t[--version]\n",
 
-   blockdevice_ARG, disk_ARG, ignorelockingfailure_ARG, partial_ARG)
+   all_ARG, blockdevice_ARG, disk_ARG, ignorelockingfailure_ARG, partial_ARG)
 
 xx(pvchange,
    "Change attributes of physical volume(s)",
@@ -372,6 +373,19 @@
    all_ARG, allocatable_ARG, allocation_ARG, autobackup_ARG, deltag_ARG,
    addtag_ARG, test_ARG, uuid_ARG)
 
+xx(pvresize,
+   "Resize physical volume(s)",
+   "pvresize " "\n"
+   "\t[-d|--debug]" "\n"
+   "\t[-h|-?|--help] " "\n"
+   "\t[--setphysicalvolumesize PhysicalVolumeSize[kKmMgGtT]" "\n"
+   "\t[-t|--test] " "\n"
+   "\t[-v|--verbose] " "\n"
+   "\t[--version] " "\n"
+   "\tPhysicalVolume [PhysicalVolume...]\n",
+
+   physicalvolumesize_ARG, test_ARG)
+
 xx(pvcreate,
    "Initialize physical volume(s) for use by LVM",
    "pvcreate " "\n"

Modified: lvm2/upstream/current/tools/lvchange.c
==============================================================================
--- lvm2/upstream/current/tools/lvchange.c	(original)
+++ lvm2/upstream/current/tools/lvchange.c	Tue Nov 15 17:45:32 2005
@@ -52,19 +52,19 @@
 
 	backup(lv->vg);
 
-	if (!suspend_lv(cmd, lv->lvid.s)) {
+	if (!suspend_lv(cmd, lv)) {
 		log_error("Failed to lock %s", lv->name);
 		vg_revert(lv->vg);
 		return 0;
 	}
 
 	if (!vg_commit(lv->vg)) {
-		resume_lv(cmd, lv->lvid.s);
+		resume_lv(cmd, lv);
 		return 0;
 	}
 
 	log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name);
-	if (!resume_lv(cmd, lv->lvid.s)) {
+	if (!resume_lv(cmd, lv)) {
 		log_error("Problem reactivating %s", lv->name);
 		return 0;
 	}
@@ -83,13 +83,13 @@
 	if (activate == CHANGE_ALN) {
 		log_verbose("Deactivating logical volume \"%s\" locally",
 			    lv->name);
-		if (!deactivate_lv_local(cmd, lv->lvid.s)) {
+		if (!deactivate_lv_local(cmd, lv)) {
 			stack;
 			return 0;
 		}
 	} else if (activate == CHANGE_AN) {
 		log_verbose("Deactivating logical volume \"%s\"", lv->name);
-		if (!deactivate_lv(cmd, lv->lvid.s)) {
+		if (!deactivate_lv(cmd, lv)) {
 			stack;
 			return 0;
 		}
@@ -103,21 +103,21 @@
 		if (lv_is_origin(lv) || (activate == CHANGE_AE)) {
 			log_verbose("Activating logical volume \"%s\" "
 				    "exclusively", lv->name);
-			if (!activate_lv_excl(cmd, lv->lvid.s)) {
+			if (!activate_lv_excl(cmd, lv)) {
 				stack;
 				return 0;
 			}
 		} else if (activate == CHANGE_ALY) {
 			log_verbose("Activating logical volume \"%s\" locally",
 				    lv->name);
-			if (!activate_lv_local(cmd, lv->lvid.s)) {
+			if (!activate_lv_local(cmd, lv)) {
 				stack;
 				return 0;
 			}
 		} else {
 			log_verbose("Activating logical volume \"%s\"",
 				    lv->name);
-			if (!activate_lv(cmd, lv->lvid.s)) {
+			if (!activate_lv(cmd, lv)) {
 				stack;
 				return 0;
 			}
@@ -137,7 +137,7 @@
 static int lvchange_refresh(struct cmd_context *cmd, struct logical_volume *lv)
 {
 	log_verbose("Refreshing logical volume \"%s\" (if active)", lv->name);
-	if (!suspend_lv(cmd, lv->lvid.s) || !resume_lv(cmd, lv->lvid.s))
+	if (!suspend_lv(cmd, lv) || !resume_lv(cmd, lv))
 		return 0;
 
 	return 1;
@@ -216,19 +216,19 @@
 
 	backup(lv->vg);
 
-	if (!suspend_lv(cmd, lv->lvid.s)) {
+	if (!suspend_lv(cmd, lv)) {
 		log_error("Failed to lock %s", lv->name);
 		vg_revert(lv->vg);
 		return 0;
 	}
 
 	if (!vg_commit(lv->vg)) {
-		resume_lv(cmd, lv->lvid.s);
+		resume_lv(cmd, lv);
 		return 0;
 	}
 
 	log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name);
-	if (!resume_lv(cmd, lv->lvid.s)) {
+	if (!resume_lv(cmd, lv)) {
 		log_error("Problem reactivating %s", lv->name);
 		return 0;
 	}
@@ -262,7 +262,7 @@
 			log_error("Major number must be specified with -My");
 			return 0;
 		}
-		if (lv_info(lv, &info, 0) && info.exists &&
+		if (lv_info(cmd, lv, &info, 0) && info.exists &&
 		    !arg_count(cmd, force_ARG)) {
 			if (yes_no_prompt("Logical volume %s will be "
 					  "deactivated temporarily. "
@@ -274,7 +274,7 @@
 			active = 1;
 		}
 		log_verbose("Ensuring %s is inactive.", lv->name);
-		if (!deactivate_lv(cmd, lv->lvid.s)) {
+		if (!deactivate_lv(cmd, lv)) {
 			log_error("%s: deactivation failed", lv->name);
 			return 0;
 		}
@@ -286,7 +286,7 @@
 		if (active) {
 			log_verbose("Re-activating logical volume \"%s\"",
 				    lv->name);
-			if (!activate_lv(cmd, lv->lvid.s)) {
+			if (!activate_lv(cmd, lv)) {
 				log_error("%s: reactivation failed", lv->name);
 				return 0;
 			}
@@ -301,19 +301,19 @@
 
 	backup(lv->vg);
 
-	if (!suspend_lv(cmd, lv->lvid.s)) {
+	if (!suspend_lv(cmd, lv)) {
 		log_error("Failed to lock %s", lv->name);
 		vg_revert(lv->vg);
 		return 0;
 	}
 
 	if (!vg_commit(lv->vg)) {
-		resume_lv(cmd, lv->lvid.s);
+		resume_lv(cmd, lv);
 		return 0;
 	}
 
 	log_very_verbose("Updating permissions for \"%s\" in kernel", lv->name);
-	if (!resume_lv(cmd, lv->lvid.s)) {
+	if (!resume_lv(cmd, lv)) {
 		log_error("Problem reactivating %s", lv->name);
 		return 0;
 	}

Modified: lvm2/upstream/current/tools/lvconvert.c
==============================================================================
--- lvm2/upstream/current/tools/lvconvert.c	(original)
+++ lvm2/upstream/current/tools/lvconvert.c	Tue Nov 15 17:45:32 2005
@@ -15,24 +15,56 @@
 #include "tools.h"
 
 struct lvconvert_params {
+	const char *lv_name;
+	uint32_t mirrors;
+
+	alloc_policy_t alloc;
+
+	int pv_count;
+	char **pvs;
 	struct list *pvh;
 };
 
-static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * lv,
-			     struct list *allocatable_pvs)
+static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
+			int argc, char **argv)
 {
-	struct lv_segment *first_seg;
-	uint32_t mirrors, existing_mirrors;
-	alloc_policy_t alloc = ALLOC_INHERIT;
-	// struct alloc_handle *ah = NULL;
-	// struct logical_volume *log_lv;
+	memset(lp, 0, sizeof(*lp));
 
+	lp->alloc = ALLOC_INHERIT;
 	if (arg_count(cmd, alloc_ARG))
-		alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, alloc);
+		lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG,
+							    lp->alloc);
+
+	if (!arg_count(cmd, mirrors_ARG)) {
+		log_error("--mirrors argument required");
+		return 0;
+	}
+
+	lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
+
+	if (!argc) {
+		log_error("Please give logical volume path");
+		return 0;
+	}
+
+	lp->lv_name = argv[0];
+	argv++, argc--;
 
-	mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
+	lp->pv_count = argc;
+	lp->pvs = argv;
 
-	if ((mirrors == 1)) {
+	return 1;
+}
+
+static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * lv,
+			     struct lvconvert_params *lp)
+{
+	struct lv_segment *seg;
+	uint32_t existing_mirrors;
+	// struct alloc_handle *ah = NULL;
+	// struct logical_volume *log_lv;
+
+	if ((lp->mirrors == 1)) {
 		if (!(lv->status & MIRRORED)) {
 			log_error("Logical volume %s is already not mirrored.",
 				  lv->name);
@@ -50,16 +82,15 @@
 					  "mirror segments.", lv->name);
 				return 0;
 			}
-			list_iterate_items(first_seg, &lv->segments)
-				break;
-			existing_mirrors = first_seg->area_count;
-			if (mirrors == existing_mirrors) {
+			seg = first_seg(lv);
+			existing_mirrors = seg->area_count;
+			if (lp->mirrors == existing_mirrors) {
 				log_error("Logical volume %s already has %"
 					  PRIu32 " mirror(s).", lv->name,
-					  mirrors - 1);
+					  lp->mirrors - 1);
 				return 1;
 			}
-			if (mirrors > existing_mirrors) {
+			if (lp->mirrors > existing_mirrors) {
 				/* FIXME Unless anywhere, remove PV of log_lv 
 				 * from allocatable_pvs & allocate 
 				 * (mirrors - existing_mirrors) new areas
@@ -69,7 +100,7 @@
 					  "supported yet.");
 				return 0;
 			} else {
-				if (!remove_mirror_images(first_seg, mirrors)) {
+				if (!remove_mirror_images(seg, lp->mirrors)) {
 					stack;
 					return 0;
 				}
@@ -93,20 +124,20 @@
 
 	backup(lv->vg);
 
-	if (!suspend_lv(cmd, lv->lvid.s)) {
+	if (!suspend_lv(cmd, lv)) {
 		log_error("Failed to lock %s", lv->name);
 		vg_revert(lv->vg);
 		return 0;
 	}
 
 	if (!vg_commit(lv->vg)) {
-		resume_lv(cmd, lv->lvid.s);
+		resume_lv(cmd, lv);
 		return 0;
 	}
 
 	log_very_verbose("Updating \"%s\" in kernel", lv->name);
 
-	if (!resume_lv(cmd, lv->lvid.s)) {
+	if (!resume_lv(cmd, lv)) {
 		log_error("Problem reactivating %s", lv->name);
 		return 0;
 	}
@@ -116,8 +147,8 @@
 	return 1;
 }
 
-static int lvconvert_single(struct cmd_context * cmd, struct logical_volume * lv,
-			     int argc, char **argv, void *handle)
+static int lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
+			    void *handle)
 {
 	struct lvconvert_params *lp = handle;
 
@@ -146,7 +177,7 @@
 	if (arg_count(cmd, mirrors_ARG)) {
 		if (!archive(lv->vg))
 			return ECMD_FAILED;
-		if (!lvconvert_mirrors(cmd, lv, lp->pvh))
+		if (!lvconvert_mirrors(cmd, lv, lp))
 			return ECMD_FAILED;
 	}
 
@@ -155,7 +186,7 @@
 
 int lvconvert(struct cmd_context * cmd, int argc, char **argv)
 {
-	const char *vg_name, *lv_name;
+	const char *vg_name;
 	char *st;
 	int consistent = 1;
 	struct volume_group *vg;
@@ -163,28 +194,20 @@
 	struct lvconvert_params lp;
 	int ret = ECMD_FAILED;
 
-	if (!arg_count(cmd, mirrors_ARG)) {
-		log_error("--mirrors argument required");
-		return EINVALID_CMD_LINE;
-	}
-
-	if (!argc) {
-		log_error("Please give logical volume path(s)");
+	if (!_read_params(&lp, cmd, argc, argv)) {
+		stack;
 		return EINVALID_CMD_LINE;
 	}
 
-	lv_name = argv[0];
-	argv++, argc--;
-
-	vg_name = extract_vgname(cmd, lv_name);
+	vg_name = extract_vgname(cmd, lp.lv_name);
 
 	if (!validate_name(vg_name)) {
 		log_error("Please provide a valid volume group name");
 		return EINVALID_CMD_LINE;
 	}
 
-	if ((st = strrchr(lv_name, '/')))
-		lv_name = st + 1;
+	if ((st = strrchr(lp.lv_name, '/')))
+		lp.lv_name = st + 1;
 
 	log_verbose("Checking for existing volume group \"%s\"", vg_name);
 
@@ -208,21 +231,22 @@
 		goto error;
 	}
 
-	if (!(lvl = find_lv_in_vg(vg, lv_name))) {
+	if (!(lvl = find_lv_in_vg(vg, lp.lv_name))) {
 		log_error("Logical volume \"%s\" not found in "
-			  "volume group \"%s\"", lv_name, vg_name);
+			  "volume group \"%s\"", lp.lv_name, vg_name);
 		goto error;
 	}
 
-	if (argc) {
-		if (!(lp.pvh = create_pv_list(cmd->mem, vg, argc, argv, 1))) {
+	if (lp.pv_count) {
+		if (!(lp.pvh = create_pv_list(cmd->mem, vg, lp.pv_count,
+					      lp.pvs, 1))) {
 			stack;
 			goto error;
 		}
 	} else
 		lp.pvh = &vg->pvs;
 
-	ret = lvconvert_single(cmd, lvl->lv, argc, argv, &lp);
+	ret = lvconvert_single(cmd, lvl->lv, &lp);
 
 error:
 	unlock_vg(cmd, vg_name);

Modified: lvm2/upstream/current/tools/lvcreate.c
==============================================================================
--- lvm2/upstream/current/tools/lvcreate.c	(original)
+++ lvm2/upstream/current/tools/lvcreate.c	Tue Nov 15 17:45:32 2005
@@ -303,6 +303,12 @@
 			return 0;
 		}
 		lp->chunk_size = 2 * arg_uint_value(cmd, chunksize_ARG, 8);
+		if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
+		    (lp->chunk_size & (lp->chunk_size - 1))) {
+			log_error("Chunk size must be a power of 2 in the "
+				  "range 4K to 512K");
+			return 0;
+		}
 		log_verbose("Setting chunksize to %d sectors.", lp->chunk_size);
 
 		if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot"))) {
@@ -353,7 +359,8 @@
 	/*
 	 * Should we zero the lv.
 	 */
-	lp->zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
+	lp->zero = strcmp(arg_str_value(cmd, zero_ARG, 
+		(lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n");
 
 	/*
 	 * Alloc policy
@@ -416,7 +423,7 @@
 
 static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
 {
-	uint32_t size_rest, region_max;
+	uint32_t size_rest;
 	uint32_t status = 0;
 	uint64_t tmp_size;
 	struct volume_group *vg;
@@ -506,6 +513,11 @@
 				  "device-mapper kernel driver");
 			return 0;
 		}
+		/* FIXME Allow exclusive activation. */
+		if (vg->status & CLUSTERED) {
+			log_error("Clustered snapshots are not yet supported.");
+			return 0;
+		}
 		if (!(org = find_lv(vg, lp->origin))) {
 			log_err("Couldn't find origin volume '%s'.",
 				lp->origin);
@@ -572,39 +584,20 @@
 	}
 
 	if (lp->mirrors > 1) {
-		/* FIXME Adjust lp->region_size if necessary */
-		region_max = (1 << (ffs(lp->extents) - 1)) * vg->extent_size;
-
-		if (region_max < lp->region_size) {
-			lp->region_size = region_max;
-			log_print("Using reduced mirror region size of %" PRIu32
-				  " sectors", lp->region_size);
-		}
+		lp->region_size = adjusted_mirror_region_size(vg->extent_size,
+							      lp->extents,
+							      lp->region_size);
 
 		/* FIXME Calculate how many extents needed for the log */
 
 		len = strlen(lv_name) + 32;
-        	if (!(log_name = alloca(len))) {
-                	log_error("log_name allocation failed. "
-	                          "Remove new LV and retry.");
-                	return 0;
-        	}
-
-        	if (lvm_snprintf(log_name, len, "%s_mlog", lv_name) < 0) {
+        	if (!(log_name = alloca(len)) ||
+		    !(generate_log_name_format(vg, lv_name, log_name, len))) {
                 	log_error("log_name allocation failed. "
 	                          "Remove new LV and retry.");
                 	return 0;
         	}
 
-		if (find_lv_in_vg(vg, log_name)) {
-        		if (lvm_snprintf(log_name, len, "%s_mlog_%%d",
-					 lv_name) < 0) {
-                		log_error("log_name allocation failed. "
-					  "Remove new LV and retry.");
-                		return 0;
-        		}
-		}
- 
 		if (!(log_lv = lv_create_empty(vg->fid, log_name, NULL,
 				VISIBLE_LV | LVM_READ | LVM_WRITE,
 				lp->alloc, 0, vg))) {
@@ -637,7 +630,7 @@
 			goto error;
 		}
 
-		if (!activate_lv(cmd, log_lv->lvid.s)) {
+		if (!activate_lv(cmd, log_lv)) {
 			log_error("Aborting. Failed to activate mirror log. "
 				  "Remove new LVs and retry.");
 			goto error;
@@ -649,7 +642,7 @@
 			goto error;
 		}
 
-		if (!deactivate_lv(cmd, log_lv->lvid.s)) {
+		if (!deactivate_lv(cmd, log_lv)) {
 			log_error("Aborting. Failed to deactivate mirror log. "
 				  "Remove new LV and retry.");
 			goto error;
@@ -725,7 +718,7 @@
 		return 0;
 	}
 
-	if (!activate_lv(cmd, lv->lvid.s)) {
+	if (!activate_lv(cmd, lv)) {
 		if (lp->snapshot)
 			/* FIXME Remove the failed lv we just added */
 			log_error("Aborting. Failed to activate snapshot "
@@ -751,17 +744,11 @@
 		/* Reset permission after zeroing */
 		if (!(lp->permission & LVM_WRITE))
 			lv->status &= ~LVM_WRITE;
-		if (!deactivate_lv(cmd, lv->lvid.s)) {
+		if (!deactivate_lv(cmd, lv)) {
 			log_err("Couldn't deactivate new snapshot.");
 			return 0;
 		}
 
-		/* FIXME write/commit/backup sequence issue */
-		if (!suspend_lv(cmd, org->lvid.s)) {
-			log_error("Failed to suspend origin %s", org->name);
-			return 0;
-		}
-
 		if (!vg_add_snapshot(vg->fid, NULL, org, lv, NULL,
 				     org->le_count, lp->chunk_size)) {
 			log_err("Couldn't create snapshot.");
@@ -769,10 +756,18 @@
 		}
 
 		/* store vg on disk(s) */
-		if (!vg_write(vg) || !vg_commit(vg))
+		if (!vg_write(vg))
+			return 0;
+
+		if (!suspend_lv(cmd, org)) {
+			log_error("Failed to suspend origin %s", org->name);
+			return 0;
+		}
+
+		if (!vg_commit(vg))
 			return 0;
 
-		if (!resume_lv(cmd, org->lvid.s)) {
+		if (!resume_lv(cmd, org)) {
 			log_error("Problem reactivating origin %s", org->name);
 			return 0;
 		}

Modified: lvm2/upstream/current/tools/lvmcmdline.c
==============================================================================
--- lvm2/upstream/current/tools/lvmcmdline.c	(original)
+++ lvm2/upstream/current/tools/lvmcmdline.c	Tue Nov 15 17:45:32 2005
@@ -350,26 +350,35 @@
 
 char yes_no_prompt(const char *prompt, ...)
 {
-	int c = 0;
+	int c = 0, ret = 0;
 	va_list ap;
 
-	while (c != 'y' && c != 'n') {
-		if (c == '\n' || c == 0) {
+	do {
+		if (c == '\n' || !c) {
 			va_start(ap, prompt);
 			vprintf(prompt, ap);
 			va_end(ap);
 		}
-		c = tolower(getchar());
-	}
 
-	while (getchar() != '\n') ;
+		if ((c = getchar()) == EOF) {
+			ret = 'n';
+			break;
+		}
+
+		c = tolower(c);
+		if ((c == 'y') || (c == 'n'))
+			ret = c;
+	} while (!ret || c != '\n');
+
+	if (c != '\n')
+		printf("\n");
 
-	return c;
+	return ret;
 }
 
 static void __alloc(int size)
 {
-	if (!(_commands = dbg_realloc(_commands, sizeof(*_commands) * size))) {
+	if (!(_commands = dm_realloc(_commands, sizeof(*_commands) * size))) {
 		log_fatal("Couldn't allocate memory.");
 		exit(ECMD_FAILED);
 	}
@@ -418,7 +427,7 @@
 	va_end(ap);
 
 	/* allocate space for them */
-	if (!(args = dbg_malloc(sizeof(*args) * nargs))) {
+	if (!(args = dm_malloc(sizeof(*args) * nargs))) {
 		log_fatal("Out of memory.");
 		exit(ECMD_FAILED);
 	}
@@ -775,29 +784,29 @@
 	 * Build up the complete command line, used as a
 	 * description for backups.
 	 */
-	if (!pool_begin_object(cmd->mem, 128))
+	if (!dm_pool_begin_object(cmd->mem, 128))
 		goto bad;
 
 	for (i = 0; i < argc; i++) {
-		if (!pool_grow_object(cmd->mem, argv[i], strlen(argv[i])))
+		if (!dm_pool_grow_object(cmd->mem, argv[i], strlen(argv[i])))
 			goto bad;
 
 		if (i < (argc - 1))
-			if (!pool_grow_object(cmd->mem, " ", 1))
+			if (!dm_pool_grow_object(cmd->mem, " ", 1))
 				goto bad;
 	}
 
 	/*
 	 * Terminate.
 	 */
-	if (!pool_grow_object(cmd->mem, "\0", 1))
+	if (!dm_pool_grow_object(cmd->mem, "\0", 1))
 		goto bad;
 
-	return pool_end_object(cmd->mem);
+	return dm_pool_end_object(cmd->mem);
 
       bad:
 	log_err("Couldn't copy command line.");
-	pool_abandon_object(cmd->mem);
+	dm_pool_abandon_object(cmd->mem);
 	return NULL;
 }
 
@@ -871,7 +880,7 @@
 	/*
 	 * free off any memory the command used.
 	 */
-	pool_empty(cmd->mem);
+	dm_pool_empty(cmd->mem);
 
 	if (ret == EINVALID_CMD_LINE && !_interactive)
 		_usage(cmd->command->name);
@@ -959,9 +968,9 @@
 	int i;
 
 	for (i = 0; i < _num_commands; i++)
-		dbg_free(_commands[i].valid_args);
+		dm_free(_commands[i].valid_args);
 
-	dbg_free(_commands);
+	dm_free(_commands);
 }
 
 static void _fin(struct cmd_context *cmd)
@@ -1259,7 +1268,7 @@
 
 	cmd->argv = argv;
 
-	if (!(cmdcopy = dbg_strdup(cmdline))) {
+	if (!(cmdcopy = dm_strdup(cmdline))) {
 		log_error("Cmdline copy failed.");
 		ret = ECMD_FAILED;
 		goto out;
@@ -1280,7 +1289,7 @@
 	ret = _run_command(cmd, argc, argv);
 
       out:
-	dbg_free(cmdcopy);
+	dm_free(cmdcopy);
 
 	if (oneoff)
 		lvm2_exit(handle);

Modified: lvm2/upstream/current/tools/lvremove.c
==============================================================================
--- lvm2/upstream/current/tools/lvremove.c	(original)
+++ lvm2/upstream/current/tools/lvremove.c	Tue Nov 15 17:45:32 2005
@@ -20,6 +20,7 @@
 {
 	struct volume_group *vg;
 	struct lvinfo info;
+	struct logical_volume *origin = NULL;
 
 	vg = lv->vg;
 
@@ -53,7 +54,7 @@
 
 	/* FIXME Ensure not referred to by another existing LVs */
 
-	if (lv_info(lv, &info, 1)) {
+	if (lv_info(cmd, lv, &info, 1)) {
 		if (info.open_count) {
 			log_error("Can't remove open logical volume \"%s\"",
 				  lv->name);
@@ -74,13 +75,15 @@
 	if (!archive(vg))
 		return ECMD_FAILED;
 
-	if (!deactivate_lv(cmd, lv->lvid.s)) {
+	/* FIXME Snapshot commit out of sequence if it fails after here? */
+	if (!deactivate_lv(cmd, lv)) {
 		log_error("Unable to deactivate logical volume \"%s\"",
 			  lv->name);
 		return ECMD_FAILED;
 	}
 
 	if (lv_is_cow(lv)) {
+		origin = find_cow(lv)->origin;
 		log_verbose("Removing snapshot %s", lv->name);
 		if (!vg_remove_snapshot(lv)) {
 			stack;
@@ -103,6 +106,14 @@
 	if (!vg_commit(vg))
 		return ECMD_FAILED;
 
+	/* If no snapshots left, reload without -real. */
+	if (origin && !lv_is_origin(origin)) {
+		if (!suspend_lv(cmd, origin))
+			log_error("Failed to refresh %s without snapshot.", origin->name);
+		else if (!resume_lv(cmd, origin))
+			log_error("Failed to resume %s.", origin->name);
+	}
+
 	log_print("Logical volume \"%s\" successfully removed", lv->name);
 	return ECMD_PROCESSED;
 }

Modified: lvm2/upstream/current/tools/lvrename.c
==============================================================================
--- lvm2/upstream/current/tools/lvrename.c	(original)
+++ lvm2/upstream/current/tools/lvrename.c	Tue Nov 15 17:45:32 2005
@@ -145,7 +145,7 @@
 		goto error;
 	}
 
-	if (!(lv->name = pool_strdup(cmd->mem, lv_name_new))) {
+	if (!(lv->name = dm_pool_strdup(cmd->mem, lv_name_new))) {
 		log_error("Failed to allocate space for new name");
 		goto error;
 	}
@@ -158,18 +158,19 @@
 
 	backup(lv->vg);
 
-	if (!suspend_lv(cmd, lv->lvid.s)) {
+	if (!suspend_lv(cmd, lv)) {
 		stack;
+		vg_revert(vg);
 		goto error;
 	}
 
 	if (!vg_commit(vg)) {
 		stack;
-		resume_lv(cmd, lv->lvid.s);
+		resume_lv(cmd, lv);
 		goto error;
 	}
 
-	resume_lv(cmd, lv->lvid.s);
+	resume_lv(cmd, lv);
 
 	unlock_vg(cmd, vg_name);
 

Modified: lvm2/upstream/current/tools/lvresize.c
==============================================================================
--- lvm2/upstream/current/tools/lvresize.c	(original)
+++ lvm2/upstream/current/tools/lvresize.c	Tue Nov 15 17:45:32 2005
@@ -124,7 +124,7 @@
 	uint32_t extents_used = 0;
 	uint32_t size_rest;
 	alloc_policy_t alloc;
-	char *lock_lvid;
+	struct logical_volume *lock_lv;
 	struct lv_list *lvl;
 	int consistent = 1;
 	struct lv_segment *seg;
@@ -388,7 +388,7 @@
 	}
 
 	if (lp->mirrors && activation() &&
-	    lv_info(lv, &info, 0) && info.exists) {
+	    lv_info(cmd, lv, &info, 0) && info.exists) {
 		log_error("Mirrors cannot be resized while active yet.");
 		return ECMD_FAILED;
 	}
@@ -402,7 +402,7 @@
 
 		memset(&info, 0, sizeof(info));
 
-		if (lv_info(lv, &info, 0) && info.exists) {
+		if (lv_info(cmd, lv, &info, 0) && info.exists) {
 			log_error("Snapshot origin volumes can be resized "
 				  "only while inactive: try lvchange -an");
 			return ECMD_FAILED;
@@ -421,7 +421,7 @@
 	if (lp->resize == LV_REDUCE || lp->resizefs) {
 		memset(&info, 0, sizeof(info));
 
-		if (!lv_info(lv, &info, 1) && driver_version(NULL, 0)) {
+		if (!lv_info(cmd, lv, &info, 1) && driver_version(NULL, 0)) {
 			log_error("lv_info failed: aborting");
 			return ECMD_FAILED;
 		}
@@ -518,11 +518,11 @@
 
 	/* If snapshot, must suspend all associated devices */
 	if ((snap_seg = find_cow(lv)))
-		lock_lvid = snap_seg->origin->lvid.s;
+		lock_lv = snap_seg->origin;
 	else
-		lock_lvid = lv->lvid.s;
+		lock_lv = lv;
 
-	if (!suspend_lv(cmd, lock_lvid)) {
+	if (!suspend_lv(cmd, lock_lv)) {
 		log_error("Failed to suspend %s", lp->lv_name);
 		vg_revert(vg);
 		return ECMD_FAILED;
@@ -530,11 +530,11 @@
 
 	if (!vg_commit(vg)) {
 		stack;
-		resume_lv(cmd, lock_lvid);
+		resume_lv(cmd, lock_lv);
 		return ECMD_FAILED;
 	}
 
-	if (!resume_lv(cmd, lock_lvid)) {
+	if (!resume_lv(cmd, lock_lv)) {
 		log_error("Problem reactivating %s", lp->lv_name);
 		return ECMD_FAILED;
 	}

Modified: lvm2/upstream/current/tools/lvscan.c
==============================================================================
--- lvm2/upstream/current/tools/lvscan.c	(original)
+++ lvm2/upstream/current/tools/lvscan.c	Tue Nov 15 17:45:32 2005
@@ -24,8 +24,13 @@
 
 	const char *active_str, *snapshot_str;
 
+	/* FIXME Avoid snapshot special-case */
+	if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV) &&
+	    !(lv_is_cow(lv)))
+		return ECMD_PROCESSED;
+
 /* FIXME Add -D arg to skip this! */
-	if (lv_info(lv, &info, 0) && info.exists)
+	if (lv_info(cmd, lv, &info, 0) && info.exists)
 		active_str = "ACTIVE   ";
 	else
 		active_str = "inactive ";

Modified: lvm2/upstream/current/tools/polldaemon.c
==============================================================================
--- lvm2/upstream/current/tools/polldaemon.c	(original)
+++ lvm2/upstream/current/tools/polldaemon.c	Tue Nov 15 17:45:32 2005
@@ -72,8 +72,6 @@
 	float segment_percent = 0.0, overall_percent = 0.0;
 	uint32_t event_nr = 0;
 
-void *x;
-
 	/* By default, caller should not retry */
 	*finished = 1;
 
@@ -87,7 +85,7 @@
 		return 0;
 	}
 
-	if (!lv_mirror_percent(lv_mirr, !parms->interval, &segment_percent,
+	if (!lv_mirror_percent(cmd, lv_mirr, !parms->interval, &segment_percent,
 			       &event_nr)) {
 		log_error("ABORTING: Mirror percentage check failed.");
 		return 0;
@@ -99,9 +97,6 @@
 	else
 		log_verbose("%s: Moved: %.1f%%", name, overall_percent);
 
-x = pool_alloc(cmd->mem, 1);
-pool_free(cmd->mem, x);
-
 	if (segment_percent < 100.0) {
 		/* The only case the caller *should* try again later */
 		*finished = 0;

Modified: lvm2/upstream/current/tools/pvcreate.c
==============================================================================
--- lvm2/upstream/current/tools/pvcreate.c	(original)
+++ lvm2/upstream/current/tools/pvcreate.c	Tue Nov 15 17:45:32 2005
@@ -62,13 +62,13 @@
 
 	/* Is there an md superblock here? */
 	if (!dev && md_filtering()) {
-		unlock_vg(cmd, "");
+		unlock_vg(cmd, ORPHAN);
 
 		persistent_filter_wipe(cmd->filter);
 		lvmcache_destroy();
 
 		init_md_filtering(0);
-		if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
+		if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
 			log_error("Can't get lock for orphan PVs");
 			init_md_filtering(1);
 			return 0;
@@ -82,6 +82,12 @@
 		return 0;
 	}
 
+	if (!dev_test_excl(dev)) {
+		log_error("Can't open %s exclusively.  Mounted filesystem?",
+			  name);
+		return 0;
+	}
+
 	/* Wipe superblock? */
 	if (dev_is_md(dev, &md_superblock) &&
 	    ((!arg_count(cmd, uuidstr_ARG) &&
@@ -158,7 +164,7 @@
 		extent_count = existing_pv->pe_count;
 	}
 
-	if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
+	if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
 		log_error("Can't get lock for orphan PVs");
 		return ECMD_FAILED;
 	}
@@ -218,8 +224,12 @@
 			log_error("%s not opened: device not zeroed", pv_name);
 			goto error;
 		}
-			
-		dev_zero(dev, UINT64_C(0), (size_t) 2048);
+
+		if (!dev_zero(dev, UINT64_C(0), (size_t) 2048)) {
+			log_error("%s not wiped: aborting", pv_name);
+			dev_close(dev);
+			goto error;
+		}
 		dev_close(dev);
 	}
 
@@ -233,11 +243,11 @@
 
 	log_print("Physical volume \"%s\" successfully created", pv_name);
 
-	unlock_vg(cmd, "");
+	unlock_vg(cmd, ORPHAN);
 	return ECMD_PROCESSED;
 
       error:
-	unlock_vg(cmd, "");
+	unlock_vg(cmd, ORPHAN);
 	return ECMD_FAILED;
 }
 

Modified: lvm2/upstream/current/tools/pvmove.c
==============================================================================
--- lvm2/upstream/current/tools/pvmove.c	(original)
+++ lvm2/upstream/current/tools/pvmove.c	Tue Nov 15 17:45:32 2005
@@ -149,7 +149,7 @@
 
 	lv_mirr->status |= (PVMOVE | LOCKED);
 
-	if (!(*lvs_changed = pool_alloc(cmd->mem, sizeof(**lvs_changed)))) {
+	if (!(*lvs_changed = dm_pool_alloc(cmd->mem, sizeof(**lvs_changed)))) {
 		log_error("lvs_changed list struct allocation failed");
 		return NULL;
 	}
@@ -219,7 +219,7 @@
 
 	/* Suspend mirrors on subsequent calls */
 	if (!first_time) {
-		if (!suspend_lv(cmd, lv_mirr->lvid.s)) {
+		if (!suspend_lv(cmd, lv_mirr)) {
 			stack;
 			resume_lvs(cmd, lvs_changed);
 			vg_revert(vg);
@@ -231,15 +231,16 @@
 	if (!vg_commit(vg)) {
 		log_error("ABORTING: Volume group metadata update failed.");
 		if (!first_time)
-			resume_lv(cmd, lv_mirr->lvid.s);
+			resume_lv(cmd, lv_mirr);
 		resume_lvs(cmd, lvs_changed);
 		return 0;
 	}
 
 	/* Activate the temporary mirror LV */
 	/* Only the first mirror segment gets activated as a mirror */
+	/* FIXME: Add option to use a log */
 	if (first_time) {
-		if (!activate_lv(cmd, lv_mirr->lvid.s)) {
+		if (!activate_lv_excl(cmd, lv_mirr)) {
 			if (!test_mode())
 				log_error("ABORTING: Temporary mirror "
 					  "activation failed.  "
@@ -248,7 +249,7 @@
 			resume_lvs(cmd, lvs_changed);
 			return 0;
 		}
-	} else if (!resume_lv(cmd, lv_mirr->lvid.s)) {
+	} else if (!resume_lv(cmd, lv_mirr)) {
 		log_error("Unable to reactivate logical volume \"%s\"",
 			  lv_mirr->name);
 		resume_lvs(cmd, lvs_changed);
@@ -317,7 +318,7 @@
 		}
 
 		/* Ensure mirror LV is active */
-		if (!activate_lv(cmd, lv_mirr->lvid.s)) {
+		if (!activate_lv_excl(cmd, lv_mirr)) {
 			log_error
 			    ("ABORTING: Temporary mirror activation failed.");
 			unlock_vg(cmd, pv->vg_name);
@@ -414,7 +415,7 @@
 	}
 
 	/* Suspend mirror LV to flush pending I/O */
-	if (!suspend_lv(cmd, lv_mirr->lvid.s)) {
+	if (!suspend_lv(cmd, lv_mirr)) {
 		log_error("Suspension of temporary mirror LV failed");
 		r = 0;
 	}
@@ -424,13 +425,13 @@
 		log_error("ABORTING: Failed to write new data locations "
 			  "to disk.");
 		vg_revert(vg);
-		resume_lv(cmd, lv_mirr->lvid.s);
+		resume_lv(cmd, lv_mirr);
 		resume_lvs(cmd, lvs_changed);
 		return 0;
 	}
 
 	/* Release mirror LV.  (No pending I/O because it's been suspended.) */
-	if (!resume_lv(cmd, lv_mirr->lvid.s)) {
+	if (!resume_lv(cmd, lv_mirr)) {
 		log_error("Unable to reactivate logical volume \"%s\"",
 			  lv_mirr->name);
 		r = 0;
@@ -440,7 +441,7 @@
 	resume_lvs(cmd, lvs_changed);
 
 	/* Deactivate mirror LV */
-	if (!deactivate_lv(cmd, lv_mirr->lvid.s)) {
+	if (!deactivate_lv(cmd, lv_mirr)) {
 		log_error("ABORTING: Unable to deactivate temporary logical "
 			  "volume \"%s\"", lv_mirr->name);
 		r = 0;
@@ -506,7 +507,7 @@
 
 		/* Drop any PE lists from PV name */
 		if ((colon = strchr(pv_name, ':'))) {
-			if (!(pv_name = pool_strndup(cmd->mem, pv_name,
+			if (!(pv_name = dm_pool_strndup(cmd->mem, pv_name,
 						     (unsigned) (colon -
 								 pv_name)))) {
 				log_error("Failed to clone PV name");

Modified: lvm2/upstream/current/tools/pvremove.c
==============================================================================
--- lvm2/upstream/current/tools/pvremove.c	(original)
+++ lvm2/upstream/current/tools/pvremove.c	Tue Nov 15 17:45:32 2005
@@ -72,7 +72,7 @@
 {
 	struct device *dev;
 
-	if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
+	if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
 		log_error("Can't get lock for orphan PVs");
 		return ECMD_FAILED;
 	}
@@ -86,6 +86,12 @@
 		goto error;
 	}
 
+	if (!dev_test_excl(dev)) {
+		log_error("Can't open %s exclusively.  Mounted filesystem?",
+			  dev_name(dev));
+		return 0;
+	}
+
 	/* Wipe existing label(s) */
 	if (!label_remove(dev)) {
 		log_error("Failed to wipe existing label(s) on %s", pv_name);
@@ -95,11 +101,11 @@
 	log_print("Labels on physical volume \"%s\" successfully wiped",
 		  pv_name);
 
-	unlock_vg(cmd, "");
+	unlock_vg(cmd, ORPHAN);
 	return ECMD_PROCESSED;
 
       error:
-	unlock_vg(cmd, "");
+	unlock_vg(cmd, ORPHAN);
 	return ECMD_FAILED;
 }
 

Added: lvm2/upstream/current/tools/pvresize.c
==============================================================================
--- (empty file)
+++ lvm2/upstream/current/tools/pvresize.c	Tue Nov 15 17:45:32 2005
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. 
+ * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2005 Zak Kipling. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tools.h"
+
+struct pvresize_params {
+	uint64_t new_size;
+
+	unsigned done;
+	unsigned total;
+};
+
+static int _pvresize_single(struct cmd_context *cmd,
+			    struct volume_group *vg,
+			    struct physical_volume *pv,
+			    void *handle)
+{
+	struct pv_list *pvl;
+	int consistent = 1;
+	uint64_t size = 0;
+	uint32_t new_pe_count = 0;
+	struct list mdas;
+	const char *pv_name = dev_name(pv->dev);
+	struct pvresize_params *params = (struct pvresize_params *) handle;
+	const char *vg_name;
+
+	list_init(&mdas);
+
+	params->total++;
+
+	if (!*pv->vg_name) {
+		vg_name = ORPHAN;
+
+		if (!lock_vol(cmd, vg_name, LCK_VG_WRITE)) {
+			log_error("Can't get lock for orphans");
+			return ECMD_FAILED;
+		}
+
+		if (!(pv = pv_read(cmd, pv_name, &mdas, NULL, 1))) {
+			unlock_vg(cmd, vg_name);
+			log_error("Unable to read PV \"%s\"", pv_name);
+			return ECMD_FAILED;
+		}
+
+		/* FIXME Create function to test compatibility properly */
+		if (list_size(&mdas) > 1) {
+			log_error("%s: too many metadata areas for pvresize",
+				  pv_name);
+			unlock_vg(cmd, vg_name);
+			return ECMD_FAILED;
+		}
+	} else {
+		vg_name = pv->vg_name;
+
+		if (!lock_vol(cmd, vg_name, LCK_VG_WRITE)) {
+			log_error("Can't get lock for %s", pv->vg_name);
+			return ECMD_FAILED;
+		}
+
+		if (!(vg = vg_read(cmd, vg_name, &consistent))) {
+			unlock_vg(cmd, vg_name);
+			log_error("Unable to find volume group of \"%s\"",
+				  pv_name);
+			return ECMD_FAILED;
+		}
+
+		if (vg->status & EXPORTED_VG) {
+			unlock_vg(cmd, vg_name);
+			log_error("Volume group \"%s\" is exported", vg->name);
+			return ECMD_FAILED;
+		}
+
+		if (!(vg->status & LVM_WRITE)) {
+			unlock_vg(cmd, pv->vg_name);
+			log_error("Volume group \"%s\" is read-only", vg->name);
+			return ECMD_FAILED;
+		}
+
+		if (!(pvl = find_pv_in_vg(vg, pv_name))) {
+			unlock_vg(cmd, vg_name);
+			log_error("Unable to find \"%s\" in volume group \"%s\"",
+				  pv_name, vg->name);
+			return ECMD_FAILED;
+		}
+
+		pv = pvl->pv;
+
+		if (!archive(vg))
+			return ECMD_FAILED;
+	}
+
+	if (!(pv->fmt->features & FMT_RESIZE_PV)) {
+		log_error("Physical volume %s format does not support resizing.",
+			  pv_name);
+		unlock_vg(cmd, vg_name);
+		return ECMD_FAILED;
+	}
+
+	/* Get new size */
+	if (!dev_get_size(pv->dev, &size)) {
+		log_error("%s: Couldn't get size.", pv_name);
+		unlock_vg(cmd, vg_name);
+		return ECMD_FAILED;
+	}
+	
+	if (params->new_size) {
+		if (params->new_size > size)
+			log_print("WARNING: %s: Overriding real size. "
+				  "You could lose data.", pv_name);
+		log_verbose("%s: Pretending size is %" PRIu64 " not %" PRIu64
+			    " sectors.", pv_name, params->new_size, pv->size);
+		size = params->new_size;
+	}
+
+	if (size < PV_MIN_SIZE) {
+		log_error("%s: Size must exceed minimum of %ld sectors.",
+			  pv_name, PV_MIN_SIZE);
+		unlock_vg(cmd, vg_name);
+		return ECMD_FAILED;
+	}
+
+	if (size < pv->pe_start) {
+		log_error("%s: Size must exceed physical extent start of "
+			  "%" PRIu64 " sectors.", pv_name, pv->pe_start);
+		unlock_vg(cmd, vg_name);
+		return ECMD_FAILED;
+	}
+
+	pv->size = size;
+
+	if (vg) {
+		pv->size -= pv->pe_start;
+		new_pe_count = pv->size / vg->extent_size;
+		
+ 		if (!new_pe_count) {
+			log_error("%s: Size must leave space for at "
+				  "least one physical extent of "
+				  "%" PRIu32 " sectors.", pv_name,
+				  pv->pe_size);
+			unlock_vg(cmd, vg_name);
+			return ECMD_FAILED;
+		}
+
+		if (!pv_resize(pv, vg, new_pe_count)) {
+			stack;
+			unlock_vg(cmd, vg_name);
+			return ECMD_FAILED;
+		}
+	}
+
+	log_verbose("Resizing volume \"%s\" to %" PRIu64 " sectors.",
+		    pv_name, pv->size);
+
+	log_verbose("Updating physical volume \"%s\"", pv_name);
+	if (*pv->vg_name) {
+		if (!vg_write(vg) || !vg_commit(vg)) {
+			unlock_vg(cmd, pv->vg_name);
+			log_error("Failed to store physical volume \"%s\" in "
+				  "volume group \"%s\"", pv_name, vg->name);
+			return ECMD_FAILED;
+		}
+		backup(vg);
+		unlock_vg(cmd, vg_name);
+	} else {
+		if (!(pv_write(cmd, pv, NULL, INT64_C(-1)))) {
+			unlock_vg(cmd, ORPHAN);
+			log_error("Failed to store physical volume \"%s\"",
+				  pv_name);
+			return ECMD_FAILED;
+		}
+		unlock_vg(cmd, vg_name);
+	}
+
+	log_print("Physical volume \"%s\" changed", pv_name);
+
+	params->done++;
+
+	return 1;
+}
+
+int pvresize(struct cmd_context *cmd, int argc, char **argv)
+{
+	struct pvresize_params params;
+	int ret;
+
+	if (!argc) {
+		log_error("Please supply physical volume(s)");
+		return EINVALID_CMD_LINE;
+	}
+
+	if (arg_sign_value(cmd, physicalvolumesize_ARG, 0) == SIGN_MINUS) {
+		log_error("Physical volume size may not be negative");
+		return 0;
+	}
+
+	params.new_size = arg_uint64_value(cmd, physicalvolumesize_ARG,
+					   UINT64_C(0)) * 2;
+
+	params.done = 0;
+	params.total = 0;
+
+	ret = process_each_pv(cmd, argc, argv, NULL, &params, _pvresize_single);
+
+	log_print("%d physical volume(s) resized / %d physical volume(s) "
+		  "not resized", params.done, params.total - params.done);
+
+	return ret;
+}

Modified: lvm2/upstream/current/tools/reporter.c
==============================================================================
--- lvm2/upstream/current/tools/reporter.c	(original)
+++ lvm2/upstream/current/tools/reporter.c	Tue Nov 15 17:45:32 2005
@@ -35,7 +35,9 @@
 static int _lvs_single(struct cmd_context *cmd, struct logical_volume *lv,
 		       void *handle)
 {
-	if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
+	/* FIXME Avoid snapshot special-case */
+	if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV) &&
+	    !(lv_is_cow(lv)))
 		return ECMD_PROCESSED;
 
 	if (!report_object(handle, lv->vg, lv, NULL, NULL, NULL))
@@ -81,7 +83,9 @@
 static int _lvsegs_single(struct cmd_context *cmd, struct logical_volume *lv,
 			  void *handle)
 {
-	if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
+	/* FIXME Avoid snapshot special-case */
+	if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV) &&
+	    !(lv_is_cow(lv)))
 		return ECMD_PROCESSED;
 
 	return process_each_segment_in_lv(cmd, lv, handle, _segs_single);
@@ -213,7 +217,7 @@
 			return 0;
 		}
 		if (*opts == '+') {
-			str = pool_alloc(cmd->mem,
+			str = dm_pool_alloc(cmd->mem,
 					 strlen(options) + strlen(opts) + 1);
 			strcpy(str, options);
 			strcat(str, ",");

Modified: lvm2/upstream/current/tools/stub.h
==============================================================================
--- lvm2/upstream/current/tools/stub.h	(original)
+++ lvm2/upstream/current/tools/stub.h	Tue Nov 15 17:45:32 2005
@@ -19,7 +19,6 @@
 /*int e2fsadm(struct cmd_context *cmd, int argc, char **argv) unimplemented*/
 int lvmsadc(struct cmd_context *cmd, int argc, char **argv) unimplemented
 int lvmsar(struct cmd_context *cmd, int argc, char **argv) unimplemented
-int pvresize(struct cmd_context *cmd, int argc, char **argv) unimplemented
 
 int pvdata(struct cmd_context *cmd, int argc, char **argv) {
 	log_error("There's no 'pvdata' command in LVM2.");

Modified: lvm2/upstream/current/tools/toollib.c
==============================================================================
--- lvm2/upstream/current/tools/toollib.c	(original)
+++ lvm2/upstream/current/tools/toollib.c	Tue Nov 15 17:45:32 2005
@@ -145,7 +145,7 @@
 					continue;
 				}
 				if (!str_list_add(cmd->mem, &tags,
-						  pool_strdup(cmd->mem,
+						  dm_pool_strdup(cmd->mem,
 							      vgname + 1))) {
 					log_error("strlist allocation failed");
 					return ECMD_FAILED;
@@ -191,21 +191,21 @@
 				lv_name = NULL;
 
 			if (!str_list_add(cmd->mem, &arg_vgnames,
-					  pool_strdup(cmd->mem, vgname))) {
+					  dm_pool_strdup(cmd->mem, vgname))) {
 				log_error("strlist allocation failed");
 				return ECMD_FAILED;
 			}
 
 			if (!lv_name) {
 				if (!str_list_add(cmd->mem, &arg_lvnames,
-						  pool_strdup(cmd->mem,
+						  dm_pool_strdup(cmd->mem,
 							      vgname))) {
 					log_error("strlist allocation failed");
 					return ECMD_FAILED;
 				}
 			} else {
 				vglv_sz = strlen(vgname) + strlen(lv_name) + 2;
-				if (!(vglv = pool_alloc(cmd->mem, vglv_sz)) ||
+				if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
 				    lvm_snprintf(vglv, vglv_sz, "%s/%s", vgname,
 						 lv_name) < 0) {
 					log_error("vg/lv string alloc failed");
@@ -270,7 +270,7 @@
 			} else if (!strncmp(vg_name, vgname, strlen(vgname)) &&
 				   strlen(vgname) == lv_name - vg_name) {
 				if (!str_list_add(cmd->mem, &lvnames,
-						  pool_strdup(cmd->mem,
+						  dm_pool_strdup(cmd->mem,
 							      lv_name + 1))) {
 					log_error("strlist allocation failed");
 					return ECMD_FAILED;
@@ -401,7 +401,7 @@
 					continue;
 				}
 				if (!str_list_add(cmd->mem, &tags,
-						  pool_strdup(cmd->mem,
+						  dm_pool_strdup(cmd->mem,
 							      vg_name + 1))) {
 					log_error("strlist allocation failed");
 					return ECMD_FAILED;
@@ -422,7 +422,7 @@
 				continue;
 			}
 			if (!str_list_add(cmd->mem, &arg_vgnames,
-					  pool_strdup(cmd->mem, vg_name))) {
+					  dm_pool_strdup(cmd->mem, vg_name))) {
 				log_error("strlist allocation failed");
 				return ECMD_FAILED;
 			}
@@ -547,7 +547,7 @@
 					continue;
 				}
 				if (!str_list_add(cmd->mem, &tags,
-						  pool_strdup(cmd->mem,
+						  dm_pool_strdup(cmd->mem,
 							      tagname))) {
 					log_error("strlist allocation failed");
 					return ECMD_FAILED;
@@ -661,7 +661,7 @@
 			return 0;
 		}
 
-		vg_name = pool_strdup(cmd->mem, vg_name);
+		vg_name = dm_pool_strdup(cmd->mem, vg_name);
 		if (!vg_name) {
 			log_error("Allocation of vg_name failed");
 			return 0;
@@ -709,13 +709,13 @@
 		return 0;
 	}
 
-	return pool_strdup(cmd->mem, vg_path);
+	return dm_pool_strdup(cmd->mem, vg_path);
 }
 
 /*
  * Process physical extent range specifiers
  */
-static int _add_pe_range(struct pool *mem, struct list *pe_ranges,
+static int _add_pe_range(struct dm_pool *mem, struct list *pe_ranges,
 			 uint32_t start, uint32_t count)
 {
 	struct pe_range *per;
@@ -736,7 +736,7 @@
 		}
 	}
 
-	if (!(per = pool_alloc(mem, sizeof(*per)))) {
+	if (!(per = dm_pool_alloc(mem, sizeof(*per)))) {
 		log_error("Allocation of list failed");
 		return 0;
 	}
@@ -748,7 +748,7 @@
 	return 1;
 }
 
-static int _parse_pes(struct pool *mem, char *c, struct list *pe_ranges,
+static int _parse_pes(struct dm_pool *mem, char *c, struct list *pe_ranges,
 		      uint32_t size)
 {
 	char *endptr;
@@ -820,7 +820,7 @@
 	return 0;
 }
 
-static void _create_pv_entry(struct pool *mem, struct pv_list *pvl,
+static void _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl,
 			     char *colon, int allocatable_only, struct list *r)
 {
 	const char *pvname;
@@ -839,14 +839,14 @@
 		return;
 	}
 
-	if (!(new_pvl = pool_alloc(mem, sizeof(*new_pvl)))) {
+	if (!(new_pvl = dm_pool_alloc(mem, sizeof(*new_pvl)))) {
 		log_err("Unable to allocate physical volume list.");
 		return;
 	}
 
 	memcpy(new_pvl, pvl, sizeof(*new_pvl));
 
-	if (!(pe_ranges = pool_alloc(mem, sizeof(*pe_ranges)))) {
+	if (!(pe_ranges = dm_pool_alloc(mem, sizeof(*pe_ranges)))) {
 		log_error("Allocation of pe_ranges list failed");
 		return;
 	}
@@ -862,7 +862,7 @@
 	list_add(r, &new_pvl->list);
 }
 
-struct list *create_pv_list(struct pool *mem, struct volume_group *vg, int argc,
+struct list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int argc,
 			    char **argv, int allocatable_only)
 {
 	struct list *r;
@@ -873,7 +873,7 @@
 	int i;
 
 	/* Build up list of PVs */
-	if (!(r = pool_alloc(mem, sizeof(*r)))) {
+	if (!(r = dm_pool_alloc(mem, sizeof(*r)))) {
 		log_error("Allocation of list failed");
 		return NULL;
 	}
@@ -902,7 +902,7 @@
 		pvname = argv[i];
 
 		if ((colon = strchr(pvname, ':'))) {
-			if (!(pvname = pool_strndup(mem, pvname,
+			if (!(pvname = dm_pool_strndup(mem, pvname,
 						    (unsigned) (colon -
 								pvname)))) {
 				log_error("Failed to clone PV name");
@@ -924,20 +924,20 @@
 	return list_empty(r) ? NULL : r;
 }
 
-struct list *clone_pv_list(struct pool *mem, struct list *pvsl)
+struct list *clone_pv_list(struct dm_pool *mem, struct list *pvsl)
 {
 	struct list *r;
 	struct pv_list *pvl, *new_pvl;
 
 	/* Build up list of PVs */
-	if (!(r = pool_alloc(mem, sizeof(*r)))) {
+	if (!(r = dm_pool_alloc(mem, sizeof(*r)))) {
 		log_error("Allocation of list failed");
 		return NULL;
 	}
 	list_init(r);
 
 	list_iterate_items(pvl, pvsl) {
-		if (!(new_pvl = pool_zalloc(mem, sizeof(*new_pvl)))) {
+		if (!(new_pvl = dm_pool_zalloc(mem, sizeof(*new_pvl)))) {
 			log_error("Unable to allocate physical volume list.");
 			return NULL;
 		}
@@ -969,50 +969,6 @@
 	return vg_read(cmd, vgname, &consistent);
 }
 
-/*
- * Execute and wait for external command
- */
-int exec_cmd(const char *command, const char *fscmd, const char *lv_path,
-	     const char *size)
-{
-	pid_t pid;
-	int status;
-
-	log_verbose("Executing: %s %s %s %s", command, fscmd, lv_path, size);
-
-	if ((pid = fork()) == -1) {
-		log_error("fork failed: %s", strerror(errno));
-		return 0;
-	}
-
-	if (!pid) {
-		/* Child */
-		/* FIXME Use execve directly */
-		execlp(command, command, fscmd, lv_path, size, NULL);
-		log_sys_error("execlp", command);
-		exit(errno);
-	}
-
-	/* Parent */
-	if (wait4(pid, &status, 0, NULL) != pid) {
-		log_error("wait4 child process %u failed: %s", pid,
-			  strerror(errno));
-		return 0;
-	}
-
-	if (!WIFEXITED(status)) {
-		log_error("Child %u exited abnormally", pid);
-		return 0;
-	}
-
-	if (WEXITSTATUS(status)) {
-		log_error("%s failed: %u", command, WEXITSTATUS(status));
-		return 0;
-	}
-
-	return 1;
-}
-
 int apply_lvname_restrictions(const char *name)
 {
 	if (!strncmp(name, "snapshot", 8)) {
@@ -1058,6 +1014,24 @@
 	return 1;
 }
 
+int generate_log_name_format(struct volume_group *vg, const char *lv_name,
+			     char *buffer, size_t size)
+{
+	if (lvm_snprintf(buffer, size, "%s_mlog", lv_name) < 0) {
+		stack;
+		return 0;
+	}
+
+	if (find_lv_in_vg(vg, buffer) &&
+	    lvm_snprintf(buffer, size, "%s_mlog_%%d",
+			 lv_name) < 0) {
+		stack;
+		return 0;
+	}
+
+	return 1;
+}
+
 /*
  * Volumes may be zeroed to remove old application data.
  */
@@ -1073,7 +1047,7 @@
 	 * <ejt_> k, I'll drop a fixme to that effect
 	 *           (I know the device is at least 4k, but not 32k)
 	 */
-	if (!(name = pool_alloc(cmd->mem, PATH_MAX))) {
+	if (!(name = dm_pool_alloc(cmd->mem, PATH_MAX))) {
 		log_error("Name allocation failed - device not zeroed");
 		return 0;
 	}

Modified: lvm2/upstream/current/tools/toollib.h
==============================================================================
--- lvm2/upstream/current/tools/toollib.h	(original)
+++ lvm2/upstream/current/tools/toollib.h	Tue Nov 15 17:45:32 2005
@@ -17,7 +17,6 @@
 #define _LVM_TOOLLIB_H
 
 #include "metadata.h"
-#include "pool.h"
 
 int autobackup_set(void);
 int autobackup_init(const char *backup_dir, int keep_days, int keep_number,
@@ -82,18 +81,18 @@
  * Builds a list of pv's from the names in argv.  Used in
  * lvcreate/extend.
  */
-struct list *create_pv_list(struct pool *mem, struct volume_group *vg, int argc,
+struct list *create_pv_list(struct dm_pool *mem, struct volume_group *vg, int argc,
 			    char **argv, int allocatable_only);
 
-struct list *clone_pv_list(struct pool *mem, struct list *pvs);
-
-int exec_cmd(const char *command, const char *fscmd, const char *lv_path,
-	     const char *size);
+struct list *clone_pv_list(struct dm_pool *mem, struct list *pvs);
 
 int apply_lvname_restrictions(const char *name);
 
 int validate_vg_name(struct cmd_context *cmd, const char *vg_name);
 
+int generate_log_name_format(struct volume_group *vg, const char *lv_name,
+                             char *buffer, size_t size);
+
 int zero_lv(struct cmd_context *cmd, struct logical_volume *lv);
 
 #endif

Modified: lvm2/upstream/current/tools/tools.h
==============================================================================
--- lvm2/upstream/current/tools/tools.h	(original)
+++ lvm2/upstream/current/tools/tools.h	Tue Nov 15 17:45:32 2005
@@ -20,14 +20,15 @@
 #define _FILE_OFFSET_BITS 64
 
 #include <assert.h>
+#include <libdevmapper.h>
 
+#include "lvm-types.h"
 #include "log.h"
 #include "activate.h"
 #include "archiver.h"
 #include "lvmcache.h"
 #include "config.h"
 #include "defaults.h"
-#include "dbg_malloc.h"
 #include "dev-cache.h"
 #include "device.h"
 #include "display.h"
@@ -40,9 +41,9 @@
 #include "metadata.h"
 #include "list.h"
 #include "locking.h"
+#include "lvm-exec.h"
 #include "lvm-file.h"
 #include "lvm-string.h"
-#include "pool.h"
 #include "segtype.h"
 #include "str_list.h"
 #include "toolcontext.h"

Modified: lvm2/upstream/current/tools/vgcfgbackup.c
==============================================================================
--- lvm2/upstream/current/tools/vgcfgbackup.c	(original)
+++ lvm2/upstream/current/tools/vgcfgbackup.c	Tue Nov 15 17:45:32 2005
@@ -21,24 +21,24 @@
 	char *filename;
 
 	if (security_level())
-		return dbg_strdup(template);
+		return dm_strdup(template);
 
-	filename = dbg_malloc(PATH_MAX);
+	filename = dm_malloc(PATH_MAX);
 	if (snprintf(filename, PATH_MAX, template, vg_name) < 0) {
 		log_error("Error processing filename template %s",
 			   template);
-		dbg_free(filename);	
+		dm_free(filename);	
 		return NULL;
 	}
 	if (*last_filename && !strncmp(*last_filename, filename,
 				      strlen(template))) {
 		log_error("VGs must be backed up into different files. "
 			  "Use %%s in filename for VG name.");
-		dbg_free(filename);
+		dm_free(filename);
 		return NULL;
 	}
 
-	dbg_free(*last_filename);
+	dm_free(*last_filename);
 	*last_filename = filename;
 
 	return filename;
@@ -98,7 +98,7 @@
 	ret = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, &last_filename,
 			      &vg_backup_single);
 
-	dbg_free(last_filename);
+	dm_free(last_filename);
 
 	init_pvmove(0);
 

Modified: lvm2/upstream/current/tools/vgchange.c
==============================================================================
--- lvm2/upstream/current/tools/vgchange.c	(original)
+++ lvm2/upstream/current/tools/vgchange.c	Tue Nov 15 17:45:32 2005
@@ -37,18 +37,18 @@
 			continue;
 
 		if (activate == CHANGE_AN) {
-			if (!deactivate_lv(cmd, lv->lvid.s))
+			if (!deactivate_lv(cmd, lv))
 				continue;
 		} else if (activate == CHANGE_ALN) {
-			if (!deactivate_lv_local(cmd, lv->lvid.s))
+			if (!deactivate_lv_local(cmd, lv))
 				continue;
 		} else if (lv_is_origin(lv) || (activate == CHANGE_AE)) {
-			if (!activate_lv_excl(cmd, lv->lvid.s))
+			if (!activate_lv_excl(cmd, lv))
 				continue;
 		} else if (activate == CHANGE_ALY) {
-			if (!activate_lv_local(cmd, lv->lvid.s))
+			if (!activate_lv_local(cmd, lv))
 				continue;
-		} else if (!activate_lv(cmd, lv->lvid.s))
+		} else if (!activate_lv(cmd, lv))
 			continue;
 
 		if ((lv->status & PVMOVE) &&
@@ -182,6 +182,7 @@
 			       struct volume_group *vg)
 {
 	int clustered = !strcmp(arg_str_value(cmd, clustered_ARG, "n"), "y");
+	struct lv_list *lvl;
 
 	if (clustered && (vg->status & CLUSTERED)) {
 		log_error("Volume group \"%s\" is already clustered",
@@ -195,6 +196,17 @@
 		return ECMD_FAILED;
 	}
 
+	if (clustered) {
+        	list_iterate_items(lvl, &vg->lvs) {
+                	if (lvl->lv->origin_count || lvl->lv->snapshot) {
+				log_error("Volume group %s contains snapshots "
+					  "that are not yet supported.",
+					  vg->name);
+				return ECMD_FAILED;
+			}
+		}
+	}
+
 	if (!archive(vg))
 		return ECMD_FAILED;
 

Modified: lvm2/upstream/current/tools/vgconvert.c
==============================================================================
--- lvm2/upstream/current/tools/vgconvert.c	(original)
+++ lvm2/upstream/current/tools/vgconvert.c	Tue Nov 15 17:45:32 2005
@@ -96,7 +96,7 @@
 				continue;
 			if (lvnum_from_lvid(&lv->lvid) < MAX_RESTRICTED_LVS)
 				continue;
-			if (lv_info(lv, &info, 0) && info.exists) {
+			if (lv_info(cmd, lv, &info, 0) && info.exists) {
 				log_error("Logical volume %s must be "
 					  "deactivated before conversion.",
 					   lv->name);

Modified: lvm2/upstream/current/tools/vgcreate.c
==============================================================================
--- lvm2/upstream/current/tools/vgcreate.c	(original)
+++ lvm2/upstream/current/tools/vgcreate.c	Tue Nov 15 17:45:32 2005
@@ -135,32 +135,32 @@
 	else
 		vg->status &= ~CLUSTERED;
 
-	if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
+	if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
 		log_error("Can't get lock for orphan PVs");
 		return ECMD_FAILED;
 	}
 
 	if (!lock_vol(cmd, vg_name, LCK_VG_WRITE | LCK_NONBLOCK)) {
 		log_error("Can't get lock for %s", vg_name);
-		unlock_vg(cmd, "");
+		unlock_vg(cmd, ORPHAN);
 		return ECMD_FAILED;
 	}
 
 	if (!archive(vg)) {
 		unlock_vg(cmd, vg_name);
-		unlock_vg(cmd, "");
+		unlock_vg(cmd, ORPHAN);
 		return ECMD_FAILED;
 	}
 
 	/* Store VG on disk(s) */
 	if (!vg_write(vg) || !vg_commit(vg)) {
 		unlock_vg(cmd, vg_name);
-		unlock_vg(cmd, "");
+		unlock_vg(cmd, ORPHAN);
 		return ECMD_FAILED;
 	}
 
 	unlock_vg(cmd, vg_name);
-	unlock_vg(cmd, "");
+	unlock_vg(cmd, ORPHAN);
 
 	backup(vg);
 

Modified: lvm2/upstream/current/tools/vgextend.c
==============================================================================
--- lvm2/upstream/current/tools/vgextend.c	(original)
+++ lvm2/upstream/current/tools/vgextend.c	Tue Nov 15 17:45:32 2005
@@ -36,14 +36,14 @@
 	argc--;
 	argv++;
 
-	if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
+	if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
 		log_error("Can't get lock for orphan PVs");
 		return ECMD_FAILED;
 	}
 
 	log_verbose("Checking for volume group \"%s\"", vg_name);
 	if (!lock_vol(cmd, vg_name, LCK_VG_WRITE | LCK_NONBLOCK)) {
-		unlock_vg(cmd, "");
+		unlock_vg(cmd, ORPHAN);
 		log_error("Can't get lock for %s", vg_name);
 		goto error;
 	}
@@ -71,7 +71,7 @@
 /********** FIXME
 	log_print("maximum logical volume size is %s",
 		  (dummy = lvm_show_size(LVM_LV_SIZE_MAX(vg) / 2, LONG)));
-	dbg_free(dummy);
+	dm_free(dummy);
 	dummy = NULL;
 **********/
 
@@ -93,7 +93,7 @@
 	backup(vg);
 
 	unlock_vg(cmd, vg_name);
-	unlock_vg(cmd, "");
+	unlock_vg(cmd, ORPHAN);
 
 	log_print("Volume group \"%s\" successfully extended", vg_name);
 
@@ -101,6 +101,6 @@
 
       error:
 	unlock_vg(cmd, vg_name);
-	unlock_vg(cmd, "");
+	unlock_vg(cmd, ORPHAN);
 	return ECMD_FAILED;
 }

Modified: lvm2/upstream/current/tools/vgmerge.c
==============================================================================
--- lvm2/upstream/current/tools/vgmerge.c	(original)
+++ lvm2/upstream/current/tools/vgmerge.c	Tue Nov 15 17:45:32 2005
@@ -20,6 +20,7 @@
 {
 	struct volume_group *vg_to, *vg_from;
 	struct lv_list *lvl1, *lvl2;
+	struct pv_list *pvl;
 	int active;
 	int consistent = 1;
 
@@ -122,6 +123,25 @@
 		}
 	}
 
+	/* Check no PVs are constructed from either VG */
+	list_iterate_items(pvl, &vg_to->pvs) {
+		if (pv_uses_vg(cmd, pvl->pv, vg_from)) {
+			log_error("Physical volume %s might be constructed "
+				  "from same volume group %s.",
+				  dev_name(pvl->pv->dev), vg_from->name);
+			goto error;
+		}
+	}
+
+	list_iterate_items(pvl, &vg_from->pvs) {
+		if (pv_uses_vg(cmd, pvl->pv, vg_to)) {
+			log_error("Physical volume %s might be constructed "
+				  "from same volume group %s.",
+				  dev_name(pvl->pv->dev), vg_to->name);
+			goto error;
+		}
+	}
+
 	/* FIXME List arg: vg_show_with_pv_and_lv(vg_to); */
 
 	if (!archive(vg_from) || !archive(vg_to))
@@ -136,7 +156,7 @@
 		list_add(&vg_to->pvs, pvh);
 
 		pv = list_item(pvh, struct pv_list)->pv;
-		pv->vg_name = pool_strdup(cmd->mem, vg_to->name);
+		pv->vg_name = dm_pool_strdup(cmd->mem, vg_to->name);
 	}
 	vg_to->pv_count += vg_from->pv_count;
 

Modified: lvm2/upstream/current/tools/vgreduce.c
==============================================================================
--- lvm2/upstream/current/tools/vgreduce.c	(original)
+++ lvm2/upstream/current/tools/vgreduce.c	Tue Nov 15 17:45:32 2005
@@ -61,7 +61,7 @@
 		log_verbose("Deactivating (if active) logical volume %s",
 			    lv->name);
 
-		if (!deactivate_lv(cmd, lv->lvid.s)) {
+		if (!deactivate_lv(cmd, lv)) {
 			log_error("Failed to deactivate LV %s", lv->name);
 			return 0;
 		}
@@ -69,7 +69,7 @@
 		log_verbose("Deactivating (if active) logical volume %s "
 			    "(origin of %s)", snap_seg->origin->name, lv->name);
 
-		if (!deactivate_lv(cmd, snap_seg->origin->lvid.s)) {
+		if (!deactivate_lv(cmd, snap_seg->origin)) {
 			log_error("Failed to deactivate LV %s",
 				  snap_seg->origin->name);
 			return 0;

Modified: lvm2/upstream/current/tools/vgremove.c
==============================================================================
--- lvm2/upstream/current/tools/vgremove.c	(original)
+++ lvm2/upstream/current/tools/vgremove.c	Tue Nov 15 17:45:32 2005
@@ -87,7 +87,7 @@
 {
 	int ret;
 
-	if (!lock_vol(cmd, "", LCK_VG_WRITE)) {
+	if (!lock_vol(cmd, ORPHAN, LCK_VG_WRITE)) {
 		log_error("Can't get lock for orphan PVs");
 		return ECMD_FAILED;
 	}
@@ -96,7 +96,7 @@
 			      LCK_VG_WRITE | LCK_NONBLOCK, 1, 
 			      NULL, &vgremove_single);
 
-	unlock_vg(cmd, "");
+	unlock_vg(cmd, ORPHAN);
 
 	return ret;
 }



More information about the pkg-lvm-commits mailing list