All of lore.kernel.org
 help / color / mirror / Atom feed
From: agk@sourceware.org <agk@sourceware.org>
To: lvm-devel@redhat.com
Subject: LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ...
Date: 9 Nov 2010 12:34:53 -0000	[thread overview]
Message-ID: <20101109123453.7567.qmail@sourceware.org> (raw)

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk at sourceware.org	2010-11-09 12:34:44

Modified files:
	.              : WHATS_NEW 
	doc            : example.conf.in 
	lib/activate   : activate.c 
	lib/datastruct : str_list.c str_list.h 
	lib/display    : display.c 
	lib/metadata   : lv_manip.c metadata.c mirror.c vg.h 
	man            : lvm.conf.5.in 
	tools          : toollib.c 

Log message:
	Extend cling allocation policy to recognise PV tags (cling_by_tags).
	Add allocation/cling_tag_list to lvm.conf.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1792&r2=1.1793
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.c.diff?cvsroot=lvm2&r1=1.179&r2=1.180
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/datastruct/str_list.c.diff?cvsroot=lvm2&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/datastruct/str_list.h.diff?cvsroot=lvm2&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/display/display.c.diff?cvsroot=lvm2&r1=1.113&r2=1.114
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/lv_manip.c.diff?cvsroot=lvm2&r1=1.235&r2=1.236
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.408&r2=1.409
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/mirror.c.diff?cvsroot=lvm2&r1=1.136&r2=1.137
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/vg.h.diff?cvsroot=lvm2&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/lvm.conf.5.in.diff?cvsroot=lvm2&r1=1.15&r2=1.16
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/toollib.c.diff?cvsroot=lvm2&r1=1.210&r2=1.211

--- LVM2/WHATS_NEW	2010/11/09 11:15:34	1.1792
+++ LVM2/WHATS_NEW	2010/11/09 12:34:40	1.1793
@@ -1,5 +1,7 @@
 Version 2.02.77 -
 ===================================
+  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)
 
 Version 2.02.76 - 8th November 2010
--- LVM2/doc/example.conf.in	2010/10/25 11:20:55	1.16
+++ LVM2/doc/example.conf.in	2010/11/09 12:34:41	1.17
@@ -146,6 +146,25 @@
     require_restorefile_with_uuid = 1
 }
 
+# This section allows you to configure the way in which LVM selects
+# free space for its Logical Volumes.
+#allocation {
+#    When searching for free space to extend an LV, the "cling"
+#    allocation policy will choose space on the same PVs as the last
+#    segment of the existing LV.  If there is insufficient space and a
+#    list of tags is defined here, it will check whether any of them are
+#    attached to the PVs concerned and then seek to match those PV tags
+#    between existing extents and new extents.
+#    Use the special tag "@*" as a wildcard to match any PV tag.
+#    
+#    Example: LVs are mirrored between two sites within a single VG.
+#    PVs are tagged with either @site1 or @site2 to indicate where
+#    they are situated.
+#
+#    cling_tag_list = [ "@site1", "@site2" ]
+#    cling_tag_list = [ "@*" ]
+#}
+
 # This section that allows you to configure the nature of the
 # information that LVM2 reports.
 log {
--- LVM2/lib/activate/activate.c	2010/11/05 18:18:12	1.179
+++ LVM2/lib/activate/activate.c	2010/11/09 12:34:41	1.180
@@ -275,8 +275,8 @@
 			return 1;
 
 		/* If any host tag matches any LV or VG tag, activate */
-		if (str_list_match_list(&cmd->tags, &lv->tags) ||
-		    str_list_match_list(&cmd->tags, &lv->vg->tags))
+		if (str_list_match_list(&cmd->tags, &lv->tags, NULL) ||
+		    str_list_match_list(&cmd->tags, &lv->vg->tags, NULL))
 			return 1;
 
 		log_verbose("No host tag matches %s/%s",
@@ -314,9 +314,9 @@
 			}
 			/* If any host tag matches any LV or VG tag, activate */
 			if (!strcmp(str, "*")) {
-				if (str_list_match_list(&cmd->tags, &lv->tags)
+				if (str_list_match_list(&cmd->tags, &lv->tags, NULL)
 				    || str_list_match_list(&cmd->tags,
-							   &lv->vg->tags))
+							   &lv->vg->tags, NULL))
 					    return 1;
 				else
 					continue;
--- LVM2/lib/datastruct/str_list.c	2009/07/27 11:00:18	1.12
+++ LVM2/lib/datastruct/str_list.c	2010/11/09 12:34:41	1.13
@@ -93,14 +93,18 @@
 
 /*
  * Is at least one item on both lists?
+ * If tag_matched is non-NULL, it is set to the tag that matched.
  */
-int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2)
+int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, char **tag_matched)
 {
 	struct str_list *sl;
 
 	dm_list_iterate_items(sl, sll)
-	    if (str_list_match_item(sll2, sl->str))
-		return 1;
+		if (str_list_match_item(sll2, sl->str)) {
+			if (tag_matched)
+				*tag_matched = sl->str;
+			return 1;
+		}
 
 	return 0;
 }
--- LVM2/lib/datastruct/str_list.h	2008/11/03 22:14:27	1.9
+++ LVM2/lib/datastruct/str_list.h	2010/11/09 12:34:42	1.10
@@ -20,7 +20,7 @@
 int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str);
 int str_list_del(struct dm_list *sll, const char *str);
 int str_list_match_item(const struct dm_list *sll, const char *str);
-int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2);
+int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, char **tag_matched);
 int str_list_lists_equal(const struct dm_list *sll, const struct dm_list *sll2);
 int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew,
 		 const struct dm_list *sllold);
--- LVM2/lib/display/display.c	2010/10/25 13:54:29	1.113
+++ LVM2/lib/display/display.c	2010/11/09 12:34:42	1.114
@@ -26,12 +26,13 @@
 
 static const struct {
 	alloc_policy_t alloc;
-	const char str[12]; /* must be changed when size extends 11 chars */
+	const char str[14]; /* must be changed when size extends 13 chars */
 	const char repchar;
 } _policies[] = {
 	{
 	ALLOC_CONTIGUOUS, "contiguous", 'c'}, {
 	ALLOC_CLING, "cling", 'l'}, {
+	ALLOC_CLING_BY_TAGS, "cling_by_tags", 't'}, {	/* Only used in log mesgs */
 	ALLOC_NORMAL, "normal", 'n'}, {
 	ALLOC_ANYWHERE, "anywhere", 'a'}, {
 	ALLOC_INHERIT, "inherit", 'i'}
@@ -147,12 +148,16 @@
 {
 	int i;
 
+	/* cling_by_tags is part of cling */
+	if (!strcmp("cling_by_tags", str))
+		return ALLOC_CLING;
+
 	for (i = 0; i < _num_policies; i++)
 		if (!strcmp(_policies[i].str, str))
 			return _policies[i].alloc;
 
 	/* Special case for old metadata */
-	if(!strcmp("next free", str))
+	if (!strcmp("next free", str))
 		return ALLOC_NORMAL;
 
 	log_error("Unrecognised allocation policy %s", str);
--- LVM2/lib/metadata/lv_manip.c	2010/11/05 18:18:12	1.235
+++ LVM2/lib/metadata/lv_manip.c	2010/11/09 12:34:42	1.236
@@ -526,6 +526,8 @@
 	uint32_t region_size;		/* Mirror region size */
 	uint32_t total_area_len;	/* Total number of parallel extents */
 
+	const struct config_node *cling_tag_list_cn;
+
 	struct dm_list *parallel_areas;	/* PVs to avoid */
 
 	/*
@@ -640,6 +642,8 @@
 
 	ah->parallel_areas = parallel_areas;
 
+	ah->cling_tag_list_cn = find_config_tree_node(cmd, "allocation/cling_tag_list");
+
 	return ah;
 }
 
@@ -927,18 +931,19 @@
  * Search for pvseg that matches condition
  */
 struct pv_match {
-	int (*condition)(struct pv_segment *pvseg, struct pv_area *pva);
+	int (*condition)(struct pv_match *pvmatch, struct pv_segment *pvseg, struct pv_area *pva);
 
 	struct pv_area_used *areas;
 	struct pv_area *pva;
 	uint32_t areas_size;
+	const struct config_node *cling_tag_list_cn;
 	int s;	/* Area index of match */
 };
 
 /*
  * Is PV area on the same PV?
  */
-static int _is_same_pv(struct pv_segment *pvseg, struct pv_area *pva)
+static int _is_same_pv(struct pv_match *pvmatch __attribute((unused)), struct pv_segment *pvseg, struct pv_area *pva)
 {
 	if (pvseg->pv != pva->map->pv)
 		return 0;
@@ -947,9 +952,70 @@
 }
 
 /*
+ * Does PV area have a tag listed in allocation/cling_tag_list that 
+ * matches a tag of the PV of the existing segment?
+ */
+static int _has_matching_pv_tag(struct pv_match *pvmatch, struct pv_segment *pvseg, struct pv_area *pva)
+{
+	struct config_value *cv;
+	char *str;
+	char *tag_matched;
+
+	for (cv = pvmatch->cling_tag_list_cn->v; cv; cv = cv->next) {
+		if (cv->type != CFG_STRING) {
+			log_error("Ignoring invalid string in config file entry "
+				  "allocation/cling_tag_list");
+			continue;
+		}
+		str = cv->v.str;
+		if (!*str) {
+			log_error("Ignoring empty string in config file entry "
+				  "allocation/cling_tag_list");
+			continue;
+		}
+
+		if (*str != '@') {
+			log_error("Ignoring string not starting with @ in config file entry "
+				  "allocation/cling_tag_list: %s", str);
+			continue;
+		}
+
+		str++;
+
+		if (!*str) {
+			log_error("Ignoring empty tag in config file entry "
+				  "allocation/cling_tag_list");
+			continue;
+		}
+
+		/* Wildcard matches any tag against any tag. */
+		if (!strcmp(str, "*")) {
+			if (!str_list_match_list(&pvseg->pv->tags, &pva->map->pv->tags, &tag_matched))
+				continue;
+			else {
+				log_debug("Matched allocation PV tag %s on existing %s with free space on %s.",
+					  tag_matched, pv_dev_name(pvseg->pv), pv_dev_name(pva->map->pv));
+				return 1;
+			}
+		}
+
+		if (!str_list_match_item(&pvseg->pv->tags, str) ||
+		    !str_list_match_item(&pva->map->pv->tags, str))
+			continue;
+		else {
+			log_debug("Matched allocation PV tag %s on existing %s with free space on %s.",
+				  str, pv_dev_name(pvseg->pv), pv_dev_name(pva->map->pv));
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
  * Is PV area contiguous to PV segment?
  */
-static int _is_contiguous(struct pv_segment *pvseg, struct pv_area *pva)
+static int _is_contiguous(struct pv_match *pvmatch __attribute((unused)), struct pv_segment *pvseg, struct pv_area *pva)
 {
 	if (pvseg->pv != pva->map->pv)
 		return 0;
@@ -966,7 +1032,7 @@
 {
 	struct pv_match *pvmatch = data;
 
-	if (!pvmatch->condition(pvseg, pvmatch->pva))
+	if (!pvmatch->condition(pvmatch, pvseg, pvmatch->pva))
 		return 1;	/* Continue */
 
 	if (s >= pvmatch->areas_size)
@@ -991,16 +1057,18 @@
  * Is pva on same PV as any existing areas?
  */
 static int _check_cling(struct cmd_context *cmd,
+			const struct config_node *cling_tag_list_cn,
 			struct lv_segment *prev_lvseg, struct pv_area *pva,
 			struct pv_area_used *areas, uint32_t areas_size)
 {
 	struct pv_match pvmatch;
 	int r;
 
-	pvmatch.condition = _is_same_pv;
+	pvmatch.condition = cling_tag_list_cn ? _has_matching_pv_tag : _is_same_pv;
 	pvmatch.areas = areas;
 	pvmatch.areas_size = areas_size;
 	pvmatch.pva = pva;
+	pvmatch.cling_tag_list_cn = cling_tag_list_cn;
 
 	/* FIXME Cope with stacks by flattening */
 	if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
@@ -1029,6 +1097,7 @@
 	pvmatch.areas = areas;
 	pvmatch.areas_size = areas_size;
 	pvmatch.pva = pva;
+	pvmatch.cling_tag_list_cn = NULL;
 
 	/* FIXME Cope with stacks by flattening */
 	if (!(r = _for_each_pv(cmd, prev_lvseg->lv,
@@ -1056,7 +1125,7 @@
 	struct pv_area *pva;
 	struct pv_list *pvl;
 	unsigned already_found_one = 0;
-	unsigned contiguous = 0, cling = 0, preferred_count = 0;
+	unsigned contiguous = 0, cling = 0, use_cling_tags = 0, preferred_count = 0;
 	unsigned ix, last_ix;
 	unsigned ix_offset = 0;	/* Offset for non-preferred allocations */
 	unsigned ix_log_offset; /* Offset to start of areas to use for log */
@@ -1089,7 +1158,10 @@
 			contiguous = 1;
 		else if ((alloc == ALLOC_CLING))
 			cling = 1;
-		else
+		else if ((alloc == ALLOC_CLING_BY_TAGS)) {
+			cling = 1;
+			use_cling_tags = 1;
+		} else
 			ix_offset = 0;
 	}
 
@@ -1176,9 +1248,10 @@
 					if (cling) {
 						if (prev_lvseg &&
 						    _check_cling(ah->cmd,
-								   prev_lvseg,
-								   pva, *areas_ptr,
-								   *areas_size_ptr)) {
+								 use_cling_tags ? ah->cling_tag_list_cn : NULL,
+								 prev_lvseg,
+								 pva, *areas_ptr,
+								 *areas_size_ptr)) {
 							preferred_count++;
 						}
 						goto next_pv;
@@ -1361,8 +1434,18 @@
 		return 0;
 	}
 
+	/*
+	 * cling includes implicit cling_by_tags
+	 * but it does nothing unless the lvm.conf setting is present.
+	 */
+	if (ah->alloc == ALLOC_CLING)
+		ah->alloc = ALLOC_CLING_BY_TAGS;
+
 	/* Attempt each defined allocation policy in turn */
 	for (alloc = ALLOC_CONTIGUOUS; alloc < ALLOC_INHERIT; alloc++) {
+		/* Skip cling_by_tags if no list defined */
+		if (alloc == ALLOC_CLING_BY_TAGS && !ah->cling_tag_list_cn)
+			continue;
 		old_allocated = allocated;
 		log_debug("Trying allocation using %s policy.  "
 			  "Need %" PRIu32 " extents for %" PRIu32 " parallel areas and %" PRIu32 " log areas of %" PRIu32 " extents. "
@@ -1829,8 +1912,8 @@
 	/*
 	 * Compose a new name for sub lv:
 	 *   e.g. new name is "lvol1_mlog"
-	 *        if the sub LV is "lvol0_mlog" and
-	 *        a new name for main LV is "lvol1"
+	 *	if the sub LV is "lvol0_mlog" and
+	 *	a new name for main LV is "lvol1"
 	 */
 	len = strlen(lv_name_new) + strlen(suffix) + 1;
 	new_name = dm_pool_alloc(cmd->mem, len);
@@ -2339,7 +2422,7 @@
 		}
 	}
 
-        return lv_remove_single(cmd, lv, force);
+	return lv_remove_single(cmd, lv, force);
 }
 
 /*
--- LVM2/lib/metadata/metadata.c	2010/10/25 13:54:29	1.408
+++ LVM2/lib/metadata/metadata.c	2010/11/09 12:34:42	1.409
@@ -2164,6 +2164,12 @@
 	uint32_t num_snapshots = 0;
 	uint32_t loop_counter1, loop_counter2;
 
+	if (vg->alloc == ALLOC_CLING_BY_TAGS) {
+		log_error(INTERNAL_ERROR "VG %s allocation policy set to invalid cling_by_tags.",
+			  vg->name);
+		r = 0;
+	}
+
 	/* FIXME Also check there's no data/metadata overlap */
 	dm_list_iterate_items(pvl, &vg->pvs) {
 		if (++pv_count > vg->pv_count) {
@@ -2233,6 +2239,12 @@
 			r = 0;
 		}
 
+		if (lvl->lv->alloc == ALLOC_CLING_BY_TAGS) {
+			log_error(INTERNAL_ERROR "LV %s allocation policy set to invalid cling_by_tags.",
+				  lvl->lv->name);
+			r = 0;
+		}
+
 		if (lvl->lv->status & VISIBLE_LV)
 			continue;
 
--- LVM2/lib/metadata/mirror.c	2010/10/14 20:03:13	1.136
+++ LVM2/lib/metadata/mirror.c	2010/11/09 12:34:43	1.137
@@ -400,7 +400,7 @@
 	struct str_list *sl;
 
 	/* Inherit tags - maybe needed for activation */
-	if (!str_list_match_list(&mirror_lv->tags, &lv->tags)) {
+	if (!str_list_match_list(&mirror_lv->tags, &lv->tags, NULL)) {
 		dm_list_iterate_items(sl, &mirror_lv->tags)
 			if (!str_list_add(cmd->mem, &lv->tags, sl->str)) {
 				log_error("Aborting. Unable to tag.");
--- LVM2/lib/metadata/vg.h	2010/10/25 12:01:59	1.7
+++ LVM2/lib/metadata/vg.h	2010/11/09 12:34:43	1.8
@@ -25,6 +25,7 @@
 	ALLOC_INVALID,
 	ALLOC_CONTIGUOUS,
 	ALLOC_CLING,
+	ALLOC_CLING_BY_TAGS,	/* Internal - never written or displayed. */
 	ALLOC_NORMAL,
 	ALLOC_ANYWHERE,
 	ALLOC_INHERIT
--- LVM2/man/lvm.conf.5.in	2010/10/15 16:24:01	1.15
+++ LVM2/man/lvm.conf.5.in	2010/11/09 12:34:43	1.16
@@ -172,6 +172,28 @@
 the respective operation. Setting the parameter to 0 disables the counters
 altogether.
 .TP
+\fBallocation\fP \(em Space allocation policies
+.IP
+\fBcling_tag_list\fP \(em List of PV tags matched by the \fBcling\fP allocation policy.
+.IP
+When searching for free space to extend an LV, the \fBcling\fP
+allocation policy will choose space on the same PVs as the last
+segment of the existing LV.  If there is insufficient space and a
+list of tags is defined here, it will check whether any of them are
+attached to the PVs concerned and then seek to match those PV tags
+between existing extents and new extents.
+.IP 
+The @ prefix for tags is required.
+Use the special tag "@*" as a wildcard to match any PV tag and so use 
+all PV tags for this purpose.
+.IP
+For example, LVs are mirrored between two sites within a single VG.
+PVs are tagged with either @site1 or @site2 to indicate where
+they are situated and these two PV tags are selected for use with this
+allocation policy:
+.IP
+cling_tag_list = [ "@site1", "@site2" ]
+.TP
 \fBlog\fP \(em Default log settings
 .IP
 \fBfile\fP \(em Location of log file.  If this entry is not present, no
--- LVM2/tools/toollib.c	2010/10/25 12:08:15	1.210
+++ LVM2/tools/toollib.c	2010/11/09 12:34:43	1.211
@@ -115,7 +115,7 @@
 
 	/* Or if VG tags match */
 	if (!process_lv && tags_supplied &&
-	    str_list_match_list(tags, &vg->tags)) {
+	    str_list_match_list(tags, &vg->tags, NULL)) {
 		process_all = 1;
 	}
 
@@ -141,7 +141,7 @@
 
 		/* LV tag match? */
 		if (!process_lv && tags_supplied &&
-		    str_list_match_list(tags, &lvl->lv->tags)) {
+		    str_list_match_list(tags, &lvl->lv->tags, NULL)) {
 			process_lv = 1;
 		}
 
@@ -487,7 +487,7 @@
 		if (!dm_list_empty(tags) &&
 		    /* Only process if a tag matches or it's on arg_vgnames */
 		    !str_list_match_item(arg_vgnames, vg_name) &&
-		    !str_list_match_list(tags, &cvl_vg->vg->tags))
+		    !str_list_match_list(tags, &cvl_vg->vg->tags, NULL))
 			break;
 
 		ret = process_single_vg(cmd, vg_name, cvl_vg->vg, handle);
@@ -606,7 +606,7 @@
 
 	dm_list_iterate_items(pvl, &vg->pvs) {
 		if (tags && !dm_list_empty(tags) &&
-		    !str_list_match_list(tags, &pvl->pv->tags)) {
+		    !str_list_match_list(tags, &pvl->pv->tags, NULL)) {
 			continue;
 		}
 		if ((ret = process_single_pv(cmd, vg, pvl->pv, handle)) > ret_max)



             reply	other threads:[~2010-11-09 12:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-09 12:34 agk [this message]
  -- strict thread matches above, loose matches on Subject: below --
2011-06-17 14:50 LVM2 ./WHATS_NEW doc/example.conf.in lib/activ prajnoha
2011-09-22 17:39 prajnoha
2011-11-28 20:37 agk
2012-01-12  1:51 agk
2012-03-02 21:49 zkabelac
2012-03-14 17:12 zkabelac

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101109123453.7567.qmail@sourceware.org \
    --to=agk@sourceware.org \
    --cc=lvm-devel@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.