public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2012-02-01 13:42 zkabelac
  0 siblings, 0 replies; 16+ messages in thread
From: zkabelac @ 2012-02-01 13:42 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	zkabelac@sourceware.org	2012-02-01 13:42:19

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/misc       : lvm-globals.h 

Log message:
	Avoid warning for small pv_min_size
	
	Do not print warning for pv_min_size set in range between 512KB and 2MB.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.2251&r2=1.2252
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.147&r2=1.148
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-globals.h.diff?cvsroot=lvm2&r1=1.14&r2=1.15

--- LVM2/WHATS_NEW	2012/02/01 13:08:39	1.2251
+++ LVM2/WHATS_NEW	2012/02/01 13:42:18	1.2252
@@ -1,5 +1,6 @@
 Version 2.02.90 - 
 ===================================
+  Do not print warning for pv_min_size set in range between 512KB and 2MB.
   Clean up systemd unit ordering and requirements.
   Fix lcov reports when srcdir != builddir.
   Allow ALLOC_NORMAL to track reserved extents for log and data on same PV.
--- LVM2/lib/commands/toolcontext.c	2012/01/23 17:46:32	1.147
+++ LVM2/lib/commands/toolcontext.c	2012/02/01 13:42:19	1.148
@@ -377,10 +377,10 @@
 						       DEFAULT_METADATA_READ_ONLY);
 
 	pv_min_kb = find_config_tree_int64(cmd, "devices/pv_min_size", DEFAULT_PV_MIN_SIZE_KB);
-	if (pv_min_kb < DEFAULT_PV_MIN_SIZE_KB) {
+	if (pv_min_kb < PV_MIN_SIZE_KB) {
 		log_warn("Ignoring too small pv_min_size %" PRId64 "KB, using default %dKB.",
-			 pv_min_kb, DEFAULT_PV_MIN_SIZE_KB);
-		pv_min_kb = DEFAULT_PV_MIN_SIZE_KB;
+			 pv_min_kb, PV_MIN_SIZE_KB);
+		pv_min_kb = PV_MIN_SIZE_KB;
 	}
 	/* LVM stores sizes internally in units of 512-byte sectors. */
 	init_pv_min_size((uint64_t)pv_min_kb * (1024 >> SECTOR_SHIFT));
--- LVM2/lib/misc/lvm-globals.h	2011/09/22 17:39:57	1.14
+++ LVM2/lib/misc/lvm-globals.h	2012/02/01 13:42:19	1.15
@@ -18,6 +18,7 @@
 
 #define VERBOSE_BASE_LEVEL _LOG_WARN
 #define SECURITY_LEVEL 0
+#define PV_MIN_SIZE_KB 512
 
 void init_verbose(int level);
 void init_test(int level);


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2012-01-11 20:38 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2012-01-11 20:38 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2012-01-11 20:38:43

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/filters    : filter.c 

Log message:
	Give priority to emcpower devices with duplicate PVIDs.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.2218&r2=1.2219
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.145&r2=1.146
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter.c.diff?cvsroot=lvm2&r1=1.66&r2=1.67

--- LVM2/WHATS_NEW	2012/01/09 12:31:52	1.2218
+++ LVM2/WHATS_NEW	2012/01/11 20:38:42	1.2219
@@ -1,5 +1,6 @@
 Version 2.02.89 - 
 ==================================
+  Give priority to emcpower devices with duplicate PVIDs.
   Add check for error in _adjust_policy_params() (lvextend --use-policies).
   Supports rounding of percentage (%LV, %VG...) for LV resize upward.
   Use dmeventd_lvm2_command in dmeventd plugins snapshot, raid, mirror.
--- LVM2/lib/commands/toolcontext.c	2012/01/10 02:03:31	1.145
+++ LVM2/lib/commands/toolcontext.c	2012/01/11 20:38:42	1.146
@@ -98,7 +98,7 @@
 	}
 
 	if (!(fp = fopen(proc_mounts, "r"))) {
-		log_sys_error("_get_sysfs_dir: fopen %s", proc_mounts);
+		log_sys_error("_get_sysfs_dir fopen", proc_mounts);
 		return;
 	}
 
--- LVM2/lib/filters/filter.c	2011/11/18 19:36:10	1.66
+++ LVM2/lib/filters/filter.c	2012/01/11 20:38:42	1.67
@@ -44,6 +44,7 @@
 static int _blkext_major = -1;
 static int _drbd_major = -1;
 static int _device_mapper_major = -1;
+static int _emcpower_major = -1;
 
 int dm_major(void)
 {
@@ -70,6 +71,9 @@
 	if (MAJOR(dev->dev) == _drbd_major)
 		return 1;
 
+	if (MAJOR(dev->dev) == _emcpower_major)
+		return 1;
+
 	if ((MAJOR(dev->dev) == _blkext_major) &&
 	    (get_primary_dev(sysfs_dir_path(), dev, &primary_dev)) &&
 	    (MAJOR(primary_dev) == _md_major))
@@ -86,6 +90,9 @@
 	if (MAJOR(dev->dev) == _drbd_major)
 		return "DRBD";
 
+	if (MAJOR(dev->dev) == _emcpower_major)
+		return "EMCPOWER";
+
 	if (MAJOR(dev->dev) == _blkext_major)
 		return "BLKEXT";
 
@@ -246,6 +253,10 @@
 		if (!strncmp("drbd", line + i, 4) && isspace(*(line + i + 4)))
 			_drbd_major = line_maj;
 
+		/* Look for EMC powerpath */
+		if (!strncmp("emcpower", line + i, 8) && isspace(*(line + i + 8)))
+			_emcpower_major = line_maj;
+
 		/* Look for device-mapper device */
 		/* FIXME Cope with multiple majors */
 		if (!strncmp("device-mapper", line + i, 13) && isspace(*(line + i + 13)))


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2011-01-06 15:29 zkabelac
  0 siblings, 0 replies; 16+ messages in thread
From: zkabelac @ 2011-01-06 15:29 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	zkabelac@sourceware.org	2011-01-06 15:29:24

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/filters    : filter-persistent.c 

Log message:
	Fix memory leak in filter creation error path
	
	If some allocation for peristent filter fails its memory reference
	was lost, fix it by calling filter's destructor.
	
	Fix log_error messages for failing allocation.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1862&r2=1.1863
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.113&r2=1.114
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter-persistent.c.diff?cvsroot=lvm2&r1=1.47&r2=1.48

--- LVM2/WHATS_NEW	2011/01/05 23:18:46	1.1862
+++ LVM2/WHATS_NEW	2011/01/06 15:29:24	1.1863
@@ -1,5 +1,6 @@
 Version 2.02.80 - 
 ====================================
+  Fix memory leak in filter creation error path.
   Add missing tests in _setup_task().
   Fail poll daemon creation when lvmcache_init() fails.
   Return defined value for errors in _copy_percent() and _snap_percent().
--- LVM2/lib/commands/toolcontext.c	2010/12/20 14:34:49	1.113
+++ LVM2/lib/commands/toolcontext.c	2011/01/06 15:29:24	1.114
@@ -708,6 +708,7 @@
 		    cache_dir ? : DEFAULT_CACHE_SUBDIR,
 		    cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
 			log_error("Persistent cache filename too long.");
+			f3->destroy(f3);
 			return 0;
 		}
 	} else if (!(dev_cache = find_config_tree_str(cmd, "devices/cache", NULL)) &&
@@ -716,6 +717,7 @@
 				cmd->system_dir, DEFAULT_CACHE_SUBDIR,
 				DEFAULT_CACHE_FILE_PREFIX) < 0)) {
 		log_error("Persistent cache filename too long.");
+		f3->destroy(f3);
 		return 0;
 	}
 
@@ -723,8 +725,9 @@
 		dev_cache = cache_file;
 
 	if (!(f4 = persistent_filter_create(f3, dev_cache))) {
-		log_error("Failed to create persistent device filter");
-		return 0;
+		log_verbose("Failed to create persistent device filter.");
+		f3->destroy(f3);
+		return_0;
 	}
 
 	/* Should we ever dump persistent filter state? */
--- LVM2/lib/filters/filter-persistent.c	2010/12/20 13:12:56	1.47
+++ LVM2/lib/filters/filter-persistent.c	2011/01/06 15:29:24	1.48
@@ -318,13 +318,16 @@
 	struct dev_filter *f = NULL;
 	struct stat info;
 
-	if (!(pf = dm_zalloc(sizeof(*pf))))
-		return_NULL;
+	if (!(pf = dm_zalloc(sizeof(*pf)))) {
+		log_error("Allocation of persistent filter failed.");
+		return NULL;
+	}
 
-	if (!(pf->file = dm_malloc(strlen(file) + 1)))
-		goto_bad;
+	if (!(pf->file = dm_strdup(file))) {
+		log_error("Filename duplication for persistent filter failed.");
+		goto bad;
+	}
 
-	strcpy(pf->file, file);
 	pf->real = real;
 
 	if (!(_init_hash(pf))) {
@@ -332,8 +335,10 @@
 		goto bad;
 	}
 
-	if (!(f = dm_malloc(sizeof(*f))))
-		goto_bad;
+	if (!(f = dm_malloc(sizeof(*f)))) {
+		log_error("Allocation of device filter for persistent filter failed.");
+		goto bad;
+	}
 
 	/* Only merge cache file before dumping it if it changed externally. */
 	if (!stat(pf->file, &info))


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2010-11-11 17:29 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2010-11-11 17:29 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2010-11-11 17:29:06

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c toolcontext.h 
	lib/metadata   : lv_manip.c metadata-exported.h 
	liblvm         : lvm_lv.c 
	tools          : args.h lvchange.c lvcreate.c lvm.c 
	                 lvm2cmdline.h lvmcmdline.c pvchange.c tools.h 
	                 vgchange.c vgcreate.c 

Log message:
	Support repetition of --addtag and --deltag arguments.
	Add infrastructure for specific cmdline arguments to be repeated in groups.
	Split the_args cmdline arguments and values into arg_props and arg_values.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1795&r2=1.1796
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.107&r2=1.108
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.h.diff?cvsroot=lvm2&r1=1.40&r2=1.41
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.237&r2=1.238
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.169&r2=1.170
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/liblvm/lvm_lv.c.diff?cvsroot=lvm2&r1=1.27&r2=1.28
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/args.h.diff?cvsroot=lvm2&r1=1.80&r2=1.81
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvchange.c.diff?cvsroot=lvm2&r1=1.126&r2=1.127
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvcreate.c.diff?cvsroot=lvm2&r1=1.224&r2=1.225
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvm.c.diff?cvsroot=lvm2&r1=1.114&r2=1.115
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvm2cmdline.h.diff?cvsroot=lvm2&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.129&r2=1.130
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/pvchange.c.diff?cvsroot=lvm2&r1=1.84&r2=1.85
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/tools.h.diff?cvsroot=lvm2&r1=1.72&r2=1.73
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgchange.c.diff?cvsroot=lvm2&r1=1.116&r2=1.117
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/vgcreate.c.diff?cvsroot=lvm2&r1=1.80&r2=1.81

--- LVM2/WHATS_NEW	2010/11/10 16:14:02	1.1795
+++ LVM2/WHATS_NEW	2010/11/11 17:29:05	1.1796
@@ -1,7 +1,10 @@
 Version 2.02.77 -
 ===================================
-  Fix fsadm need of using '-f' for downsize of unmounted filesystem.
-  Fix fsadm regression in detection of mounted filesystem for older systems (2.0.75).
+  Support repetition of --addtag and --deltag arguments.
+  Add infrastructure for specific cmdline arguments to be repeated in groups.
+  Split the_args cmdline arguments and values into arg_props and arg_values.
+FIXME??? Fix fsadm need of using '-f' for downsize of unmounted filesystem.
+  Fix fsadm to detect mounted filesystems on older systems. (2.0.75)
   Extend cling allocation policy to recognise PV tags (cling_by_tags).
   Add allocation/cling_tag_list to lvm.conf.
   Regenerate configure with 'autoreconf' for --enable-ocf. (2.02.76)
--- LVM2/lib/commands/toolcontext.c	2010/10/25 11:20:55	1.107
+++ LVM2/lib/commands/toolcontext.c	2010/11/11 17:29:05	1.108
@@ -1136,6 +1136,7 @@
 	cmd->handles_missing_pvs = 0;
 	cmd->handles_unknown_segments = 0;
 	cmd->hosttags = 0;
+	dm_list_init(&cmd->arg_value_groups);
 	dm_list_init(&cmd->formats);
 	dm_list_init(&cmd->segtypes);
 	dm_list_init(&cmd->tags);
--- LVM2/lib/commands/toolcontext.h	2010/10/25 11:20:55	1.40
+++ LVM2/lib/commands/toolcontext.h	2010/11/11 17:29:06	1.41
@@ -49,6 +49,7 @@
 struct config_tree;
 struct archive_params;
 struct backup_params;
+struct arg_values;
 
 /* FIXME Split into tool & library contexts */
 /* command-instance-related variables needed by library */
@@ -68,6 +69,8 @@
 	const char *cmd_line;
 	struct command *command;
 	char **argv;
+	struct arg_values *arg_values;
+	struct dm_list arg_value_groups;
 	unsigned is_long_lived:1;	/* Optimises persistent_filter handling */
 	unsigned handles_missing_pvs:1;
 	unsigned handles_unknown_segments:1;
--- LVM2/lib/metadata/lv_manip.c	2010/11/11 12:32:34	1.237
+++ LVM2/lib/metadata/lv_manip.c	2010/11/11 17:29:06	1.238
@@ -3248,7 +3248,7 @@
 	if (!archive(vg))
 		return 0;
 
-	if (lp->tag) {
+	if (!dm_list_empty(&lp->tags)) {
 		if (!(vg->fid->fmt->features & FMT_TAGS)) {
 			log_error("Volume group %s does not support tags",
 				  vg->name);
@@ -3283,11 +3283,8 @@
 			    lv->minor);
 	}
 
-	if (lp->tag && !str_list_add(cmd->mem, &lv->tags, lp->tag)) {
-		log_error("Failed to add tag %s to %s/%s",
-			  lp->tag, lv->vg->name, lv->name);
-		return 0;
-	}
+	if (!dm_list_empty(&lp->tags))
+		dm_list_splice(&lv->tags, &lp->tags);
 
 	if (!lv_extend(lv, lp->segtype, lp->stripes, lp->stripe_size,
 		       1, lp->extents, NULL, 0u, 0u, lp->pvh, lp->alloc))
--- LVM2/lib/metadata/metadata-exported.h	2010/10/12 16:41:17	1.169
+++ LVM2/lib/metadata/metadata-exported.h	2010/11/11 17:29:06	1.170
@@ -516,7 +516,7 @@
 	uint32_t read_ahead; /* all */
 	alloc_policy_t alloc; /* all */
 
-	const char *tag; /* all */
+	struct dm_list tags;	/* all */
 };
 
 int lv_create_single(struct volume_group *vg,
--- LVM2/liblvm/lvm_lv.c	2010/10/25 14:09:08	1.27
+++ LVM2/liblvm/lvm_lv.c	2010/11/11 17:29:06	1.28
@@ -113,7 +113,7 @@
 	lp->permission = LVM_READ | LVM_WRITE;
 	lp->read_ahead = DM_READ_AHEAD_NONE;
 	lp->alloc = ALLOC_INHERIT;
-	lp->tag = NULL;
+	dm_list_init(&lp->tags);
 }
 
 /* Set default for linear segment specific LV parameters */
--- LVM2/tools/args.h	2010/10/13 10:34:32	1.80
+++ LVM2/tools/args.h	2010/11/11 17:29:06	1.81
@@ -40,8 +40,8 @@
 arg(removemissing_ARG, '\0', "removemissing", NULL, 0)
 arg(restoremissing_ARG, '\0', "restoremissing", NULL, 0)
 arg(abort_ARG, '\0', "abort", NULL, 0)
-arg(addtag_ARG, '\0', "addtag", tag_arg, 0)
-arg(deltag_ARG, '\0', "deltag", tag_arg, 0)
+arg(addtag_ARG, '\0', "addtag", tag_arg, ARG_GROUPABLE)
+arg(deltag_ARG, '\0', "deltag", tag_arg, ARG_GROUPABLE)
 arg(refresh_ARG, '\0', "refresh", NULL, 0)
 arg(mknodes_ARG, '\0', "mknodes", NULL, 0)
 arg(minor_ARG, '\0', "minor", minor_arg, 0)
@@ -90,11 +90,11 @@
 arg(colon_ARG, 'c', "colon", NULL, 0)
 arg(columns_ARG, 'C', "columns", NULL, 0)
 arg(contiguous_ARG, 'C', "contiguous", yes_no_arg, 0)
-arg(debug_ARG, 'd', "debug", NULL, ARG_REPEATABLE)
+arg(debug_ARG, 'd', "debug", NULL, ARG_COUNTABLE)
 arg(exported_ARG, 'e', "exported", NULL, 0)
 arg(physicalextent_ARG, 'E', "physicalextent", NULL, 0)
 arg(file_ARG, 'f', "file", string_arg, 0)
-arg(force_ARG, 'f', "force", NULL, ARG_REPEATABLE)
+arg(force_ARG, 'f', "force", NULL, ARG_COUNTABLE)
 arg(full_ARG, 'f', "full", NULL, 0)
 arg(help_ARG, 'h', "help", NULL, 0)
 arg(help2_ARG, '?', "", NULL, 0)
@@ -137,7 +137,7 @@
 arg(uuid_ARG, 'u', "uuid", NULL, 0)
 arg(uuidstr_ARG, 'u', "uuid", string_arg, 0)
 arg(uuidlist_ARG, 'U', "uuidlist", NULL, 0)
-arg(verbose_ARG, 'v', "verbose", NULL, ARG_REPEATABLE)
+arg(verbose_ARG, 'v', "verbose", NULL, ARG_COUNTABLE)
 arg(volumegroup_ARG, 'V', "volumegroup", NULL, 0)
 arg(allocatable_ARG, 'x', "allocatable", yes_no_arg, 0)
 arg(resizeable_ARG, 'x', "resizeable", yes_no_arg, 0)
--- LVM2/tools/lvchange.c	2010/10/26 01:37:59	1.126
+++ LVM2/tools/lvchange.c	2010/11/11 17:29:06	1.127
@@ -495,14 +495,20 @@
 			int arg)
 {
 	const char *tag;
+	struct arg_value_group_list *current_group;
 
-	if (!(tag = arg_str_value(cmd, arg, NULL))) {
-		log_error("Failed to get tag");
-		return 0;
-	}
+	dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
+		if (!grouped_arg_is_set(current_group->arg_values, arg))
+			continue;
 
-	if (!lv_change_tag(lv, tag, arg == addtag_ARG))
-		return_0;
+		if (!(tag = grouped_arg_str_value(current_group->arg_values, arg, NULL))) {
+			log_error("Failed to get tag");
+			return 0;
+		}
+
+		if (!lv_change_tag(lv, tag, arg == addtag_ARG))
+			return_0;
+	}
 
 	log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
 
--- LVM2/tools/lvcreate.c	2010/10/25 12:05:46	1.224
+++ LVM2/tools/lvcreate.c	2010/11/11 17:29:06	1.225
@@ -327,9 +327,12 @@
 {
 	int contiguous;
 	unsigned pagesize;
+	struct arg_value_group_list *current_group;
+	const char *tag;
 
 	memset(lp, 0, sizeof(*lp));
 	memset(lcp, 0, sizeof(*lcp));
+	dm_list_init(&lp->tags);
 
 	/*
 	 * Check selected options are compatible and determine segtype
@@ -507,7 +510,20 @@
 		return 0;
 	}
 
-	lp->tag = arg_str_value(cmd, addtag_ARG, NULL);
+	dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
+		if (!grouped_arg_is_set(current_group->arg_values, addtag_ARG))
+			continue;
+
+		if (!(tag = grouped_arg_str_value(current_group->arg_values, addtag_ARG, NULL))) {
+			log_error("Failed to get tag");
+			return 0;
+		}
+
+		if (!str_list_add(cmd->mem, &lp->tags, tag)) {
+                	log_error("Unable to allocate memory for tag %s", tag);
+			return 0;
+		}
+        }
 
 	lcp->pv_count = argc;
 	lcp->pvs = argv;
--- LVM2/tools/lvm.c	2010/10/25 12:57:00	1.114
+++ LVM2/tools/lvm.c	2010/11/11 17:29:06	1.115
@@ -95,7 +95,7 @@
 		while (match_no < com->num_args) {
 			char s[3];
 			char c;
-			if (!(c = (_cmdline->the_args +
+			if (!(c = (_cmdline->arg_props +
 				   com->valid_args[match_no++])->short_arg))
 				continue;
 
@@ -111,7 +111,7 @@
 
 	while (match_no - com->num_args < com->num_args) {
 		const char *l;
-		l = (_cmdline->the_args +
+		l = (_cmdline->arg_props +
 		     com->valid_args[match_no++ - com->num_args])->long_arg;
 		if (*(l + 2) && !strncmp(text, l, len))
 			return strdup(l);
--- LVM2/tools/lvm2cmdline.h	2010/01/11 19:19:17	1.9
+++ LVM2/tools/lvm2cmdline.h	2010/11/11 17:29:06	1.10
@@ -19,7 +19,7 @@
 struct cmd_context;
 
 struct cmdline_context {
-        struct arg *the_args;
+        struct arg_props *arg_props;
         struct command *commands;
         int num_commands;
         int commands_size;
--- LVM2/tools/lvmcmdline.c	2010/10/25 11:20:56	1.129
+++ LVM2/tools/lvmcmdline.c	2010/11/11 17:29:06	1.130
@@ -50,8 +50,8 @@
 /*
  * Table of valid switches
  */
-static struct arg _the_args[ARG_COUNT + 1] = {
-#define arg(a, b, c, d, e) {b, "", "--" c, d, e, 0, NULL, 0, 0, INT64_C(0), UINT64_C(0), SIGN_NONE, PERCENT_NONE},
+static struct arg_props _arg_props[ARG_COUNT + 1] = {
+#define arg(a, b, c, d, e) {b, "", "--" c, d, e},
 #include "args.h"
 #undef arg
 };
@@ -59,10 +59,14 @@
 static struct cmdline_context _cmdline;
 
 /* Command line args */
-/* FIXME: Move static _the_args into cmd? */
-unsigned arg_count(const struct cmd_context *cmd __attribute__((unused)), int a)
+unsigned arg_count(const struct cmd_context *cmd, int a)
 {
-	return _the_args[a].count;
+	return cmd->arg_values[a].count;
+}
+
+unsigned grouped_arg_count(const struct arg_values *av, int a)
+{
+	return av[a].count;
 }
 
 unsigned arg_is_set(const struct cmd_context *cmd, int a)
@@ -70,71 +74,81 @@
 	return arg_count(cmd, a) ? 1 : 0;
 }
 
-const char *arg_value(struct cmd_context *cmd __attribute__((unused)), int a)
+unsigned grouped_arg_is_set(const struct arg_values *av, int a)
+{
+	return grouped_arg_count(av, a) ? 1 : 0;
+}
+
+const char *arg_value(struct cmd_context *cmd, int a)
 {
-	return _the_args[a].value;
+	return cmd->arg_values[a].value;
 }
 
 const char *arg_str_value(struct cmd_context *cmd, int a, const char *def)
 {
-	return arg_count(cmd, a) ? _the_args[a].value : def;
+	return arg_count(cmd, a) ? cmd->arg_values[a].value : def;
+}
+
+const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def)
+{
+	return grouped_arg_count(av, a) ? av[a].value : def;
 }
 
 int32_t arg_int_value(struct cmd_context *cmd, int a, const int32_t def)
 {
-	return arg_count(cmd, a) ? _the_args[a].i_value : def;
+	return arg_count(cmd, a) ? cmd->arg_values[a].i_value : def;
 }
 
 uint32_t arg_uint_value(struct cmd_context *cmd, int a, const uint32_t def)
 {
-	return arg_count(cmd, a) ? _the_args[a].ui_value : def;
+	return arg_count(cmd, a) ? cmd->arg_values[a].ui_value : def;
 }
 
 int64_t arg_int64_value(struct cmd_context *cmd, int a, const int64_t def)
 {
-	return arg_count(cmd, a) ? _the_args[a].i64_value : def;
+	return arg_count(cmd, a) ? cmd->arg_values[a].i64_value : def;
 }
 
 uint64_t arg_uint64_value(struct cmd_context *cmd, int a, const uint64_t def)
 {
-	return arg_count(cmd, a) ? _the_args[a].ui64_value : def;
+	return arg_count(cmd, a) ? cmd->arg_values[a].ui64_value : def;
 }
 
 /* No longer used.
 const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def)
 {
-	return arg_count(cmd, a) ? _the_args[a].ptr : def;
+	return arg_count(cmd, a) ? cmd->arg_values[a].ptr : def;
 }
 */
 
 sign_t arg_sign_value(struct cmd_context *cmd, int a, const sign_t def)
 {
-	return arg_count(cmd, a) ? _the_args[a].sign : def;
+	return arg_count(cmd, a) ? cmd->arg_values[a].sign : def;
 }
 
 percent_t arg_percent_value(struct cmd_context *cmd, int a, const percent_t def)
 {
-	return arg_count(cmd, a) ? _the_args[a].percent : def;
+	return arg_count(cmd, a) ? cmd->arg_values[a].percent : def;
 }
 
-int arg_count_increment(struct cmd_context *cmd __attribute__((unused)), int a)
+int arg_count_increment(struct cmd_context *cmd, int a)
 {
-	return _the_args[a].count++;
+	return cmd->arg_values[a].count++;
 }
 
-int yes_no_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int yes_no_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
-	a->sign = SIGN_NONE;
-	a->percent = PERCENT_NONE;
+	av->sign = SIGN_NONE;
+	av->percent = PERCENT_NONE;
 
-	if (!strcmp(a->value, "y")) {
-		a->i_value = 1;
-		a->ui_value = 1;
+	if (!strcmp(av->value, "y")) {
+		av->i_value = 1;
+		av->ui_value = 1;
 	}
 
-	else if (!strcmp(a->value, "n")) {
-		a->i_value = 0;
-		a->ui_value = 0;
+	else if (!strcmp(av->value, "n")) {
+		av->i_value = 0;
+		av->ui_value = 0;
 	}
 
 	else
@@ -143,37 +157,36 @@
 	return 1;
 }
 
-int yes_no_excl_arg(struct cmd_context *cmd __attribute__((unused)),
-		    struct arg *a)
+int yes_no_excl_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
-	a->sign = SIGN_NONE;
-	a->percent = PERCENT_NONE;
+	av->sign = SIGN_NONE;
+	av->percent = PERCENT_NONE;
 
-	if (!strcmp(a->value, "e") || !strcmp(a->value, "ey") ||
-	    !strcmp(a->value, "ye")) {
-		a->i_value = CHANGE_AE;
-		a->ui_value = CHANGE_AE;
+	if (!strcmp(av->value, "e") || !strcmp(av->value, "ey") ||
+	    !strcmp(av->value, "ye")) {
+		av->i_value = CHANGE_AE;
+		av->ui_value = CHANGE_AE;
 	}
 
-	else if (!strcmp(a->value, "y")) {
-		a->i_value = CHANGE_AY;
-		a->ui_value = CHANGE_AY;
+	else if (!strcmp(av->value, "y")) {
+		av->i_value = CHANGE_AY;
+		av->ui_value = CHANGE_AY;
 	}
 
-	else if (!strcmp(a->value, "n") || !strcmp(a->value, "en") ||
-		 !strcmp(a->value, "ne")) {
-		a->i_value = CHANGE_AN;
-		a->ui_value = CHANGE_AN;
+	else if (!strcmp(av->value, "n") || !strcmp(av->value, "en") ||
+		 !strcmp(av->value, "ne")) {
+		av->i_value = CHANGE_AN;
+		av->ui_value = CHANGE_AN;
 	}
 
-	else if (!strcmp(a->value, "ln") || !strcmp(a->value, "nl")) {
-		a->i_value = CHANGE_ALN;
-		a->ui_value = CHANGE_ALN;
+	else if (!strcmp(av->value, "ln") || !strcmp(av->value, "nl")) {
+		av->i_value = CHANGE_ALN;
+		av->ui_value = CHANGE_ALN;
 	}
 
-	else if (!strcmp(a->value, "ly") || !strcmp(a->value, "yl")) {
-		a->i_value = CHANGE_ALY;
-		a->ui_value = CHANGE_ALY;
+	else if (!strcmp(av->value, "ly") || !strcmp(av->value, "yl")) {
+		av->i_value = CHANGE_ALY;
+		av->ui_value = CHANGE_ALY;
 	}
 
 	else
@@ -182,30 +195,30 @@
 	return 1;
 }
 
-int metadatatype_arg(struct cmd_context *cmd, struct arg *a)
+int metadatatype_arg(struct cmd_context *cmd, struct arg_values *av)
 {
-	return get_format_by_name(cmd, a->value) ? 1 : 0;
+	return get_format_by_name(cmd, av->value) ? 1 : 0;
 }
 
-static int _get_int_arg(struct arg *a, char **ptr)
+static int _get_int_arg(struct arg_values *av, char **ptr)
 {
 	char *val;
 	long v;
 
-	a->percent = PERCENT_NONE;
+	av->percent = PERCENT_NONE;
 
-	val = a->value;
+	val = av->value;
 	switch (*val) {
 	case '+':
-		a->sign = SIGN_PLUS;
+		av->sign = SIGN_PLUS;
 		val++;
 		break;
 	case '-':
-		a->sign = SIGN_MINUS;
+		av->sign = SIGN_MINUS;
 		val++;
 		break;
 	default:
-		a->sign = SIGN_NONE;
+		av->sign = SIGN_NONE;
 	}
 
 	if (!isdigit(*val))
@@ -216,16 +229,16 @@
 	if (*ptr == val)
 		return 0;
 
-	a->i_value = (int32_t) v;
-	a->ui_value = (uint32_t) v;
-	a->i64_value = (int64_t) v;
-	a->ui64_value = (uint64_t) v;
+	av->i_value = (int32_t) v;
+	av->ui_value = (uint32_t) v;
+	av->i64_value = (int64_t) v;
+	av->ui64_value = (uint64_t) v;
 
 	return 1;
 }
 
 /* Size stored in sectors */
-static int _size_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a, int factor)
+static int _size_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av, int factor)
 {
 	char *ptr;
 	int i;
@@ -234,20 +247,20 @@
 	double v;
 	uint64_t v_tmp, adjustment;
 
-	a->percent = PERCENT_NONE;
+	av->percent = PERCENT_NONE;
 
-	val = a->value;
+	val = av->value;
 	switch (*val) {
 	case '+':
-		a->sign = SIGN_PLUS;
+		av->sign = SIGN_PLUS;
 		val++;
 		break;
 	case '-':
-		a->sign = SIGN_MINUS;
+		av->sign = SIGN_MINUS;
 		val++;
 		break;
 	default:
-		a->sign = SIGN_NONE;
+		av->sign = SIGN_NONE;
 	}
 
 	if (!isdigit(*val))
@@ -289,50 +302,50 @@
 	} else
 		v *= factor;
 
-	a->i_value = (int32_t) v;
-	a->ui_value = (uint32_t) v;
-	a->i64_value = (int64_t) v;
-	a->ui64_value = (uint64_t) v;
+	av->i_value = (int32_t) v;
+	av->ui_value = (uint32_t) v;
+	av->i64_value = (int64_t) v;
+	av->ui64_value = (uint64_t) v;
 
 	return 1;
 }
 
-int size_kb_arg(struct cmd_context *cmd, struct arg *a)
+int size_kb_arg(struct cmd_context *cmd, struct arg_values *av)
 {
-	return _size_arg(cmd, a, 2);
+	return _size_arg(cmd, av, 2);
 }
 
-int size_mb_arg(struct cmd_context *cmd, struct arg *a)
+int size_mb_arg(struct cmd_context *cmd, struct arg_values *av)
 {
-	return _size_arg(cmd, a, 2048);
+	return _size_arg(cmd, av, 2048);
 }
 
-int int_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int int_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
 	char *ptr;
 
-	if (!_get_int_arg(a, &ptr) || (*ptr) || (a->sign == SIGN_MINUS))
+	if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS))
 		return 0;
 
 	return 1;
 }
 
-int int_arg_with_sign(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int int_arg_with_sign(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
 	char *ptr;
 
-	if (!_get_int_arg(a, &ptr) || (*ptr))
+	if (!_get_int_arg(av, &ptr) || (*ptr))
 		return 0;
 
 	return 1;
 }
 
 int int_arg_with_sign_and_percent(struct cmd_context *cmd __attribute__((unused)),
-				  struct arg *a)
+				  struct arg_values *av)
 {
 	char *ptr;
 
-	if (!_get_int_arg(a, &ptr))
+	if (!_get_int_arg(av, &ptr))
 		return 0;
 
 	if (!*ptr)
@@ -342,32 +355,32 @@
 		return 0;
 
 	if (!strcasecmp(ptr, "V") || !strcasecmp(ptr, "VG"))
-		a->percent = PERCENT_VG;
+		av->percent = PERCENT_VG;
 	else if (!strcasecmp(ptr, "L") || !strcasecmp(ptr, "LV"))
-		a->percent = PERCENT_LV;
+		av->percent = PERCENT_LV;
 	else if (!strcasecmp(ptr, "P") || !strcasecmp(ptr, "PV") ||
 		 !strcasecmp(ptr, "PVS"))
-		a->percent = PERCENT_PVS;
+		av->percent = PERCENT_PVS;
 	else if (!strcasecmp(ptr, "F") || !strcasecmp(ptr, "FR") ||
 		 !strcasecmp(ptr, "FREE"))
-		a->percent = PERCENT_FREE;
+		av->percent = PERCENT_FREE;
 	else if (!strcasecmp(ptr, "O") || !strcasecmp(ptr, "OR") ||
 		 !strcasecmp(ptr, "ORIGIN"))
-		a->percent = PERCENT_ORIGIN;
+		av->percent = PERCENT_ORIGIN;
 	else
 		return 0;
 
 	return 1;
 }
 
-int minor_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int minor_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
 	char *ptr;
 
-	if (!_get_int_arg(a, &ptr) || (*ptr) || (a->sign == SIGN_MINUS))
+	if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS))
 		return 0;
 
-	if (a->i_value > 255) {
+	if (av->i_value > 255) {
 		log_error("Minor number outside range 0-255");
 		return 0;
 	}
@@ -375,14 +388,14 @@
 	return 1;
 }
 
-int major_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int major_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
 	char *ptr;
 
-	if (!_get_int_arg(a, &ptr) || (*ptr) || (a->sign == SIGN_MINUS))
+	if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS))
 		return 0;
 
-	if (a->i_value > 255) {
+	if (av->i_value > 255) {
 		log_error("Major number outside range 0-255");
 		return 0;
 	}
@@ -393,14 +406,14 @@
 }
 
 int string_arg(struct cmd_context *cmd __attribute__((unused)),
-	       struct arg *a __attribute__((unused)))
+	       struct arg_values *av __attribute__((unused)))
 {
 	return 1;
 }
 
-int tag_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int tag_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
-	char *pos = a->value;
+	char *pos = av->value;
 
 	if (*pos == '@')
 		pos++;
@@ -408,20 +421,20 @@
 	if (!validate_name(pos))
 		return 0;
 
-	a->value = pos;
+	av->value = pos;
 
 	return 1;
 }
 
-int permission_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int permission_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
-	a->sign = SIGN_NONE;
+	av->sign = SIGN_NONE;
 
-	if ((!strcmp(a->value, "rw")) || (!strcmp(a->value, "wr")))
-		a->ui_value = LVM_READ | LVM_WRITE;
+	if ((!strcmp(av->value, "rw")) || (!strcmp(av->value, "wr")))
+		av->ui_value = LVM_READ | LVM_WRITE;
 
-	else if (!strcmp(a->value, "r"))
-		a->ui_value = LVM_READ;
+	else if (!strcmp(av->value, "r"))
+		av->ui_value = LVM_READ;
 
 	else
 		return 0;
@@ -429,45 +442,45 @@
 	return 1;
 }
 
-int alloc_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int alloc_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
 	alloc_policy_t alloc;
 
-	a->sign = SIGN_NONE;
+	av->sign = SIGN_NONE;
 
-	alloc = get_alloc_from_string(a->value);
+	alloc = get_alloc_from_string(av->value);
 	if (alloc == ALLOC_INVALID)
 		return 0;
 
-	a->ui_value = (uint32_t) alloc;
+	av->ui_value = (uint32_t) alloc;
 
 	return 1;
 }
 
-int segtype_arg(struct cmd_context *cmd, struct arg *a)
+int segtype_arg(struct cmd_context *cmd, struct arg_values *av)
 {
-	return get_segtype_from_string(cmd, a->value) ? 1 : 0;
+	return get_segtype_from_string(cmd, av->value) ? 1 : 0;
 }
 
 /*
  * Positive integer, zero or "auto".
  */
-int readahead_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+int readahead_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
 {
-	if (!strcasecmp(a->value, "auto")) {
-		a->ui_value = DM_READ_AHEAD_AUTO;
+	if (!strcasecmp(av->value, "auto")) {
+		av->ui_value = DM_READ_AHEAD_AUTO;
 		return 1;
 	}
 
-	if (!strcasecmp(a->value, "none")) {
-		a->ui_value = DM_READ_AHEAD_NONE;
+	if (!strcasecmp(av->value, "none")) {
+		av->ui_value = DM_READ_AHEAD_NONE;
 		return 1;
 	}
 
-	if (!_size_arg(cmd, a, 1))
+	if (!_size_arg(cmd, av, 1))
 		return 0;
 
-	if (a->sign == SIGN_MINUS)
+	if (av->sign == SIGN_MINUS)
 		return 0;
 
 	return 1;
@@ -476,22 +489,21 @@
 /*
  * Non-zero, positive integer, "all", or "unmanaged"
  */
-int metadatacopies_arg(struct cmd_context *cmd __attribute__((unused)),
-			 struct arg *a)
+int metadatacopies_arg(struct cmd_context *cmd, struct arg_values *av)
 {
 	if (!strncmp(cmd->command->name, "vg", 2)) {
-		if (!strcasecmp(a->value, "all")) {
-			a->ui_value = VGMETADATACOPIES_ALL;
+		if (!strcasecmp(av->value, "all")) {
+			av->ui_value = VGMETADATACOPIES_ALL;
 			return 1;
 		}
 
-		if (!strcasecmp(a->value, "unmanaged")) {
-			a->ui_value = VGMETADATACOPIES_UNMANAGED;
+		if (!strcasecmp(av->value, "unmanaged")) {
+			av->ui_value = VGMETADATACOPIES_UNMANAGED;
 			return 1;
 		}
 	}
 
-	return int_arg(cmd, a);
+	return int_arg(cmd, av);
 }
 
 static void __alloc(int size)
@@ -618,7 +630,7 @@
  */
 static void _add_getopt_arg(int arg, char **ptr, struct option **o)
 {
-	struct arg *a = _cmdline.the_args + arg;
+	struct arg_props *a = _cmdline.arg_props + arg;
 
 	if (a->short_arg) {
 		*(*ptr)++ = a->short_arg;
@@ -640,14 +652,14 @@
 #endif
 }
 
-static struct arg *_find_arg(struct command *com, int opt)
+static int _find_arg(struct command *com, int opt)
 {
-	struct arg *a;
+	struct arg_props *a;
 	int i, arg;
 
 	for (i = 0; i < com->num_args; i++) {
 		arg = com->valid_args[i];
-		a = _cmdline.the_args + arg;
+		a = _cmdline.arg_props + arg;
 
 		/*
 		 * opt should equal either the
@@ -656,30 +668,25 @@
 		 */
 		if ((a->short_arg && (opt == a->short_arg)) ||
 		    (!a->short_arg && (opt == arg)))
-			return a;
+			return arg;
 	}
 
-	return 0;
+	return -1;
 }
 
 static int _process_command_line(struct cmd_context *cmd, int *argc,
 				 char ***argv)
 {
-	int i, opt;
+	int i, opt, arg;
 	char str[((ARG_COUNT + 1) * 2) + 1], *ptr = str;
 	struct option opts[ARG_COUNT + 1], *o = opts;
-	struct arg *a;
-
-	for (i = 0; i < ARG_COUNT; i++) {
-		a = _cmdline.the_args + i;
+	struct arg_props *a;
+	struct arg_values *av;
+	struct arg_value_group_list *current_group = NULL;
 
-		/* zero the count and arg */
-		a->count = 0;
-		a->value = 0;
-		a->i_value = 0;
-		a->ui_value = 0;
-		a->i64_value = 0;
-		a->ui64_value = 0;
+	if (!(cmd->arg_values = dm_pool_zalloc(cmd->mem, sizeof(*cmd->arg_values) * ARG_COUNT))) {
+		log_fatal("Unable to allocate memory for command line arguments.");
+		return 0;
 	}
 
 	/* fill in the short and long opts */
@@ -697,15 +704,33 @@
 		if (opt == '?')
 			return 0;
 
-		a = _find_arg(cmd->command, opt);
-
-		if (!a) {
+		if ((arg = _find_arg(cmd->command, opt)) < 0) {
 			log_fatal("Unrecognised option.");
 			return 0;
 		}
 
-		if (a->count && !(a->flags & ARG_REPEATABLE)) {
-			log_error("Option%s%c%s%s may not be repeated",
+		a = _cmdline.arg_props + arg;
+
+		av = &cmd->arg_values[arg];
+
+		if (a->flags & ARG_GROUPABLE) {
+			/* Start a new group of arguments the first time or if a non-countable argument is repeated. */
+			if (!current_group || (current_group->arg_values[arg].count && !(a->flags & ARG_COUNTABLE))) {
+				/* FIXME Reduce size including only groupable args */
+				if (!(current_group = dm_pool_zalloc(cmd->mem, sizeof(struct arg_value_group_list) + sizeof(*cmd->arg_values) * ARG_COUNT))) {
+					log_fatal("Unable to allocate memory for command line arguments.");
+					return 0;
+				}
+
+				dm_list_add(&cmd->arg_value_groups, &current_group->list);
+			}
+			/* Maintain total argument count as well as count within each group */
+			av->count++;
+			av = &current_group->arg_values[arg];
+		}
+
+		if (av->count && !(a->flags & ARG_COUNTABLE)) {
+			log_error("Option%s%c%s%s may not be repeated.",
 				  a->short_arg ? " -" : "",
 				  a->short_arg ? : ' ',
 				  (a->short_arg && a->long_arg) ?
@@ -719,15 +744,15 @@
 				return 0;
 			}
 
-			a->value = optarg;
+			av->value = optarg;
 
-			if (!a->fn(cmd, a)) {
-				log_error("Invalid argument %s", optarg);
+			if (!a->fn(cmd, av)) {
+				log_error("Invalid argument for %s: %s", a->long_arg, optarg);
 				return 0;
 			}
 		}
 
-		a->count++;
+		av->count++;
 	}
 
 	*argc -= optind;
@@ -737,20 +762,20 @@
 
 static int _merge_synonym(struct cmd_context *cmd, int oldarg, int newarg)
 {
-	const struct arg *old;
-	struct arg *new;
+	const struct arg_values *old;
+	struct arg_values *new;
 
 	if (arg_count(cmd, oldarg) && arg_count(cmd, newarg)) {
 		log_error("%s and %s are synonyms.  Please only supply one.",
-			  _cmdline.the_args[oldarg].long_arg, _cmdline.the_args[newarg].long_arg);
+			  _cmdline.arg_props[oldarg].long_arg, _cmdline.arg_props[newarg].long_arg);
 		return 0;
 	}
 
 	if (!arg_count(cmd, oldarg))
 		return 1;
 
-	old = _cmdline.the_args + oldarg;
-	new = _cmdline.the_args + newarg;
+	old = cmd->arg_values + oldarg;
+	new = cmd->arg_values + newarg;
 
 	new->count = old->count;
 	new->value = old->value;
@@ -1120,6 +1145,7 @@
 	/*
 	 * free off any memory the command used.
 	 */
+	dm_list_init(&cmd->arg_value_groups);
 	dm_pool_empty(cmd->mem);
 
 	reset_lvm_errno(1);
@@ -1250,11 +1276,11 @@
 {
 	struct cmd_context *cmd;
 
-	_cmdline.the_args = &_the_args[0];
-
 	if (!(cmd = create_toolcontext(0, NULL)))
 		return_NULL;
 
+	_cmdline.arg_props = &_arg_props[0];
+
 	if (stored_errno()) {
 		destroy_toolcontext(cmd);
 		return_NULL;
--- LVM2/tools/pvchange.c	2010/09/23 12:02:34	1.84
+++ LVM2/tools/pvchange.c	2010/11/11 17:29:06	1.85
@@ -36,6 +36,8 @@
 	int r = 0;
 	int mda_ignore = 0;
 
+	struct arg_value_group_list *current_group;
+
 	if (arg_count(cmd, addtag_ARG))
 		tagarg = addtag_ARG;
 	else if (arg_count(cmd, deltag_ARG))
@@ -47,10 +49,6 @@
 	if (arg_count(cmd, metadataignore_ARG))
 		mda_ignore = !strcmp(arg_str_value(cmd, metadataignore_ARG, "n"),
 				      "y");
-	else if (tagarg && !(tag = arg_str_value(cmd, tagarg, NULL))) {
-		log_error("Failed to get tag");
-		return 0;
-	}
 
 	/* If in a VG, must change using volume group. */
 	if (!is_orphan(pv)) {
@@ -108,16 +106,25 @@
 		}
 	} else if (tagarg) {
 		/* tag or deltag */
-		if ((tagarg == addtag_ARG)) {
-			if (!str_list_add(cmd->mem, &pv->tags, tag)) {
-				log_error("Failed to add tag %s to physical "
-					  "volume %s", tag, pv_name);
+
+		dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
+			if (!grouped_arg_is_set(current_group->arg_values, tagarg))
+				continue;
+
+			if (!(tag = grouped_arg_str_value(current_group->arg_values, tagarg, NULL))) {
+				log_error("Failed to get tag");
 				goto out;
 			}
-		} else {
-			if (!str_list_del(&pv->tags, tag)) {
+
+			if ((tagarg == addtag_ARG)) {
+				if (!str_list_add(cmd->mem, &pv->tags, tag)) {
+					log_error("Failed to add tag %s to physical "
+						  "volume %s", tag, pv_name);
+					goto out;
+				}
+			} else if (!str_list_del(&pv->tags, tag)) {
 				log_error("Failed to remove tag %s from "
-					  "physical volume" "%s", tag, pv_name);
+				  	"physical volume" "%s", tag, pv_name);
 				goto out;
 			}
 		}
@@ -202,8 +209,8 @@
 	struct dm_list *vgnames;
 	struct str_list *sll;
 
-	if (arg_count(cmd, allocatable_ARG) + arg_count(cmd, addtag_ARG) +
-	    arg_count(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) +
+	if (arg_count(cmd, allocatable_ARG) + arg_is_set(cmd, addtag_ARG) +
+	    arg_is_set(cmd, deltag_ARG) + arg_count(cmd, uuid_ARG) +
 	    arg_count(cmd, metadataignore_ARG) != 1) {
 		log_error("Please give exactly one option of -x, -uuid, "
 			  "--addtag or --deltag");
--- LVM2/tools/tools.h	2010/10/25 11:20:56	1.72
+++ LVM2/tools/tools.h	2010/11/11 17:29:06	1.73
@@ -95,17 +95,10 @@
 	CHANGE_ALN = 4
 };
 
-#define ARG_REPEATABLE 0x00000001
-
-/* a global table of possible arguments */
-struct arg {
-	const char short_arg;
-	char _padding[7];
-	const char *long_arg;
-
-	int (*fn) (struct cmd_context * cmd, struct arg * a);
-	uint32_t flags;
+#define ARG_COUNTABLE 0x00000001	/* E.g. -vvvv */
+#define ARG_GROUPABLE 0x00000002	/* E.g. --addtag */
 
+struct arg_values {
 	unsigned count;
 	char *value;
 	int32_t i_value;
@@ -117,6 +110,21 @@
 /*	void *ptr; // Currently not used. */
 };
 
+/* a global table of possible arguments */
+struct arg_props {
+	const char short_arg;
+	char _padding[7];
+	const char *long_arg;
+
+	int (*fn) (struct cmd_context *cmd, struct arg_values *av);
+	uint32_t flags;
+};
+
+struct arg_value_group_list {
+        struct dm_list list;
+        struct arg_values arg_values[0];
+};
+
 #define CACHE_VGMETADATA	0x00000001
 #define PERMITTED_READ_ONLY 	0x00000002
 
@@ -136,24 +144,24 @@
 void usage(const char *name);
 
 /* the argument verify/normalise functions */
-int yes_no_arg(struct cmd_context *cmd, struct arg *a);
-int yes_no_excl_arg(struct cmd_context *cmd, struct arg *a);
-int size_kb_arg(struct cmd_context *cmd, struct arg *a);
-int size_mb_arg(struct cmd_context *cmd, struct arg *a);
-int int_arg(struct cmd_context *cmd, struct arg *a);
-int int_arg_with_sign(struct cmd_context *cmd, struct arg *a);
-int int_arg_with_sign_and_percent(struct cmd_context *cmd, struct arg *a);
-int major_arg(struct cmd_context *cmd, struct arg *a);
-int minor_arg(struct cmd_context *cmd, struct arg *a);
-int string_arg(struct cmd_context *cmd, struct arg *a);
-int tag_arg(struct cmd_context *cmd, struct arg *a);
-int permission_arg(struct cmd_context *cmd, struct arg *a);
-int metadatatype_arg(struct cmd_context *cmd, struct arg *a);
-int units_arg(struct cmd_context *cmd, struct arg *a);
-int segtype_arg(struct cmd_context *cmd, struct arg *a);
-int alloc_arg(struct cmd_context *cmd, struct arg *a);
-int readahead_arg(struct cmd_context *cmd, struct arg *a);
-int metadatacopies_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a);
+int yes_no_arg(struct cmd_context *cmd, struct arg_values *av);
+int yes_no_excl_arg(struct cmd_context *cmd, struct arg_values *av);
+int size_kb_arg(struct cmd_context *cmd, struct arg_values *av);
+int size_mb_arg(struct cmd_context *cmd, struct arg_values *av);
+int int_arg(struct cmd_context *cmd, struct arg_values *av);
+int int_arg_with_sign(struct cmd_context *cmd, struct arg_values *av);
+int int_arg_with_sign_and_percent(struct cmd_context *cmd, struct arg_values *av);
+int major_arg(struct cmd_context *cmd, struct arg_values *av);
+int minor_arg(struct cmd_context *cmd, struct arg_values *av);
+int string_arg(struct cmd_context *cmd, struct arg_values *av);
+int tag_arg(struct cmd_context *cmd, struct arg_values *av);
+int permission_arg(struct cmd_context *cmd, struct arg_values *av);
+int metadatatype_arg(struct cmd_context *cmd, struct arg_values *av);
+int units_arg(struct cmd_context *cmd, struct arg_values *av);
+int segtype_arg(struct cmd_context *cmd, struct arg_values *av);
+int alloc_arg(struct cmd_context *cmd, struct arg_values *av);
+int readahead_arg(struct cmd_context *cmd, struct arg_values *av);
+int metadatacopies_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av);
 
 /* we use the enums to access the switches */
 unsigned arg_count(const struct cmd_context *cmd, int a);
@@ -169,6 +177,10 @@
 percent_t arg_percent_value(struct cmd_context *cmd, int a, const percent_t def);
 int arg_count_increment(struct cmd_context *cmd, int a);
 
+unsigned grouped_arg_count(const struct arg_values *av, int a);
+unsigned grouped_arg_is_set(const struct arg_values *av, int a);
+const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def);
+
 const char *command_name(struct cmd_context *cmd);
 
 int pvmove_poll(struct cmd_context *cmd, const char *pv, unsigned background);
--- LVM2/tools/vgchange.c	2010/10/29 21:15:23	1.116
+++ LVM2/tools/vgchange.c	2010/11/11 17:29:06	1.117
@@ -364,14 +364,21 @@
 			 int arg)
 {
 	const char *tag;
+	struct arg_value_group_list *current_group;
 
-	if (!(tag = arg_str_value(cmd, arg, NULL))) {
-		log_error("Failed to get tag");
-		return 0;
-	}
+	dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
+		if (!grouped_arg_is_set(current_group->arg_values, arg))
+			continue;
+
+		if (!(tag = grouped_arg_str_value(current_group->arg_values, arg, NULL))) {
+			log_error("Failed to get tag");
+			return 0;
+		}
 
-	if (!vg_change_tag(vg, tag, arg == addtag_ARG))
-		return_0;
+		if (!vg_change_tag(vg, tag, arg == addtag_ARG))
+			return_0;
+
+	}
 
 	return 1;
 }
--- LVM2/tools/vgcreate.c	2010/06/30 20:03:53	1.80
+++ LVM2/tools/vgcreate.c	2010/11/11 17:29:06	1.81
@@ -24,6 +24,7 @@
 	const char *clustered_message = "";
 	char *vg_name;
 	struct pvcreate_params pp;
+	struct arg_value_group_list *current_group;
 
 	if (!argc) {
 		log_error("Please provide volume group name and "
@@ -85,21 +86,24 @@
 			 "(0 means unlimited)", vg->max_pv);
 
 	if (arg_count(cmd, addtag_ARG)) {
-		if (!(tag = arg_str_value(cmd, addtag_ARG, NULL))) {
-			log_error("Failed to get tag");
-			goto bad;
-		}
+		dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
+			if (!grouped_arg_is_set(current_group->arg_values, addtag_ARG))
+				continue;
+
+			if (!(tag = grouped_arg_str_value(current_group->arg_values, addtag_ARG, NULL))) {
+				log_error("Failed to get tag");
+				goto bad;
+			}
 
-		if (!vg_change_tag(vg, tag, 1))
-			goto_bad;
+			if (!vg_change_tag(vg, tag, 1))
+				goto_bad;
+		}
 	}
 
-	if (vg_is_clustered(vg)) {
+	if (vg_is_clustered(vg))
 		clustered_message = "Clustered ";
-	} else {
-		if (locking_is_clustered())
-			clustered_message = "Non-clustered ";
-	}
+	else if (locking_is_clustered())
+		clustered_message = "Non-clustered ";
 
 	if (!archive(vg))
 		goto_bad;


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2010-09-09 13:07 prajnoha
  0 siblings, 0 replies; 16+ messages in thread
From: prajnoha @ 2010-09-09 13:07 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	prajnoha@sourceware.org	2010-09-09 13:07:15

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/format_text: archiver.c 

Log message:
	Reinitialize archive and backup handling on toolcontext refresh.
	
	For example, when using '--config "backup { ... }"' line, the values from
	lvm.conf (or default values) should be overridden. This patch adds
	reinitialisation of archive and backup handling on toolcontext refresh
	which makes these settings to be applied.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1727&r2=1.1728
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.103&r2=1.104
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/archiver.c.diff?cvsroot=lvm2&r1=1.33&r2=1.34

--- LVM2/WHATS_NEW	2010/08/30 18:37:42	1.1727
+++ LVM2/WHATS_NEW	2010/09/09 13:07:13	1.1728
@@ -1,5 +1,6 @@
 Version 2.02.74 - 
 ==================================
+  Reinitialize archive and backup handling on toolcontext refresh.
   Fix opprobriously slow I/O to cluster mirrors created with --nosync.
   Make poll_mirror_progress report PROGRESS_CHECK_FAILED if LV is not a mirror.
   Like mirrors, don't scan origins if ignore_suspended_devices() is set.
--- LVM2/lib/commands/toolcontext.c	2010/08/11 12:14:23	1.103
+++ LVM2/lib/commands/toolcontext.c	2010/09/09 13:07:14	1.104
@@ -1343,6 +1343,9 @@
 	if (!_init_segtypes(cmd))
 		return 0;
 
+	if (!_init_backup(cmd))
+		return 0;
+
 	cmd->config_valid = 1;
 
 	reset_lvm_errno(1);
--- LVM2/lib/format_text/archiver.c	2010/07/08 18:24:29	1.33
+++ LVM2/lib/format_text/archiver.c	2010/09/09 13:07:14	1.34
@@ -40,6 +40,8 @@
 		 unsigned int keep_days, unsigned int keep_min,
 		 int enabled)
 {
+	archive_exit(cmd);
+
 	if (!(cmd->archive_params = dm_pool_zalloc(cmd->libmem,
 						sizeof(*cmd->archive_params)))) {
 		log_error("archive_params alloc failed");
@@ -156,6 +158,8 @@
 int backup_init(struct cmd_context *cmd, const char *dir,
 		int enabled)
 {
+	backup_exit(cmd);
+
 	if (!(cmd->backup_params = dm_pool_zalloc(cmd->libmem,
 					       sizeof(*cmd->backup_params)))) {
 		log_error("backup_params alloc failed");


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2010-08-11 12:14 prajnoha
  0 siblings, 0 replies; 16+ messages in thread
From: prajnoha @ 2010-08-11 12:14 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	prajnoha@sourceware.org	2010-08-11 12:14:24

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c toolcontext.h 
	lib/device     : device.c device.h 
	lib/filters    : filter.c 
	lib/misc       : lvm-globals.c lvm-globals.h 

Log message:
	Recognise and give preference to md device partitions (blkext major).
	
	We can already detect MD devices internally. But when using MD partitions,
	these have "block extended major" (blkext) assigned (259). Blkext major
	is also used in general, so we need to check whether the original device
	is an MD device actually.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1698&r2=1.1699
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.102&r2=1.103
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.h.diff?cvsroot=lvm2&r1=1.38&r2=1.39
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/device/device.c.diff?cvsroot=lvm2&r1=1.33&r2=1.34
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/device/device.h.diff?cvsroot=lvm2&r1=1.43&r2=1.44
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter.c.diff?cvsroot=lvm2&r1=1.55&r2=1.56
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-globals.c.diff?cvsroot=lvm2&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-globals.h.diff?cvsroot=lvm2&r1=1.6&r2=1.7

--- LVM2/WHATS_NEW	2010/08/09 14:06:03	1.1698
+++ LVM2/WHATS_NEW	2010/08/11 12:14:23	1.1699
@@ -1,5 +1,6 @@
 Version 2.02.73 - 
 ================================
+  Recognise and give preference to md device partitions (blkext major).
   Never scan internal LVM devices.
   Split-mirror operations were ignoring user-specified PVs.
   Fix data corruption bug in cluster mirrors.
--- LVM2/lib/commands/toolcontext.c	2010/07/02 10:25:16	1.102
+++ LVM2/lib/commands/toolcontext.c	2010/08/11 12:14:23	1.103
@@ -240,7 +240,9 @@
 		cmd->proc_dir[0] = '\0';
 	}
 
+	/* FIXME Use global value of sysfs_dir everywhere instead cmd->sysfs_dir. */
 	_get_sysfs_dir(cmd);
+	set_sysfs_dir_path(cmd->sysfs_dir);
 
 	/* activation? */
 	cmd->default_settings.activation = find_config_tree_int(cmd,
--- LVM2/lib/commands/toolcontext.h	2010/04/29 01:38:14	1.38
+++ LVM2/lib/commands/toolcontext.h	2010/08/11 12:14:23	1.39
@@ -95,7 +95,7 @@
 	char system_dir[PATH_MAX];
 	char dev_dir[PATH_MAX];
 	char proc_dir[PATH_MAX];
-	char sysfs_dir[PATH_MAX];
+	char sysfs_dir[PATH_MAX]; /* FIXME Use global value instead. */
 };
 
 /*
--- LVM2/lib/device/device.c	2010/04/06 17:36:42	1.33
+++ LVM2/lib/device/device.c	2010/08/11 12:14:24	1.34
@@ -278,7 +278,7 @@
 #ifdef linux
 
 int get_primary_dev(const char *sysfs_dir,
-		    struct device *dev, dev_t *result)
+		    const struct device *dev, dev_t *result)
 {
 	char path[PATH_MAX+1];
 	char temp_path[PATH_MAX+1];
--- LVM2/lib/device/device.h	2009/08/01 17:11:02	1.43
+++ LVM2/lib/device/device.h	2010/08/11 12:14:24	1.44
@@ -101,7 +101,7 @@
 int is_partitioned_dev(struct device *dev);
 
 int get_primary_dev(const char *sysfs_dir,
-		    struct device *dev, dev_t *result);
+		    const struct device *dev, dev_t *result);
 
 unsigned long dev_alignment_offset(const char *sysfs_dir,
 				   struct device *dev);
--- LVM2/lib/filters/filter.c	2010/07/09 15:34:43	1.55
+++ LVM2/lib/filters/filter.c	2010/08/11 12:14:24	1.56
@@ -59,6 +59,8 @@
 
 int dev_subsystem_part_major(const struct device *dev)
 {
+	dev_t primary_dev;
+
 	if (MAJOR(dev->dev) == -1)
 		return 0;
 
@@ -68,6 +70,11 @@
 	if (MAJOR(dev->dev) == _drbd_major)
 		return 1;
 
+	if ((MAJOR(dev->dev) == _blkext_major) &&
+	    (get_primary_dev(sysfs_dir_path(), dev, &primary_dev)) &&
+	    (MAJOR(primary_dev) == _md_major))
+		return 1;
+
 	return 0;
 }
 
@@ -79,6 +86,9 @@
 	if (MAJOR(dev->dev) == _drbd_major)
 		return "DRBD";
 
+	if (MAJOR(dev->dev) == _blkext_major)
+		return "BLKEXT";
+
 	return "";
 }
 
--- LVM2/lib/misc/lvm-globals.c	2010/01/11 15:40:04	1.5
+++ LVM2/lib/misc/lvm-globals.c	2010/08/11 12:14:24	1.6
@@ -40,6 +40,7 @@
 static int _error_message_produced = 0;
 static unsigned _is_static = 0;
 static int _udev_checking = 1;
+static char _sysfs_dir_path[PATH_MAX] = "";
 
 void init_verbose(int level)
 {
@@ -127,6 +128,12 @@
 	_cmd_name[sizeof(_cmd_name) - 1] = '\0';
 }
 
+void set_sysfs_dir_path(const char *path)
+{
+	strncpy(_sysfs_dir_path, path, sizeof(_sysfs_dir_path));
+	_sysfs_dir_path[sizeof(_sysfs_dir_path) - 1] = '\0';
+}
+
 const char *log_command_name()
 {
 	if (!_log_cmd_name)
@@ -224,3 +231,8 @@
 {
 	return _udev_checking;
 }
+
+const char *sysfs_dir_path()
+{
+	return _sysfs_dir_path;
+}
--- LVM2/lib/misc/lvm-globals.h	2010/01/11 15:40:04	1.6
+++ LVM2/lib/misc/lvm-globals.h	2010/08/11 12:14:24	1.7
@@ -39,6 +39,7 @@
 void init_udev_checking(int checking);
 
 void set_cmd_name(const char *cmd_name);
+void set_sysfs_dir_path(const char *path);
 
 int test_mode(void);
 int md_filtering(void);
@@ -56,6 +57,7 @@
 const char *log_command_name(void);
 unsigned is_static(void);
 int udev_checking(void);
+const char *sysfs_dir_path(void);
 
 #define DMEVENTD_MONITOR_IGNORE -1
 int dmeventd_monitor_mode(void);


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2010-04-29  1:38 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2010-04-29  1:38 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2010-04-29 01:38:14

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c toolcontext.h 
	tools          : lvcreate.c lvmcmdline.c lvresize.c tools.h 

Log message:
	Remove no-longer-used arg_ptr_value.
	Fix -M and --type to use strings not pointers that change on config refresh.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1540&r2=1.1541
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.93&r2=1.94
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.h.diff?cvsroot=lvm2&r1=1.37&r2=1.38
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvcreate.c.diff?cvsroot=lvm2&r1=1.220&r2=1.221
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.117&r2=1.118
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvresize.c.diff?cvsroot=lvm2&r1=1.121&r2=1.122
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/tools.h.diff?cvsroot=lvm2&r1=1.66&r2=1.67

--- LVM2/WHATS_NEW	2010/04/27 15:26:58	1.1540
+++ LVM2/WHATS_NEW	2010/04/29 01:38:12	1.1541
@@ -1,5 +1,8 @@
 Version 2.02.64 -
 =================================
+  Remove no-longer-used arg_ptr_value.
+  Fix -M and --type to use strings not pointers that change on config refresh.
+  Fix regression in down-convert of mirror images with partial PV specification.
   Fix lvconvert error message when existing mirrored LV is not found.
   Disallow the direct removal of a merging snapshot.
   Set appropriate udev flags for reserved LVs.
--- LVM2/lib/commands/toolcontext.c	2010/04/01 10:34:09	1.93
+++ LVM2/lib/commands/toolcontext.c	2010/04/29 01:38:14	1.94
@@ -733,6 +733,19 @@
 	return 1;
 }
 
+struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format)
+{
+        struct format_type *fmt;
+
+        dm_list_iterate_items(fmt, &cmd->formats)
+                if (!strcasecmp(fmt->name, format) ||
+                    !strcasecmp(fmt->name + 3, format) ||
+                    (fmt->alias && !strcasecmp(fmt->alias, format)))
+                        return fmt;
+
+        return NULL;
+}
+
 static int _init_formats(struct cmd_context *cmd)
 {
 	const char *format;
@@ -806,8 +819,8 @@
 	dm_list_iterate_items(fmt, &cmd->formats) {
 		if (!strcasecmp(fmt->name, format) ||
 		    (fmt->alias && !strcasecmp(fmt->alias, format))) {
-			cmd->default_settings.fmt = fmt;
-			cmd->fmt = cmd->default_settings.fmt;
+			cmd->default_settings.fmt_name = fmt->name;
+			cmd->fmt = fmt;
 			return 1;
 		}
 	}
@@ -1190,7 +1203,7 @@
 	return cmd;
 }
 
-static void _destroy_formats(struct dm_list *formats)
+static void _destroy_formats(struct cmd_context *cmd, struct dm_list *formats)
 {
 	struct dm_list *fmtl, *tmp;
 	struct format_type *fmt;
@@ -1268,7 +1281,7 @@
 	lvmcache_destroy(cmd, 0);
 	label_exit();
 	_destroy_segtypes(&cmd->segtypes);
-	_destroy_formats(&cmd->formats);
+	_destroy_formats(cmd, &cmd->formats);
 	if (cmd->filter) {
 		cmd->filter->destroy(cmd->filter);
 		cmd->filter = NULL;
@@ -1329,7 +1342,7 @@
 	lvmcache_destroy(cmd, 0);
 	label_exit();
 	_destroy_segtypes(&cmd->segtypes);
-	_destroy_formats(&cmd->formats);
+	_destroy_formats(cmd, &cmd->formats);
 	if (cmd->filter)
 		cmd->filter->destroy(cmd->filter);
 	if (cmd->mem)
--- LVM2/lib/commands/toolcontext.h	2010/01/07 19:54:22	1.37
+++ LVM2/lib/commands/toolcontext.h	2010/04/29 01:38:14	1.38
@@ -38,7 +38,7 @@
 	int udev_sync;
 	int cache_vgmetadata;
 	const char *msg_prefix;
-	struct format_type *fmt;
+	const char *fmt_name;
 	uint64_t unit_factor;
 	int cmd_name;		/* Show command name? */
 	mode_t umask;
@@ -110,4 +110,6 @@
 int config_files_changed(struct cmd_context *cmd);
 int init_lvmcache_orphans(struct cmd_context *cmd);
 
+struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format);
+
 #endif
--- LVM2/tools/lvcreate.c	2010/04/13 01:54:34	1.220
+++ LVM2/tools/lvcreate.c	2010/04/29 01:38:14	1.221
@@ -330,9 +330,7 @@
 	/*
 	 * Check selected options are compatible and determine segtype
 	 */
-	lp->segtype = (const struct segment_type *)
-	    arg_ptr_value(cmd, type_ARG,
-			  get_segtype_from_string(cmd, "striped"));
+	lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, "striped"));
 
 	if (arg_count(cmd, snapshot_ARG) || seg_is_snapshot(lp) ||
 	    arg_count(cmd, virtualsize_ARG))
--- LVM2/tools/lvmcmdline.c	2010/03/23 15:13:03	1.117
+++ LVM2/tools/lvmcmdline.c	2010/04/29 01:38:14	1.118
@@ -51,7 +51,7 @@
  * Table of valid switches
  */
 static struct arg _the_args[ARG_COUNT + 1] = {
-#define arg(a, b, c, d, e) {b, "", "--" c, d, e, 0, NULL, 0, 0, INT64_C(0), UINT64_C(0), SIGN_NONE, PERCENT_NONE, NULL},
+#define arg(a, b, c, d, e) {b, "", "--" c, d, e, 0, NULL, 0, 0, INT64_C(0), UINT64_C(0), SIGN_NONE, PERCENT_NONE},
 #include "args.h"
 #undef arg
 };
@@ -100,10 +100,12 @@
 	return arg_count(cmd, a) ? _the_args[a].ui64_value : def;
 }
 
+/* No longer used.
 const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def)
 {
 	return arg_count(cmd, a) ? _the_args[a].ptr : def;
 }
+*/
 
 sign_t arg_sign_value(struct cmd_context *cmd, int a, const sign_t def)
 {
@@ -182,21 +184,7 @@
 
 int metadatatype_arg(struct cmd_context *cmd, struct arg *a)
 {
-	struct format_type *fmt;
-	char *format;
-
-	format = a->value;
-
-	dm_list_iterate_items(fmt, &cmd->formats) {
-		if (!strcasecmp(fmt->name, format) ||
-		    !strcasecmp(fmt->name + 3, format) ||
-		    (fmt->alias && !strcasecmp(fmt->alias, format))) {
-			a->ptr = fmt;
-			return 1;
-		}
-	}
-
-	return 0;
+	return get_format_by_name(cmd, a->value) ? 1 : 0;
 }
 
 static int _get_int_arg(struct arg *a, char **ptr)
@@ -458,10 +446,7 @@
 
 int segtype_arg(struct cmd_context *cmd, struct arg *a)
 {
-	if (!(a->ptr = (void *) get_segtype_from_string(cmd, a->value)))
-		return 0;
-
-	return 1;
+	return get_segtype_from_string(cmd, a->value) ? 1 : 0;
 }
 
 /*
@@ -912,8 +897,9 @@
 
 	set_activation(cmd->current_settings.activation);
 
-	cmd->fmt = arg_ptr_value(cmd, metadatatype_ARG,
-				 cmd->current_settings.fmt);
+	cmd->fmt = get_format_by_name(cmd, arg_str_value(cmd, metadatatype_ARG,
+				      cmd->current_settings.fmt_name));
+
 	cmd->handles_missing_pvs = 0;
 }
 
--- LVM2/tools/lvresize.c	2010/04/09 01:00:11	1.121
+++ LVM2/tools/lvresize.c	2010/04/29 01:38:14	1.122
@@ -420,7 +420,8 @@
 	}
 
 	/* FIXME Support LVs with mixed segment types */
-	if (lp->segtype != arg_ptr_value(cmd, type_ARG, lp->segtype)) {
+	if (lp->segtype != get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG,
+								      lp->segtype->name))) {
 		log_error("VolumeType does not match (%s)", lp->segtype->name);
 		return EINVALID_CMD_LINE;
 	}
--- LVM2/tools/tools.h	2010/02/03 03:58:08	1.66
+++ LVM2/tools/tools.h	2010/04/29 01:38:14	1.67
@@ -114,7 +114,7 @@
 	uint64_t ui64_value;
 	sign_t sign;
 	percent_t percent;
-	void *ptr;
+/*	void *ptr; // Currently not used. */
 };
 
 #define CACHE_VGMETADATA 0x00000001


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2009-07-08 12:36 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2009-07-08 12:36 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2009-07-08 12:36:01

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/metadata   : segtype.h 

Log message:
	Permit several segment types to be registered by a single shared object.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1166&r2=1.1167
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.76&r2=1.77
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/segtype.h.diff?cvsroot=lvm2&r1=1.23&r2=1.24

--- LVM2/WHATS_NEW	2009/07/06 19:17:15	1.1166
+++ LVM2/WHATS_NEW	2009/07/08 12:36:01	1.1167
@@ -1,5 +1,6 @@
 Version 2.02.49 - 
 ================================
+  Permit several segment types to be registered by a single shared object.
   Update the man pages to document size units uniformly.
   Allow commandline sizes to be specified in terms of bytes and sectors.
   Update 'md_chunk_alignment' to use stripe-width to align PV data area.
--- LVM2/lib/commands/toolcontext.c	2009/06/17 20:54:20	1.76
+++ LVM2/lib/commands/toolcontext.c	2009/07/08 12:36:01	1.77
@@ -806,12 +806,59 @@
 	return 1;
 }
 
+struct segtype_library {
+	struct cmd_context *cmd;
+	void *lib;
+	const char *libname;
+};
+
+int lvm_register_segtype(struct segtype_library *seglib,
+			 struct segment_type *segtype)
+{
+	struct segment_type *segtype2;
+
+	segtype->library = seglib->lib;
+	segtype->cmd = seglib->cmd;
+
+	dm_list_iterate_items(segtype2, &seglib->cmd->segtypes) {
+		if (strcmp(segtype2->name, segtype->name))
+			continue;
+		log_error("Duplicate segment type %s: "
+			  "unloading shared library %s",
+			  segtype->name, seglib->libname);
+		segtype->ops->destroy(segtype);
+		return 0;
+	}
+
+	dm_list_add(&seglib->cmd->segtypes, &segtype->list);
+
+	return 1;
+}
+
+static int _init_single_segtype(struct segtype_library *seglib)
+{
+	struct segment_type *(*init_segtype_fn) (struct cmd_context *);
+	struct segment_type *segtype;
+
+	if (!(init_segtype_fn = dlsym(seglib->lib, "init_segtype"))) {
+		log_error("Shared library %s does not contain segment type "
+			  "functions", seglib->libname);
+		return 0;
+	}
+
+	if (!(segtype = init_segtype_fn(seglib->cmd)))
+		return_0;
+
+	return lvm_register_segtype(seglib, segtype);
+}
+
 static int _init_segtypes(struct cmd_context *cmd)
 {
 	struct segment_type *segtype;
 
 #ifdef HAVE_LIBDL
 	const struct config_node *cn;
+	struct segtype_library seglib;
 #endif
 
 	if (!(segtype = init_striped_segtype(cmd)))
@@ -854,9 +901,9 @@
 	    (cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
 
 		struct config_value *cv;
-		struct segment_type *(*init_segtype_fn) (struct cmd_context *);
-		void *lib;
-		struct segment_type *segtype2;
+		int (*init_multiple_segtypes_fn) (struct segtype_library *);
+
+		seglib.cmd = cmd;
 
 		for (cv = cn->v; cv; cv = cv->next) {
 			if (cv->type != CFG_STRING) {
@@ -864,32 +911,37 @@
 					  "global/segment_libraries");
 				return 0;
 			}
-			if (!(lib = load_shared_library(cmd, cv->v.str,
+			seglib.libname = cv->v.str;
+			if (!(seglib.lib = load_shared_library(cmd,
+							seglib.libname,
 							"segment type", 0)))
 				return_0;
 
-			if (!(init_segtype_fn = dlsym(lib, "init_segtype"))) {
-				log_error("Shared library %s does not contain "
-					  "segment type functions", cv->v.str);
-				dlclose(lib);
-				return 0;
-			}
-
-			if (!(segtype = init_segtype_fn(cmd)))
-				return 0;
-			segtype->library = lib;
-			dm_list_add(&cmd->segtypes, &segtype->list);
-
-			dm_list_iterate_items(segtype2, &cmd->segtypes) {
-				if ((segtype == segtype2) ||
-				     strcmp(segtype2->name, segtype->name))
-					continue;
-				log_error("Duplicate segment type %s: "
-					  "unloading shared library %s",
-					  segtype->name, cv->v.str);
-				dm_list_del(&segtype->list);
-				segtype->ops->destroy(segtype);
-				dlclose(lib);
+			if ((init_multiple_segtypes_fn =
+			    dlsym(seglib.lib, "init_multiple_segtypes"))) {
+				if (dlsym(seglib.lib, "init_segtype"))
+					log_warn("WARNING: Shared lib %s has "
+						 "conflicting init fns.  Using"
+						 " init_multiple_segtypes().",
+						 seglib.libname);
+			} else
+				init_multiple_segtypes_fn =
+				    _init_single_segtype;
+ 
+			if (!init_multiple_segtypes_fn(&seglib)) {
+				struct dm_list *sgtl, *tmp;
+				log_error("init_multiple_segtypes() failed: "
+					  "Unloading shared library %s",
+					  seglib.libname);
+				dm_list_iterate_safe(sgtl, tmp, &cmd->segtypes) {
+					segtype = dm_list_item(sgtl, struct segment_type);
+					if (segtype->library == seglib.lib) {
+						dm_list_del(&segtype->list);
+						segtype->ops->destroy(segtype);
+					}
+				}
+				dlclose(seglib.lib);
+				return_0;
 			}
 		}
 	}
@@ -1154,8 +1206,18 @@
 		lib = segtype->library;
 		segtype->ops->destroy(segtype);
 #ifdef HAVE_LIBDL
-		if (lib)
+		/*
+		 * If no segtypes remain from this library, close it.
+		 */
+		if (lib) {
+			struct segment_type *segtype2;
+			dm_list_iterate_items(segtype2, segtypes)
+				if (segtype2->library == lib)
+					goto skip_dlclose;
 			dlclose(lib);
+skip_dlclose:
+			;
+		}
 #endif
 	}
 }
--- LVM2/lib/metadata/segtype.h	2009/02/28 20:04:25	1.23
+++ LVM2/lib/metadata/segtype.h	2009/07/08 12:36:01	1.24
@@ -47,13 +47,13 @@
 #define segtype_is_virtual(segtype)	((segtype)->flags & SEG_VIRTUAL ? 1 : 0)
 
 struct segment_type {
-	struct dm_list list;
-	struct cmd_context *cmd;
+	struct dm_list list;		/* Internal */
+	struct cmd_context *cmd;	/* lvm_register_segtype() sets this. */
 	uint32_t flags;
 	struct segtype_handler *ops;
 	const char *name;
-	void *library;
-	void *private;
+	void *library;			/* lvm_register_segtype() sets this. */
+	void *private;			/* For the segtype handler to use. */
 };
 
 struct segtype_handler {
@@ -93,6 +93,10 @@
 struct segment_type *get_segtype_from_string(struct cmd_context *cmd,
 					     const char *str);
 
+struct segtype_library;
+int lvm_register_segtype(struct segtype_library *seglib,
+			 struct segment_type *segtype);
+
 struct segment_type *init_striped_segtype(struct cmd_context *cmd);
 struct segment_type *init_zero_segtype(struct cmd_context *cmd);
 struct segment_type *init_error_segtype(struct cmd_context *cmd);


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2008-12-07  4:27 wysochanski
  0 siblings, 0 replies; 16+ messages in thread
From: wysochanski @ 2008-12-07  4:27 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	wysochanski@sourceware.org	2008-12-07 04:27:57

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c toolcontext.h 
	lib/format_text: archive.c format-text.c 
	lib/misc       : lvm-file.c lvm-file.h 
	tools          : lvmcmdline.c 

Log message:
	Make _init_rand() thread safe - use rand_r() instead of rand().
	
	Use good entropy for seed value if possible.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1005&r2=1.1006
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.64&r2=1.65
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.h.diff?cvsroot=lvm2&r1=1.27&r2=1.28
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/archive.c.diff?cvsroot=lvm2&r1=1.32&r2=1.33
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.98&r2=1.99
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-file.c.diff?cvsroot=lvm2&r1=1.25&r2=1.26
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-file.h.diff?cvsroot=lvm2&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.75&r2=1.76

--- LVM2/WHATS_NEW	2008/12/07 04:23:37	1.1005
+++ LVM2/WHATS_NEW	2008/12/07 04:27:56	1.1006
@@ -1,5 +1,6 @@
 Version 2.02.44 - 
 ====================================
+  Use better random seed value in temp file creation.
   Add generic function to read /dev/urandom, used in uuid calculation.
   Use displayable_lvs_in_vg and lv_is_displayable for consistency throughout.
   Fix race in vgcreate that would result in second caller overwriting first.
--- LVM2/lib/commands/toolcontext.c	2008/11/03 22:14:27	1.64
+++ LVM2/lib/commands/toolcontext.c	2008/12/07 04:27:56	1.65
@@ -979,6 +979,14 @@
 	return 1;
 }
 
+static void _init_rand(struct cmd_context *cmd)
+{
+	if (read_urandom(&cmd->rand_seed, sizeof(cmd->rand_seed)))
+		return;
+
+	cmd->rand_seed = (unsigned) time(NULL) + (unsigned) getpid();
+}
+
 /* Entry point */
 struct cmd_context *create_toolcontext(struct arg *the_args, unsigned is_static,
 				       unsigned is_long_lived)
@@ -1077,6 +1085,8 @@
 	if (!_init_backup(cmd))
 		goto error;
 
+	_init_rand(cmd);
+
 	cmd->default_settings.cache_vgmetadata = 1;
 	cmd->current_settings = cmd->default_settings;
 
--- LVM2/lib/commands/toolcontext.h	2008/11/03 22:14:27	1.27
+++ LVM2/lib/commands/toolcontext.h	2008/12/07 04:27:56	1.28
@@ -62,6 +62,7 @@
 	const char *hostname;
 	const char *kernel_vsn;
 
+	unsigned rand_seed;
 	char *cmd_line;
 	struct command *command;
 	struct arg *args;
--- LVM2/lib/format_text/archive.c	2008/11/03 22:14:28	1.32
+++ LVM2/lib/format_text/archive.c	2008/12/07 04:27:56	1.33
@@ -236,7 +236,8 @@
 	/*
 	 * Write the vg out to a temporary file.
 	 */
-	if (!create_temp_name(dir, temp_file, sizeof(temp_file), &fd)) {
+	if (!create_temp_name(dir, temp_file, sizeof(temp_file), &fd,
+			      &vg->cmd->rand_seed)) {
 		log_err("Couldn't create temporary archive name.");
 		return 0;
 	}
--- LVM2/lib/format_text/format-text.c	2008/11/03 22:14:28	1.98
+++ LVM2/lib/format_text/format-text.c	2008/12/07 04:27:57	1.99
@@ -848,7 +848,8 @@
 		return 0;
 	}
 
-	if (!create_temp_name(temp_dir, temp_file, sizeof(temp_file), &fd)) {
+	if (!create_temp_name(temp_dir, temp_file, sizeof(temp_file), &fd,
+			      &vg->cmd->rand_seed)) {
 		log_err("Couldn't create temporary text file name.");
 		return 0;
 	}
--- LVM2/lib/misc/lvm-file.c	2008/01/30 14:00:00	1.25
+++ LVM2/lib/misc/lvm-file.c	2008/12/07 04:27:57	1.26
@@ -29,7 +29,8 @@
  * rename the file after successfully writing it.  Grab
  * NFS-supported exclusive fcntl discretionary lock.
  */
-int create_temp_name(const char *dir, char *buffer, size_t len, int *fd)
+int create_temp_name(const char *dir, char *buffer, size_t len, int *fd,
+		     unsigned *seed)
 {
 	int i, num;
 	pid_t pid;
@@ -41,7 +42,7 @@
 		.l_len = 0
 	};
 
-	num = rand();
+	num = rand_r(seed);
 	pid = getpid();
 	if (gethostname(hostname, sizeof(hostname)) < 0) {
 		log_sys_error("gethostname", "");
--- LVM2/lib/misc/lvm-file.h	2007/08/20 20:55:27	1.12
+++ LVM2/lib/misc/lvm-file.h	2008/12/07 04:27:57	1.13
@@ -19,7 +19,8 @@
 /*
  * Create a temporary filename, and opens a descriptor to the file.
  */
-int create_temp_name(const char *dir, char *buffer, size_t len, int *fd);
+int create_temp_name(const char *dir, char *buffer, size_t len, int *fd,
+		     unsigned *seed);
 
 /*
  * NFS-safe rename of a temporary file to a common name, designed
--- LVM2/tools/lvmcmdline.c	2008/11/18 10:13:23	1.75
+++ LVM2/tools/lvmcmdline.c	2008/12/07 04:27:57	1.76
@@ -997,11 +997,6 @@
 	return *argc;
 }
 
-static void _init_rand(void)
-{
-	srand((unsigned) time(NULL) + (unsigned) getpid());
-}
-
 static const char *_get_cmdline(pid_t pid)
 {
 	static char _proc_cmdline[32];
@@ -1096,8 +1091,6 @@
 	if (!(cmd = create_toolcontext(_cmdline.the_args, is_static, 0)))
 		return_NULL;
 
-	_init_rand();
-
 	_apply_settings(cmd);
 
 	return cmd;


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2007-07-28 12:26 meyering
  0 siblings, 0 replies; 16+ messages in thread
From: meyering @ 2007-07-28 12:26 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	meyering@sourceware.org	2007-07-28 12:26:21

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/format_text: archiver.c format-text.c 
	lib/locking    : file_locking.c 
	lib/misc       : lvm-file.c lvm-file.h 

Log message:
	Remove create_dir function; use now-equivalent dm_create_dir instead.
	* lib/misc/lvm-file.c (_create_dir_recursive, create_dir): Remove functions.
	* lib/misc/lvm-file.h (create_dir): Remove declaration.
	* lib/commands/toolcontext.c (create_toolcontext): s/create_dir/dm_create_dir/
	* lib/format_text/archiver.c (archive, backup): Likewise.
	* lib/format_text/format-text.c (_add_dir): Likewise.
	* lib/locking/file_locking.c (init_file_locking): Likewise.
	Patch by Jun'ichi Nomura.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.672&r2=1.673
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.52&r2=1.53
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/archiver.c.diff?cvsroot=lvm2&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/format-text.c.diff?cvsroot=lvm2&r1=1.78&r2=1.79
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/locking/file_locking.c.diff?cvsroot=lvm2&r1=1.28&r2=1.29
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-file.c.diff?cvsroot=lvm2&r1=1.21&r2=1.22
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-file.h.diff?cvsroot=lvm2&r1=1.10&r2=1.11

--- LVM2/WHATS_NEW	2007/07/26 13:28:32	1.672
+++ LVM2/WHATS_NEW	2007/07/28 12:26:21	1.673
@@ -1,5 +1,6 @@
 Version 2.02.28 -
 ================================
+  Remove create_dir function; use now-equivalent dm_create_dir instead
   Detect stream write failure reliably; new fn: lvm_fclose; use dm_fclose
   Fix clvmd if compiled with gulm support. (2.02.26)
   Trivial fix to lvdisplay man page.
--- LVM2/lib/commands/toolcontext.c	2007/07/23 10:45:49	1.52
+++ LVM2/lib/commands/toolcontext.c	2007/07/28 12:26:21	1.53
@@ -939,7 +939,7 @@
 		goto error;
 
 	/* Create system directory if it doesn't already exist */
-	if (*cmd->sys_dir && !create_dir(cmd->sys_dir)) {
+	if (*cmd->sys_dir && !dm_create_dir(cmd->sys_dir)) {
 		log_error("Failed to create LVM2 system dir for metadata backups, config "
 			  "files and internal cache.");
 		log_error("Set environment variable LVM_SYSTEM_DIR to alternative location "
--- LVM2/lib/format_text/archiver.c	2007/06/28 17:33:44	1.7
+++ LVM2/lib/format_text/archiver.c	2007/07/28 12:26:21	1.8
@@ -117,7 +117,7 @@
 		return 1;
 	}
 
-	if (!create_dir(vg->cmd->archive_params->dir))
+	if (!dm_create_dir(vg->cmd->archive_params->dir))
 		return 0;
 
 	/* Trap a read-only file system */
@@ -223,7 +223,7 @@
 		return 1;
 	}
 
-	if (!create_dir(vg->cmd->backup_params->dir))
+	if (!dm_create_dir(vg->cmd->backup_params->dir))
 		return 0;
 
 	/* Trap a read-only file system */
--- LVM2/lib/format_text/format-text.c	2007/07/24 17:48:08	1.78
+++ LVM2/lib/format_text/format-text.c	2007/07/28 12:26:21	1.79
@@ -1856,7 +1856,7 @@
 {
 	struct dir_list *dl;
 
-	if (create_dir(dir)) {
+	if (dm_create_dir(dir)) {
 		if (!(dl = dm_malloc(sizeof(struct list) + strlen(dir) + 1))) {
 			log_error("_add_dir allocation failed");
 			return 0;
--- LVM2/lib/locking/file_locking.c	2007/07/20 15:22:46	1.28
+++ LVM2/lib/locking/file_locking.c	2007/07/28 12:26:21	1.29
@@ -284,7 +284,7 @@
 						DEFAULT_LOCK_DIR),
 		sizeof(_lock_dir));
 
-	if (!create_dir(_lock_dir))
+	if (!dm_create_dir(_lock_dir))
 		return 0;
 
 	/* Trap a read-only file system */
--- LVM2/lib/misc/lvm-file.c	2007/07/24 17:48:08	1.21
+++ LVM2/lib/misc/lvm-file.c	2007/07/28 12:26:21	1.22
@@ -140,56 +140,6 @@
 	return 1;
 }
 
-static int _create_dir_recursive(const char *dir)
-{
-	char *orig, *s;
-	int rc;
-
-	log_verbose("Creating directory \"%s\"", dir);
-	/* Create parent directories */
-	orig = s = dm_strdup(dir);
-	while ((s = strchr(s, '/')) != NULL) {
-		*s = '\0';
-		if (*orig) {
-			rc = mkdir(orig, 0777);
-			if (rc < 0 && errno != EEXIST) {
-				if (errno != EROFS)
-					log_sys_error("mkdir", orig);
-				dm_free(orig);
-				return 0;
-			}
-		}
-		*s++ = '/';
-	}
-	dm_free(orig);
-
-	/* Create final directory */
-	rc = mkdir(dir, 0777);
-	if (rc < 0 && errno != EEXIST) {
-		if (errno != EROFS)
-			log_sys_error("mkdir", dir);
-		return 0;
-	}
-	return 1;
-}
-
-int create_dir(const char *dir)
-{
-	struct stat info;
-
-	if (!*dir)
-		return 1;
-
-	if (stat(dir, &info) < 0)
-		return _create_dir_recursive(dir);
-
-	if (S_ISDIR(info.st_mode))
-		return 1;
-
-	log_error("Directory \"%s\" not found", dir);
-	return 0;
-}
-
 int is_empty_dir(const char *dir)
 {
 	struct dirent *dirent;
@@ -273,7 +223,7 @@
 	if ((c = strrchr(dir, '/')))
 		*c = '\0';
 
-	if (!create_dir(dir)) {
+	if (!dm_create_dir(dir)) {
 		dm_free(dir);
 		return -1;
 	}
--- LVM2/lib/misc/lvm-file.h	2007/07/24 17:48:08	1.10
+++ LVM2/lib/misc/lvm-file.h	2007/07/28 12:26:21	1.11
@@ -39,12 +39,6 @@
  */
 int is_empty_dir(const char *dir);
 
-/*
- * Create directory (recursively) if necessary.  Return 1
- * if directory was successfully created (or already exists), else 0.
- */
-int create_dir(const char *dir);
-
 /* Sync directory changes */
 void sync_dir(const char *file);
 


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2007-07-23 10:45 mbroz
  0 siblings, 0 replies; 16+ messages in thread
From: mbroz @ 2007-07-23 10:45 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	mbroz@sourceware.org	2007-07-23 10:45:49

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/device     : dev-cache.c 

Log message:
	Fix loading of persistent cache if cache_dir is used. (2.02.23)
	Move lstat warning in _compare_paths to verbose output only.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.666&r2=1.667
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.51&r2=1.52
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/device/dev-cache.c.diff?cvsroot=lvm2&r1=1.48&r2=1.49

--- LVM2/WHATS_NEW	2007/07/20 15:48:39	1.666
+++ LVM2/WHATS_NEW	2007/07/23 10:45:49	1.667
@@ -1,4 +1,6 @@
 Version 2.02.28 -
+================================
+  Fix loading of persistent cache if cache_dir is used. (2.02.23)
   Eliminate uses of strdup+basename.  Use last_path_component instead.
   Use gcc's printf attribute wherever possible.
   In _line_append, use "sizeof buf - 1" rather than equivalent "4095"
--- LVM2/lib/commands/toolcontext.c	2007/06/28 17:33:44	1.51
+++ LVM2/lib/commands/toolcontext.c	2007/07/23 10:45:49	1.52
@@ -611,7 +611,10 @@
 		return 0;
 	}
 
-	if (!(f4 = persistent_filter_create(f3, dev_cache ? : cache_file))) {
+	if (!dev_cache)
+		dev_cache = cache_file;
+
+	if (!(f4 = persistent_filter_create(f3, dev_cache))) {
 		log_error("Failed to create persistent device filter");
 		return 0;
 	}
--- LVM2/lib/device/dev-cache.c	2007/04/27 18:52:05	1.48
+++ LVM2/lib/device/dev-cache.c	2007/07/23 10:45:49	1.49
@@ -205,11 +205,11 @@
 			*s1 = '\0';
 		}
 		if (lstat(p0, &stat0)) {
-			log_sys_error("lstat", p0);
+			log_sys_very_verbose("lstat", p0);
 			return 1;
 		}
 		if (lstat(p1, &stat1)) {
-			log_sys_error("lstat", p1);
+			log_sys_very_verbose("lstat", p1);
 			return 0;
 		}
 		if (S_ISLNK(stat0.st_mode) && !S_ISLNK(stat1.st_mode))


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2006-11-04  3:34 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2006-11-04  3:34 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2006-11-04 03:34:10

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/config     : config.c config.h 
	lib/filters    : filter-persistent.c filter-persistent.h 
	lib/format_text: import.c 
	lib/misc       : lvm-file.c lvm-file.h 

Log message:
	Protect .cache manipulations with fcntl locking.
	Change .cache timestamp comparisons to use ctime.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.489&r2=1.490
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.42&r2=1.43
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/config.c.diff?cvsroot=lvm2&r1=1.47&r2=1.48
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/config.h.diff?cvsroot=lvm2&r1=1.20&r2=1.21
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter-persistent.c.diff?cvsroot=lvm2&r1=1.27&r2=1.28
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter-persistent.h.diff?cvsroot=lvm2&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import.c.diff?cvsroot=lvm2&r1=1.41&r2=1.42
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-file.c.diff?cvsroot=lvm2&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-file.h.diff?cvsroot=lvm2&r1=1.7&r2=1.8

--- LVM2/WHATS_NEW	2006/11/02 23:33:20	1.489
+++ LVM2/WHATS_NEW	2006/11/04 03:34:09	1.490
@@ -1,5 +1,7 @@
 Version 2.02.14 - 
 ===================================
+  Protect .cache manipulations with fcntl locking.
+  Change .cache timestamp comparisons to use ctime.
   Fix mirror log LV writing to set all bits in whole LV.
   Fix clustered VG detection and default runlevels in clvmd_init_rhel4.
   Fix high-level free space check for partial allocations.
--- LVM2/lib/commands/toolcontext.c	2006/08/31 22:21:00	1.42
+++ LVM2/lib/commands/toolcontext.c	2006/11/04 03:34:09	1.43
@@ -330,7 +330,7 @@
 		return 0;
 	}
 
-	if (!(cfl->cft = create_config_tree(config_file))) {
+	if (!(cfl->cft = create_config_tree(config_file, 0))) {
 		log_error("config_tree allocation failed");
 		return 0;
 	}
@@ -370,7 +370,7 @@
 {
 	/* No config file if LVM_SYSTEM_DIR is empty */
 	if (!*cmd->sys_dir) {
-		if (!(cmd->cft = create_config_tree(NULL))) {
+		if (!(cmd->cft = create_config_tree(NULL, 0))) {
 			log_error("Failed to create config tree");
 			return 0;
 		}
@@ -408,7 +408,7 @@
 
 	/* Replace temporary duplicate copy of lvm.conf */
 	if (cmd->cft->root) {
-		if (!(cmd->cft = create_config_tree(NULL))) {
+		if (!(cmd->cft = create_config_tree(NULL, 0))) {
 			log_error("Failed to create config tree");
 			return 0;
 		}
@@ -609,8 +609,8 @@
 		cmd->dump_filter = 0;
 
 	if (!stat(dev_cache, &st) &&
-	    (st.st_mtime > config_file_timestamp(cmd->cft)) &&
-	    !persistent_filter_load(f4))
+	    (st.st_ctime != config_file_timestamp(cmd->cft)) &&
+	    !persistent_filter_load(f4, NULL))
 		log_verbose("Failed to load existing device cache from %s",
 			    dev_cache);
 
--- LVM2/lib/config/config.c	2006/08/17 18:23:43	1.47
+++ LVM2/lib/config/config.c	2006/11/04 03:34:09	1.48
@@ -58,6 +58,8 @@
 	time_t timestamp;
 	char *filename;
 	int exists;
+	int keep_open;
+	struct device *dev;
 };
 
 static void _get_token(struct parser *p, int tok_prev);
@@ -95,7 +97,7 @@
 /*
  * public interface
  */
-struct config_tree *create_config_tree(const char *filename)
+struct config_tree *create_config_tree(const char *filename, int keep_open)
 {
 	struct cs *c;
 	struct dm_pool *mem = dm_pool_create("config", 10 * 1024);
@@ -115,6 +117,8 @@
 	c->cft.root = (struct config_node *) NULL;
 	c->timestamp = 0;
 	c->exists = 0;
+	c->keep_open = keep_open;
+	c->dev = 0;
 	if (filename)
 		c->filename = dm_pool_strdup(c->mem, filename);
 	return &c->cft;
@@ -122,7 +126,12 @@
 
 void destroy_config_tree(struct config_tree *cft)
 {
-	dm_pool_destroy(((struct cs *) cft)->mem);
+	struct cs *c = (struct cs *) cft;
+
+	if (c->dev)
+		dev_close(c->dev);
+
+	dm_pool_destroy(c->mem);
 }
 
 static int _parse_config_file(struct parser *p, struct config_tree *cft)
@@ -143,7 +152,7 @@
 	struct config_tree *cft;
 	struct parser *p;
 
-	if (!(cft = create_config_tree(NULL)))
+	if (!(cft = create_config_tree(NULL, 0)))
 		return_NULL;
 
 	c = (struct cs *) cft;
@@ -250,7 +259,6 @@
 {
 	struct cs *c = (struct cs *) cft;
 	struct stat info;
-	struct device *dev;
 	int r = 1;
 
 	if (stat(c->filename, &info)) {
@@ -272,22 +280,23 @@
 		return 1;
 	}
 
-	if (!(dev = dev_create_file(c->filename, NULL, NULL, 1))) {
-		stack;
-		return 0;
-	}
+	if (!c->dev) {
+		if (!(c->dev = dev_create_file(c->filename, NULL, NULL, 1)))
+			return_0;
 
-	if (!dev_open_flags(dev, O_RDONLY, 0, 0)) {
-		stack;
-		return 0;
+		if (!dev_open_flags(c->dev, O_RDONLY, 0, 0))
+			return_0;
 	}
 
-	r = read_config_fd(cft, dev, 0, (size_t) info.st_size, 0, 0,
+	r = read_config_fd(cft, c->dev, 0, (size_t) info.st_size, 0, 0,
 			   (checksum_fn_t) NULL, 0);
 
-	dev_close(dev);
+	if (!c->keep_open) {
+		dev_close(c->dev);
+		c->dev = 0;
+	}
 
-	c->timestamp = info.st_mtime;
+	c->timestamp = info.st_ctime;
 
 	return r;
 }
@@ -331,7 +340,7 @@
 	}
 
 	/* Unchanged? */
-	if (c->timestamp == info.st_mtime)
+	if (c->timestamp == info.st_ctime)
 		return 0;
 
       reload:
--- LVM2/lib/config/config.h	2006/05/16 16:48:30	1.20
+++ LVM2/lib/config/config.h	2006/11/04 03:34:09	1.21
@@ -53,7 +53,7 @@
 	struct config_tree *cft;
 };
 
-struct config_tree *create_config_tree(const char *filename);
+struct config_tree *create_config_tree(const char *filename, int keep_open);
 struct config_tree *create_config_tree_from_string(struct cmd_context *cmd,
 						   const char *config_settings);
 void destroy_config_tree(struct config_tree *cft);
--- LVM2/lib/filters/filter-persistent.c	2006/04/19 15:33:06	1.27
+++ LVM2/lib/filters/filter-persistent.c	2006/11/04 03:34:09	1.28
@@ -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-2006 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -17,6 +17,7 @@
 #include "config.h"
 #include "dev-cache.h"
 #include "filter-persistent.h"
+#include "lvm-file.h"
 
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -26,11 +27,12 @@
 	char *file;
 	struct dm_hash_table *devices;
 	struct dev_filter *real;
+	time_t ctime;
 };
 
 /*
- * entries in the table can be in one of these
- * states.
+ * The hash table holds one of these two states
+ * against each entry.
  */
 #define PF_BAD_DEVICE ((void *) 1)
 #define PF_GOOD_DEVICE ((void *) 2)
@@ -93,22 +95,26 @@
 	return 1;
 }
 
-int persistent_filter_load(struct dev_filter *f)
+int persistent_filter_load(struct dev_filter *f, struct config_tree **cft_out)
 {
 	struct pfilter *pf = (struct pfilter *) f->private;
-
-	int r = 0;
 	struct config_tree *cft;
+        struct stat info;
+	int r = 0;
 
-	if (!(cft = create_config_tree(pf->file))) {
-		stack;
-		return 0;
+        if (!stat(pf->file, &info))
+		pf->ctime = info.st_ctime;
+	else {
+                log_very_verbose("%s: stat failed: %s", pf->file,
+				 strerror(errno));
+		return_0;
 	}
 
-	if (!read_config_file(cft)) {
-		stack;
-		goto out;
-	}
+	if (!(cft = create_config_tree(pf->file, 1)))
+		return_0;
+
+	if (!read_config_file(cft))
+		goto_out;
 
 	_read_array(pf, cft, "persistent_filter_cache/valid_devices",
 		    PF_GOOD_DEVICE);
@@ -126,7 +132,10 @@
 	log_very_verbose("Loaded persistent filter cache from %s", pf->file);
 
       out:
-	destroy_config_tree(cft);
+	if (r && cft_out)
+		*cft_out = cft;
+	else
+		destroy_config_tree(cft);
 	return r;
 }
 
@@ -163,8 +172,12 @@
 int persistent_filter_dump(struct dev_filter *f)
 {
 	struct pfilter *pf = (struct pfilter *) f->private;
-
+	char *tmp_file;
+	struct stat info, info2;
+	struct config_tree *cft = NULL;
 	FILE *fp;
+	int lockfd;
+	int r = 0;
 
 	if (!dm_hash_get_num_entries(pf->devices)) {
 		log_very_verbose("Internal persistent device cache empty "
@@ -179,11 +192,43 @@
 
 	log_very_verbose("Dumping persistent device cache to %s", pf->file);
 
-	fp = fopen(pf->file, "w");
-	if (!fp) {
-		if (errno != EROFS)
-			log_sys_error("fopen", pf->file);
-		return 0;
+	while (1) {
+		if ((lockfd = fcntl_lock_file(pf->file, F_WRLCK, 0)) < 0)
+			return_0;
+
+		/*
+		 * Ensure we locked the file we expected
+		 */
+		if (fstat(lockfd, &info)) {
+			log_sys_error("fstat", pf->file);
+			goto out;
+		}
+		if (stat(pf->file, &info2)) {
+			log_sys_error("stat", pf->file);
+			goto out;
+		}
+
+		if (!memcmp(&info.st_ino, &info2.st_ino, sizeof(ino_t)))
+			break;
+	
+		fcntl_unlock_file(lockfd);
+	}
+
+	/*
+	 * If file contents changed since we loaded it, merge new contents
+	 */
+	if (info.st_ctime != pf->ctime)
+		/* Keep cft open to avoid losing lock */
+		persistent_filter_load(f, &cft);
+
+	tmp_file = alloca(strlen(pf->file) + 5);
+	sprintf(tmp_file, "%s.tmp", pf->file);
+
+	if (!(fp = fopen(tmp_file, "w"))) {
+		/* EACCES has been reported over NFS */
+		if (errno != EROFS && errno != EACCES)
+			log_sys_error("fopen", tmp_file);
+		goto out;
 	}
 
 	fprintf(fp, "# This file is automatically maintained by lvm.\n\n");
@@ -195,7 +240,20 @@
 
 	fprintf(fp, "}\n");
 	fclose(fp);
-	return 1;
+
+	if (rename(tmp_file, pf->file))
+		log_error("%s: rename to %s failed: %s", tmp_file, pf->file,
+			  strerror(errno));
+
+	r = 1;
+
+out:
+	fcntl_unlock_file(lockfd);
+
+	if (cft)
+		destroy_config_tree(cft);
+
+	return r;
 }
 
 static int _lookup_p(struct dev_filter *f, struct device *dev)
--- LVM2/lib/filters/filter-persistent.h	2004/03/30 19:35:38	1.4
+++ LVM2/lib/filters/filter-persistent.h	2006/11/04 03:34:09	1.5
@@ -22,7 +22,7 @@
 					    const char *file);
 
 int persistent_filter_wipe(struct dev_filter *f);
-int persistent_filter_load(struct dev_filter *f);
+int persistent_filter_load(struct dev_filter *f, struct config_tree **cft_out);
 int persistent_filter_dump(struct dev_filter *f);
 
 #endif
--- LVM2/lib/format_text/import.c	2006/05/11 17:58:58	1.41
+++ LVM2/lib/format_text/import.c	2006/11/04 03:34:09	1.42
@@ -43,7 +43,7 @@
 		_text_import_initialised = 1;
 	}
 
-	if (!(cft = create_config_tree(NULL)))
+	if (!(cft = create_config_tree(NULL, 0)))
 		return_NULL;
 
 	if ((!dev && !read_config_file(cft)) ||
@@ -94,7 +94,7 @@
 	*desc = NULL;
 	*when = 0;
 
-	if (!(cft = create_config_tree(file)))
+	if (!(cft = create_config_tree(file, 0)))
 		return_NULL;
 
 	if ((!dev && !read_config_file(cft)) ||
--- LVM2/lib/misc/lvm-file.c	2006/08/21 12:54:53	1.16
+++ LVM2/lib/misc/lvm-file.c	2006/11/04 03:34:10	1.17
@@ -244,3 +244,61 @@
       out:
 	dm_free(dir);
 }
+
+/*
+ * Attempt to obtain fcntl lock on a file, if necessary creating file first
+ * or waiting.
+ * Returns file descriptor on success, else -1.
+ * mode is F_WRLCK or F_RDLCK
+ */
+int fcntl_lock_file(const char *file, short lock_type, int warn_if_read_only)
+{
+	int lockfd;
+	struct flock lock = {
+		.l_type = lock_type,
+		.l_whence = 0,
+		.l_start = 0,
+		.l_len = 0
+	};
+
+	log_very_verbose("Locking %s (%s, %hd)", file,
+			 (lock_type == F_WRLCK) ? "F_WRLCK" : "F_RDLCK",
+			 lock_type);
+	if ((lockfd = open(file, O_RDWR | O_CREAT, 0777)) < 0) {
+		/* EACCES has been reported on NFS */
+		if (warn_if_read_only || (errno != EROFS && errno != EACCES))
+			log_sys_error("open", file);
+		else
+			stack;
+
+		return -1;
+	}
+
+	if (fcntl(lockfd, F_SETLKW, &lock)) {
+		log_sys_error("fcntl", file);
+		return -1;
+	}
+
+	return lockfd;
+}
+
+void fcntl_unlock_file(int lockfd)
+{
+	struct flock lock = {
+		.l_type = F_UNLCK,
+		.l_whence = 0,
+		.l_start = 0,
+		.l_len = 0
+	};
+
+	log_very_verbose("Unlocking fd %d", lockfd);
+
+	if (fcntl(lockfd, F_SETLK, &lock) == -1)
+		log_error("fcntl unlock failed on fd %d: %s", lockfd,
+			  strerror(errno));
+
+	if (close(lockfd))
+		log_error("lock file close failed on fd %d: %s", lockfd,
+			  strerror(errno));
+}
+
--- LVM2/lib/misc/lvm-file.h	2006/05/09 21:23:50	1.7
+++ LVM2/lib/misc/lvm-file.h	2006/11/04 03:34:10	1.8
@@ -48,4 +48,8 @@
 /* Sync directory changes */
 void sync_dir(const char *file);
 
+/* fcntl locking wrappers */
+int fcntl_lock_file(const char *file, short lock_type, int warn_if_read_only);
+void fcntl_unlock_file(int lockfd);
+
 #endif


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2006-08-31 22:21 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2006-08-31 22:21 UTC (permalink / raw)
  To: lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2006-08-31 22:21:00

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/locking    : locking.c 
	lib/misc       : sharedlib.c 

Log message:
	lvm.static uses built-in cluster locking instead of external locking.
	Don't attempt to load shared libraries if built statically.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.433&r2=1.434
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.41&r2=1.42
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/locking/locking.c.diff?cvsroot=lvm2&r1=1.31&r2=1.32
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/sharedlib.c.diff?cvsroot=lvm2&r1=1.12&r2=1.13

--- LVM2/WHATS_NEW	2006/08/31 20:56:33	1.433
+++ LVM2/WHATS_NEW	2006/08/31 22:21:00	1.434
@@ -1,5 +1,7 @@
 Version 2.02.10 - 
 ==================================
+  lvm.static uses built-in cluster locking instead of external locking.
+  Don't attempt to load shared libraries if built statically.
   Change default locking_lib to liblvm2clusterlock.so.
   Add skip_dev_dir() to process command line VGs.
   Stop clvmd complaining about nodes that have left the cluster.
--- LVM2/lib/commands/toolcontext.c	2006/08/21 12:54:51	1.41
+++ LVM2/lib/commands/toolcontext.c	2006/08/31 22:21:00	1.42
@@ -646,8 +646,9 @@
 #endif
 
 #ifdef HAVE_LIBDL
-	/* Load any formats in shared libs */
-	if ((cn = find_config_tree_node(cmd, "global/format_libraries"))) {
+	/* Load any formats in shared libs if not static */
+	if (!cmd->is_static &&
+	    (cn = find_config_tree_node(cmd, "global/format_libraries"))) {
 
 		struct config_value *cv;
 		struct format_type *(*init_format_fn) (struct cmd_context *);
@@ -740,8 +741,9 @@
 #endif
 
 #ifdef HAVE_LIBDL
-	/* Load any formats in shared libs */
-	if ((cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
+	/* Load any formats in shared libs unless static */
+	if (!cmd->is_static &&
+	    (cn = find_config_tree_node(cmd, "global/segment_libraries"))) {
 
 		struct config_value *cv;
 		struct segment_type *(*init_segtype_fn) (struct cmd_context *);
--- LVM2/lib/locking/locking.c	2006/08/21 12:54:52	1.31
+++ LVM2/lib/locking/locking.c	2006/08/31 22:21:00	1.32
@@ -134,24 +134,27 @@
 		return 1;
 
 	case 1:
+		log_very_verbose("File-based locking selected.");
 		if (!init_file_locking(&_locking, cmd))
 			break;
-		log_very_verbose("File-based locking enabled.");
 		return 1;
 
 #ifdef HAVE_LIBDL
 	case 2:
-		if (!init_external_locking(&_locking, cmd))
-			break;
-		log_very_verbose("External locking enabled.");
-		return 1;
+		if (!cmd->is_static) {
+			log_very_verbose("External locking selected.");
+			if (!init_external_locking(&_locking, cmd))
+				break;
+			return 1;
+		}
+		/* Fall through */
 #endif
 
 #ifdef CLUSTER_LOCKING_INTERNAL
 	case 3:
+		log_very_verbose("Cluster locking selected.");
 		if (!init_cluster_locking(&_locking, cmd))
 			break;
-		log_very_verbose("Cluster locking enabled.");
 		return 1;
 #endif
 
--- LVM2/lib/misc/sharedlib.c	2006/08/21 12:54:53	1.12
+++ LVM2/lib/misc/sharedlib.c	2006/08/31 22:21:00	1.13
@@ -17,6 +17,7 @@
 #include "config.h"
 #include "lvm-string.h"
 #include "sharedlib.h"
+#include "toolcontext.h"
 
 #include <limits.h>
 #include <sys/stat.h>
@@ -43,6 +44,12 @@
 	char path[PATH_MAX];
 	void *library;
 
+	if (cmd->is_static) {
+		log_error("Not loading shared %s library %s in static mode.",
+			  desc, libname);
+		return NULL;
+	}
+
 	get_shared_library_path(cmd, libname, path, sizeof(path));
 
 	log_very_verbose("Opening shared %s library %s", desc, path);


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2006-04-03 18:43 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2006-04-03 18:43 UTC (permalink / raw)
  To: lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2006-04-03 18:43:55

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/locking    : external_locking.c 
	lib/misc       : sharedlib.c sharedlib.h 

Log message:
	Suppress locking library load failure message if --ignorelockingfailure.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.349&r2=1.350
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.35&r2=1.36
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/locking/external_locking.c.diff?cvsroot=lvm2&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/sharedlib.c.diff?cvsroot=lvm2&r1=1.6&r2=1.7
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/sharedlib.h.diff?cvsroot=lvm2&r1=1.4&r2=1.5


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2004-12-10 16:01 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2004-12-10 16:01 UTC (permalink / raw)
  To: lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2004-12-10 16:01:35

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/device     : dev-cache.c dev-io.c device.c device.h 
	lib/filters    : filter.c 
	lib/log        : log.c 
	tools          : lvmcmdline.c 

Log message:
	Additional device-handling debug messages.
	Additional verbosity level -vvvv includes line numbers and backtraces.
	Verbose messages now go to stderr not stdout.
	Close any stray file descriptors before starting.
	Refine partitionable checks for certain device types.
	Allow devices/types to override built-ins.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.126&r2=1.127
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.27&r2=1.28
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/device/dev-cache.c.diff?cvsroot=lvm2&r1=1.33&r2=1.34
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/device/dev-io.c.diff?cvsroot=lvm2&r1=1.40&r2=1.41
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/device/device.c.diff?cvsroot=lvm2&r1=1.17&r2=1.18
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/device/device.h.diff?cvsroot=lvm2&r1=1.24&r2=1.25
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter.c.diff?cvsroot=lvm2&r1=1.24&r2=1.25
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/log/log.c.diff?cvsroot=lvm2&r1=1.25&r2=1.26
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.17&r2=1.18


^ permalink raw reply	[flat|nested] 16+ messages in thread

* LVM2 ./WHATS_NEW lib/commands/toolcontext.c li ...
@ 2004-11-19 19:25 agk
  0 siblings, 0 replies; 16+ messages in thread
From: agk @ 2004-11-19 19:25 UTC (permalink / raw)
  To: lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2004-11-19 19:25:07

Modified files:
	.              : WHATS_NEW 
	lib/commands   : toolcontext.c 
	lib/filters    : filter-md.c 
	lib/log        : log.c log.h 
	tools          : pvcreate.c 

Log message:
	pvcreate wipes md superblocks. (With --uuid or --restorefile it prompts.)

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.109&r2=1.110
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.25&r2=1.26
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/filters/filter-md.c.diff?cvsroot=lvm2&r1=1.2&r2=1.3
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/log/log.c.diff?cvsroot=lvm2&r1=1.24&r2=1.25
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/lib/log/log.h.diff?cvsroot=lvm2&r1=1.24&r2=1.25
http://sources.redhat.com/cgi-bin/cvsweb.cgi/LVM2/tools/pvcreate.c.diff?cvsroot=lvm2&r1=1.39&r2=1.40


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2012-02-01 13:42 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-01 13:42 LVM2 ./WHATS_NEW lib/commands/toolcontext.c li zkabelac
  -- strict thread matches above, loose matches on Subject: below --
2012-01-11 20:38 agk
2011-01-06 15:29 zkabelac
2010-11-11 17:29 agk
2010-09-09 13:07 prajnoha
2010-08-11 12:14 prajnoha
2010-04-29  1:38 agk
2009-07-08 12:36 agk
2008-12-07  4:27 wysochanski
2007-07-28 12:26 meyering
2007-07-23 10:45 mbroz
2006-11-04  3:34 agk
2006-08-31 22:21 agk
2006-04-03 18:43 agk
2004-12-10 16:01 agk
2004-11-19 19:25 agk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).