1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-28 02:50:41 +03:00

More LV-related tidying. lvdisplay without args now shows all LVs.

This commit is contained in:
Alasdair Kergon 2001-11-14 18:38:07 +00:00
parent 6e74833c6c
commit 9b7742bb36
11 changed files with 183 additions and 215 deletions

View File

@ -52,4 +52,8 @@ static inline int list_empty(struct list *head) {
#define list_item(v, t) \
((t *)((char *)(v) - (unsigned int) &((t *) 0)->list))
/* Given a known element in a known structure, locate the struct list */
#define list_head(v, t, e) \
(((t *)((char *)(v) - (unsigned int) &((t *) 0)->e))->list)
#endif

View File

@ -175,7 +175,7 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
}
static char *_generate_lv_name(struct volume_group *vg,
char *buffer, size_t len)
char *buffer, size_t len)
{
struct list *lvh;
struct logical_volume *lv;
@ -229,8 +229,7 @@ struct logical_volume *lv_create(const char *name,
return NULL;
}
if (!name &&
!(name = _generate_lv_name(vg, dname, sizeof(dname)))) {
if (!name && !(name = _generate_lv_name(vg, dname, sizeof(dname)))) {
log_error("Failed to generate unique name for the new "
"logical volume");
return NULL;
@ -350,19 +349,17 @@ int lv_extend(struct logical_volume *lv, uint32_t extents,
return 0;
}
int lv_remove(struct volume_group *vg, struct list *lvh)
int lv_remove(struct volume_group *vg, struct logical_volume *lv)
{
int i;
struct logical_volume *lv;
lv = &list_item(lvh, struct lv_list)->lv;
for (i = 0; i < lv->le_count; i++)
lv->map[i].pv->pe_allocated--;
vg->lv_count--;
vg->free_count += lv->le_count;
list_del(lvh);
list_del(&list_head(lv, struct lv_list, lv));
return 1;
}

View File

@ -248,7 +248,8 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents);
int lv_extend(struct logical_volume *lv,
uint32_t extents, struct list *allocatable_pvs);
int lv_remove(struct volume_group *vg, struct list *lvh);
/* lv must be part of vg->lvs */
int lv_remove(struct volume_group *vg, struct logical_volume *lv);
/* FIXME: Move to other files */

View File

@ -52,4 +52,8 @@ static inline int list_empty(struct list *head) {
#define list_item(v, t) \
((t *)((char *)(v) - (unsigned int) &((t *) 0)->list))
/* Given a known element in a known structure, locate the struct list */
#define list_head(v, t, e) \
(((t *)((char *)(v) - (unsigned int) &((t *) 0)->e))->list)
#endif

View File

@ -20,7 +20,7 @@
#include "tools.h"
static int lvchange_single(char *lv_name);
static int lvchange_single(struct volume_group *vg, struct logical_volume *lv);
static int lvchange_permission(struct logical_volume *lv);
static int lvchange_availability(struct logical_volume *lv);
static int lvchange_contiguous(struct logical_volume *lv);
@ -28,10 +28,6 @@ static int lvchange_readahead(struct logical_volume *lv);
int lvchange(int argc, char **argv)
{
int opt;
int ret = 0;
int ret_max = 0;
if (!arg_count(available_ARG) && !arg_count(contiguous_ARG)
&& !arg_count(permission_ARG) && !arg_count(readahead_ARG)) {
log_error("One or more of -a, -C, -p or -r required");
@ -43,59 +39,28 @@ int lvchange(int argc, char **argv)
return EINVALID_CMD_LINE;
}
/* Walk through logical volumes */
for (opt = 0; opt < argc; opt++) {
ret = lvchange_single(argv[opt]);
if (ret > ret_max)
ret_max = ret;
}
return ret_max;
return process_each_lv(argc, argv, &lvchange_single);
}
static int lvchange_single(char *lv_name)
static int lvchange_single(struct volume_group *vg, struct logical_volume *lv)
{
char *vg_name;
int doit = 0;
struct volume_group *vg;
struct list *lvh;
struct logical_volume *lv;
/* FIXME Common code here - Add to a foreach? */
/* does VG exist? */
if (!(vg_name = extract_vgname(fid, lv_name))) {
return ECMD_FAILED;
}
log_verbose("Finding volume group %s", vg_name);
if (!(vg = fid->ops->vg_read(fid, 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 changing a "
"logical volume", vg_name);
return ECMD_FAILED;
}
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_item(lvh, struct lv_list)->lv;
if (lv->status & SNAPSHOT_ORG) {
log_error("Can't change logical volume %s under snapshot",
lv_name);
lv->name);
return ECMD_FAILED;
}
if (lv->status & SNAPSHOT) {
log_error("Can't change snapshot logical volume %s", lv_name);
log_error("Can't change snapshot logical volume %s", lv->name);
return ECMD_FAILED;
}
@ -196,9 +161,10 @@ static int lvchange_availability(struct logical_volume *lv)
if (lv_stat & ACTIVE) {
if (!lv_activate(lv))
return 0;
} else
} else {
if (!lv_deactivate(lv))
return 0;
}
return 1;
}
@ -220,24 +186,24 @@ static int lvchange_contiguous(struct logical_volume *lv)
if (!(lv_allocation & ALLOC_CONTIGUOUS) &&
!(lv->status & ALLOC_CONTIGUOUS)) {
log_error("Allocation policy of logical volume %s is already"
" not contiguous", lv->name);
" not contiguous", lv->name);
return 0;
}
/******** FIXME lv_check_contiguous?
if ((lv_allocation & ALLOC_CONTIGUOUS)
&& (ret = lv_check_contiguous(vg, lv_index + 1)) == FALSE) {
log_error("No contiguous logical volume \"%s\"", lv_name);
log_error("No contiguous logical volume %s", lv->name);
return 0;
*********/
if (lv_allocation & ALLOC_CONTIGUOUS) {
lv->status |= ALLOC_CONTIGUOUS;
log_verbose("Setting contiguous allocation policy for %s",
lv->name);
log_verbose("Setting contiguous allocation policy for %s",
lv->name);
} else {
lv->status &= ~ALLOC_CONTIGUOUS;
log_verbose("Removing contiguous allocation policy for %s",
log_verbose("Removing contiguous allocation policy for %s",
lv->name);
}

View File

@ -220,8 +220,8 @@ int lvcreate(int argc, char **argv)
}
*************/
if (!(lv = lv_create(lv_name, status, stripes, stripesize,
extents, vg, pvh)))
if (!(lv = lv_create(lv_name, status, stripes, stripesize, extents,
vg, pvh)))
return ECMD_FAILED;
if (arg_count(readahead_ARG)) {

View File

@ -20,60 +20,22 @@
#include "tools.h"
int lvdisplay_single(char *lv_name);
static int lvdisplay_single(struct volume_group *vg, struct logical_volume *lv);
int lvdisplay(int argc, char **argv)
{
int ret = 0;
int ret_max = 0;
int opt = 0;
/* FIXME Allow VG / all arguments via a process_each? */
if (!argc) {
log_error("Please enter one or more logical volume paths");
return EINVALID_CMD_LINE;
}
/* FIXME Allow VG args via process_each */
if (arg_count(colon_ARG) && arg_count(verbose_ARG)) {
log_error("Options -v and -c are incompatible");
return EINVALID_CMD_LINE;
}
for (opt = 0; opt < argc; opt++) {
ret = lvdisplay_single(argv[opt]);
if (ret > ret_max)
ret_max = ret;
}
return ret_max;
return process_each_lv(argc, argv, &lvdisplay_single);
}
int lvdisplay_single(char *lv_name)
static int lvdisplay_single(struct volume_group *vg, struct logical_volume *lv)
{
char *vg_name = NULL;
struct volume_group *vg;
struct list *lvh;
struct logical_volume *lv;
/* does VG exist? */
if (!(vg_name = extract_vgname(fid, lv_name))) {
return ECMD_FAILED;
}
log_verbose("Finding volume group %s", vg_name);
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group %s doesn't exist", vg_name);
return ECMD_FAILED;
}
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_item(lvh, struct lv_list)->lv;
if (arg_count(colon_ARG))
lvdisplay_colons(lv);
else {

View File

@ -20,62 +20,29 @@
#include "tools.h"
int lvremove_single(char *lv_name);
static int lvremove_single(struct volume_group *vg, struct logical_volume *lv);
int lvremove(int argc, char **argv)
{
int opt;
int ret = 0;
if (!argc) {
log_error("Please enter one or more logical volume paths");
return EINVALID_CMD_LINE;
}
for (opt = 0; opt < argc; opt++) {
if ((ret = lvremove_single(argv[opt])))
break;
}
return ret;
return process_each_lv(argc, argv, &lvremove_single);
}
int lvremove_single(char *lv_name)
static int lvremove_single(struct volume_group *vg, struct logical_volume *lv)
{
char *vg_name = NULL;
struct volume_group *vg;
struct list *lvh;
struct logical_volume *lv;
/* does VG exist? */
if (!(vg_name = extract_vgname(fid, lv_name))) {
return ECMD_FAILED;
}
log_verbose("Finding volume group %s", vg_name);
if (!(vg = fid->ops->vg_read(fid, 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 a "
"logical volume", vg_name);
"logical volume", vg->name);
return ECMD_FAILED;
}
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_item(lvh, struct lv_list)->lv;
if (lv->status & SNAPSHOT_ORG) {
log_error("Can't remove logical volume %s under snapshot",
lv_name);
lv->name);
return ECMD_FAILED;
}
@ -83,7 +50,7 @@ int lvremove_single(char *lv_name)
if (lv->open) {
log_error("can't remove open %s logical volume %s",
lv->status & SNAPSHOT ? "snapshot" : "",
lv_name);
lv->name);
return ECMD_FAILED;
}
************/
@ -91,21 +58,21 @@ int lvremove_single(char *lv_name)
if (!arg_count(force_ARG)) {
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);
lv->name) == 'n') {
log_print("Logical volume %s not removed", lv->name);
return 0;
}
}
log_verbose("Releasing logical volume %s", lv_name);
if (!lv_remove(vg, lvh)) {
log_error("Error releasing logical volume %s", lv_name);
log_verbose("Releasing logical volume %s", lv->name);
if (!lv_remove(vg, lv)) {
log_error("Error releasing logical volume %s", lv->name);
return ECMD_FAILED;
}
/********* FIXME
log_verbose("Unlinking special file %s", lv_name);
if (!lvm_check_devfs() && unlink(lv_name) == -1)
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);
**********/
@ -114,10 +81,10 @@ int lvremove_single(char *lv_name)
return ECMD_FAILED;
/******** FIXME
if ((ret = do_autobackup(vg_name, vg)))
if ((ret = do_autobackup(vg->name, vg)))
return ret;
**********/
log_print("logical volume %s successfully removed", lv_name);
log_print("logical volume %s successfully removed", lv->name);
return 0;
}

View File

@ -20,18 +20,16 @@
#include "tools.h"
static int lvscan_single(const char *vg_name);
static int lvscan_single(struct volume_group *vg, struct logical_volume *lv);
int lvscan(int argc, char **argv)
{
int ret;
if (argc) {
log_error("No additional command line arguments allowed");
return EINVALID_CMD_LINE;
}
ret = process_each_vg(argc, argv, &lvscan_single);
return process_each_lv(argc, argv, &lvscan_single);
/*********** FIXME Count! Add private struct to process_each*
if (!lv_total)
@ -54,51 +52,29 @@ int lvscan(int argc, char **argv)
}
*************/
return ret;
}
static int lvscan_single(const char *vg_name)
static int lvscan_single(struct volume_group *vg, struct logical_volume *lv)
{
int lv_active = 0;
int lv_total = 0;
ulong lv_capacity_total = 0;
int vg_total = 0;
char *dummy;
const char *active_str, *snapshot_str;
struct volume_group *vg;
struct logical_volume *lv;
struct list *lvh;
if (lv->status & ACTIVE) {
active_str = "ACTIVE ";
lv_active++;
} else
active_str = "inactive ";
log_verbose("Checking for volume group %s", vg_name);
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group %s not found", vg_name);
return ECMD_FAILED;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group %s is exported", vg_name);
return ECMD_FAILED;
}
vg_total++;
list_iterate(lvh, &vg->lvs) {
lv = &list_item(lvh, struct lv_list)->lv;
if (lv->status & ACTIVE) {
active_str = "ACTIVE ";
lv_active++;
} else
active_str = "inactive ";
if (lv->status & SNAPSHOT_ORG)
snapshot_str = "Original";
else if (lv->status & SNAPSHOT)
snapshot_str = "Snapshot";
else
snapshot_str = " ";
if (lv->status & SNAPSHOT_ORG)
snapshot_str = "Original";
else if (lv->status & SNAPSHOT)
snapshot_str = "Snapshot";
else
snapshot_str = " ";
/********** FIXME Snapshot
if (lv->status & SNAPSHOT)
@ -108,19 +84,18 @@ static int lvscan_single(const char *vg_name)
SIZE_SHORT);
else
***********/
dummy =
display_size(lv->size / 2, SIZE_SHORT);
dummy = display_size(lv->size / 2, SIZE_SHORT);
log_print("%s%s '%s%s/%s' [%s]%s%s", active_str, snapshot_str,
fid->cmd->dev_dir, vg->name, lv->name, dummy,
(lv->status & ALLOC_STRICT) ? " strict" : "",
(lv->status & ALLOC_CONTIGUOUS) ? " contiguous" : "");
log_print("%s%s '%s%s/%s' [%s]%s%s", active_str, snapshot_str,
fid->cmd->dev_dir, vg->name, lv->name, dummy,
(lv->status & ALLOC_STRICT) ? " strict" : "",
(lv->status & ALLOC_CONTIGUOUS) ? " contiguous" : "");
dbg_free(dummy);
dbg_free(dummy);
/* FIXME sprintf? */
if (lv->stripes > 1 && !(lv->status & SNAPSHOT))
log_print(" striped[%u]", lv->stripes);
/* FIXME sprintf? */
if (lv->stripes > 1 && !(lv->status & SNAPSHOT))
log_print(" striped[%u]", lv->stripes);
/******** FIXME Device number display & Snapshot
if (arg_count(blockdevice_ARG))
@ -132,7 +107,7 @@ static int lvscan_single(const char *vg_name)
printf(" of %s", lv->lv_snapshot_org->name);
*****************/
lv_total++;
lv_total++;
/******** FIXME Snapshot
if (lv->status & SNAPSHOT)
@ -140,9 +115,7 @@ static int lvscan_single(const char *vg_name)
lv->lv_remap_end * lv->lv_chunk_size
else
********/
lv_capacity_total += lv->size;
}
lv_capacity_total += lv->size;
return 0;
}

View File

@ -87,6 +87,92 @@ int do_autobackup(struct volume_group *vg)
return 0;
}
int process_each_lv(int argc, char **argv,
int (*process_single) (struct volume_group * vg,
struct logical_volume * lv))
{
int opt = 0;
int ret_max = 0;
int ret = 0;
int vg_count = 0;
struct list *lvh;
struct list *vgh, *vgs;
struct volume_group *vg;
struct logical_volume *lv;
char *vg_name;
if (argc) {
log_verbose("Using logical volume(s) on command line");
for (; opt < argc; opt++) {
char *lv_name = argv[opt];
/* does VG exist? */
if (!(vg_name = extract_vgname(fid, lv_name))) {
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
continue;
}
log_verbose("Finding volume group %s", vg_name);
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group %s doesn't exist",
vg_name);
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
continue;
}
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);
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
continue;
}
lv = &list_item(lvh, struct lv_list)->lv;
if ((ret = process_single(vg, lv)) > ret_max)
ret_max = ret;
}
} else {
log_verbose("Finding all logical volume(s)");
if (!(vgs = fid->ops->get_vgs(fid))) {
log_error("No volume groups found");
return ECMD_FAILED;
}
list_iterate(vgh, vgs) {
vg_name = list_item(vgh, struct name_list)->name;
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group %s not found", vg_name);
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
continue;
}
/* FIXME Export-handling */
if (vg->status & EXPORTED_VG) {
log_error("Volume group %s is exported",
vg_name);
if (ret_max < ECMD_FAILED)
ret_max = ECMD_FAILED;
continue;
}
list_iterate(lvh, &vg->lvs) {
lv = &list_item(lvh, struct lv_list)->lv;
ret = process_single(vg, lv);
if (ret > ret_max)
ret_max = ret;
}
vg_count++;
}
}
return ret_max;
}
int process_each_vg(int argc, char **argv,
int (*process_single) (const char *vg_name))
{
@ -95,7 +181,7 @@ int process_each_vg(int argc, char **argv,
int ret = 0;
struct list *vgh;
struct list *vgs_list;
struct list *vgs;
if (argc) {
log_verbose("Using volume group(s) on command line");
@ -104,13 +190,14 @@ int process_each_vg(int argc, char **argv,
ret_max = ret;
} else {
log_verbose("Finding all volume group(s)");
if (!(vgs_list = fid->ops->get_vgs(fid))) {
if (!(vgs = fid->ops->get_vgs(fid))) {
log_error("No volume groups found");
return ECMD_FAILED;
}
list_iterate(vgh, vgs_list) {
ret = process_single(
list_item(vgh, struct name_list)->name);
list_iterate(vgh, vgs) {
ret =
process_single(list_item(vgh, struct name_list)->
name);
if (ret > ret_max)
ret_max = ret;
}
@ -138,16 +225,18 @@ int process_each_pv(int argc, char **argv, struct volume_group *vg,
vg->name);
continue;
}
ret = process_single(vg,
&list_item(pvh, struct pv_list)->pv);
ret = process_single(vg,
&list_item(pvh,
struct pv_list)->pv);
if (ret > ret_max)
ret_max = ret;
}
} else {
log_verbose("Using all physical volume(s) in volume group");
list_iterate(pvh, &vg->pvs) {
ret = process_single(vg,
&list_item(pvh, struct pv_list)->pv);
ret = process_single(vg,
&list_item(pvh,
struct pv_list)->pv);
if (ret > ret_max)
ret_max = ret;
}
@ -166,7 +255,7 @@ int is_valid_chars(char *n)
}
char *extract_vgname(struct format_instance *fi, char *lv_name)
{
{
char *vg_name = lv_name;
char *st;
char *dev_dir = fi->cmd->dev_dir;
@ -180,7 +269,8 @@ char *extract_vgname(struct format_instance *fi, char *lv_name)
/* Require exactly one slash */
/* FIXME But allow for consecutive slashes */
if (!(st = strchr(vg_name, '/')) || (strchr(st + 1, '/'))) {
log_error("%s: Invalid path for Logical Volume", lv_name);
log_error("%s: Invalid path for Logical Volume",
lv_name);
return 0;
}
@ -196,10 +286,11 @@ char *extract_vgname(struct format_instance *fi, char *lv_name)
if (!(vg_name = default_vgname(fid))) {
if (lv_name)
log_error("Path required for Logical Volume %s", lv_name);
log_error("Path required for Logical Volume %s",
lv_name);
return 0;
}
return vg_name;
}
@ -209,7 +300,7 @@ char *default_vgname(struct format_instance *fi)
char *dev_dir = fi->cmd->dev_dir;
/* Take default VG from environment? */
vg_path = getenv("LVM_VG_NAME");
vg_path = getenv("LVM_VG_NAME");
if (!vg_path)
return 0;
@ -218,11 +309,10 @@ char *default_vgname(struct format_instance *fi)
vg_path += strlen(dev_dir);
if (strchr(vg_path, '/')) {
log_error("Environment Volume Group in LVM_VG_NAME invalid: %s",
log_error("Environment Volume Group in LVM_VG_NAME invalid: %s",
vg_path);
return 0;
}
return pool_strdup(fid->cmd->mem, vg_path);
}

View File

@ -32,6 +32,10 @@ int process_each_pv(int argc, char **argv, struct volume_group *vg,
int (*process_single) (struct volume_group *vg,
struct physical_volume *pv));
int process_each_lv(int argc, char **argv,
int (*process_single) (struct volume_group *vg,
struct logical_volume *lv));
int is_valid_chars(char *n);
char *default_vgname(struct format_instance *fi);