1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

o read-only device support

o name/uuid disambiguation
This commit is contained in:
Alasdair Kergon 2002-03-25 18:54:59 +00:00
parent c1b5fc6673
commit e04c519896

View File

@ -56,7 +56,8 @@
enum { enum {
ACTIVE = 0, ACTIVE = 0,
DIRTY = 1, DIRTY = 1,
VISIBLE = 2 VISIBLE = 2,
READWRITE = 3
}; };
typedef enum { typedef enum {
@ -252,7 +253,7 @@ static char *_build_dlid(struct pool *mem, const char *lvid, const char *layer)
/* /*
* Low level device-layer operations. * Low level device-layer operations.
*/ */
static struct dm_task *_setup_task(const char *name, int task) static struct dm_task *_setup_task(const char *name, const char *uuid, int task)
{ {
struct dm_task *dmt; struct dm_task *dmt;
@ -261,26 +262,27 @@ static struct dm_task *_setup_task(const char *name, int task)
return NULL; return NULL;
} }
dm_task_set_name(dmt, name); if (name)
dm_task_set_name(dmt, name);
if (uuid && *uuid)
dm_task_set_uuid(dmt, uuid);
return dmt; return dmt;
} }
static int _info(const char *name, const char *uuid, struct dm_info *info, static int _info_run(const char *name, const char *uuid, struct dm_info *info,
struct pool *mem, char **uuid_out) struct pool *mem, char **uuid_out)
{ {
int r = 0; int r = 0;
struct dm_task *dmt; struct dm_task *dmt;
const char *u; const char *u;
log_debug("Getting device info for %s", name); if (!(dmt = _setup_task(name, uuid, DM_DEVICE_INFO))) {
if (!(dmt = _setup_task(name, DM_DEVICE_INFO))) {
stack; stack;
return 0; return 0;
} }
if (uuid)
dm_task_set_uuid(dmt, uuid);
if (!dm_task_run(dmt)) { if (!dm_task_run(dmt)) {
stack; stack;
goto out; goto out;
@ -305,6 +307,19 @@ static int _info(const char *name, const char *uuid, struct dm_info *info,
return r; return r;
} }
static int _info(const char *name, const char *uuid, struct dm_info *info,
struct pool *mem, char **uuid_out)
{
if (uuid && *uuid && _info_run(NULL, uuid, info, mem, uuid_out)
&& info->exists)
return 1;
if (name)
return _info_run(name, NULL, info, mem, uuid_out);
return 0;
}
static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname) static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname)
{ {
int r = 1; int r = 1;
@ -312,7 +327,7 @@ static int _rename(struct dev_manager *dm, struct dev_layer *dl, char *newname)
log_verbose("Renaming %s to %s", dl->name, newname); log_verbose("Renaming %s to %s", dl->name, newname);
if (!(dmt = _setup_task(dl->name, DM_DEVICE_RENAME))) { if (!(dmt = _setup_task(dl->name, NULL, DM_DEVICE_RENAME))) {
stack; stack;
return 0; return 0;
} }
@ -342,7 +357,8 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
struct dm_task *dmt; struct dm_task *dmt;
log_verbose("Loading %s", dl->name); log_verbose("Loading %s", dl->name);
if (!(dmt = _setup_task(dl->name, task))) { if (!(dmt = _setup_task(task == DM_DEVICE_CREATE ? dl->name : NULL,
dl->dlid, task))) {
stack; stack;
return 0; return 0;
} }
@ -356,7 +372,14 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
goto out; goto out;
} }
dm_task_set_uuid(dmt, dl->dlid); if (!_get_flag(dl, READWRITE)) {
if (!dm_task_set_ro(dmt)) {
log_error("Failed to set %s read-only during "
"activation.", dl->name);
goto out;
} else
log_very_verbose("Activating %s read-only", dl->name);
}
if (!(r = dm_task_run(dmt))) if (!(r = dm_task_run(dmt)))
log_error("Couldn't load device '%s'.", dl->name); log_error("Couldn't load device '%s'.", dl->name);
@ -387,7 +410,7 @@ static int _remove(struct dev_layer *dl)
else else
log_very_verbose("Removing %s", dl->name); log_very_verbose("Removing %s", dl->name);
if (!(dmt = _setup_task(dl->name, DM_DEVICE_REMOVE))) { if (!(dmt = _setup_task(dl->name, NULL, DM_DEVICE_REMOVE))) {
stack; stack;
return 0; return 0;
} }
@ -418,7 +441,7 @@ static int _suspend_or_resume(const char *name, suspend_t suspend)
int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME; int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME;
log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name); log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name);
if (!(dmt = _setup_task(name, task))) { if (!(dmt = _setup_task(name, NULL, task))) {
stack; stack;
return 0; return 0;
} }
@ -673,8 +696,8 @@ int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
char *name; char *name;
/* /*
* Build a name for the top layer. * Build a name for the top layer.
*/ */
if (!(name = _build_name(dm->mem, lv->vg->name, lv->name, NULL))) { if (!(name = _build_name(dm->mem, lv->vg->name, lv->name, NULL))) {
stack; stack;
return 0; return 0;
@ -683,6 +706,7 @@ int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
/* /*
* Try and get some info on this device. * Try and get some info on this device.
*/ */
log_debug("Getting device info for %s", name);
if (!_info(name, lv->lvid.s, info, NULL, NULL)) { if (!_info(name, lv->lvid.s, info, NULL, NULL)) {
stack; stack;
return 0; return 0;
@ -725,6 +749,7 @@ static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
dl->name = name; dl->name = name;
log_debug("Getting device info for %s", dl->name);
if (!_info(dl->name, dlid, &dl->info, dm->mem, &uuid)) { if (!_info(dl->name, dlid, &dl->info, dm->mem, &uuid)) {
stack; stack;
return NULL; return NULL;
@ -746,6 +771,12 @@ static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
return dl; return dl;
} }
static inline int _read_only_lv(struct logical_volume *lv)
{
return (!(lv->vg->status & LVM_WRITE) ||
!(lv->status & LVM_WRITE));
}
static struct dev_layer *_create_layer(struct dev_manager *dm, static struct dev_layer *_create_layer(struct dev_manager *dm,
const char *layer, const char *layer,
struct logical_volume *lv) struct logical_volume *lv)
@ -771,6 +802,9 @@ static struct dev_layer *_create_layer(struct dev_manager *dm,
dl->lv = lv; dl->lv = lv;
if (!_read_only_lv(lv))
_set_flag(dl, READWRITE);
return dl; return dl;
} }
@ -1046,7 +1080,6 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl)
struct list *sh; struct list *sh;
struct dev_layer *dep; struct dev_layer *dep;
char *dlid, *newname, *suffix; char *dlid, *newname, *suffix;
int suspended = 0;
list_iterate(sh, &dl->pre_create) { list_iterate(sh, &dl->pre_create) {
dlid = list_item(sh, struct str_list)->str; dlid = list_item(sh, struct str_list)->str;
@ -1056,11 +1089,10 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl)
return 0; return 0;
} }
if (dl->info.exists && !suspended && !_suspend(dl)) { if (dl->info.exists && !_suspend(dl)) {
stack; stack;
return 0; return 0;
} }
suspended = 1;
if (!strcmp(dep->dlid, dl->dlid)) { if (!strcmp(dep->dlid, dl->dlid)) {
log_error("BUG: pre-create loop detected (%s)", dlid); log_error("BUG: pre-create loop detected (%s)", dlid);
@ -1096,10 +1128,6 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl)
return 1; return 1;
} }
/* We didn't suspend it - nothing to do */
if (!suspended)
return 1;
/* Reload */ /* Reload */
if (_get_flag(dl, DIRTY) && !_load(dm, dl, DM_DEVICE_RELOAD)) { if (_get_flag(dl, DIRTY) && !_load(dm, dl, DM_DEVICE_RELOAD)) {
stack; stack;