public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ...
@ 2010-11-09 12:34 agk
0 siblings, 0 replies; 7+ messages in thread
From: agk @ 2010-11-09 12:34 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: agk@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)
^ permalink raw reply [flat|nested] 7+ messages in thread
* LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ...
@ 2011-06-17 14:50 prajnoha
0 siblings, 0 replies; 7+ messages in thread
From: prajnoha @ 2011-06-17 14:50 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: prajnoha@sourceware.org 2011-06-17 14:50:54
Modified files:
. : WHATS_NEW
doc : example.conf.in
lib/activate : dev_manager.c
lib/commands : toolcontext.c toolcontext.h
lib/config : defaults.h
tools : lvmcmdline.c
Log message:
Disable udev fallback by default and add activation/udev_fallback to lvm.conf.
We've used udev fallback code till now to check whether udev
created/removed the entries in /dev correctly and if not,
a repair was done (giving a warning messagea about that).
This patch adds a possibility to enable this additional check
and subsequent fallback only when required (debugging purposes
mostly) and trust udev completely.
So let's disable the fallback code by default and add a new
configuration option "activation/udev_fallback".
(The original code for creating the nodes will still be used
in case the device directory that is set in lvm.conf differs
from the one that udev uses and also when activation/udev_rules
is set to 0 - otherwise we would end up with no nodes/symlinks
at all)
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.2022&r2=1.2023
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.25&r2=1.26
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.c.diff?cvsroot=lvm2&r1=1.219&r2=1.220
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.119&r2=1.120
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.h.diff?cvsroot=lvm2&r1=1.43&r2=1.44
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/defaults.h.diff?cvsroot=lvm2&r1=1.75&r2=1.76
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvmcmdline.c.diff?cvsroot=lvm2&r1=1.142&r2=1.143
--- LVM2/WHATS_NEW 2011/06/17 14:39:10 1.2022
+++ LVM2/WHATS_NEW 2011/06/17 14:50:53 1.2023
@@ -1,5 +1,6 @@
Version 2.02.86 -
=================================
+ Disable udev fallback by default and add activation/udev_fallback to lvm.conf.
Call vg_mark_partial_lvs() before VG structure is returned from the cache.
Remove unused internal flag ACTIVATE_EXCL from the code.
Remove useless test of ACTIVATE_EXCL in lv_add_mirrors() clustered code path.
--- LVM2/doc/example.conf.in 2011/04/28 17:33:35 1.25
+++ LVM2/doc/example.conf.in 2011/06/17 14:50:53 1.26
@@ -428,6 +428,13 @@
# while any logical volumes are active.
udev_rules = 1
+ # Set to 1 to enable udev fallback. This will enable additional checks and
+ # possible repairs done on entries in the device directory after udev has
+ # completed processing the events. This is normally not needed if udev
+ # works correctly but it may be used in some problematic situations or
+ # for debugging purposes.
+ udev_fallback = 0
+
# How to fill in missing stripes if activating an incomplete volume.
# Using "error" will make inaccessible parts of the device return
# I/O errors on access. You can instead use a device path, in which
--- LVM2/lib/activate/dev_manager.c 2011/06/17 14:22:48 1.219
+++ LVM2/lib/activate/dev_manager.c 2011/06/17 14:50:53 1.220
@@ -874,6 +874,13 @@
uint16_t udev_flags = 0;
/*
+ * Instruct also libdevmapper to disable udev
+ * fallback in accordance to LVM2 settings.
+ */
+ if (!dm->cmd->current_settings.udev_fallback)
+ udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK;
+
+ /*
* Is this top-level and visible device?
* If not, create just the /dev/mapper content.
*/
@@ -1584,6 +1591,10 @@
const char *name;
int r = 1;
+ /* Nothing to do if udev fallback is disabled. */
+ if (!dm->cmd->current_settings.udev_fallback)
+ return 1;
+
while ((child = dm_tree_next_child(&handle, root, 0))) {
if (!(lvlayer = dm_tree_node_get_context(child)))
continue;
@@ -1626,6 +1637,10 @@
char *vgname, *lvname, *layer;
int r = 1;
+ /* Nothing to do if udev fallback is disabled. */
+ if (!dm->cmd->current_settings.udev_fallback)
+ return 1;
+
while ((child = dm_tree_next_child(&handle, root, 0))) {
if (!dm_split_lvm_name(dm->mem, dm_tree_node_get_name(child), &vgname, &lvname, &layer)) {
r = 0;
--- LVM2/lib/commands/toolcontext.c 2011/05/07 13:50:12 1.119
+++ LVM2/lib/commands/toolcontext.c 2011/06/17 14:50:54 1.120
@@ -285,6 +285,21 @@
"activation/udev_sync",
DEFAULT_UDEV_SYNC);
+ #ifdef UDEV_SYNC_SUPPORT
+ /*
+ * We need udev rules to be applied, otherwise we would end up with no
+ * nodes and symlinks! However, we can disable the synchronization itself
+ * in runtime and still have only udev to create the nodes and symlinks
+ * without any fallback.
+ */
+ cmd->default_settings.udev_fallback = cmd->default_settings.udev_rules ?
+ find_config_tree_int(cmd, "activation/udev_fallback",
+ DEFAULT_UDEV_FALLBACK) : 1;
+ #else
+ /* We must use old node/symlink creation code if not compiled with udev support at all! */
+ cmd->default_settings.udev_fallback = 1;
+ #endif
+
cmd->stripe_filler = find_config_tree_str(cmd,
"activation/missing_stripe_filler",
DEFAULT_STRIPE_FILLER);
--- LVM2/lib/commands/toolcontext.h 2011/05/07 13:50:12 1.43
+++ LVM2/lib/commands/toolcontext.h 2011/06/17 14:50:54 1.44
@@ -36,6 +36,7 @@
int read_ahead; /* DM_READ_AHEAD_NONE or _AUTO */
int udev_rules;
int udev_sync;
+ int udev_fallback;
int cache_vgmetadata;
const char *msg_prefix;
const char *fmt_name;
--- LVM2/lib/config/defaults.h 2011/04/28 17:33:35 1.75
+++ LVM2/lib/config/defaults.h 2011/06/17 14:50:54 1.76
@@ -78,6 +78,7 @@
#define DEFAULT_READ_AHEAD "auto"
#define DEFAULT_UDEV_RULES 1
#define DEFAULT_UDEV_SYNC 0
+#define DEFAULT_UDEV_FALLBACK 0
#define DEFAULT_EXTENT_SIZE 4096 /* In KB */
#define DEFAULT_MAX_PV 0
#define DEFAULT_MAX_LV 0
--- LVM2/tools/lvmcmdline.c 2011/05/07 13:50:11 1.142
+++ LVM2/tools/lvmcmdline.c 2011/06/17 14:50:54 1.143
@@ -952,7 +952,7 @@
cmd->handles_missing_pvs = 0;
}
-static int _set_udev_checking(struct cmd_context *cmd)
+static int _set_udev_fallback(struct cmd_context *cmd)
{
#ifdef UDEV_SYNC_SUPPORT
const char *udev_dev_dir;
@@ -984,6 +984,9 @@
cmd->dev_dir, udev_dev_dir);
dm_udev_set_checking(0);
init_udev_checking(0);
+
+ /* Device directories differ - we must use the fallback code! */
+ cmd->current_settings.udev_fallback = 1;
}
#endif
@@ -1088,7 +1091,7 @@
log_debug("O_DIRECT will be used");
#endif
- if (!_set_udev_checking(cmd))
+ if (!_set_udev_fallback(cmd))
goto_out;
if ((ret = _process_common_commands(cmd))) {
^ permalink raw reply [flat|nested] 7+ messages in thread
* LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ...
@ 2011-09-22 17:39 prajnoha
0 siblings, 0 replies; 7+ messages in thread
From: prajnoha @ 2011-09-22 17:39 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: prajnoha@sourceware.org 2011-09-22 17:39:58
Modified files:
. : WHATS_NEW
doc : example.conf.in
lib/activate : dev_manager.c
lib/commands : toolcontext.c
lib/config : defaults.h
lib/misc : lvm-globals.c lvm-globals.h
Log message:
Add activation/retry_deactivation to lvm.conf to retry deactivation of an LV.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.2131&r2=1.2132
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.31&r2=1.32
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.c.diff?cvsroot=lvm2&r1=1.231&r2=1.232
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.136&r2=1.137
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/defaults.h.diff?cvsroot=lvm2&r1=1.83&r2=1.84
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-globals.c.diff?cvsroot=lvm2&r1=1.14&r2=1.15
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/misc/lvm-globals.h.diff?cvsroot=lvm2&r1=1.13&r2=1.14
--- LVM2/WHATS_NEW 2011/09/22 17:33:50 1.2131
+++ LVM2/WHATS_NEW 2011/09/22 17:39:56 1.2132
@@ -1,5 +1,6 @@
Version 2.02.89 -
==================================
+ Add activation/retry_deactivation to lvm.conf to retry deactivation of an LV.
Replace open_count check with holders/mounted_fs check on lvremove path.
Disallow the creation of mirrors (mirror or raid1 segtype) with only one leg.
Cleanup restart clvmd code (no memory allocation, debug print passed args).
--- LVM2/doc/example.conf.in 2011/08/12 02:16:46 1.31
+++ LVM2/doc/example.conf.in 2011/09/22 17:39:57 1.32
@@ -465,6 +465,11 @@
# Useful for diagnosing problems with LVM2/udev interactions.
verify_udev_operations = 0
+ # If set to 1 and if deactivation of an LV fails, perhaps because
+ # a process run from a quick udev rule temporarily opened the device,
+ # retry the operation for a few seconds before failing.
+ retry_deactivation = 1
+
# How to fill in missing stripes if activating an incomplete volume.
# Using "error" will make inaccessible parts of the device return
# I/O errors on access. You can instead use a device path, in which
--- LVM2/lib/activate/dev_manager.c 2011/08/30 14:55:16 1.231
+++ LVM2/lib/activate/dev_manager.c 2011/09/22 17:39:57 1.232
@@ -1782,6 +1782,8 @@
goto_out;
break;
case DEACTIVATE:
+ if (retry_deactivation())
+ dm_tree_retry_remove(root);
/* Deactivate LV and all devices it references that nothing else has open. */
r = dm_tree_deactivate_children(root, dlid, ID_LEN + sizeof(UUID_PREFIX) - 1);
if (!r)
--- LVM2/lib/commands/toolcontext.c 2011/09/22 17:33:51 1.136
+++ LVM2/lib/commands/toolcontext.c 2011/09/22 17:39:57 1.137
@@ -303,6 +303,9 @@
"activation/udev_sync",
DEFAULT_UDEV_SYNC);
+ init_retry_deactivation(find_config_tree_int(cmd, "activation/retry_deactivation",
+ DEFAULT_RETRY_DEACTIVATION));
+
init_activation_checks(find_config_tree_int(cmd, "activation/checks",
DEFAULT_ACTIVATION_CHECKS));
--- LVM2/lib/config/defaults.h 2011/09/09 00:54:49 1.83
+++ LVM2/lib/config/defaults.h 2011/09/22 17:39:57 1.84
@@ -81,6 +81,7 @@
#define DEFAULT_UDEV_RULES 1
#define DEFAULT_UDEV_SYNC 1
#define DEFAULT_VERIFY_UDEV_OPERATIONS 0
+#define DEFAULT_RETRY_DEACTIVATION 1
#define DEFAULT_ACTIVATION_CHECKS 0
#define DEFAULT_EXTENT_SIZE 4096 /* In KB */
#define DEFAULT_MAX_PV 0
--- LVM2/lib/misc/lvm-globals.c 2011/09/01 13:30:11 1.14
+++ LVM2/lib/misc/lvm-globals.c 2011/09/22 17:39:57 1.15
@@ -42,6 +42,7 @@
static int _error_message_produced = 0;
static unsigned _is_static = 0;
static int _udev_checking = 1;
+static int _retry_deactivation = DEFAULT_RETRY_DEACTIVATION;
static int _activation_checks = 0;
static char _sysfs_dir_path[PATH_MAX] = "";
static int _dev_disable_after_error_count = DEFAULT_DISABLE_AFTER_ERROR_COUNT;
@@ -134,6 +135,11 @@
log_debug("LVM udev checking disabled");
}
+void init_retry_deactivation(int retry)
+{
+ _retry_deactivation = retry;
+}
+
void init_activation_checks(int checks)
{
if ((_activation_checks = checks))
@@ -272,6 +278,11 @@
return _udev_checking;
}
+int retry_deactivation(void)
+{
+ return _retry_deactivation;
+}
+
int activation_checks(void)
{
return _activation_checks;
--- LVM2/lib/misc/lvm-globals.h 2011/08/11 17:46:14 1.13
+++ LVM2/lib/misc/lvm-globals.h 2011/09/22 17:39:57 1.14
@@ -42,6 +42,7 @@
void init_pv_min_size(uint64_t sectors);
void init_activation_checks(int checks);
void init_detect_internal_vg_cache_corruption(int detect);
+void init_retry_deactivation(int retry);
void set_cmd_name(const char *cmd_name);
void set_sysfs_dir_path(const char *path);
@@ -67,6 +68,7 @@
uint64_t pv_min_size(void);
int activation_checks(void);
int detect_internal_vg_cache_corruption(void);
+int retry_deactivation(void);
#define DMEVENTD_MONITOR_IGNORE -1
int dmeventd_monitor_mode(void);
^ permalink raw reply [flat|nested] 7+ messages in thread
* LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ...
@ 2011-11-28 20:37 agk
0 siblings, 0 replies; 7+ messages in thread
From: agk @ 2011-11-28 20:37 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: agk@sourceware.org 2011-11-28 20:37:54
Modified files:
. : WHATS_NEW
doc : example.conf.in
lib/activate : activate.h dev_manager.c
lib/commands : toolcontext.c toolcontext.h
lib/config : defaults.h
lib/mirror : mirrored.c
lib/replicator : replicator.c
lib/striped : striped.c
lib/thin : thin.c
Log message:
Add activation/use_linear_target enabled by default. (prajnoha)
LVM metadata knows only of striped segments - not linear ones.
The activation code detects segments with a single stripe and switches
them to use the linear target.
If the new lvm.conf setting is set to 0 (e.g. in a test script), this
'optimisation' is turned off.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.2197&r2=1.2198
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.36&r2=1.37
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.h.diff?cvsroot=lvm2&r1=1.88&r2=1.89
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.c.diff?cvsroot=lvm2&r1=1.252&r2=1.253
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.c.diff?cvsroot=lvm2&r1=1.141&r2=1.142
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/commands/toolcontext.h.diff?cvsroot=lvm2&r1=1.46&r2=1.47
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/defaults.h.diff?cvsroot=lvm2&r1=1.88&r2=1.89
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/mirror/mirrored.c.diff?cvsroot=lvm2&r1=1.91&r2=1.92
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/replicator/replicator.c.diff?cvsroot=lvm2&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/striped/striped.c.diff?cvsroot=lvm2&r1=1.39&r2=1.40
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/thin/thin.c.diff?cvsroot=lvm2&r1=1.33&r2=1.34
--- LVM2/WHATS_NEW 2011/11/23 12:21:41 1.2197
+++ LVM2/WHATS_NEW 2011/11/28 20:37:51 1.2198
@@ -1,5 +1,6 @@
Version 2.02.89 -
==================================
+ Add activation/use_linear_target enabled by default.
Use gcc warning options only with .c to .o compilation.
Move y/n prompts to stderr and repeat if response has both 'n' and 'y'.
Replace the unit testing framework with CUnit (--enable-testing).
--- LVM2/doc/example.conf.in 2011/11/11 15:11:09 1.36
+++ LVM2/doc/example.conf.in 2011/11/28 20:37:51 1.37
@@ -490,6 +490,11 @@
# or snapshotted volumes is likely to result in data corruption.
missing_stripe_filler = "error"
+ # The linear target is an optimised version of the striped target
+ # that only handles a single stripe. Set this to 0 to disable this
+ # optimisation and always use the striped target.
+ use_linear_target = 1
+
# How much stack (in KB) to reserve for use while devices suspended
# Prior to version 2.02.89 this used to be set to 256KB
reserved_stack = 64
--- LVM2/lib/activate/activate.h 2011/11/11 16:41:37 1.88
+++ LVM2/lib/activate/activate.h 2011/11/28 20:37:51 1.89
@@ -128,6 +128,10 @@
int evmask __attribute__((unused)), int set, int timeout);
#endif
+int add_linear_area_to_dtree(struct dm_tree_node *node, uint64_t size,
+ uint32_t extent_size, int use_linear_target,
+ const char *vgname, const char *lvname);
+
/*
* Returns 1 if PV has a dependency tree that uses anything in VG.
*/
--- LVM2/lib/activate/dev_manager.c 2011/11/18 19:42:03 1.252
+++ LVM2/lib/activate/dev_manager.c 2011/11/28 20:37:51 1.253
@@ -441,6 +441,42 @@
return r;
}
+int add_linear_area_to_dtree(struct dm_tree_node *node, uint64_t size, uint32_t extent_size, int use_linear_target, const char *vgname, const char *lvname)
+{
+ uint32_t page_size;
+
+ /*
+ * Use striped or linear target?
+ */
+ if (!use_linear_target) {
+ page_size = lvm_getpagesize() >> SECTOR_SHIFT;
+
+ /*
+ * We'll use the extent size as the stripe size.
+ * Extent size and page size are always powers of 2.
+ * The striped target requires that the stripe size is
+ * divisible by the page size.
+ */
+ if (extent_size >= page_size) {
+ /* Use striped target */
+ if (!dm_tree_node_add_striped_target(node, size, extent_size))
+ return_0;
+ return 1;
+ } else
+ /* Some exotic cases are unsupported by striped. */
+ log_warn("WARNING: Using linear target for %s/%s: Striped requires extent size (%" PRIu32 " sectors) >= page size (%" PRIu32 ").",
+ vgname, lvname, extent_size, page_size);
+ }
+
+ /*
+ * Use linear target.
+ */
+ if (!dm_tree_node_add_linear_target(node, size))
+ return_0;
+
+ return 1;
+}
+
static percent_range_t _combine_percent(percent_t a, percent_t b,
uint32_t numerator, uint32_t denominator)
{
--- LVM2/lib/commands/toolcontext.c 2011/11/18 19:31:09 1.141
+++ LVM2/lib/commands/toolcontext.c 2011/11/28 20:37:51 1.142
@@ -333,6 +333,10 @@
cmd->default_settings.udev_fallback = 1;
#endif
+ cmd->use_linear_target = find_config_tree_int(cmd,
+ "activation/use_linear_target",
+ DEFAULT_USE_LINEAR_TARGET);
+
cmd->stripe_filler = find_config_tree_str(cmd,
"activation/missing_stripe_filler",
DEFAULT_STRIPE_FILLER);
--- LVM2/lib/commands/toolcontext.h 2011/09/02 01:32:09 1.46
+++ LVM2/lib/commands/toolcontext.h 2011/11/28 20:37:52 1.47
@@ -81,6 +81,7 @@
unsigned is_long_lived:1; /* Optimises persistent_filter handling */
unsigned handles_missing_pvs:1;
unsigned handles_unknown_segments:1;
+ unsigned use_linear_target:1;
unsigned partial_activation:1;
unsigned si_unit_consistency:1;
unsigned metadata_read_only:1;
--- LVM2/lib/config/defaults.h 2011/11/11 15:11:11 1.88
+++ LVM2/lib/config/defaults.h 2011/11/28 20:37:52 1.89
@@ -127,6 +127,7 @@
# define DEFAULT_ACTIVATION 0
#endif
+#define DEFAULT_USE_LINEAR_TARGET 1
#define DEFAULT_STRIPE_FILLER "error"
#define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */
#define DEFAULT_INTERVAL 15
--- LVM2/lib/mirror/mirrored.c 2011/08/31 15:19:20 1.91
+++ LVM2/lib/mirror/mirrored.c 2011/11/28 20:37:52 1.92
@@ -427,7 +427,9 @@
}
if (mirror_status != MIRR_RUNNING) {
- if (!dm_tree_node_add_linear_target(node, len))
+ if (!add_linear_area_to_dtree(node, len, seg->lv->vg->extent_size,
+ cmd->use_linear_target,
+ seg->lv->vg->name, seg->lv->name))
return_0;
goto done;
}
--- LVM2/lib/replicator/replicator.c 2011/08/30 14:55:18 1.9
+++ LVM2/lib/replicator/replicator.c 2011/11/28 20:37:52 1.10
@@ -625,7 +625,9 @@
/* Create passive linear mapping */
log_very_verbose("Inactive replicator %s using %s.",
seg->lv->name, seg->lv->rdevice->lv->name);
- if (!dm_tree_node_add_linear_target(node, seg->lv->size))
+ if (!add_linear_area_to_dtree(node, seg->lv->size, seg->lv->vg->extent_size,
+ dm->cmd->use_linear_target,
+ seg->lv->vg->name, seg->lv_name))
return_0;
if (!(rdev_dlid = build_dm_uuid(mem, seg->lv->rdevice->lv->lvid.s, NULL)))
return_0;
--- LVM2/lib/striped/striped.c 2011/08/31 15:19:20 1.39
+++ LVM2/lib/striped/striped.c 2011/11/28 20:37:52 1.40
@@ -174,7 +174,9 @@
return 0;
}
if (seg->area_count == 1) {
- if (!dm_tree_node_add_linear_target(node, len))
+ if (!add_linear_area_to_dtree(node, len, seg->lv->vg->extent_size,
+ cmd->use_linear_target,
+ seg->lv->vg->name, seg->lv->name))
return_0;
} else if (!dm_tree_node_add_striped_target(node, len,
seg->stripe_size))
--- LVM2/lib/thin/thin.c 2011/11/12 22:44:10 1.33
+++ LVM2/lib/thin/thin.c 2011/11/28 20:37:52 1.34
@@ -230,7 +230,9 @@
return 0;
}
- if (!dm_tree_node_add_linear_target(node, len) ||
+ if (!add_linear_area_to_dtree(node, len, seg->lv->vg->extent_size,
+ cmd->use_linear_target,
+ seg->lv->vg->name, seg->lv->name) ||
!dm_tree_node_add_target_area(node, NULL, pool_dlid, 0))
return_0;
^ permalink raw reply [flat|nested] 7+ messages in thread
* LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ...
@ 2012-01-12 1:51 agk
0 siblings, 0 replies; 7+ messages in thread
From: agk @ 2012-01-12 1:51 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: agk@sourceware.org 2012-01-12 01:51:56
Modified files:
. : WHATS_NEW
doc : example.conf.in
lib/activate : activate.c activate.h dev_manager.c
dev_manager.h
Log message:
Add activation/read_only_volume_list to override LV permission in metadata.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.2219&r2=1.2220
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.40&r2=1.41
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.c.diff?cvsroot=lvm2&r1=1.226&r2=1.227
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/activate.h.diff?cvsroot=lvm2&r1=1.90&r2=1.91
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.c.diff?cvsroot=lvm2&r1=1.256&r2=1.257
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.h.diff?cvsroot=lvm2&r1=1.41&r2=1.42
--- LVM2/WHATS_NEW 2012/01/11 20:38:42 1.2219
+++ LVM2/WHATS_NEW 2012/01/12 01:51:56 1.2220
@@ -1,5 +1,6 @@
Version 2.02.89 -
==================================
+ Add activation/read_only_volume_list to override LV permission in metadata.
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.
--- LVM2/doc/example.conf.in 2011/12/21 13:10:52 1.40
+++ LVM2/doc/example.conf.in 2012/01/12 01:51:56 1.41
@@ -513,6 +513,16 @@
#
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
+ # If read_only_volume_list is defined, each LV that is to be activated
+ # is checked against the list, and if it matches, it as activated
+ # in read-only mode. (This overrides '--permission rw' stored in the
+ # metadata.)
+ # "vgname" and "vgname/lvname" are matched exactly.
+ # "@tag" matches any tag set in the LV or VG.
+ # "@*" matches if any tag defined on the host is also set in the LV or VG
+ #
+ # read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
+
# Size (in KB) of each copy operation when mirroring
mirror_region_size = 512
--- LVM2/lib/activate/activate.c 2011/12/21 13:10:05 1.226
+++ LVM2/lib/activate/activate.c 2012/01/12 01:51:56 1.227
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -288,49 +288,29 @@
return _activation;
}
-static int _passes_activation_filter(struct cmd_context *cmd,
- struct logical_volume *lv)
+static int _passes_volumes_filter(struct cmd_context *cmd,
+ struct logical_volume *lv,
+ const struct dm_config_node *cn,
+ const char *config_path)
{
- const struct dm_config_node *cn;
const struct dm_config_value *cv;
const char *str;
static char path[PATH_MAX];
- if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
- log_verbose("activation/volume_list configuration setting "
- "not defined, checking only host tags for %s/%s",
- lv->vg->name, lv->name);
-
- /* If no host tags defined, activate */
- if (dm_list_empty(&cmd->tags))
- return 1;
-
- /* If any host tag matches any LV or VG tag, activate */
- 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",
- lv->vg->name, lv->name);
-
- /* Don't activate */
- return 0;
- }
- else
- log_verbose("activation/volume_list configuration setting "
- "defined, checking the list to match %s/%s",
- lv->vg->name, lv->name);
+ log_verbose("%s configuration setting defined: "
+ "Checking the list to match %s/%s",
+ config_path, lv->vg->name, lv->name);
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
- log_error("Ignoring invalid string in config file "
- "activation/volume_list");
+ log_error("Ignoring invalid string in config file %s",
+ config_path);
continue;
}
str = cv->v.str;
if (!*str) {
- log_error("Ignoring empty string in config file "
- "activation/volume_list");
+ log_error("Ignoring empty string in config file %s",
+ config_path);
continue;
}
@@ -340,7 +320,7 @@
str++;
if (!*str) {
log_error("Ignoring empty tag in config file "
- "activation/volume_list");
+ "%s", config_path);
continue;
}
/* If any host tag matches any LV or VG tag, activate */
@@ -377,12 +357,52 @@
return 1;
}
- log_verbose("No item supplied in activation/volume_list configuration "
- "setting matches %s/%s", lv->vg->name, lv->name);
+ log_verbose("No item supplied in %s configuration setting "
+ "matches %s/%s", config_path, lv->vg->name, lv->name);
return 0;
}
+static int _passes_activation_filter(struct cmd_context *cmd,
+ struct logical_volume *lv)
+{
+ const struct dm_config_node *cn;
+
+ if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
+ log_verbose("activation/volume_list configuration setting "
+ "not defined: Checking only host tags for %s/%s",
+ lv->vg->name, lv->name);
+
+ /* If no host tags defined, activate */
+ if (dm_list_empty(&cmd->tags))
+ return 1;
+
+ /* If any host tag matches any LV or VG tag, activate */
+ 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",
+ lv->vg->name, lv->name);
+
+ /* Don't activate */
+ return 0;
+ }
+
+ return _passes_volumes_filter(cmd, lv, cn, "activation/volume_list");
+}
+
+static int _passes_readonly_filter(struct cmd_context *cmd,
+ struct logical_volume *lv)
+{
+ struct dm_config_node *cn;
+
+ if (!(cn = find_config_tree_node(cmd, "activation/read_only_volume_list")))
+ return 0;
+
+ return _passes_volumes_filter(cmd, lv, cn, "activation/read_only_volume_list");
+}
+
int library_version(char *version, size_t size)
{
if (!activation())
@@ -755,16 +775,22 @@
static int _lv_preload(struct logical_volume *lv, struct lv_activate_opts *laopts,
int *flush_required)
{
- int r;
+ int r = 0;
struct dev_manager *dm;
+ int old_readonly = laopts->read_only;
+
+ laopts->read_only = _passes_readonly_filter(lv->vg->cmd, lv);
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, (lv->status & PVMOVE) ? 0 : 1)))
- return_0;
+ goto_out;
if (!(r = dev_manager_preload(dm, lv, laopts, flush_required)))
stack;
dev_manager_destroy(dm);
+
+ laopts->read_only = old_readonly;
+out:
return r;
}
@@ -789,6 +815,8 @@
int r;
struct dev_manager *dm;
+ laopts->read_only = _passes_readonly_filter(lv->vg->cmd, lv);
+
/*
* When we are asked to manipulate (normally suspend/resume) the PVMOVE
* device directly, we don't want to touch the devices that use it.
@@ -1463,6 +1491,8 @@
goto out;
}
+ laopts->read_only = _passes_readonly_filter(cmd, lv);
+
if (!_lv_activate_lv(lv, laopts))
goto_out;
@@ -1652,13 +1682,21 @@
goto out;
}
- log_debug("Activating %s/%s%s.", lv->vg->name, lv->name,
- laopts->exclusive ? " exclusively" : "");
+ if (filter)
+ laopts->read_only = _passes_readonly_filter(cmd, lv);
+
+ log_debug("Activating %s/%s%s%s.", lv->vg->name, lv->name,
+ laopts->exclusive ? " exclusively" : "",
+ laopts->read_only ? " read-only" : "");
if (!lv_info(cmd, lv, 0, &info, 0, 0))
goto_out;
- if (info.exists && !info.suspended && info.live_table) {
+ /*
+ * Nothing to do?
+ */
+ if (info.exists && !info.suspended && info.live_table &&
+ (info.read_only == read_only_lv(lv, laopts))) {
r = 1;
goto out;
}
--- LVM2/lib/activate/activate.h 2011/12/21 13:10:06 1.90
+++ LVM2/lib/activate/activate.h 2012/01/12 01:51:56 1.91
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -36,6 +36,7 @@
int no_merging;
int real_pool;
unsigned revert;
+ unsigned read_only;
};
/* target attribute flags */
--- LVM2/lib/activate/dev_manager.c 2011/12/21 13:09:33 1.256
+++ LVM2/lib/activate/dev_manager.c 2012/01/12 01:51:56 1.257
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -61,9 +61,9 @@
static const char thin_layer[] = "tpool";
-static int _read_only_lv(struct logical_volume *lv)
+int read_only_lv(struct logical_volume *lv, struct lv_activate_opts *laopts)
{
- return (!(lv->vg->status & LVM_WRITE) || !(lv->status & LVM_WRITE));
+ return (laopts->read_only || !(lv->vg->status & LVM_WRITE) || !(lv->status & LVM_WRITE));
}
/*
@@ -1724,7 +1724,7 @@
if (!(dnode = dm_tree_add_new_dev_with_udev_flags(dtree, name, dlid,
layer ? UINT32_C(0) : (uint32_t) lv->major,
layer ? UINT32_C(0) : (uint32_t) lv->minor,
- _read_only_lv(lv),
+ read_only_lv(lv, laopts),
((lv->vg->status & PRECOMMITTED) | laopts->revert) ? 1 : 0,
lvlayer,
_get_udev_flags(dm, lv, layer))))
--- LVM2/lib/activate/dev_manager.h 2011/12/21 13:09:34 1.41
+++ LVM2/lib/activate/dev_manager.h 2012/01/12 01:51:56 1.42
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -26,6 +26,8 @@
struct dm_info;
struct device;
+int read_only_lv(struct logical_volume *lv, struct lv_activate_opts *laopts);
+
/*
* Constructor and destructor.
*/
^ permalink raw reply [flat|nested] 7+ messages in thread
* LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ...
@ 2012-03-02 21:49 zkabelac
0 siblings, 0 replies; 7+ messages in thread
From: zkabelac @ 2012-03-02 21:49 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: zkabelac@sourceware.org 2012-03-02 21:49:44
Modified files:
. : WHATS_NEW
doc : example.conf.in
lib/activate : dev_manager.c
lib/config : defaults.h
Log message:
Add support for thin check
Use libdm callback to execute thin_check before activation
thin pool and after deactivation as well.
Supporting thin_check_executable which may pass in extra options for
the tool.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.2333&r2=1.2334
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.44&r2=1.45
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.c.diff?cvsroot=lvm2&r1=1.272&r2=1.273
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/defaults.h.diff?cvsroot=lvm2&r1=1.96&r2=1.97
--- LVM2/WHATS_NEW 2012/03/02 17:25:21 1.2333
+++ LVM2/WHATS_NEW 2012/03/02 21:49:43 1.2334
@@ -1,5 +1,6 @@
Version 2.02.94 -
====================================
+ Add support to execute thin_check with each de/active of thin pool.
Fix automatic estimation of metadata device size for thin pool.
Test for alloc fail from _alloc_pv_segment() in _extend_pv().
Check for alloc fail from get_segtype_from_string() in _lvcreate_params().
--- LVM2/doc/example.conf.in 2012/02/23 13:11:10 1.44
+++ LVM2/doc/example.conf.in 2012/03/02 21:49:43 1.45
@@ -650,6 +650,16 @@
thin_pool_autoextend_threshold = 100
thin_pool_autoextend_percent = 20
+ # Full path of the utility called to check that a thin metadata device
+ # is in a state that allows it to be used.
+ # Each time a thin pool needs to be activated, this utility is executed.
+ # The activation will only proceed if the utility has an exit status of 0.
+ # Set to "" to skip this check. (Not recommended.)
+ # The thin tools are available as part of the device-mapper-persistent-data
+ # package from https://github.com/jthornber/thin-provisioning-tools.
+ #
+ thin_check_executable = "/sbin/thin_check -q"
+
# While activating devices, I/O to devices being (re)configured is
# suspended, and as a precaution against deadlocks, LVM2 needs to pin
# any memory it is using so it is not paged out. Groups of pages that
--- LVM2/lib/activate/dev_manager.c 2012/02/28 14:24:57 1.272
+++ LVM2/lib/activate/dev_manager.c 2012/03/02 21:49:44 1.273
@@ -26,6 +26,7 @@
#include "config.h"
#include "filter.h"
#include "activate.h"
+#include "lvm-exec.h"
#include <limits.h>
#include <dirent.h>
@@ -1193,6 +1194,89 @@
return 1;
}
+struct thin_cb_data {
+ const struct logical_volume *pool_lv;
+ struct dev_manager *dm;
+};
+
+static int _thin_pool_callback(struct dm_tree_node *node,
+ dm_node_callback_t type, void *cb_data)
+{
+ int ret, status;
+ const struct thin_cb_data *data = cb_data;
+ const char *dmdir = dm_dir();
+ const char *thin_check =
+ find_config_tree_str_allow_empty(data->pool_lv->vg->cmd,
+ "global/thin_check_executable",
+ DEFAULT_THIN_CHECK_EXECUTABLE);
+ const struct logical_volume *mlv = first_seg(data->pool_lv)->metadata_lv;
+ size_t len = strlen(dmdir) + strlen(mlv->vg->name) + strlen(mlv->name) + 3;
+ char meta_path[len];
+ int args;
+ char *argv[19]; /* Max supported 15 args */
+ char *split;
+
+ if (!thin_check[0])
+ return 1; /* Checking disabled */
+
+ if (dm_snprintf(meta_path, len, "%s/%s-%s", dmdir,
+ mlv->vg->name, mlv->name) < 0) {
+ log_error("Failed to build thin metadata path.");
+ return 0;
+ }
+
+ if (!(split = dm_pool_strdup(data->dm->mem, thin_check))) {
+ log_error("Failed to duplicate thin check string.");
+ return 0;
+ }
+
+ args = dm_split_words(split, 16, 0, argv);
+ argv[args++] = meta_path;
+ argv[args] = NULL;
+
+ if (!(ret = exec_cmd(data->pool_lv->vg->cmd, (const char * const *)argv,
+ &status, 0))) {
+ log_err_once("Check of thin pool %s/%s failed (status:%d). "
+ "Manual repair required (thin_repair %s)!",
+ data->pool_lv->vg->name, data->pool_lv->name,
+ status, meta_path);
+ /*
+ * FIXME: What should we do here??
+ *
+ * Maybe mark the node, so it's not activating
+ * as thin_pool but as error/linear and let the
+ * dm tree resolve the issue.
+ */
+ }
+
+ dm_pool_free(data->dm->mem, split);
+
+ return ret;
+}
+
+static int _thin_pool_register_callback(struct dev_manager *dm,
+ struct dm_tree_node *node,
+ const struct logical_volume *lv)
+{
+ struct thin_cb_data *data;
+
+ /* Skip metadata testing for unused pool. */
+ if (!first_seg(lv)->transaction_id)
+ return 1;
+
+ if (!(data = dm_pool_alloc(dm->mem, sizeof(*data)))) {
+ log_error("Failed to allocated path for callback.");
+ return 0;
+ }
+
+ data->dm = dm;
+ data->pool_lv = lv;
+
+ dm_tree_node_set_callback(node, _thin_pool_callback, data);
+
+ return 1;
+}
+
/*
* Add LV and any known dependencies
*/
@@ -1202,11 +1286,8 @@
uint32_t s;
struct seg_list *sl;
struct lv_segment *seg = first_seg(lv);
-#if 0
- /* FIXME For dm_tree_node_skip_children optimisation below */
struct dm_tree_node *thin_node;
const char *uuid;
-#endif
if ((!origin_only || lv_is_thin_volume(lv)) &&
!_add_dev_to_dtree(dm, dtree, lv, NULL))
@@ -1263,6 +1344,12 @@
return_0;
if (!_add_dev_to_dtree(dm, dtree, lv, _thin_layer))
return_0;
+ /* If the partial tree is used for deactivation, setup callback */
+ if (!(uuid = build_dm_uuid(dm->mem, lv->lvid.s, _thin_layer)))
+ return_0;
+ if ((thin_node = dm_tree_find_node_by_uuid(dtree, uuid)) &&
+ !_thin_pool_register_callback(dm, thin_node, lv))
+ return_0;
}
return 1;
@@ -1879,6 +1966,11 @@
dm_tree_node_set_read_ahead(dnode, read_ahead, read_ahead_flags);
+ /* Setup thin pool callback */
+ if (layer && lv_is_thin_pool(lv) &&
+ !_thin_pool_register_callback(dm, dnode, lv))
+ return_0;
+
/* Add any LVs referencing a PVMOVE LV unless told not to */
if (dm->track_pvmove_deps && (lv->status & PVMOVE))
dm_list_iterate_items(sl, &lv->segs_using_this_lv)
--- LVM2/lib/config/defaults.h 2012/01/26 14:02:44 1.96
+++ LVM2/lib/config/defaults.h 2012/03/02 21:49:44 1.97
@@ -64,6 +64,7 @@
#define DEFAULT_DMEVENTD_MONITOR 1
#define DEFAULT_BACKGROUND_POLLING 1
+#define DEFAULT_THIN_CHECK_EXECUTABLE "/sbin/thin_check -q"
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
^ permalink raw reply [flat|nested] 7+ messages in thread
* LVM2 ./WHATS_NEW doc/example.conf.in lib/activ ...
@ 2012-03-14 17:12 zkabelac
0 siblings, 0 replies; 7+ messages in thread
From: zkabelac @ 2012-03-14 17:12 UTC (permalink / raw)
To: lvm-devel, lvm2-cvs
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: zkabelac@sourceware.org 2012-03-14 17:12:06
Modified files:
. : WHATS_NEW
doc : example.conf.in
lib/activate : dev_manager.c
lib/config : defaults.h
Log message:
Improve thin_check option passing
Update a way we handle option passing - so we now support path and options
with space inside.
Fix dm name usage for thin pools with '-' in name.
Use new lvm.conf option thin_check_options to pass in options as string array.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.2355&r2=1.2356
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/doc/example.conf.in.diff?cvsroot=lvm2&r1=1.45&r2=1.46
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/activate/dev_manager.c.diff?cvsroot=lvm2&r1=1.275&r2=1.276
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/config/defaults.h.diff?cvsroot=lvm2&r1=1.98&r2=1.99
--- LVM2/WHATS_NEW 2012/03/14 17:09:00 1.2355
+++ LVM2/WHATS_NEW 2012/03/14 17:12:05 1.2356
@@ -1,5 +1,6 @@
Version 2.02.96 -
================================
+ Improve thin_check option passing and use configured path.
Add --with-thin-check configure option for path to thin_check.
Detect lvm binary path in lvmetad udev rules.
Fix error message when pvmove LV activation fails with name already in use.
--- LVM2/doc/example.conf.in 2012/03/02 21:49:43 1.45
+++ LVM2/doc/example.conf.in 2012/03/14 17:12:05 1.46
@@ -658,7 +658,11 @@
# The thin tools are available as part of the device-mapper-persistent-data
# package from https://github.com/jthornber/thin-provisioning-tools.
#
- thin_check_executable = "/sbin/thin_check -q"
+ thin_check_executable = "@THIN_CHECK_CMD@"
+
+ # String with options passed with thin_check command. By default,
+ # option '-q' is for quite output.
+ thin_check_options = [ "-q", 121e321 ]
# While activating devices, I/O to devices being (re)configured is
# suspended, and as a precaution against deadlocks, LVM2 needs to pin
--- LVM2/lib/activate/dev_manager.c 2012/03/05 15:05:25 1.275
+++ LVM2/lib/activate/dev_manager.c 2012/03/14 17:12:05 1.276
@@ -1205,39 +1205,55 @@
int ret, status;
const struct thin_cb_data *data = cb_data;
const char *dmdir = dm_dir();
+ const struct dm_config_node *cn;
+ const struct dm_config_value *cv;
const char *thin_check =
find_config_tree_str_allow_empty(data->pool_lv->vg->cmd,
"global/thin_check_executable",
- DEFAULT_THIN_CHECK_EXECUTABLE);
+ THIN_CHECK_CMD);
const struct logical_volume *mlv = first_seg(data->pool_lv)->metadata_lv;
- size_t len = strlen(dmdir) + strlen(mlv->vg->name) + strlen(mlv->name) + 3;
+ size_t len = strlen(dmdir) + 2 * (strlen(mlv->vg->name) + strlen(mlv->name)) + 3;
char meta_path[len];
- int args;
- char *argv[19]; /* Max supported 15 args */
- char *split;
+ int args = 0;
+ const char *argv[19]; /* Max supported 15 args */
+ char *split, *dm_name;
if (!thin_check[0])
return 1; /* Checking disabled */
- if (dm_snprintf(meta_path, len, "%s/%s-%s", dmdir,
- mlv->vg->name, mlv->name) < 0) {
+ if (!(dm_name = dm_build_dm_name(data->dm->mem, mlv->vg->name,
+ mlv->name, NULL)) ||
+ (dm_snprintf(meta_path, len, "%s/%s", dmdir, dm_name) < 0)) {
log_error("Failed to build thin metadata path.");
return 0;
}
- if (!(split = dm_pool_strdup(data->dm->mem, thin_check))) {
- log_error("Failed to duplicate thin check string.");
- return 0;
+ if ((cn = find_config_tree_node(mlv->vg->cmd, "global/thin_check_options"))) {
+ for (cv = cn->v; cv && args < 16; cv = cv->next) {
+ if (cv->type != DM_CFG_STRING) {
+ log_error("Invalid string in config file: "
+ "global/thin_check_options");
+ return 0;
+ }
+ argv[++args] = cv->v.str;
+ }
+ } else {
+ /* Use default options (no support for options with spaces) */
+ if (!(split = dm_pool_strdup(data->dm->mem, DEFAULT_THIN_CHECK_OPTIONS))) {
+ log_error("Failed to duplicate thin check string.");
+ return 0;
+ }
+ args = dm_split_words(split, 16, 0, (char**) argv + 1);
}
- args = dm_split_words(split, 16, 0, argv);
-
if (args == 16) {
log_error("Too many options for thin check command.");
return 0;
}
- argv[args++] = meta_path;
- argv[args] = NULL;
+
+ argv[0] = thin_check;
+ argv[++args] = meta_path;
+ argv[++args] = NULL;
if (!(ret = exec_cmd(data->pool_lv->vg->cmd, (const char * const *)argv,
&status, 0))) {
@@ -1262,7 +1278,7 @@
*/
}
- dm_pool_free(data->dm->mem, split);
+ dm_pool_free(data->dm->mem, dm_name);
return ret;
}
--- LVM2/lib/config/defaults.h 2012/03/05 14:19:14 1.98
+++ LVM2/lib/config/defaults.h 2012/03/14 17:12:06 1.99
@@ -64,7 +64,7 @@
#define DEFAULT_DMEVENTD_MONITOR 1
#define DEFAULT_BACKGROUND_POLLING 1
-#define DEFAULT_THIN_CHECK_EXECUTABLE "/sbin/thin_check -q"
+#define DEFAULT_THIN_CHECK_OPTIONS "-q"
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-03-14 17:12 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-09 12:34 LVM2 ./WHATS_NEW doc/example.conf.in lib/activ agk
2011-06-17 14:50 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
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).