Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8a7682cbc982004e…
Commit: 8a7682cbc982004e880a740d61ca5d12f0caf769
Parent: 8740ecfa6492d149637a2f23d3bd7328863f0a78
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Fri Aug 15 13:45:55 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Fri Aug 15 13:45:55 2014 +0100
libdm: Add DM_DEFERRED_REMOVE to dm-ioctl.h.
---
WHATS_NEW_DM | 1 +
libdm/misc/dm-ioctl.h | 17 ++++++++++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index cf74aca..41aa89d 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.89 -
=================================
+ Update dm-ioctl.h to include DM_DEFERRED_REMOVE flag.
Add support for selection to match string list subset, recognize { } operator.
Fix string list selection with '[value]' to not match list that's superset.
Fix string list selection to match whole words only, not prefixes.
diff --git a/libdm/misc/dm-ioctl.h b/libdm/misc/dm-ioctl.h
index 76316b0..01a2b9e 100644
--- a/libdm/misc/dm-ioctl.h
+++ b/libdm/misc/dm-ioctl.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001 - 2003 Sistina Software (UK) Limited.
- * Copyright (C) 2004 - 2013 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004 - 2014 Red Hat, Inc. All rights reserved.
*
* This file is released under the LGPL.
*/
@@ -269,9 +269,9 @@ enum {
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 24
+#define DM_VERSION_MINOR 27
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2013-01-15)"
+#define DM_VERSION_EXTRA "-ioctl (2013-10-30)"
/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
@@ -343,4 +343,15 @@ enum {
*/
#define DM_DATA_OUT_FLAG (1 << 16) /* Out */
+/*
+ * If set with DM_DEV_REMOVE or DM_REMOVE_ALL this indicates that if
+ * the device cannot be removed immediately because it is still in use
+ * it should instead be scheduled for removal when it gets closed.
+ *
+ * On return from DM_DEV_REMOVE, DM_DEV_STATUS or other ioctls, this
+ * flag indicates that the device is scheduled to be removed when it
+ * gets closed.
+ */
+#define DM_DEFERRED_REMOVE (1 << 17) /* In/Out */
+
#endif /* _LINUX_DM_IOCTL_H */
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=bf78e55ef311b0be…
Commit: bf78e55ef311b0bea7993c5405d637e46a1b8394
Parent: 20503ff0675616823bcc9aa67f3e6d14a4172277
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Aug 14 01:30:01 2014 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Aug 14 01:30:01 2014 +0100
pvcreate: Fix cache state with filters/sig wiping.
_pvcreate_check() has two missing requirements:
After refreshing filters there must be a rescan.
(Otherwise the persistent filter may remain empty.)
After wiping a signature, the filters must be refreshed.
(A device that was previously excluded by the filter due to
its signature might now need to be included.)
If several devices are added at once, the repeated scanning isn't
strictly needed, but we can address that later as part of the command
processing restructuring (by grouping the devices).
Replace the new pvcreate code added by commit
54685c20fc9dfb155a2e5bc9d8cf5f0aad944305 "filters: fix regression caused
by commit e80884cd080cad7e10be4588e3493b9000649426"
with this change to _pvcreate_check().
The filter refresh problem dates back to commit
acb4b5e4de3c49d36fe756f6fb9997ec179b89c2 "Fix pvcreate device check."
---
WHATS_NEW | 1 +
lib/metadata/metadata.c | 48 ++++++++++++++++++++++++++++------------------
tools/pvcreate.c | 9 --------
3 files changed, 30 insertions(+), 28 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 28f7e36..0ca0485 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.110 -
==================================
+ Fix pvcreate_check() to update cache correctly after signature wiping.
Fix primary device lookup failure for partition when processing mpath filter.
If LV inactive and non-clustered, do not issue "Cannot deactivate" on -aln.
Remove spurious "Skipping mirror LV" message on pvmove of clustered mirror.
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 6f88fd8..d483225 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1329,11 +1329,14 @@ int vg_split_mdas(struct cmd_context *cmd __attribute__((unused)),
* See if we may pvcreate on this device.
* 0 indicates we may not.
*/
-static int pvcreate_check(struct cmd_context *cmd, const char *name,
- struct pvcreate_params *pp)
+static int _pvcreate_check(struct cmd_context *cmd, const char *name,
+ struct pvcreate_params *pp)
{
struct physical_volume *pv;
struct device *dev;
+ int r = 0;
+ int scan_needed = 0;
+ int filter_refresh_needed = 0;
/* FIXME Check partition type is LVM unless --force is given */
@@ -1345,7 +1348,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name,
if (pv && !is_orphan(pv) && pp->force != DONT_PROMPT_OVERRIDE) {
log_error("Can't initialize physical volume \"%s\" of "
"volume group \"%s\" without -ff", name, pv_vg_name(pv));
- goto bad;
+ goto out;
}
/* prompt */
@@ -1353,28 +1356,29 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name,
yes_no_prompt("Really INITIALIZE physical volume \"%s\" of volume group \"%s\" [y/n]? ",
name, pv_vg_name(pv)) == 'n') {
log_error("%s: physical volume not initialized", name);
- goto bad;
+ goto out;
}
if (sigint_caught())
- goto_bad;
+ goto_out;
dev = dev_cache_get(name, cmd->filter);
/* Is there an md superblock here? */
- /* FIXME: still possible issues here - rescan cache? */
if (!dev && md_filtering()) {
if (!refresh_filters(cmd))
- goto_bad;
+ goto_out;
init_md_filtering(0);
dev = dev_cache_get(name, cmd->filter);
init_md_filtering(1);
+
+ scan_needed = 1;
}
if (!dev) {
log_error("Device %s not found (or ignored by filtering).", name);
- goto bad;
+ goto out;
}
/*
@@ -1384,33 +1388,39 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name,
/* FIXME Detect whether device-mapper itself is still using it */
log_error("Can't open %s exclusively. Mounted filesystem?",
name);
- goto bad;
+ goto out;
}
if (!wipe_known_signatures(cmd, dev, name,
TYPE_LVM1_MEMBER | TYPE_LVM2_MEMBER,
0, pp->yes, pp->force)) {
log_error("Aborting pvcreate on %s.", name);
- goto bad;
- }
+ goto out;
+ } else
+ filter_refresh_needed = scan_needed = 1;
+
if (sigint_caught())
- goto_bad;
+ goto_out;
- if (pv && !is_orphan(pv) && pp->force) {
+ if (pv && !is_orphan(pv) && pp->force)
log_warn("WARNING: Forcing physical volume creation on "
"%s%s%s%s", name,
!is_orphan(pv) ? " of volume group \"" : "",
pv_vg_name(pv),
!is_orphan(pv) ? "\"" : "");
- }
- free_pv_fid(pv);
- return 1;
+ r = 1;
+
+out:
+ if (filter_refresh_needed)
+ refresh_filters(cmd);
+
+ if (scan_needed)
+ lvmcache_label_scan(cmd, 2);
-bad:
free_pv_fid(pv);
- return 0;
+ return r;
}
void pvcreate_params_set_defaults(struct pvcreate_params *pp)
@@ -1542,7 +1552,7 @@ struct physical_volume *pvcreate_vol(struct cmd_context *cmd, const char *pv_nam
}
}
- if (!pvcreate_check(cmd, pv_name, pp))
+ if (!_pvcreate_check(cmd, pv_name, pp))
goto_bad;
if (sigint_caught())
diff --git a/tools/pvcreate.c b/tools/pvcreate.c
index 67ecd41..958e353 100644
--- a/tools/pvcreate.c
+++ b/tools/pvcreate.c
@@ -105,15 +105,6 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
- /*
- * Make sure we don't overwrite any existing signature
- * that may have been created after last time we did filtering.
- */
- if (!(refresh_filters(cmd))) {
- log_error("Failed to refresh filters before pvcreate.");
- return ECMD_FAILED;
- }
-
for (i = 0; i < argc; i++) {
if (sigint_caught())
return_ECMD_FAILED;
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fa793bed64a72818…
Commit: fa793bed64a728185a9f8aa6196f0d411f89daf5
Parent: 6dd98c1fa89abb8ee9b91504a73d3a1c3f10e6d4
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Wed Aug 13 15:39:03 2014 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Wed Aug 13 16:10:12 2014 +0200
select: add support for selection to match string list subset, recognize { } operator
Using "[ ]" operator together with "&&" (or ",") inside causes the
string list to be matched if and only if all the items given match
the value reported and the number of items also match. This is
strict list matching and the original behaviour we already have.
In contrast to that, the new "{ }" operator together with "&&" inside
causes the string list to be matched if and only if all the items given
match the value reported but the number of items don't need to match.
So we can provide a subset in selection criteria and if the subset
is found, it matches.
For example:
$ lvs -o name,tags
LV LV Tags
lvol0 a
lvol1 a,b
lvol2 b,c,x
lvol3 a,b,y
$ lvs -o name,tags -S 'tags=[a,b]'
LV LV Tags
lvol1 a,b
$ lvs -o name,tags -S 'tags={a,b}'
LV LV Tags
lvol1 a,b
lvol3 a,b,y
So in the example above the a,b is subset of a,b,y and therefore
it also matches.
Clearly, when using "||" (or "#") inside, the { } and [ ] is the
same:
$ lvs -o name,tags -S 'tags=[a#b]'
LV LV Tags
lvol0 a
lvol1 a,b
lvol2 b,c,x
lvol3 a,b,y
$ lvs -o name,tags -S 'tags={a#b}'
LV LV Tags
lvol0 a
lvol1 a,b
lvol2 b,c,x
lvol3 a,b,y
Also in addition to the above feature, fix list with single value
matching when using [ ]:
Before this patch:
$ lvs -o name,tags -S 'tags=[a]'
LV LV Tags
lvol0 a
lvol1 a,b
lvol3 a,b,y
With this patch applied:
$ lvs -o name,tags -S 'tags=[a]'
LV LV Tags
lvol0 a
In case neither [] or {} is used, assume {} (the behaviour is not
changed here):
$ lvs -o name,tags -S 'tags=a'
LV LV Tags
lvol0 a
lvol1 a,b
lvol3 a,b,y
So in new terms 'tags=a' is equal to 'tags={a}'.
---
WHATS_NEW_DM | 2 +
libdm/libdm-report.c | 109 +++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 92 insertions(+), 19 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 7bb3f4c..cf74aca 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,7 @@
Version 1.02.89 -
=================================
+ Add support for selection to match string list subset, recognize { } operator.
+ Fix string list selection with '[value]' to not match list that's superset.
Fix string list selection to match whole words only, not prefixes.
Version 1.02.88 - 5th August 2014
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 620283c..9363a92 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -131,6 +131,8 @@ static struct op_def _op_cmp[] = {
#define SEL_LIST_MASK 0x000F0000
#define SEL_LIST_LS 0x00010000
#define SEL_LIST_LE 0x00020000
+#define SEL_LIST_SUBSET_LS 0x00040000
+#define SEL_LIST_SUBSET_LE 0x00080000
static struct op_def _op_log[] = {
{ "&&", SEL_AND, "All fields must match" },
@@ -142,6 +144,8 @@ static struct op_def _op_log[] = {
{ ")", SEL_PRECEDENCE_PE, "Right parenthesis" },
{ "[", SEL_LIST_LS, "List start" },
{ "]", SEL_LIST_LE, "List end"},
+ { "{", SEL_LIST_SUBSET_LS, "List subset start"},
+ { "}", SEL_LIST_SUBSET_LE, "List subset end"},
{ NULL, 0, NULL},
};
@@ -1247,9 +1251,9 @@ static int _cmp_field_string(const char *field_id, const char *a, const char *b,
return 0;
}
-/* Matches if all items from selection string list match. */
-static int _cmp_field_string_list_all(const struct str_list_sort_value *val,
- const struct selection_str_list *sel)
+/* Matches if all items from selection string list match list value strictly 1:1. */
+static int _cmp_field_string_list_strict_all(const struct str_list_sort_value *val,
+ const struct selection_str_list *sel)
{
struct dm_str_list *sel_item;
unsigned int i = 1;
@@ -1269,7 +1273,36 @@ static int _cmp_field_string_list_all(const struct str_list_sort_value *val,
return 1;
}
-/* Matches if any item from selection string list matches. */
+/* Matches if all items from selection string list match a subset of list value. */
+static int _cmp_field_string_list_subset_all(const struct str_list_sort_value *val,
+ const struct selection_str_list *sel)
+{
+ struct dm_str_list *sel_item;
+ unsigned int i = 1, last_found = 1;;
+ int r = 0;
+
+ /* if value has no items and selection has at leas one, it's clear there's no match */
+ if ((val->items[0].len == 0) && dm_list_size(sel->list))
+ return 0;
+
+ /* Check selection is a subset of the value. */
+ dm_list_iterate_items(sel_item, sel->list) {
+ r = 0;
+ for (i = last_found; i <= val->items[0].len; i++) {
+ if ((strlen(sel_item->str) == val->items[i].len) &&
+ !strncmp(sel_item->str, val->value + val->items[i].pos, val->items[i].len)) {
+ last_found = i;
+ r = 1;
+ }
+ }
+ if (!r)
+ break;
+ }
+
+ return r;
+}
+
+/* Matches if any item from selection string list matches list value. */
static int _cmp_field_string_list_any(const struct str_list_sort_value *val,
const struct selection_str_list *sel)
{
@@ -1299,11 +1332,24 @@ static int _cmp_field_string_list(const char *field_id,
const struct str_list_sort_value *value,
const struct selection_str_list *selection, uint32_t flags)
{
- int r;
+ int subset, r;
+
+ switch (selection->type & SEL_LIST_MASK) {
+ case SEL_LIST_LS:
+ subset = 0;
+ break;
+ case SEL_LIST_SUBSET_LS:
+ subset = 1;
+ break;
+ default:
+ log_error(INTERNAL_ERROR "_cmp_field_string_list: unknown list type");
+ return 0;
+ }
switch (selection->type & SEL_MASK) {
case SEL_AND:
- r = _cmp_field_string_list_all(value, selection);
+ r = subset ? _cmp_field_string_list_subset_all(value, selection)
+ : _cmp_field_string_list_strict_all(value, selection);
break;
case SEL_OR:
r = _cmp_field_string_list_any(value, selection);
@@ -1932,11 +1978,11 @@ static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
struct selection_str_list *ssl = NULL;
struct dm_str_list *item;
const char *begin_item, *end_item, *tmp;
- uint32_t end_op_flags, end_op_flag_hit = 0;
+ uint32_t op_flags, end_op_flag_expected, end_op_flag_hit = 0;
struct dm_str_list **arr;
size_t list_size;
unsigned int i;
- int list_end;
+ int list_end = 0;
char c;
if (!(ssl = dm_pool_alloc(mem, sizeof(*ssl))) ||
@@ -1948,8 +1994,8 @@ static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
ssl->type = 0;
*begin = s;
- if (!_tok_op_log(s, &tmp, SEL_LIST_LS)) {
- /* Only one item - SEL_LIST_LS and SEL_LIST_LE not used */
+ if (!(op_flags = _tok_op_log(s, &tmp, SEL_LIST_LS | SEL_LIST_SUBSET_LS))) {
+ /* Only one item - SEL_LIST_{SUBSET_}LS and SEL_LIST_{SUBSET_}LE not used */
c = _get_and_skip_quote_char(&s);
if (!(s = _tok_value_string(s, &begin_item, &end_item, c, SEL_AND | SEL_OR | SEL_PRECEDENCE_PE, NULL))) {
log_error(_str_list_item_parsing_failed, ft->id);
@@ -1957,32 +2003,47 @@ static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
}
if (!_add_item_to_string_list(mem, begin_item, end_item, ssl->list))
goto_bad;
- ssl->type = SEL_OR;
+ ssl->type = SEL_OR | SEL_LIST_LS;
goto out;
}
- /* More than one item - items enclosed in SEL_LIST_LS and SEL_LIST_LE.
+ /* More than one item - items enclosed in SEL_LIST_LS and SEL_LIST_LE
+ * or SEL_LIST_SUBSET_LS and SEL_LIST_SUBSET_LE.
* Each element is terminated by AND or OR operator or 'list end'.
* The first operator hit is then the one allowed for the whole list,
* no mixing allowed!
*/
- end_op_flags = SEL_LIST_LE | SEL_AND | SEL_OR;
+
+ /* Are we using [] or {} for the list? */
+ end_op_flag_expected = (op_flags == SEL_LIST_LS) ? SEL_LIST_LE : SEL_LIST_SUBSET_LE;
+
+ op_flags = SEL_LIST_LE | SEL_LIST_SUBSET_LE | SEL_AND | SEL_OR;
s++;
while (*s) {
s = _skip_space(s);
c = _get_and_skip_quote_char(&s);
- if (!(s = _tok_value_string(s, &begin_item, &end_item, c, end_op_flags, NULL))) {
+ if (!(s = _tok_value_string(s, &begin_item, &end_item, c, op_flags, NULL))) {
log_error(_str_list_item_parsing_failed, ft->id);
goto bad;
}
s = _skip_space(s);
- if (!(end_op_flag_hit = _tok_op_log(s, &tmp, end_op_flags))) {
+ if (!(end_op_flag_hit = _tok_op_log(s, &tmp, op_flags))) {
log_error("Invalid operator in selection list.");
goto bad;
}
- list_end = end_op_flag_hit == SEL_LIST_LE;
+ if (end_op_flag_hit & (SEL_LIST_LE | SEL_LIST_SUBSET_LE)) {
+ list_end = 1;
+ if (end_op_flag_hit != end_op_flag_expected) {
+ for (i = 0; _op_log[i].string; i++)
+ if (_op_log[i].flags == end_op_flag_expected)
+ break;
+ log_error("List ended with incorrect character, "
+ "expecting \'%s\'.", _op_log[i].string);
+ goto bad;
+ }
+ }
if (ssl->type) {
if (!list_end && !(ssl->type & end_op_flag_hit)) {
@@ -1990,8 +2051,12 @@ static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
"in selection list at a time.");
goto bad;
}
- } else
- ssl->type = list_end ? SEL_OR : end_op_flag_hit;
+ } else {
+ if (list_end)
+ ssl->type = end_op_flag_expected == SEL_LIST_LE ? SEL_AND : SEL_OR;
+ else
+ ssl->type = end_op_flag_hit;
+ }
if (!_add_item_to_string_list(mem, begin_item, end_item, ssl->list))
goto_bad;
@@ -2002,11 +2067,17 @@ static const char *_tok_value_string_list(const struct dm_report_field_type *ft,
break;
}
- if (end_op_flag_hit != SEL_LIST_LE) {
+ if (!(end_op_flag_hit & (SEL_LIST_LE | SEL_LIST_SUBSET_LE))) {
log_error("Missing list end for selection field %s", ft->id);
goto bad;
}
+ /* Store information whether [] or {} was used. */
+ if ((end_op_flag_expected == SEL_LIST_LE))
+ ssl->type |= SEL_LIST_LS;
+ else
+ ssl->type |= SEL_LIST_SUBSET_LS;
+
/* Sort the list. */
if (!(list_size = dm_list_size(ssl->list))) {
log_error(INTERNAL_ERROR "_tok_value_string_list: list has no items");