From 7f64c8e5fa18b517c5841d276bf8317ce20911d6 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Wed, 15 Sep 2004 15:02:36 +0000 Subject: [PATCH] Export dm name build & split functions. --- WHATS_NEW | 1 + lib/activate/dev_manager.c | 115 +++++++------------------------------ lib/misc/lvm-string.c | 105 +++++++++++++++++++++++++++++++++ lib/misc/lvm-string.h | 8 +++ 4 files changed, 134 insertions(+), 95 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 1758e5b96..15f130234 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.00.23 - ==================================== + Export dm name build & split functions. Use O_NOATIME on devices if available. Write log message when each segtype/format gets initialised. New commands 'segtypes' and 'formats'. diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 5f6a02fdd..f6fb683bd 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -165,89 +165,6 @@ static inline void _clear_flag(struct dev_layer *dl, int bit) dl->flags &= ~(1 << bit); } -/* - * Device layer names are all of the form --, any - * other hyphens that appear in these names are quoted with yet - * another hyphen. The top layer of any device has no layer - * name. eg, vg0-lvol0. - */ -static void _count_hyphens(const char *str, size_t *len, int *hyphens) -{ - const char *ptr; - - for (ptr = str; *ptr; ptr++, (*len)++) - if (*ptr == '-') - (*hyphens)++; -} - -/* - * Copies a string, quoting hyphens with hyphens. - */ -static void _quote_hyphens(char **out, const char *src) -{ - while (*src) { - if (*src == '-') - *(*out)++ = '-'; - - *(*out)++ = *src++; - } -} - -/* - * -- or if !layer just -. - */ -static char *_build_name(struct pool *mem, const char *vg, - const char *lv, const char *layer) -{ - size_t len = 0; - int hyphens = 0; - char *r, *out; - - _count_hyphens(vg, &len, &hyphens); - _count_hyphens(lv, &len, &hyphens); - - if (layer && *layer) - _count_hyphens(layer, &len, &hyphens); - - len += hyphens + 2; - - if (!(r = pool_alloc(mem, len))) { - stack; - return NULL; - } - - out = r; - _quote_hyphens(&out, vg); - *out++ = '-'; - _quote_hyphens(&out, lv); - - if (layer && *layer) { - *out++ = '-'; - _quote_hyphens(&out, layer); - } - *out = '\0'; - - return r; -} - -/* Find start of LV component in hyphenated name */ -static char *_find_lv_name(char *vg) -{ - char *c = vg; - - while (*c && *(c + 1)) { - if (*c == '-') { - if (*(c + 1) == '-') - c++; - else - return (c + 1); - } - c++; - } - - return NULL; -} - static char *_build_dlid(struct pool *mem, const char *lvid, const char *layer) { char *dlid; @@ -519,10 +436,16 @@ static int _percent(struct dev_manager *dm, const char *name, const char *uuid, return 0; } -static int _rename(struct dev_layer *dl, char *newname) +static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname) { int r = 1; struct dm_task *dmt; + char *vgname, *lvname, *layer; + + if (!split_dm_name(dm->mem, dl->name, &vgname, &lvname, &layer)) { + log_error("Couldn't split up dm layer name %s", dl->name); + return 0; + } log_verbose("Renaming %s to %s", dl->name, newname); @@ -537,11 +460,13 @@ static int _rename(struct dev_layer *dl, char *newname) goto out; } - if (!(r = dm_task_run(dmt))) + if (!(r = dm_task_run(dmt))) { log_error("Couldn't rename device '%s'.", dl->name); + goto out; + } if (r && _get_flag(dl, VISIBLE)) - fs_rename_lv(dl->lv, newname, _find_lv_name(dl->name)); + fs_rename_lv(dl->lv, newname, lvname); dl->name = newname; @@ -1052,7 +977,7 @@ int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv, /* * Build a name for the top layer. */ - if (!(name = _build_name(dm->mem, lv->vg->name, lv->name, NULL))) { + if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL))) { stack; return 0; } @@ -1077,7 +1002,7 @@ int dev_manager_snapshot_percent(struct dev_manager *dm, /* * Build a name for the top layer. */ - if (!(name = _build_name(dm->mem, lv->vg->name, lv->name, NULL))) { + if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL))) { stack; return 0; } @@ -1109,7 +1034,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm, /* * Build a name for the top layer. */ - if (!(name = _build_name(dm->mem, lv->vg->name, lv->name, NULL))) { + if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, NULL))) { stack; return 0; } @@ -1173,7 +1098,7 @@ static struct dev_layer *_create_layer(struct dev_manager *dm, char *name, *dlid; struct dev_layer *dl; - if (!(name = _build_name(dm->mem, lv->vg->name, lv->name, layer))) { + if (!(name = build_dm_name(dm->mem, lv->vg->name, lv->name, layer))) { stack; return NULL; } @@ -1618,11 +1543,11 @@ static int _create_rec(struct dev_manager *dm, struct dev_layer *dl) if (dl->info.exists) { if ((suffix = rindex(dl->dlid, '-'))) suffix++; - newname = _build_name(dm->mem, dm->vg_name, dl->lv->name, - suffix); + newname = build_dm_name(dm->mem, dm->vg_name, dl->lv->name, + suffix); if (strcmp(newname, dl->name)) { if (!_suspend_parents(dm, dl) || - !_suspend(dl) || !_rename(dl, newname)) { + !_suspend(dl) || !_rename(dm, dl, newname)) { stack; return 0; } @@ -2227,8 +2152,8 @@ int dev_manager_lv_mknodes(const struct logical_volume *lv) { char *name; - if (!(name = _build_name(lv->vg->cmd->mem, lv->vg->name, - lv->name, NULL))) { + if (!(name = build_dm_name(lv->vg->cmd->mem, lv->vg->name, + lv->name, NULL))) { stack; return 0; } diff --git a/lib/misc/lvm-string.c b/lib/misc/lvm-string.c index 18c8a9f39..a3028dafc 100644 --- a/lib/misc/lvm-string.c +++ b/lib/misc/lvm-string.c @@ -16,6 +16,7 @@ #include "lib.h" #include "lvm-types.h" #include "lvm-string.h" +#include "pool.h" #include @@ -98,3 +99,107 @@ int split_words(char *buffer, unsigned max, char **argv) return arg; } + +/* + * Device layer names are all of the form --, any + * other hyphens that appear in these names are quoted with yet + * another hyphen. The top layer of any device has no layer + * name. eg, vg0-lvol0. + */ +static void _count_hyphens(const char *str, size_t *len, int *hyphens) +{ + const char *ptr; + + for (ptr = str; *ptr; ptr++, (*len)++) + if (*ptr == '-') + (*hyphens)++; +} + +/* + * Copies a string, quoting hyphens with hyphens. + */ +static void _quote_hyphens(char **out, const char *src) +{ + while (*src) { + if (*src == '-') + *(*out)++ = '-'; + + *(*out)++ = *src++; + } +} + +/* + * -- or if !layer just -. + */ +char *build_dm_name(struct pool *mem, const char *vg, + const char *lv, const char *layer) +{ + size_t len = 0; + int hyphens = 0; + char *r, *out; + + _count_hyphens(vg, &len, &hyphens); + _count_hyphens(lv, &len, &hyphens); + + if (layer && *layer) + _count_hyphens(layer, &len, &hyphens); + + len += hyphens + 2; + + if (!(r = pool_alloc(mem, len))) { + stack; + return NULL; + } + + out = r; + _quote_hyphens(&out, vg); + *out++ = '-'; + _quote_hyphens(&out, lv); + + if (layer && *layer) { + *out++ = '-'; + _quote_hyphens(&out, layer); + } + *out = '\0'; + + return r; +} + +/* + * Remove hyphen quoting from a component of a name. + * NULL-terminates the component and returns start of next component. + */ +static char *_unquote(char *component) +{ + char *c = component; + char *o = c; + + while (*c) { + if (*(c + 1)) { + if (*c == '-') { + if (*(c + 1) == '-') + c++; + else + break; + } + } + *o = *c; + o++; + c++; + } + + *o = '\0'; + return (c + 1); +} + +int split_dm_name(struct pool *mem, const char *dmname, + char **vgname, char **lvname, char **layer) +{ + if (!(*vgname = pool_strdup(mem, dmname))) + return 0; + + _unquote(*layer = _unquote(*lvname = _unquote(*vgname))); + + return 1; +} + diff --git a/lib/misc/lvm-string.h b/lib/misc/lvm-string.h index af5be880f..104d1de24 100644 --- a/lib/misc/lvm-string.h +++ b/lib/misc/lvm-string.h @@ -19,6 +19,8 @@ #include #include +struct pool; + /* * On error, up to glibc 2.0.6, snprintf returned -1 if buffer was too small; * From glibc 2.1 it returns number of chars (excl. trailing null) that would @@ -32,4 +34,10 @@ int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...); int split_words(char *buffer, unsigned max, char **argv); +char *build_dm_name(struct pool *mem, const char *vg, + const char *lv, const char *layer); + +int split_dm_name(struct pool *mem, const char *dmname, + char **vgname, char **lvname, char **layer); + #endif