mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvremove
This commit is contained in:
parent
952152fd96
commit
cfd658dab0
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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=\
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;}
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user