mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +03:00
lvdisplay & lvreduce
This commit is contained in:
parent
f90fc5faf0
commit
94b8220f6a
@ -52,45 +52,41 @@ static struct dm_task *_info(struct logical_volume *lv)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_active(struct logical_volume *lv, int *result)
|
int lv_active(struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = -1;
|
||||||
struct dm_task *dmt;
|
struct dm_task *dmt;
|
||||||
|
|
||||||
if (!(dmt = _info(lv))) {
|
if (!(dmt = _info(lv))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dm_task_exists(dmt, result)) {
|
if (!dm_task_exists(dmt, &r)) {
|
||||||
stack;
|
stack;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = 1;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_open_count(struct logical_volume *lv, int *result)
|
int lv_open_count(struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = -1;
|
||||||
struct dm_task *dmt;
|
struct dm_task *dmt;
|
||||||
|
|
||||||
if (!(dmt = _info(lv))) {
|
if (!(dmt = _info(lv))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dm_task_open_count(dmt, result)) {
|
if (!dm_task_open_count(dmt, &r)) {
|
||||||
stack;
|
stack;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = 1;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
return r;
|
return r;
|
||||||
@ -230,15 +226,12 @@ int activate_lvs_in_vg(struct volume_group *vg)
|
|||||||
{
|
{
|
||||||
struct list *lvh;
|
struct list *lvh;
|
||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
int count = 0, exists;
|
int count = 0;
|
||||||
|
|
||||||
list_iterate(lvh, &vg->lvs) {
|
list_iterate(lvh, &vg->lvs) {
|
||||||
lv = &(list_item(lvh, struct lv_list)->lv);
|
lv = &(list_item(lvh, struct lv_list)->lv);
|
||||||
|
|
||||||
if (!lv_active(lv, &exists) || exists)
|
count += (!lv_active(lv) && lv_activate(lv));
|
||||||
continue;
|
|
||||||
|
|
||||||
count += lv_activate(lv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@ -253,15 +246,12 @@ int deactivate_lvs_in_vg(struct volume_group *vg)
|
|||||||
{
|
{
|
||||||
struct list *lvh;
|
struct list *lvh;
|
||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
int count = 0, exists;
|
int count = 0;
|
||||||
|
|
||||||
list_iterate(lvh, &vg->lvs) {
|
list_iterate(lvh, &vg->lvs) {
|
||||||
lv = &(list_item(lvh, struct lv_list)->lv);
|
lv = &(list_item(lvh, struct lv_list)->lv);
|
||||||
|
|
||||||
if (!lv_active(lv, &exists) || !exists)
|
count += ((lv_active(lv) == 1) && lv_deactivate(lv));
|
||||||
continue;
|
|
||||||
|
|
||||||
count += lv_activate(lv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@ -271,17 +261,12 @@ int lvs_in_vg_activated(struct volume_group *vg)
|
|||||||
{
|
{
|
||||||
struct list *lvh;
|
struct list *lvh;
|
||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
int exists, count = 0;
|
int count = 0;
|
||||||
|
|
||||||
list_iterate(lvh, &vg->lvs) {
|
list_iterate(lvh, &vg->lvs) {
|
||||||
lv = &(list_item(lvh, struct lv_list)->lv);
|
lv = &(list_item(lvh, struct lv_list)->lv);
|
||||||
|
|
||||||
if (!lv_active(lv, &exists)) {
|
count += (lv_active(lv) == 1);
|
||||||
stack;
|
|
||||||
continue; /* FIXME: what is the right thing here ? */
|
|
||||||
}
|
|
||||||
|
|
||||||
count += exists ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@ -291,17 +276,12 @@ int lvs_in_vg_opened(struct volume_group *vg)
|
|||||||
{
|
{
|
||||||
struct list *lvh;
|
struct list *lvh;
|
||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
int open, count = 0;
|
int count = 0;
|
||||||
|
|
||||||
list_iterate(lvh, &vg->lvs) {
|
list_iterate(lvh, &vg->lvs) {
|
||||||
lv = &(list_item(lvh, struct lv_list)->lv);
|
lv = &(list_item(lvh, struct lv_list)->lv);
|
||||||
|
|
||||||
if (!lv_open_count(lv, &open)) {
|
count += (lv_open_count(lv) == 1);
|
||||||
stack;
|
|
||||||
continue; /* FIXME: what is the right thing here ? */
|
|
||||||
}
|
|
||||||
|
|
||||||
count += open ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
/* FIXME Snapshot handling? */
|
/* FIXME Snapshot handling? */
|
||||||
|
|
||||||
int lv_active(struct logical_volume *lv, int *result);
|
int lv_active(struct logical_volume *lv);
|
||||||
int lv_open_count(struct logical_volume *lv, int *result);
|
int lv_open_count(struct logical_volume *lv);
|
||||||
|
|
||||||
int lv_activate(struct logical_volume *lv);
|
int lv_activate(struct logical_volume *lv);
|
||||||
int lv_reactivate(struct logical_volume *lv);
|
int lv_reactivate(struct logical_volume *lv);
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "dbg_malloc.h"
|
#include "dbg_malloc.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
|
#include "activate.h"
|
||||||
|
|
||||||
#define SIZE_BUF 128
|
#define SIZE_BUF 128
|
||||||
|
|
||||||
@ -205,141 +206,199 @@ void pv_display_short(struct physical_volume *pv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
void lvdisplay_colons(struct logical_volume *lv)
|
||||||
/******** FIXME
|
|
||||||
void pv_display_pe(pv_t * pv, pe_disk_t * pe)
|
|
||||||
{
|
{
|
||||||
int p;
|
log_print("%s/%s:%s:%d:%d:-1:%d:%llu:%d:-1:%d:%d:-1:-1",
|
||||||
|
/* FIXME Prefix - attach to struct volume_group? */
|
||||||
for (p = 0; p < pv->pe_total; p++)
|
lv->vg->name,
|
||||||
printf("pe#: %4d vg: %s lv: %d le: %d\n",
|
lv->name,
|
||||||
p, pv->vg_name, pe[p].lv_num, pe[p].le_num);
|
lv->vg->name,
|
||||||
|
(lv->status & (LVM_READ | LVM_WRITE)) >> 8,
|
||||||
return;
|
lv->status & ACTIVE,
|
||||||
}
|
/* FIXME lv->lv_number, */
|
||||||
*******/
|
lvs_in_vg_opened(lv->vg),
|
||||||
|
lv->size,
|
||||||
void pv_display_pe_text(pv_t * pv, pe_disk_t * pe, lv_disk_t * lvs)
|
lv->le_count,
|
||||||
{
|
/* FIXME num allocated? */
|
||||||
int flag = 0;
|
(lv->status & (ALLOC_STRICT | ALLOC_CONTIGUOUS)) >> 12,
|
||||||
int lv_num_last = 0;
|
lv->read_ahead
|
||||||
int p = 0;
|
/* FIXME device num MAJOR(lv->lv_dev), MINOR(lv->lv_dev) */
|
||||||
int pe_free = 0;
|
);
|
||||||
int *pe_this_count = NULL;
|
|
||||||
int pt = 0;
|
|
||||||
int pt_count = 0;
|
|
||||||
lv_disk_t *lv;
|
|
||||||
char *lv_name_this = NULL;
|
|
||||||
char *lv_names = NULL;
|
|
||||||
char *lv_names_sav = NULL;
|
|
||||||
pe_disk_t *pe_this = NULL;
|
|
||||||
|
|
||||||
if ((pe_this = dbg_malloc(pv->pe_total * sizeof (pe_disk_t))) == NULL) {
|
|
||||||
log_error("pe_this allocation failed");
|
|
||||||
goto pv_display_pe_text_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pe_this_count = dbg_malloc(pv->pe_total * sizeof (int))) == NULL) {
|
|
||||||
log_error("pe_this_count allocation failed");
|
|
||||||
goto pv_display_pe_text_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(pe_this, 0, pv->pe_total * sizeof (pe_disk_t));
|
|
||||||
memset(pe_this_count, 0, pv->pe_total * sizeof (int));
|
|
||||||
|
|
||||||
/* get PE and LE summaries */
|
|
||||||
pt_count = 0;
|
|
||||||
for (p = pt_count; p < pv->pe_total; p++) {
|
|
||||||
if (pe[p].lv_num != 0) {
|
|
||||||
flag = 0;
|
|
||||||
for (pt = 0; pt < pt_count; pt++) {
|
|
||||||
if (pe_this[pt].lv_num == pe[p].lv_num) {
|
|
||||||
flag = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flag == 0) {
|
|
||||||
pe_this[pt_count].lv_num = pe[p].lv_num;
|
|
||||||
for (pt = 0; pt < pv->pe_total; pt++)
|
|
||||||
if (pe_this[pt_count].lv_num ==
|
|
||||||
pe[pt].lv_num)
|
|
||||||
pe_this_count[pt_count]++;
|
|
||||||
pt_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lv = lvs;
|
|
||||||
printf(" --- Distribution of physical volume ---\n"
|
|
||||||
" LV Name LE of LV PE for LV\n");
|
|
||||||
for (pt = 0; pt < pt_count; pt++) {
|
|
||||||
printf(" %-25s ", lv->lv_name);
|
|
||||||
if (strlen(lv->lv_name) > 25)
|
|
||||||
printf("\n ");
|
|
||||||
printf("%-8u %-8d\n",
|
|
||||||
lv->lv_allocated_le,
|
|
||||||
pe_this_count[pt]);
|
|
||||||
if (pe_this[pt].lv_num > lv_num_last) {
|
|
||||||
lv_num_last = pe_this[pt].lv_num;
|
|
||||||
lv_names_sav = lv_names;
|
|
||||||
if ((lv_names = dbg_realloc(lv_names,
|
|
||||||
lv_num_last * NAME_LEN)) ==
|
|
||||||
NULL) {
|
|
||||||
log_error("realloc error in %s [line %d]",
|
|
||||||
__FILE__, __LINE__);
|
|
||||||
goto pv_display_pe_text_out;
|
|
||||||
} else
|
|
||||||
lv_names_sav = NULL;
|
|
||||||
}
|
|
||||||
strcpy(&lv_names[(pe_this[pt].lv_num - 1) * NAME_LEN],
|
|
||||||
lv->lv_name);
|
|
||||||
lv++;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\n --- Physical extents ---\n"
|
|
||||||
" PE LV LE Disk sector\n");
|
|
||||||
pe_free = -1;
|
|
||||||
for (p = 0; p < pv->pe_total; p++) {
|
|
||||||
if (pe[p].lv_num != 0) {
|
|
||||||
if (pe_free > -1) {
|
|
||||||
pv_display_pe_free(pe_free, p);
|
|
||||||
pe_free = -1;
|
|
||||||
}
|
|
||||||
lv_name_this = &lv_names[(pe[p].lv_num - 1) * NAME_LEN];
|
|
||||||
printf(" %05d %-25s ", p, lv_name_this);
|
|
||||||
if (strlen(lv_name_this) > 25)
|
|
||||||
printf("\n ");
|
|
||||||
printf("%05d %ld\n", pe[p].le_num,
|
|
||||||
get_pe_offset(p, pv));
|
|
||||||
|
|
||||||
} else if (pe_free == -1)
|
|
||||||
pe_free = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pe_free > 0)
|
|
||||||
pv_display_pe_free(pe_free, p);
|
|
||||||
|
|
||||||
pv_display_pe_text_out:
|
|
||||||
if (lv_names != NULL)
|
|
||||||
dbg_free(lv_names);
|
|
||||||
else if (lv_names_sav != NULL)
|
|
||||||
dbg_free(lv_names_sav);
|
|
||||||
if (pe_this != NULL)
|
|
||||||
dbg_free(pe_this);
|
|
||||||
if (pe_this_count != NULL)
|
|
||||||
dbg_free(pe_this_count);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pv_display_pe_free(int pe_free, int p)
|
void lvdisplay_extents(struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
printf(" %05d free\n", pe_free);
|
|
||||||
|
|
||||||
if (p - pe_free > 1)
|
|
||||||
printf(" .....\n %05d free\n", p - 1);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lvdisplay_full(struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
char *size;
|
||||||
|
uint32_t alloc;
|
||||||
|
|
||||||
|
log_print("--- Logical volume ---");
|
||||||
|
|
||||||
|
/* FIXME prefix */
|
||||||
|
log_print("LV Name %s/%s", lv->vg->name, lv->name);
|
||||||
|
log_print("VG Name %s", lv->vg->name);
|
||||||
|
|
||||||
|
log_print("LV Write Access %s",
|
||||||
|
(lv->status & LVM_WRITE) ? "read/write" : "read only");
|
||||||
|
|
||||||
|
/******* FIXME Snapshot
|
||||||
|
if (lv->status & (LVM_SNAPSHOT_ORG | LVM_SNAPSHOT)) {
|
||||||
|
if (lvm_tab_vg_read_with_pv_and_lv(vg_name, &vg) < 0) {
|
||||||
|
ret = -LVM_ELV_SHOW_VG_READ_WITH_PV_AND_LV;
|
||||||
|
goto lv_show_end;
|
||||||
|
}
|
||||||
|
printf("LV snapshot status ");
|
||||||
|
if (vg_check_active(vg_name) == TRUE) {
|
||||||
|
vg_t *vg_core;
|
||||||
|
if ((ret = vg_status_with_pv_and_lv(vg_name, &vg_core)) == 0) {
|
||||||
|
lv_t *lv_ptr =
|
||||||
|
vg_core->
|
||||||
|
lv[lv_get_index_by_name(vg_core, lv->lv_name)];
|
||||||
|
if (lv_ptr->lv_access & LV_SNAPSHOT) {
|
||||||
|
if (lv_ptr->lv_status & LV_ACTIVE)
|
||||||
|
printf("active ");
|
||||||
|
else
|
||||||
|
printf("INACTIVE ");
|
||||||
|
}
|
||||||
|
if (lv_ptr->lv_access & LV_SNAPSHOT_ORG) {
|
||||||
|
printf("source of\n");
|
||||||
|
while (lv_ptr->lv_snapshot_next != NULL) {
|
||||||
|
lv_ptr = lv_ptr->lv_snapshot_next;
|
||||||
|
printf(" %s [%s]\n",
|
||||||
|
lv_ptr->lv_name,
|
||||||
|
(lv_ptr->
|
||||||
|
lv_status & LV_ACTIVE) ? "active" :
|
||||||
|
"INACTIVE");
|
||||||
|
}
|
||||||
|
vg_free(vg_core, TRUE);
|
||||||
|
} else {
|
||||||
|
printf("destination for %s\n",
|
||||||
|
lv_ptr->lv_snapshot_org->lv_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("INACTIVE ");
|
||||||
|
if (lv->lv_access & LV_SNAPSHOT_ORG)
|
||||||
|
printf("original\n");
|
||||||
|
else
|
||||||
|
printf("snapshot\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
***********/
|
||||||
|
|
||||||
|
log_print("LV Status %savailable",
|
||||||
|
(lv->status & ACTIVE) ? "" : "NOT ");
|
||||||
|
|
||||||
|
/********* FIXME lv_number
|
||||||
|
log_print("LV # %u", lv->lv_number + 1);
|
||||||
|
************/
|
||||||
|
|
||||||
|
/********* FIXME lv_open
|
||||||
|
log_print("# open %u\n", lv->lv_open);
|
||||||
|
**********/
|
||||||
|
/********
|
||||||
|
#ifdef LVM_FUTURE
|
||||||
|
printf("Mirror copies %u\n", lv->lv_mirror_copies);
|
||||||
|
printf("Consistency recovery ");
|
||||||
|
if (lv->lv_recovery | LV_BADBLOCK_ON)
|
||||||
|
printf("bad blocks\n");
|
||||||
|
else
|
||||||
|
printf("none\n");
|
||||||
|
printf("Schedule %u\n", lv->lv_schedule);
|
||||||
#endif
|
#endif
|
||||||
|
********/
|
||||||
|
|
||||||
|
|
||||||
|
size = display_size(lv->size / 2, SIZE_SHORT);
|
||||||
|
log_print("LV Size %s", size);
|
||||||
|
dbg_free(size);
|
||||||
|
|
||||||
|
log_print("Current LE %u", lv->le_count);
|
||||||
|
|
||||||
|
/********** FIXME allocation
|
||||||
|
log_print("Allocated LE %u", lv->allocated_le);
|
||||||
|
**********/
|
||||||
|
|
||||||
|
/********** FIXME Snapshot
|
||||||
|
if (lv->lv_access & LV_SNAPSHOT) {
|
||||||
|
printf("snapshot chunk size %s\n",
|
||||||
|
(dummy = lvm_show_size(lv->lv_chunk_size / 2, SHORT)));
|
||||||
|
dbg_free(dummy);
|
||||||
|
dummy = NULL;
|
||||||
|
if (lv->lv_remap_end > 0) {
|
||||||
|
lv_remap_ptr = lv->lv_remap_ptr;
|
||||||
|
if (lv_remap_ptr > lv->lv_remap_end)
|
||||||
|
lv_remap_ptr = lv->lv_remap_end;
|
||||||
|
dummy = lvm_show_size(lv_remap_ptr *
|
||||||
|
lv->lv_chunk_size / 2, SHORT);
|
||||||
|
dummy1 = lvm_show_size(lv->lv_remap_end *
|
||||||
|
lv->lv_chunk_size / 2, SHORT);
|
||||||
|
printf("Allocated to snapshot %.2f%% [%s/%s]\n",
|
||||||
|
(float) lv_remap_ptr * 100 / lv->lv_remap_end,
|
||||||
|
dummy, dummy1);
|
||||||
|
dbg_free(dummy);
|
||||||
|
dbg_free(dummy1);
|
||||||
|
dummy =
|
||||||
|
lvm_show_size((vg->
|
||||||
|
lv[lv_get_index_by_number
|
||||||
|
(vg,
|
||||||
|
lv->lv_number)]->lv_size -
|
||||||
|
lv->lv_remap_end * lv->lv_chunk_size) / 2,
|
||||||
|
SHORT);
|
||||||
|
printf("Allocated to COW-table %s\n", dummy);
|
||||||
|
dbg_free(dummy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
******************/
|
||||||
|
|
||||||
|
if (lv->stripes > 1) {
|
||||||
|
log_print("Stripes %u", lv->stripes);
|
||||||
|
/*********** FIXME stripesize
|
||||||
|
log_print("Stripe size (KByte) %u", lv->stripesize / 2);
|
||||||
|
***********/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**************
|
||||||
|
#ifdef LVM_FUTURE
|
||||||
|
printf("Bad block ");
|
||||||
|
if (lv->lv_badblock == LV_BADBLOCK_ON)
|
||||||
|
printf("on\n");
|
||||||
|
else
|
||||||
|
printf("off\n");
|
||||||
|
#endif
|
||||||
|
***************/
|
||||||
|
|
||||||
|
alloc = lv->status & (ALLOC_STRICT | ALLOC_CONTIGUOUS);
|
||||||
|
log_print("Allocation %s%s%s%s",
|
||||||
|
!(alloc & (ALLOC_STRICT | ALLOC_CONTIGUOUS)) ? "next free" : "",
|
||||||
|
(alloc == ALLOC_STRICT) ? "strict" : "",
|
||||||
|
(alloc == ALLOC_CONTIGUOUS) ? "contiguous" : "",
|
||||||
|
(alloc == (ALLOC_STRICT | ALLOC_CONTIGUOUS)) ? "strict/contiguous" : ""
|
||||||
|
);
|
||||||
|
|
||||||
|
log_print("Read ahead sectors %u\n", lv->read_ahead);
|
||||||
|
|
||||||
|
/****************
|
||||||
|
#ifdef LVM_FUTURE
|
||||||
|
printf("IO Timeout (seconds) ");
|
||||||
|
if (lv->lv_io_timeout == 0)
|
||||||
|
printf("default\n\n");
|
||||||
|
else
|
||||||
|
printf("%lu\n\n", lv->lv_io_timeout);
|
||||||
|
#endif
|
||||||
|
*************/
|
||||||
|
|
||||||
|
/********* FIXME blockdev
|
||||||
|
printf("Block device %d:%d\n",
|
||||||
|
MAJOR(lv->lv_dev), MINOR(lv->lv_dev));
|
||||||
|
*************/
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
|
|||||||
#define log_err(x...) plog(_LOG_ERR, x)
|
#define log_err(x...) plog(_LOG_ERR, x)
|
||||||
#define log_fatal(x...) plog(_LOG_FATAL, x)
|
#define log_fatal(x...) plog(_LOG_FATAL, x)
|
||||||
|
|
||||||
#define stack log_debug("stack")
|
#define stack log_debug( "s" )
|
||||||
|
|
||||||
#define log_error(fmt, args...) log_err(fmt , ## args)
|
#define log_error(fmt, args...) log_err(fmt , ## args)
|
||||||
#define log_print(fmt, args...) log_warn(fmt , ## args)
|
#define log_print(fmt, args...) log_warn(fmt , ## args)
|
||||||
|
@ -23,8 +23,10 @@ VPATH = @srcdir@
|
|||||||
SOURCES=\
|
SOURCES=\
|
||||||
lvchange.c \
|
lvchange.c \
|
||||||
lvcreate.c \
|
lvcreate.c \
|
||||||
|
lvdisplay.c \
|
||||||
lvm.c \
|
lvm.c \
|
||||||
lvmchange.c \
|
lvmchange.c \
|
||||||
|
lvreduce.c \
|
||||||
lvremove.c \
|
lvremove.c \
|
||||||
lvscan.c \
|
lvscan.c \
|
||||||
pvchange.c \
|
pvchange.c \
|
||||||
|
86
tools/lvdisplay.c
Normal file
86
tools/lvdisplay.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Sistina Software
|
||||||
|
*
|
||||||
|
* LVM is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* LVM is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LVM; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
int lvdisplay_single(char *lv_name);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lvdisplay_single(char *lv_name)
|
||||||
|
{
|
||||||
|
char *vg_name = NULL;
|
||||||
|
|
||||||
|
struct volume_group *vg;
|
||||||
|
struct list *lvh;
|
||||||
|
struct logical_volume *lv;
|
||||||
|
|
||||||
|
/* does VG exist? */
|
||||||
|
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);
|
||||||
|
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 {
|
||||||
|
lvdisplay_full(lv);
|
||||||
|
if (arg_count(verbose_ARG))
|
||||||
|
lvdisplay_extents(lv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
183
tools/lvreduce.c
Normal file
183
tools/lvreduce.c
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Sistina Software
|
||||||
|
*
|
||||||
|
* LVM is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* LVM is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with LVM; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
int lvreduce(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct volume_group *vg;
|
||||||
|
struct logical_volume *lv;
|
||||||
|
struct list *lvh;
|
||||||
|
int32_t extents = 0;
|
||||||
|
int32_t size = 0;
|
||||||
|
char *lv_name, *vg_name;
|
||||||
|
char *st;
|
||||||
|
|
||||||
|
if (arg_count(extents_ARG) + arg_count(size_ARG) != 1) {
|
||||||
|
log_error("Please specify either size or extents (not both)");
|
||||||
|
return EINVALID_CMD_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME signed use throughout halves the maximum... */
|
||||||
|
if (arg_count(extents_ARG))
|
||||||
|
extents = arg_int_value(extents_ARG, 0);
|
||||||
|
|
||||||
|
if (arg_count(size_ARG))
|
||||||
|
size = arg_int_value(size_ARG, 0);
|
||||||
|
|
||||||
|
if (!argc) {
|
||||||
|
log_error("Please provide the logical volume name");
|
||||||
|
return EINVALID_CMD_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_name = argv[0];
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
|
||||||
|
if (!(vg_name = extract_vgname(ios, lv_name))) {
|
||||||
|
log_error("Please provide a volume group name");
|
||||||
|
return EINVALID_CMD_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((st = strrchr(lv_name, '/')))
|
||||||
|
lv_name = st + 1;
|
||||||
|
|
||||||
|
/* does VG exist? */
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* does LV exist? */
|
||||||
|
if (!(lvh = find_lv_in_vg(vg, lv_name))) {
|
||||||
|
log_error("Logical volume %s not found in volume group %s",
|
||||||
|
lv_name, vg_name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv = &list_item(lvh, struct lv_list)->lv;
|
||||||
|
|
||||||
|
if (!(lv->status & ACTIVE)) {
|
||||||
|
log_error("Logical volume %s must be active before reduction",
|
||||||
|
lv_name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
/* No of 512-byte sectors */
|
||||||
|
extents = size * 2;
|
||||||
|
|
||||||
|
if (extents % vg->extent_size) {
|
||||||
|
char *s1;
|
||||||
|
|
||||||
|
extents += (signed) vg->extent_size -
|
||||||
|
(signed) (extents % vg->extent_size);
|
||||||
|
log_print("Rounding up size to full physical extent %s",
|
||||||
|
(s1 =
|
||||||
|
display_size(abs(extents) / 2, SIZE_SHORT)));
|
||||||
|
dbg_free(s1);
|
||||||
|
}
|
||||||
|
|
||||||
|
extents /= (signed) vg->extent_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extents) {
|
||||||
|
log_error("New size of 0 not permitted");
|
||||||
|
return EINVALID_CMD_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extents < 0) {
|
||||||
|
if (1 - extents > lv->le_count) {
|
||||||
|
log_error("Unable to reduce %s below 1 extent",
|
||||||
|
lv_name);
|
||||||
|
return EINVALID_CMD_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv->le_count += extents;
|
||||||
|
} else {
|
||||||
|
if (extents >= lv->le_count) {
|
||||||
|
log_error("New size given (%d extents) not less than "
|
||||||
|
"existing size (%d extents)", extents,
|
||||||
|
lv->le_count);
|
||||||
|
return EINVALID_CMD_LINE;
|
||||||
|
}
|
||||||
|
lv->le_count = extents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************ FIXME Stripes
|
||||||
|
size_rest = new_size % (vg->lv[l]->lv_stripes * vg->pe_size);
|
||||||
|
if (size_rest != 0) {
|
||||||
|
log_print
|
||||||
|
("rounding size %ld KB to stripe boundary size ",
|
||||||
|
new_size / 2);
|
||||||
|
new_size = new_size - size_rest;
|
||||||
|
printf("%ld KB\n", new_size / 2);
|
||||||
|
}
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
if (lv->status & ACTIVE || lv_active(lv) > 0) {
|
||||||
|
char *dummy;
|
||||||
|
log_print("WARNING: Reducing active%s logical volume to %s",
|
||||||
|
(lv_open_count(lv) > 0) ? " and open" : "",
|
||||||
|
(dummy =
|
||||||
|
display_size(lv->le_count * vg->extent_size / 2,
|
||||||
|
SIZE_SHORT)));
|
||||||
|
log_print("THIS MAY DESTROY YOUR DATA (filesystem etc.)");
|
||||||
|
dbg_free(dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arg_count(force_ARG)) {
|
||||||
|
if (yes_no_prompt
|
||||||
|
("Do you really want to reduce %s? [y/n]: ", lv_name)
|
||||||
|
== 'n') {
|
||||||
|
log_print("Logical volume %s NOT reduced", lv_name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********* FIXME Suspend lv ***********/
|
||||||
|
|
||||||
|
/* store vg on disk(s) */
|
||||||
|
if (!ios->vg_write(ios, vg))
|
||||||
|
return ECMD_FAILED;
|
||||||
|
|
||||||
|
/* FIXME Ensure it always displays errors? */
|
||||||
|
if (!lv_reactivate(lv))
|
||||||
|
return ECMD_FAILED;
|
||||||
|
|
||||||
|
/********* FIXME Resume *********/
|
||||||
|
|
||||||
|
/********* FIXME Backup
|
||||||
|
if ((ret = do_autobackup(vg_name, vg)))
|
||||||
|
return ret;
|
||||||
|
************/
|
||||||
|
|
||||||
|
log_print("Logical volume %s reduced", lv_name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -19,12 +19,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int e2fsadm(int argc, char **argv) {return 1;}
|
int e2fsadm(int argc, char **argv) {return 1;}
|
||||||
int lvdisplay(int argc, char **argv) {return 1;}
|
|
||||||
int lvextend(int argc, char **argv) {return 1;}
|
int lvextend(int argc, char **argv) {return 1;}
|
||||||
int lvmdiskscan(int argc, char **argv) {return 1;}
|
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 lvrename(int argc, char **argv) {return 1;}
|
int lvrename(int argc, char **argv) {return 1;}
|
||||||
int pvdata(int argc, char **argv) {return 1;}
|
int pvdata(int argc, char **argv) {return 1;}
|
||||||
int vgcfgbackup(int argc, char **argv) {return 1;}
|
int vgcfgbackup(int argc, char **argv) {return 1;}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user