From cfd658dab0671854ed0e3f3a750cdeb134e692ca Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Mon, 29 Oct 2001 13:52:23 +0000 Subject: [PATCH] lvremove --- lib/format1/disk-rep.c | 2 ++ lib/format1/import-export.c | 39 ++-------------------- lib/metadata/metadata.c | 64 ++++++++++++++++++++++++++++++++++--- lib/metadata/metadata.h | 22 ++++++++----- make.tmpl.in | 2 +- tools/Makefile.in | 3 +- tools/lvremove.c | 46 +++++++++++++------------- tools/stub.h | 1 - tools/toollib.c | 48 ++++++++++++++++++++++++++++ tools/toollib.h | 2 ++ 10 files changed, 155 insertions(+), 74 deletions(-) diff --git a/lib/format1/disk-rep.c b/lib/format1/disk-rep.c index 50f4a7fd9..ba2bc0e06 100644 --- a/lib/format1/disk-rep.c +++ b/lib/format1/disk-rep.c @@ -295,6 +295,8 @@ struct disk_list *read_pv(struct device *dev, struct pool *mem, goto bad; } + log_very_verbose("Found %s in VG %s", name, data->pv.vg_name); + return data; bad: diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c index 9b74c5694..27c065df9 100644 --- a/lib/format1/import-export.c +++ b/lib/format1/import-export.c @@ -34,41 +34,6 @@ static char *_create_lv_name(struct pool *mem, const char *full_name) return pool_strdup(mem, ptr); } -static struct logical_volume *_find_lv(struct volume_group *vg, - const char *name) -{ - struct list_head *tmp; - struct logical_volume *lv; - struct lv_list *ll; - const char *ptr = strrchr(name, '/') + 1; - - list_for_each(tmp, &vg->lvs) { - ll = list_entry(tmp, struct lv_list, list); - lv = &ll->lv; - - if (!strcmp(ptr, lv->name)) - return lv; - } - - return NULL; -} - -static struct physical_volume *_find_pv(struct volume_group *vg, - struct device *dev) -{ - struct list_head *tmp; - struct physical_volume *pv; - struct pv_list *pl; - - list_for_each(tmp, &vg->pvs) { - pl = list_entry(tmp, struct pv_list, list); - pv = &pl->pv; - if (dev == pv->dev) - return pv; - } - return NULL; -} - static int _fill_lv_array(struct logical_volume **lvs, struct volume_group *vg, struct disk_list *dl) { @@ -79,7 +44,7 @@ static int _fill_lv_array(struct logical_volume **lvs, list_for_each(tmp, &dl->lvs) { struct lvd_list *ll = list_entry(tmp, struct lvd_list, list); - if (!(lv = _find_lv(vg, ll->lv.lv_name))) { + if (!(lv = find_lv(vg, ll->lv.lv_name))) { stack; return 0; } @@ -475,7 +440,7 @@ int import_lvs(struct pool *mem, struct volume_group *vg, ll = list_entry(tmp2, struct lvd_list, list); lvd = &ll->lv; - if (!_find_lv(vg, lvd->lv_name) && + if (!find_lv(vg, lvd->lv_name) && !_add_lv(mem, vg, lvd)) { stack; return 0; diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index 0a8f26af0..19194a693 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -218,15 +218,71 @@ struct physical_volume *pv_create(struct io_space *ios, const char *name) struct list_head *find_pv_in_vg(struct volume_group *vg, const char *pv_name) { - struct list_head *tmp; + struct list_head *pvh; struct pv_list *pv; - list_for_each(tmp, &vg->pvs) { - pv = list_entry(tmp, struct pv_list, list); + list_for_each(pvh, &vg->pvs) { + pv = list_entry(pvh, struct pv_list, list); + /* FIXME check dev not name */ if (!strcmp(dev_name(pv->pv.dev), pv_name)) - return tmp; + return pvh; } return NULL; } + +struct list_head *find_lv_in_vg(struct volume_group *vg, const char *lv_name) +{ + struct list_head *lvh; + + const char *ptr; + + /* Use last component */ + if ((ptr = strrchr(lv_name, '/'))) + ptr++; + else + ptr = lv_name; + + list_for_each(lvh, &vg->lvs) + if (!strcmp(list_entry(lvh, struct lv_list, list)->lv.name, + ptr)) + return lvh; + + return NULL; +} + +struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name) +{ + struct list_head *lvh; + + if ((lvh = find_lv_in_vg(vg, lv_name))) + return &list_entry(lvh, struct lv_list, list)->lv; + else + return NULL; +} + +struct physical_volume *_find_pv(struct volume_group *vg, + struct device *dev) +{ + struct list_head *tmp; + struct physical_volume *pv; + struct pv_list *pl; + + list_for_each(tmp, &vg->pvs) { + pl = list_entry(tmp, struct pv_list, list); + pv = &pl->pv; + if (dev == pv->dev) + return pv; + } + return NULL; +} + +int lv_remove(struct volume_group *vg, struct list_head *lvh) +{ + list_del(lvh); + vg->lv_count--; + + return 1; +} + diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 7900191dc..fcba4de7a 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -232,16 +232,22 @@ struct physical_volume *pv_find(struct volume_group *vg, int lv_add(struct volume_group *vg, struct logical_volume *lv); /* Remove an LV from a given VG */ -int lv_remove(struct volume_group *vg, struct logical_volume *lv); - -/* ? Return the VG that contains a given LV (based on path given in lv_name) */ -/* (or environment var?) */ -struct volume_group *vg_find(const char *lv_name); - -/* Find an LV within a given VG */ -struct logical_volume *lv_find(struct volume_group *vg, const char *lv_name); +int lv_remove(struct volume_group *vg, struct list_head *lvh); /* Find a PV within a given VG */ struct list_head *find_pv_in_vg(struct volume_group *vg, const char *pv_name); +/* Find an LV within a given VG */ +struct list_head *find_lv_in_vg(struct volume_group *vg, const char *lv_name); + +/* Return the VG that contains a given LV (based on path given in lv_name) */ +/* or environment var */ +struct volume_group *find_vg_with_lv(const char *lv_name); + + +/* FIXME Merge these functions with ones above */ +struct physical_volume *_find_pv(struct volume_group *vg, struct device *dev); +struct logical_volume *find_lv(struct volume_group *vg, const char *lv_name); + + #endif diff --git a/make.tmpl.in b/make.tmpl.in index acc063fd1..3098e87fb 100644 --- a/make.tmpl.in +++ b/make.tmpl.in @@ -51,7 +51,7 @@ SUFFIXES= SUFFIXES=.c .d .o CFLAGS+=-Wall -CFLAGS+=-O2 +#CFLAGS+=-O2 CFLAGS+=-g -fno-omit-frame-pointer #CFLAGS+=-pg CFLAGS+=-DDEBUG_MEM -DDEBUG diff --git a/tools/Makefile.in b/tools/Makefile.in index f88b8bf70..167b3c75b 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -23,6 +23,7 @@ VPATH = @srcdir@ SOURCES=\ lvm.c \ lvmchange.c \ + lvremove.c \ pvchange.c \ pvcreate.c \ pvdisplay.c \ @@ -33,8 +34,8 @@ SOURCES=\ vgcreate.c \ vgextend.c \ vgreduce.c \ - vgrename.c \ vgremove.c \ + vgrename.c \ vgscan.c TARGETS=\ diff --git a/tools/lvremove.c b/tools/lvremove.c index e3bf06c72..44458de68 100644 --- a/tools/lvremove.c +++ b/tools/lvremove.c @@ -26,19 +26,15 @@ int lvremove(int argc, char **argv) { int opt; int ret = 0; - char *lv_name; - if (argc == 0) { - log_error("please enter a logical volume path"); + if (!argc) { + log_error("Please enter one or more logical volume paths"); return EINVALID_CMD_LINE; } for (opt = 0; opt < argc; opt++) { - lv_name = argv[opt]; - - if ((ret = lvremove_single(lv_name))) + if ((ret = lvremove_single(argv[opt]))) break; - } return ret; @@ -46,38 +42,39 @@ int lvremove(int argc, char **argv) int lvremove_single(char *lv_name) { - int ret = 0; char *vg_name = NULL; - char buffer[NAME_LEN]; struct volume_group *vg; + struct list_head *lvh; struct logical_volume *lv; - - lv_name = lvm_check_default_vg_name(lv_name, buffer, sizeof (buffer)); /* does VG exist? */ - vg_name = vg_name_of_lv(lv_name); + if (!(vg_name = extract_vgname(ios, lv_name))) { + return ECMD_FAILED; + } log_verbose("Finding volume group %s", vg_name); if (!(vg = ios->vg_read(ios, vg_name))) { - log_error("volume group %s doesn't exist", vg_name); + log_error("Volume group %s doesn't exist", vg_name); return ECMD_FAILED; } if (!(vg->status & ACTIVE)) { - log_error("volume group %s must be active before removing " + log_error("Volume group %s must be active before removing a " "logical volume", vg_name); return ECMD_FAILED; } - if (!(lv = lv_find(vg, lv_name))) { - log_error("can't find logical volume %s in volume group %s", + if (!(lvh = find_lv_in_vg(vg, lv_name))) { + log_error("Can't find logical volume %s in volume group %s", lv_name, vg_name); return ECMD_FAILED; } + lv = &list_entry(lvh, struct lv_list, list)->lv; + if (lv->status & SNAPSHOT_ORG) { - log_error("can't remove logical volume %s under snapshot", + log_error("Can't remove logical volume %s under snapshot", lv_name); return ECMD_FAILED; } @@ -95,28 +92,33 @@ int lvremove_single(char *lv_name) if (yes_no_prompt ("Do you really want to remove %s? [y/n]: ", lv_name) == 'n') { - log_print("logical volume %s not removed", lv_name); + log_print("Logical volume %s not removed", lv_name); return 0; } } - log_verbose("releasing logical volume %s", lv_name); - if (lv_remove(vg, lv)) { + log_verbose("Releasing logical volume %s", lv_name); + if (lv_remove(vg, lvh)) { log_error("Error releasing logical volume %s", lv_name); return ECMD_FAILED; } - log_verbose("unlinking special file %s", lv_name); +/********* FIXME + log_verbose("Unlinking special file %s", lv_name); if (!lvm_check_devfs() && unlink(lv_name) == -1) log_error("Error unlinking special file %s", lv_name); +**********/ /* store it on disks */ - if (ios->vg_write(vg)) + if (ios->vg_write(ios, vg)) return ECMD_FAILED; +/******** FIXME if ((ret = do_autobackup(vg_name, vg))) return ret; +**********/ log_print("logical volume %s successfully removed", lv_name); return 0; } + diff --git a/tools/stub.h b/tools/stub.h index 51c81547e..d6dc783b7 100644 --- a/tools/stub.h +++ b/tools/stub.h @@ -27,7 +27,6 @@ int lvmdiskscan(int argc, char **argv) {return 1;} int lvmsadc(int argc, char **argv) {return 1;} int lvmsar(int argc, char **argv) {return 1;} int lvreduce(int argc, char **argv) {return 1;} -int lvremove(int argc, char **argv) {return 1;} int lvrename(int argc, char **argv) {return 1;} int lvscan(int argc, char **argv) {return 1;} int pvdata(int argc, char **argv) {return 1;} diff --git a/tools/toollib.c b/tools/toollib.c index a5f2adc52..25783fcd4 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -166,3 +166,51 @@ int is_valid_chars(char *n) return 1; } +char *extract_vgname(struct io_space *ios, char *lv_name) +{ + char *vg_name = lv_name; + char *vg_path, *st; + + /* Path supplied? */ + if (strchr(vg_name, '/')) { + /* Strip prefix (optional) */ + if (!strncmp(vg_name, ios->prefix, strlen(ios->prefix))) + vg_name += strlen(ios->prefix); + + /* Require exactly one slash */ + if (!(st = strchr(vg_name, '/')) || (strchr(st + 1, '/'))) { + log_error("%s: Invalid path for Logical Volume", lv_name); + return 0; + } + + vg_name = pool_strdup(ios->mem, vg_name); + if (!vg_name) { + log_error("Allocation of vg_name failed"); + return 0; + } + + *strchr(vg_name, '/') = '\0'; + return vg_name; + } + + /* Take default VG from environment? */ + vg_path = getenv("LVM_VG_NAME"); + if (!vg_path) { + log_error("Path required for Logical Volume %s", lv_name); + return 0; + } + + /* Strip prefix (optional) */ + if (!strncmp(vg_path, ios->prefix, strlen(ios->prefix))) + vg_path += strlen(ios->prefix); + + if (strchr(vg_path, '/')) { + log_error("Environment Volume Group in LVM_VG_NAME invalid: %s", + vg_path); + return 0; + } + + return pool_strdup(ios->mem, vg_path); + +} + diff --git a/tools/toollib.h b/tools/toollib.h index b44394317..260706550 100644 --- a/tools/toollib.h +++ b/tools/toollib.h @@ -34,4 +34,6 @@ int process_each_pv(int argc, char **argv, struct volume_group *vg, int is_valid_chars(char *n); +char *extract_vgname(struct io_space *ios, char *lv_name); + #endif