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

Cut the number of device-mapper calls.

This commit is contained in:
Alasdair Kergon 2002-03-15 22:59:12 +00:00
parent a6bf4bcfa2
commit a69de4919b

View File

@ -59,6 +59,16 @@ enum {
VISIBLE = 2
};
typedef enum {
ACTIVATE,
DEACTIVATE
} activate_t;
typedef enum {
SUSPEND,
RESUME
} suspend_t;
struct dev_layer {
char *name;
@ -276,6 +286,8 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
if (_get_flag(dl, VISIBLE))
fs_add_lv(dl->lv, dl->name);
_clear_flag(dl, DIRTY);
return r;
}
@ -284,29 +296,39 @@ static int _remove(struct dev_layer *dl)
int r;
struct dm_task *dmt;
log_verbose("Removing %s", dl->name);
if (_get_flag(dl, VISIBLE))
log_verbose("Removing %s", dl->name);
else
log_very_verbose("Removing %s", dl->name);
if (!(dmt = _setup_task(dl->name, DM_DEVICE_REMOVE))) {
stack;
return 0;
}
if (!(r = dm_task_run(dmt)))
log_error("Couldn't remove device '%s'", dl->name);
else
/* Suppress error message if it's still in use - we'll log it later */
log_suppress(1);
if ((r = dm_task_run(dmt)))
dl->info.exists = 0;
log_suppress(0);
dm_task_destroy(dmt);
if (_get_flag(dl, VISIBLE))
fs_del_lv(dl->lv);
_clear_flag(dl, ACTIVE);
return r;
}
static int _suspend_or_resume(const char *name, int sus)
static int _suspend_or_resume(const char *name, suspend_t suspend)
{
int r;
struct dm_task *dmt;
int sus = (suspend == SUSPEND) ? 1 : 0;
int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME;
log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name);
@ -328,7 +350,7 @@ static int _suspend(struct dev_layer *dl)
if (dl->info.suspended)
return 1;
if (!_suspend_or_resume(dl->name, 1)) {
if (!_suspend_or_resume(dl->name, SUSPEND)) {
stack;
return 0;
}
@ -342,7 +364,7 @@ static int _resume(struct dev_layer *dl)
if (!dl->info.suspended)
return 1;
if (!_suspend_or_resume(dl->name, 0)) {
if (!_suspend_or_resume(dl->name, RESUME)) {
stack;
return 0;
}
@ -595,7 +617,7 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
return 0;
}
if (!_suspend_or_resume(name, 1)) {
if (!_suspend_or_resume(name, SUSPEND)) {
stack;
return 0;
}
@ -926,11 +948,7 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl)
struct list *sh;
struct dev_layer *dep;
char *name;
if (dl->info.exists && !_suspend(dl)) {
stack;
return 0;
}
int suspended = 0;
list_iterate(sh, &dl->pre_create) {
name = list_item(sh, struct str_list)->str;
@ -940,30 +958,40 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl)
return 0;
}
if (dl->info.exists && !suspended && !_suspend(dl)) {
stack;
return 0;
}
suspended = 1;
if (!_create_rec(dm, dep)) {
stack;
return 0;
}
}
if (dl->info.exists) {
/* reload */
if (!_load(dm, dl, DM_DEVICE_RELOAD)) {
stack;
return 0;
}
if (!_resume(dl)) {
stack;
return 0;
}
} else {
/* create */
/* Create? */
if (!dl->info.exists) {
if (!_load(dm, dl, DM_DEVICE_CREATE)) {
stack;
return 0;
}
return 1;
}
/* We didn't suspend it - nothing to do */
if (!suspended)
return 1;
/* Reload */
if (_get_flag(dl, DIRTY) && !_load(dm, dl, DM_DEVICE_RELOAD)) {
stack;
return 0;
}
if (!_resume(dl)) {
stack;
return 0;
}
return 1;
@ -1018,35 +1046,20 @@ static int _fill_in_remove_list(struct dev_manager *dm)
int _remove_old_layers(struct dev_manager *dm)
{
int change;
struct list *rh, *n;
struct dev_layer *dl;
/*
* FIXME: quick hack. We just loop round removing
* unopened devices, until we run out of things to close.
*/
do {
struct list *rh, *n;
struct dev_layer *dl;
change = 0;
list_iterate_safe(rh, n, &dm->remove_list) {
dl = list_item(rh, struct dl_list)->dl;
if (!_info(dl->name, &dl->info)) {
stack;
return 0;
}
if (!dl->info.exists) {
list_del(rh);
continue;
}
if (!dl->info.open_count) {
if (!_remove(dl)) {
stack;
continue;
}
if (_remove(dl)) {
change = 1;
list_del(rh);
}
@ -1055,7 +1068,10 @@ int _remove_old_layers(struct dev_manager *dm)
} while (change);
if (!list_empty(&dm->remove_list)) {
log_error("Couldn't remove all redundant layers.");
list_iterate(rh, &dm->remove_list) {
dl = list_item(rh, struct dl_list)->dl;
log_error("Couldn't deactivate device %s", dl->name);
}
return 0;
}
@ -1155,29 +1171,19 @@ static int _scan_existing_devices(struct dev_manager *dm)
{
const char *dev_dir = dm_dir();
int i, count, r = 1;
struct dirent **dirent;
int r = 1;
const char *name;
struct dirent *dirent;
DIR *d;
count = scandir(dev_dir, &dirent, NULL, alphasort);
if (!count)
return 1;
if (count < 0) {
log_error("Couldn't scan device-mapper directory '%s'.",
dev_dir);
if (!(d = opendir(dev_dir))) {
log_sys_error("opendir", dev_dir);
return 0;
}
/*
* Scan the devices.
*/
for (i = 0; i < count; i++) {
name = dirent[i]->d_name;
while ((dirent = readdir(d))) {
name = dirent->d_name;
/*
* Ignore dot files.
*/
if (name[0] == '.')
continue;
@ -1192,12 +1198,8 @@ static int _scan_existing_devices(struct dev_manager *dm)
}
}
/*
* Free the directory entries.
*/
for (i = 0; i < count; i++)
free(dirent[i]);
free(dirent);
if (closedir(d))
log_sys_error("closedir", dev_dir);
return r;
}
@ -1252,7 +1254,7 @@ static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
pool_free(dm->mem, name);
if (found) {
log_debug("Active lv '%s' found.", lv->name);
log_debug("Found active lv %s", lv->name);
if (!_add_lv(dm->mem, &dm->active_list, lv)) {
stack;
@ -1264,11 +1266,8 @@ static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
return 1;
}
/*
* FIXME: There's a lot of common code between activate and
* deactivate.
*/
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
static int _activate(struct dev_manager *dm, struct logical_volume *lv,
activate_t activate)
{
if (!_scan_existing_devices(dm)) {
stack;
@ -1280,14 +1279,16 @@ int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
return 0;
}
/*
* Remove it so we don't add it twice.
*/
/* Remove from active list if present */
_remove_lv(&dm->active_list, lv);
if (!_add_lv(dm->mem, &dm->dirty_list, lv) ||
!_add_lv(dm->mem, &dm->active_list, lv)) {
stack;
return 0;
if (activate == ACTIVATE) {
/* Add to active and dirty lists */
if (!_add_lv(dm->mem, &dm->dirty_list, lv) ||
!_add_lv(dm->mem, &dm->active_list, lv)) {
stack;
return 0;
}
}
if (!_execute(dm, lv->vg)) {
@ -1298,24 +1299,13 @@ int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
return 1;
}
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
{
return _activate(dm, lv, ACTIVATE);
}
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv)
{
if (!_scan_existing_devices(dm)) {
stack;
return 0;
}
if (!_fill_in_active_list(dm, lv->vg)) {
stack;
return 0;
}
_remove_lv(&dm->active_list, lv);
if (!_execute(dm, lv->vg)) {
stack;
return 0;
}
return 0;
return _activate(dm, lv, DEACTIVATE);
}