1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00
This commit is contained in:
Alasdair Kergon 2001-10-29 13:52:23 +00:00
parent 952152fd96
commit cfd658dab0
10 changed files with 155 additions and 74 deletions

View File

@ -295,6 +295,8 @@ struct disk_list *read_pv(struct device *dev, struct pool *mem,
goto bad; goto bad;
} }
log_very_verbose("Found %s in VG %s", name, data->pv.vg_name);
return data; return data;
bad: bad:

View File

@ -34,41 +34,6 @@ static char *_create_lv_name(struct pool *mem, const char *full_name)
return pool_strdup(mem, ptr); 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, static int _fill_lv_array(struct logical_volume **lvs,
struct volume_group *vg, struct disk_list *dl) 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) { list_for_each(tmp, &dl->lvs) {
struct lvd_list *ll = list_entry(tmp, struct lvd_list, list); 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; stack;
return 0; return 0;
} }
@ -475,7 +440,7 @@ int import_lvs(struct pool *mem, struct volume_group *vg,
ll = list_entry(tmp2, struct lvd_list, list); ll = list_entry(tmp2, struct lvd_list, list);
lvd = &ll->lv; lvd = &ll->lv;
if (!_find_lv(vg, lvd->lv_name) && if (!find_lv(vg, lvd->lv_name) &&
!_add_lv(mem, vg, lvd)) { !_add_lv(mem, vg, lvd)) {
stack; stack;
return 0; return 0;

View File

@ -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 *find_pv_in_vg(struct volume_group *vg, const char *pv_name)
{ {
struct list_head *tmp; struct list_head *pvh;
struct pv_list *pv; struct pv_list *pv;
list_for_each(tmp, &vg->pvs) { list_for_each(pvh, &vg->pvs) {
pv = list_entry(tmp, struct pv_list, list); pv = list_entry(pvh, struct pv_list, list);
/* FIXME check dev not name */
if (!strcmp(dev_name(pv->pv.dev), pv_name)) if (!strcmp(dev_name(pv->pv.dev), pv_name))
return tmp; return pvh;
} }
return NULL; 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;
}

View File

@ -232,16 +232,22 @@ struct physical_volume *pv_find(struct volume_group *vg,
int lv_add(struct volume_group *vg, struct logical_volume *lv); int lv_add(struct volume_group *vg, struct logical_volume *lv);
/* Remove an LV from a given VG */ /* Remove an LV from a given VG */
int lv_remove(struct volume_group *vg, struct logical_volume *lv); int lv_remove(struct volume_group *vg, struct list_head *lvh);
/* ? 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);
/* Find a PV within a given VG */ /* Find a PV within a given VG */
struct list_head *find_pv_in_vg(struct volume_group *vg, const char *pv_name); 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 #endif

View File

@ -51,7 +51,7 @@ SUFFIXES=
SUFFIXES=.c .d .o SUFFIXES=.c .d .o
CFLAGS+=-Wall CFLAGS+=-Wall
CFLAGS+=-O2 #CFLAGS+=-O2
CFLAGS+=-g -fno-omit-frame-pointer CFLAGS+=-g -fno-omit-frame-pointer
#CFLAGS+=-pg #CFLAGS+=-pg
CFLAGS+=-DDEBUG_MEM -DDEBUG CFLAGS+=-DDEBUG_MEM -DDEBUG

View File

@ -23,6 +23,7 @@ VPATH = @srcdir@
SOURCES=\ SOURCES=\
lvm.c \ lvm.c \
lvmchange.c \ lvmchange.c \
lvremove.c \
pvchange.c \ pvchange.c \
pvcreate.c \ pvcreate.c \
pvdisplay.c \ pvdisplay.c \
@ -33,8 +34,8 @@ SOURCES=\
vgcreate.c \ vgcreate.c \
vgextend.c \ vgextend.c \
vgreduce.c \ vgreduce.c \
vgrename.c \
vgremove.c \ vgremove.c \
vgrename.c \
vgscan.c vgscan.c
TARGETS=\ TARGETS=\

View File

@ -26,19 +26,15 @@ int lvremove(int argc, char **argv)
{ {
int opt; int opt;
int ret = 0; int ret = 0;
char *lv_name;
if (argc == 0) { if (!argc) {
log_error("please enter a logical volume path"); log_error("Please enter one or more logical volume paths");
return EINVALID_CMD_LINE; return EINVALID_CMD_LINE;
} }
for (opt = 0; opt < argc; opt++) { for (opt = 0; opt < argc; opt++) {
lv_name = argv[opt]; if ((ret = lvremove_single(argv[opt])))
if ((ret = lvremove_single(lv_name)))
break; break;
} }
return ret; return ret;
@ -46,38 +42,39 @@ int lvremove(int argc, char **argv)
int lvremove_single(char *lv_name) int lvremove_single(char *lv_name)
{ {
int ret = 0;
char *vg_name = NULL; char *vg_name = NULL;
char buffer[NAME_LEN];
struct volume_group *vg; struct volume_group *vg;
struct list_head *lvh;
struct logical_volume *lv; struct logical_volume *lv;
lv_name = lvm_check_default_vg_name(lv_name, buffer, sizeof (buffer));
/* does VG exist? */ /* 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); log_verbose("Finding volume group %s", vg_name);
if (!(vg = ios->vg_read(ios, 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; return ECMD_FAILED;
} }
if (!(vg->status & ACTIVE)) { 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); "logical volume", vg_name);
return ECMD_FAILED; return ECMD_FAILED;
} }
if (!(lv = lv_find(vg, lv_name))) { if (!(lvh = find_lv_in_vg(vg, lv_name))) {
log_error("can't find logical volume %s in volume group %s", log_error("Can't find logical volume %s in volume group %s",
lv_name, vg_name); lv_name, vg_name);
return ECMD_FAILED; return ECMD_FAILED;
} }
lv = &list_entry(lvh, struct lv_list, list)->lv;
if (lv->status & SNAPSHOT_ORG) { 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); lv_name);
return ECMD_FAILED; return ECMD_FAILED;
} }
@ -95,28 +92,33 @@ int lvremove_single(char *lv_name)
if (yes_no_prompt if (yes_no_prompt
("Do you really want to remove %s? [y/n]: ", ("Do you really want to remove %s? [y/n]: ",
lv_name) == 'n') { lv_name) == 'n') {
log_print("logical volume %s not removed", lv_name); log_print("Logical volume %s not removed", lv_name);
return 0; return 0;
} }
} }
log_verbose("releasing logical volume %s", lv_name); log_verbose("Releasing logical volume %s", lv_name);
if (lv_remove(vg, lv)) { if (lv_remove(vg, lvh)) {
log_error("Error releasing logical volume %s", lv_name); log_error("Error releasing logical volume %s", lv_name);
return ECMD_FAILED; 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) if (!lvm_check_devfs() && unlink(lv_name) == -1)
log_error("Error unlinking special file %s", lv_name); log_error("Error unlinking special file %s", lv_name);
**********/
/* store it on disks */ /* store it on disks */
if (ios->vg_write(vg)) if (ios->vg_write(ios, vg))
return ECMD_FAILED; return ECMD_FAILED;
/******** FIXME
if ((ret = do_autobackup(vg_name, vg))) if ((ret = do_autobackup(vg_name, vg)))
return ret; return ret;
**********/
log_print("logical volume %s successfully removed", lv_name); log_print("logical volume %s successfully removed", lv_name);
return 0; return 0;
} }

View File

@ -27,7 +27,6 @@ int lvmdiskscan(int argc, char **argv) {return 1;}
int lvmsadc(int argc, char **argv) {return 1;} int lvmsadc(int argc, char **argv) {return 1;}
int lvmsar(int argc, char **argv) {return 1;} int lvmsar(int argc, char **argv) {return 1;}
int lvreduce(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 lvrename(int argc, char **argv) {return 1;}
int lvscan(int argc, char **argv) {return 1;} int lvscan(int argc, char **argv) {return 1;}
int pvdata(int argc, char **argv) {return 1;} int pvdata(int argc, char **argv) {return 1;}

View File

@ -166,3 +166,51 @@ int is_valid_chars(char *n)
return 1; 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);
}

View File

@ -34,4 +34,6 @@ int process_each_pv(int argc, char **argv, struct volume_group *vg,
int is_valid_chars(char *n); int is_valid_chars(char *n);
char *extract_vgname(struct io_space *ios, char *lv_name);
#endif #endif