mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
o Actually read snapshot percentage from the kernel - what a pain! :)
o Not sure if the code in dev_manager is really optimal, but it works.. will look at adjusting it a bit now. o I *think* it works right when one snapshot if full but others aren't, but I haven't really been able to test it because the full snapshot somehow resets itself and weird things start happening to the system...
This commit is contained in:
parent
64ad493eac
commit
1951dba955
@ -75,6 +75,27 @@ int lv_info(struct logical_volume *lv, struct dm_info *info)
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if percent set, else 0 on failure.
|
||||
*/
|
||||
int lv_snapshot_percentage(struct logical_volume *lv, float *percent)
|
||||
{
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(r = dev_manager_get_snapshot_use(dm, lv, percent)))
|
||||
stack;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _lv_active(struct logical_volume *lv)
|
||||
{
|
||||
struct dm_info info;
|
||||
|
@ -16,6 +16,10 @@ int library_version(char *version, size_t size);
|
||||
* Returns 1 if info structure has been populated, else 0.
|
||||
*/
|
||||
int lv_info(struct logical_volume *lv, struct dm_info *info);
|
||||
/*
|
||||
* Returns 1 if percent has been set, else 0.
|
||||
*/
|
||||
int lv_snapshot_percentage(struct logical_volume *lv, float *percent);
|
||||
|
||||
/*
|
||||
* These should eventually use config file
|
||||
|
@ -329,6 +329,60 @@ static int _info(const char *name, const char *uuid, struct dm_info *info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _status_run(const char *name, const char *uuid, char **status,
|
||||
int *size)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
void *next = NULL;
|
||||
unsigned long long start, length;
|
||||
char *type = NULL;
|
||||
char *params;
|
||||
|
||||
if (!(dmt = _setup_task(name, uuid, DM_DEVICE_STATUS))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dm_task_run(dmt)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
|
||||
do {
|
||||
next = dm_get_next_target(dmt, next, &start, &length,
|
||||
&type, ¶ms);
|
||||
if(type) {
|
||||
snprintf(*status, *size, "%lld %lld %s %s\n",
|
||||
start, length, type, params);
|
||||
}
|
||||
|
||||
} while (next);
|
||||
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int _status(const char *name, const char *uuid, char **status,
|
||||
uint32_t *size)
|
||||
{
|
||||
if (uuid && *uuid && _status_run(NULL, uuid, status, size)
|
||||
&& *status) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (name && _status_run(name, NULL, status, size)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname)
|
||||
{
|
||||
int r = 1;
|
||||
@ -729,6 +783,50 @@ int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dev_manager_get_snapshot_use(struct dev_manager *dm,
|
||||
struct logical_volume *lv, float *percent)
|
||||
{
|
||||
char *name, *status, *tmpstr;
|
||||
uint32_t size = 127;
|
||||
|
||||
if(!(status = pool_alloc(dm->mem, sizeof(*status) * size+1))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a name for the top layer.
|
||||
*/
|
||||
if(!(name = _build_name(dm->mem, lv->vg->name, lv->name, NULL))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try and get some info on this device.
|
||||
*/
|
||||
log_debug("Getting device status for %s", name);
|
||||
if(!_status(name, lv->lvid.s, &status, &size)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the snapshot isn't available, percent will be -1 */
|
||||
*percent = -1;
|
||||
|
||||
/* FIXME: is there a simpler way to do this? */
|
||||
tmpstr = strstr(status, "snapshot");
|
||||
if(!tmpstr)
|
||||
return 0;
|
||||
|
||||
tmpstr = strstr(tmpstr, " ");
|
||||
if(!tmpstr)
|
||||
return 0;
|
||||
|
||||
return sscanf(tmpstr, "%f", percent);
|
||||
|
||||
}
|
||||
|
||||
static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
|
||||
char *dlid)
|
||||
{
|
||||
|
@ -27,6 +27,8 @@ void dev_manager_destroy(struct dev_manager *dm);
|
||||
*/
|
||||
int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
|
||||
struct dm_info *info);
|
||||
int dev_manager_get_snapshot_use(struct dev_manager *dm,
|
||||
struct logical_volume *lv, float *percent);
|
||||
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
|
||||
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
|
||||
|
@ -224,6 +224,8 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
struct stripe_segment *seg;
|
||||
struct list *lvseg;
|
||||
struct logical_volume *origin;
|
||||
float snap_percent;
|
||||
int snap_active;
|
||||
|
||||
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
|
||||
stack;
|
||||
@ -254,71 +256,34 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
log_print("LV snapshot status source of");
|
||||
list_iterate(slh, snaplist) {
|
||||
snap = list_item(slh, struct snapshot_list)->snapshot;
|
||||
snap_active = lv_snapshot_percentage(snap->cow,
|
||||
&snap_percent);
|
||||
log_print(" %s%s/%s [%s]",
|
||||
lv->vg->cmd->dev_dir, lv->vg->name,
|
||||
snap->cow->name, "active");
|
||||
snap->cow->name,
|
||||
(snap_active > 0) ? "active" : "INACTIVE");
|
||||
}
|
||||
/* reset so we don't try to use this to display other snapshot
|
||||
* related information. */
|
||||
snap = NULL;
|
||||
snap_active = 0;
|
||||
}
|
||||
/* Check to see if this LV is a COW target for a snapshot */
|
||||
else if ((snap = find_cow(lv)))
|
||||
else if ((snap = find_cow(lv))) {
|
||||
snap_active = lv_snapshot_percentage(lv, &snap_percent);
|
||||
log_print("LV snapshot status %s destination for %s%s/%s",
|
||||
"active", lv->vg->cmd->dev_dir, lv->vg->name,
|
||||
(snap_active > 0) ? "active" : "INACTIVE",
|
||||
lv->vg->cmd->dev_dir, lv->vg->name,
|
||||
snap->origin->name);
|
||||
|
||||
|
||||
/******* 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");
|
||||
}
|
||||
}
|
||||
***********/
|
||||
|
||||
|
||||
if (inkernel && info.suspended)
|
||||
log_print("LV Status suspended");
|
||||
else
|
||||
log_print("LV Status %savailable",
|
||||
inkernel ? "" : "NOT ");
|
||||
!inkernel || (snap && (snap_active < 1))
|
||||
? "NOT " : "");
|
||||
|
||||
/********* FIXME lv_number - not sure that we're going to bother with this
|
||||
log_print("LV # %u", lv->lv_number + 1);
|
||||
@ -364,57 +329,32 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
seg = list_item(lvseg, struct stripe_segment);
|
||||
if(seg->stripes > 1) {
|
||||
log_print("Stripes %u", seg->stripes);
|
||||
log_print("Stripe size (KByte) %u", seg->stripe_size/2);
|
||||
log_print("Stripe size (KByte) %u",
|
||||
seg->stripe_size/2);
|
||||
}
|
||||
/* only want the first segment for LVM1 format output */
|
||||
break;
|
||||
}
|
||||
|
||||
if(snap) {
|
||||
/*char *s1, *s2;*/
|
||||
float fused, fsize;
|
||||
if(snap_percent == -1)
|
||||
snap_percent=100;
|
||||
|
||||
size = display_size(snap->chunk_size / 2, SIZE_SHORT);
|
||||
log_print("snapshot chunk size %s", size);
|
||||
dbg_free(size);
|
||||
size = display_size(lv->size / 2, SIZE_SHORT);
|
||||
/* s1 = display_size();*/
|
||||
log_print("Allocated to snapshot %s [%s/%s]", "NA", "NA", size);
|
||||
dbg_free(size);
|
||||
/* size = display_size(snap->cow->size / 2, SIZE_SHORT); */
|
||||
log_print("Allocated to COW-table %s", "NA");
|
||||
/* dbg_free(size); */
|
||||
}
|
||||
|
||||
/********** 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);
|
||||
size = display_size(lv->size / 2, SIZE_SHORT);
|
||||
sscanf(size, "%f", &fsize);
|
||||
fused = fsize * ( snap_percent / 100 );
|
||||
log_print("Allocated to snapshot %2.2f%% [%2.2f/%s]",
|
||||
snap_percent, fused, size);
|
||||
dbg_free(size);
|
||||
|
||||
/* FIXME: Think this'll make them wonder?? */
|
||||
log_print("Allocated to COW-table %s", "00.01 KB");
|
||||
}
|
||||
}
|
||||
******************/
|
||||
|
||||
/** Not in LVM1 format output **
|
||||
log_print("Segments %u", list_size(&lv->segments));
|
||||
|
Loading…
Reference in New Issue
Block a user