1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-26 08:55:06 +03:00

read_lvflags: keep flag reading focused on flags

Previous update needed to add handling segtype within flag.c
which somewhat breaks API separition and also had bug in hanlding
actual flags.

So instead keep segtype code in _read_segtype_and_lvflags() within
import_vsn1.c and handle purly flags in read_lvflags() from const
string.
This commit is contained in:
Zdenek Kabelac 2024-10-23 16:35:55 +02:00
parent 1f0530919e
commit 2916a8a1f3
3 changed files with 49 additions and 45 deletions

View File

@ -232,56 +232,41 @@ int read_flags(uint64_t *status, enum pv_vg_lv_e type, int mask, const struct dm
/*
* 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.
* Returns 0 and prints warning for an UNKNOWN flag.
*
* Note: using these segtype status flags instead of actual
* status flags ensures wanted incompatibility.
*/
struct segment_type *read_segtype_and_lvflags(struct cmd_context *cmd, uint64_t *status,
const char *segtype_str)
int read_lvflags(uint64_t *status, const char *flags_str)
{
unsigned i;
size_t len;
struct segment_type *segtype;
const struct flag *flags = _lv_flags;
char *delim, *flag, *str, buffer[2048];
const char *delim;
size_t len;
unsigned i;
if ((str = strchr(segtype_str, '+'))) {
if ((len = (strlen(segtype_str) + 1)) >= sizeof(buffer)) {
log_error("Segment string type string is too long.");
return NULL;
do {
if ((delim = strchr(flags_str, '+')))
len = delim - flags_str;
else
len = strlen(flags_str);
for (i = 0; flags[i].kind; ++i)
if ((flags[i].kind & SEGTYPE_FLAG) &&
!strncmp(flags_str, flags[i].description, len) &&
!flags[i].description[len]) {
*status |= flags[i].mask;
break; /* Found matching flag */
}
if (!flags[i].kind) {
log_warn("WARNING: Unrecognised flag(s) %s.", flags_str);
return 0; /* Unknown flag is incompatible */
}
memcpy(buffer, segtype_str, len);
delim = buffer + (str - segtype_str);
flags_str = delim + 1;
} while (delim); /* Till no more flags in type appear */
do {
flag = delim;
if ((delim = strchr(delim, '+')))
*delim++ = '\0';
for (i = 0; flags[i].kind; i++)
if ((flags[i].kind & SEGTYPE_FLAG) &&
!strcmp(flags[i].description, flag)) {
*status |= flags[i].mask;
break;
}
} while (delim && flags[i].kind); /* Till no more flags in type appear */
if (!flags[i].kind)
/* Unknown flag is incompatible - returns unmodified segtype_str */
log_warn("WARNING: Unrecognised flag %s in segment type %s.",
flag, segtype_str);
segtype_str = buffer;
}
if (!(segtype = get_segtype_from_string(cmd, segtype_str)))
return_NULL;
return segtype;
return 1;
}
int print_segtype_lvflags(char *buffer, size_t size, uint64_t status)

View File

@ -67,8 +67,7 @@ int print_flags(char *buffer, size_t size, enum pv_vg_lv_e type, int mask, uint6
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);
struct segment_type *read_segtype_and_lvflags(struct cmd_context *cmd, uint64_t *status,
const char *segtype_str);
int read_lvflags(uint64_t *status, const char *flags_str);
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, uint32_t *alloc_size);

View File

@ -371,6 +371,26 @@ static void _insert_segment(struct logical_volume *lv, struct lv_segment *seg)
dm_list_add(&lv->segments, &seg->list);
}
static struct segment_type *_read_segtype_and_lvflags(struct cmd_context *cmd,
uint64_t *status,
const char *segtype_str)
{
char buffer[128]; /* just for segtype name */
const char *str;
size_t len;
if ((str = strchr(segtype_str, '+')))
if (read_lvflags(status, ++str)) {
len = str - segtype_str - 1;
len = min(len, sizeof(buffer) - 1);
memcpy(buffer, segtype_str, len);
buffer[len] = 0;
segtype_str = buffer;
}
return get_segtype_from_string(cmd, segtype_str);
}
static int _read_segment(struct cmd_context *cmd,
struct format_type *fmt,
struct format_instance *fid,
@ -417,9 +437,9 @@ static int _read_segment(struct cmd_context *cmd,
return 0;
}
if (!(segtype = read_segtype_and_lvflags(cmd, &lv->status, segtype_str))) {
log_error("Couldn't read segtype for logical volume %s.",
display_lvname(lv));
if (!(segtype = _read_segtype_and_lvflags(cmd, &lv->status, segtype_str))) {
log_error("Couldn't read segtype %s for logical volume %s.",
segtype_str, display_lvname(lv));
return 0;
}