From 0299a7af1ec1eeb11388ed15c4c78f224fee76b2 Mon Sep 17 00:00:00 2001 From: Zdenek Kabelac Date: Mon, 29 May 2017 14:20:05 +0200 Subject: [PATCH] flags: add read and print of segtype flag Allow storing LV status bits with segment type name field. Switching to this since this field has better support for compatibility with older version of lvm2 - since such unknown segtype will not cause complete invisiblity of metadata from older lvm2 code - just the particular LV will become unusable with unknown type of segment. --- WHATS_NEW | 1 + lib/format_text/flags.c | 58 +++++++++++++++++++++++++++++++++ lib/format_text/import-export.h | 3 ++ 3 files changed, 62 insertions(+) diff --git a/WHATS_NEW b/WHATS_NEW index f38c23ca2..de65e0ef7 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.172 - =============================== + Support storing status flags via segtype name field. Stop using '--yes' mode when fsadm runs without terminal. Extend validation of filesystems resized by fsadm. Enhance lvconvert automatic settings of possible (raid) LV types. diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c index 871eeab4c..64bad1c07 100644 --- a/lib/format_text/flags.c +++ b/lib/format_text/flags.c @@ -213,3 +213,61 @@ int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm *status |= s; return 1; } + +/* + * Parse extra status flags from segment "type" string. + * These flags are seen as INCOMPATIBLE by any older lvm2 code. + * All flags separated by '+' are trimmed from passed string. + * All UNKNOWN flags will again cause the "UNKNOWN" segtype. + * + * Note: using these segtype status flags instead of actual + * status flags ensures wanted incompatiblity. + */ +int read_segtype_lvflags(uint64_t *status, char *segtype_str) +{ + unsigned i; + const struct flag *flags = _lv_flags; + char *delim; + char *flag; + + if (!(delim = strchr(segtype_str, '+'))) + return 1; /* No flags */ + + *delim = '\0'; /* Cut away 1st. '+' */ + do { + flag = delim + 1; + if ((delim = strchr(segtype_str, '+'))) + *delim = '\0'; + + for (i = 0; flags[i].description; i++) + if ((flags[i].kind & SEGTYPE_FLAG) && + !strcmp(flags[i].description, flag)) { + *status |= flags[i].mask; + break; + } + + if (!flags[i].description) { + log_error("Unknown flag %s passed with segment type %s.", + flag, segtype_str); + return 0; /* Unknown flag is incompatible */ + } + } while (delim); /* Till no more flags in type appear */ + + return 1; +} + +int print_segtype_lvflags(char *buffer, size_t size, uint64_t status) +{ + unsigned i; + const struct flag *flags = _lv_flags; + + buffer[0] = 0; + for (i = 0; flags[i].mask; i++) + if ((flags[i].kind & SEGTYPE_FLAG) && + (status & flags[i].mask) && + !emit_to_buffer(&buffer, &size, "+%s", + flags[i].description)) + return 0; + + return 1; +} diff --git a/lib/format_text/import-export.h b/lib/format_text/import-export.h index ddad50ff6..abb9b0e75 100644 --- a/lib/format_text/import-export.h +++ b/lib/format_text/import-export.h @@ -62,6 +62,9 @@ struct text_vg_version_ops *text_vg_vsn1_init(void); int print_flags(char *buffer, size_t size, enum pv_vg_lv_e type, int mask, uint64_t status); int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm_config_value *cv); +int print_segtype_lvflags(char *buffer, size_t size, uint64_t status); +int read_segtype_lvflags(uint64_t *status, char *segtype_scr); + int text_vg_export_file(struct volume_group *vg, const char *desc, FILE *fp); size_t text_vg_export_raw(struct volume_group *vg, const char *desc, char **buf); struct volume_group *text_vg_import_file(struct format_instance *fid, -- 2.43.5