1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-10 16:58:47 +03:00

pvmove support

This commit is contained in:
Alasdair Kergon 2003-04-30 15:26:25 +00:00
parent 7512e5a202
commit 10b29b8d2d
4 changed files with 120 additions and 14 deletions

View File

@ -46,6 +46,10 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
{
return 0;
}
int lv_mirror_percent(struct logical_volume *lv, float *percent, int wait)
{
return 0;
}
int lvs_in_vg_activated(struct volume_group *vg)
{
return 0;
@ -187,6 +191,29 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
return r;
}
/* FIXME Merge with snapshot_percent */
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr)
{
int r;
struct dev_manager *dm;
if (!activation())
return 0;
if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cf))) {
stack;
return 0;
}
if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
stack;
dev_manager_destroy(dm);
return r;
}
static int _lv_active(struct logical_volume *lv)
{
struct lvinfo info;

View File

@ -41,6 +41,8 @@ int lv_info(const struct logical_volume *lv, struct lvinfo *info);
* Returns 1 if percent has been set, else 0.
*/
int lv_snapshot_percent(struct logical_volume *lv, float *percent);
int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
uint32_t *event_nr);
/*
* Return number of LVs in the VG that are active.

View File

@ -88,12 +88,14 @@ struct dl_list {
};
static const char *stripe_filler = NULL;
static uint32_t mirror_region_size = 0;
struct dev_manager {
struct pool *mem;
struct config_tree *cf;
const char *stripe_filler;
uint32_t mirror_region_size;
char *vg_name;
@ -269,7 +271,8 @@ static char *_build_dlid(struct pool *mem, const char *lvid, const char *layer)
/*
* Low level device-layer operations.
*/
static struct dm_task *_setup_task(const char *name, const char *uuid, int task)
static struct dm_task *_setup_task(const char *name, const char *uuid,
uint32_t *event_nr, int task)
{
struct dm_task *dmt;
@ -284,6 +287,9 @@ static struct dm_task *_setup_task(const char *name, const char *uuid, int task)
if (uuid && *uuid)
dm_task_set_uuid(dmt, uuid);
if (event_nr)
dm_task_set_event_nr(dmt, *event_nr);
return dmt;
}
@ -294,7 +300,7 @@ static int _info_run(const char *name, const char *uuid, struct dm_info *info,
struct dm_task *dmt;
const char *u;
if (!(dmt = _setup_task(name, uuid, DM_DEVICE_INFO))) {
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_INFO))) {
stack;
return 0;
}
@ -348,7 +354,7 @@ static int _status_run(const char *name, const char *uuid,
char *type = NULL;
char *params = NULL;
if (!(dmt = _setup_task(name, uuid, DM_DEVICE_STATUS))) {
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_STATUS))) {
stack;
return 0;
}
@ -405,10 +411,12 @@ static int _status(const char *name, const char *uuid,
}
static int _percent_run(const char *name, const char *uuid,
const char *target_type, float *percent)
const char *target_type, int wait, float *percent,
uint32_t *event_nr)
{
int r = 0;
struct dm_task *dmt;
struct dm_info info;
void *next = NULL;
uint64_t start, length;
char *type = NULL;
@ -420,7 +428,9 @@ static int _percent_run(const char *name, const char *uuid,
*percent = -1;
if (!(dmt = _setup_task(name, uuid, DM_DEVICE_STATUS))) {
if (!(dmt = _setup_task(name, uuid, event_nr,
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS)))
{
stack;
return 0;
}
@ -430,6 +440,14 @@ static int _percent_run(const char *name, const char *uuid,
goto out;
}
if (!dm_task_get_info(dmt, &info) || !info.exists) {
stack;
goto out;
}
if (event_nr)
*event_nr = info.event_nr;
do {
next = dm_get_next_target(dmt, next, &start, &length, &type,
&params);
@ -437,6 +455,15 @@ static int _percent_run(const char *name, const char *uuid,
if (!type || !params || strcmp(type, target_type))
continue;
/* Mirror? */
if (!strcmp(type, "mirror") &&
sscanf(params, "%*d %*d:%*d %*d:%*d %" PRIu64 "/%" PRIu64,
&numerator, &denominator) == 2) {
total_numerator += numerator;
total_denominator += denominator;
continue;
}
if (strcmp(type, "snapshot"))
continue;
@ -455,7 +482,9 @@ static int _percent_run(const char *name, const char *uuid,
} while (next);
if (total_denominator)
*percent = (float) total_numerator *100 / total_denominator;
*percent = (float) total_numerator * 100 / total_denominator;
else
*percent = 100;
r = 1;
@ -465,12 +494,14 @@ static int _percent_run(const char *name, const char *uuid,
}
static int _percent(const char *name, const char *uuid, const char *target_type,
float *percent)
int wait, float *percent, uint32_t *event_nr)
{
if (uuid && *uuid && _percent_run(NULL, uuid, target_type, percent))
if (uuid && *uuid
&& _percent_run(NULL, uuid, target_type, wait, percent, event_nr))
return 1;
if (name && _percent_run(name, NULL, target_type, percent))
if (name && _percent_run(name, NULL, target_type, wait, percent,
event_nr))
return 1;
return 0;
@ -483,7 +514,7 @@ static int _rename(struct dev_layer *dl, char *newname)
log_verbose("Renaming %s to %s", dl->name, newname);
if (!(dmt = _setup_task(dl->name, NULL, DM_DEVICE_RENAME))) {
if (!(dmt = _setup_task(dl->name, NULL, 0, DM_DEVICE_RENAME))) {
stack;
return 0;
}
@ -514,7 +545,7 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
log_verbose("Loading %s", dl->name);
if (!(dmt = _setup_task(task == DM_DEVICE_CREATE ? dl->name : NULL,
dl->dlid, task))) {
dl->dlid, 0, task))) {
stack;
return 0;
}
@ -591,7 +622,7 @@ static int _remove(struct dev_layer *dl)
else
log_very_verbose("Removing %s", dl->name);
if (!(dmt = _setup_task(dl->name, NULL, DM_DEVICE_REMOVE))) {
if (!(dmt = _setup_task(dl->name, NULL, 0, DM_DEVICE_REMOVE))) {
stack;
return 0;
}
@ -622,7 +653,7 @@ static int _suspend_or_resume(const char *name, action_t suspend)
int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME;
log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name);
if (!(dmt = _setup_task(name, NULL, task))) {
if (!(dmt = _setup_task(name, NULL, 0, task))) {
stack;
return 0;
}
@ -690,6 +721,8 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
/* Target formats:
* linear [device offset]+
* striped #stripes stripe_size [device offset]+
* mirror #logs [log_type #log_params [log_params]*]+
* #mirrors [device offset log_number]+
*/
case SEG_STRIPED:
if (areas == 1)
@ -707,6 +740,12 @@ static int _emit_target(struct dev_manager *dm, struct dm_task *dmt,
}
break;
case SEG_MIRRORED:
target = "mirror";
if ((tw = lvm_snprintf(params, sizeof(params),
"core 1 %u %u ",
dm->mirror_region_size, areas)) < 0)
goto error;
w = tw;
break;
}
@ -869,6 +908,14 @@ struct dev_manager *dev_manager_create(const char *vg_name,
}
dm->stripe_filler = stripe_filler;
if (!mirror_region_size) {
mirror_region_size = 2 * find_config_int(cf->root,
"activation/mirror_region_size",
'/',
DEFAULT_MIRROR_REGION_SIZE);
}
dm->mirror_region_size = mirror_region_size;
if (!(dm->vg_name = pool_strdup(dm->mem, vg_name))) {
stack;
goto bad;
@ -939,7 +986,7 @@ int dev_manager_snapshot_percent(struct dev_manager *dm,
* Try and get some info on this device.
*/
log_debug("Getting device status percentage for %s", name);
if (!(_percent(name, lv->lvid.s, "snapshot", percent))) {
if (!(_percent(name, lv->lvid.s, "snapshot", 0, percent, NULL))) {
stack;
return 0;
}
@ -950,6 +997,33 @@ int dev_manager_snapshot_percent(struct dev_manager *dm,
return 1;
}
/* FIXME Merge with snapshot_percent, auto-detecting target type */
/* FIXME Cope with more than one target */
int dev_manager_mirror_percent(struct dev_manager *dm,
struct logical_volume *lv, int wait,
float *percent, uint32_t *event_nr)
{
char *name;
/*
* Build a name for the top layer.
*/
if (!(name = _build_name(dm->mem, lv->vg->name, lv->name, NULL))) {
stack;
return 0;
}
/* FIXME pool_free ? */
log_debug("Getting device mirror status percentage for %s", name);
if (!(_percent(name, lv->lvid.s, "mirror", wait, percent, event_nr))) {
stack;
return 0;
}
return 1;
}
static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
const char *dlid)
{

View File

@ -30,6 +30,9 @@ int dev_manager_info(struct dev_manager *dm, const struct logical_volume *lv,
struct dm_info *info);
int dev_manager_snapshot_percent(struct dev_manager *dm,
struct logical_volume *lv, float *percent);
int dev_manager_mirror_percent(struct dev_manager *dm,
struct logical_volume *lv, int wait,
float *percent, uint32_t *event_nr);
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);