mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
o First cut at dev scanning.
o Split up _expand_lv
This commit is contained in:
parent
0fe3a2c512
commit
11d2da4036
@ -13,6 +13,7 @@
|
||||
|
||||
#include <libdevmapper.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
* activate(dirty lvs)
|
||||
@ -44,7 +45,8 @@
|
||||
* deactivate(dirty lvs)
|
||||
* ---------------------
|
||||
*
|
||||
* 1) Examine dm directory, create active_list *excluding* dirty_list
|
||||
* 1) Examine dm directory, create active_list *excluding*
|
||||
dirty_list. All vg layers go into tree.
|
||||
*
|
||||
* 2) Build vg tree given active_list, no dirty layers.
|
||||
*
|
||||
@ -551,8 +553,9 @@ int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct dev_layer *
|
||||
_create_layer(struct pool *mem, const char *layer, struct logical_volume *lv)
|
||||
static struct dev_layer *_create_dev(struct pool *mem,
|
||||
char *name,
|
||||
struct logical_volume *lv)
|
||||
{
|
||||
struct dev_layer *dl;
|
||||
|
||||
@ -561,10 +564,7 @@ _create_layer(struct pool *mem, const char *layer, struct logical_volume *lv)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(dl->name = _build_name(mem, lv->vg->name, lv->name, layer))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
dl->name = name;
|
||||
|
||||
if (!_info(dl->name, &dl->info)) {
|
||||
stack;
|
||||
@ -578,6 +578,20 @@ _create_layer(struct pool *mem, const char *layer, struct logical_volume *lv)
|
||||
return dl;
|
||||
}
|
||||
|
||||
static struct dev_layer *_create_layer(struct pool *mem,
|
||||
const char *layer,
|
||||
struct logical_volume *lv)
|
||||
{
|
||||
char *name;
|
||||
|
||||
if (!(name = _build_name(mem, lv->vg->name, lv->name, layer))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _create_dev(mem, name, lv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds the specified layer.
|
||||
*/
|
||||
@ -598,6 +612,146 @@ static struct dev_layer *_lookup(struct dev_manager *dm,
|
||||
}
|
||||
|
||||
|
||||
static int _expand_vanilla(struct dev_manager *dm, struct logical_volume *lv)
|
||||
{
|
||||
/*
|
||||
* only one layer.
|
||||
*/
|
||||
struct dev_layer *dl;
|
||||
if (!(dl = _create_layer(dm->mem, NULL, lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_vanilla;
|
||||
_set_flag(dl, VISIBLE);
|
||||
|
||||
if (!hash_insert(dm->layers, dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _expand_origin(struct dev_manager *dm, struct logical_volume *lv)
|
||||
{
|
||||
/*
|
||||
* origin(org)
|
||||
* org
|
||||
*/
|
||||
struct dev_layer *dl;
|
||||
char *real_name;
|
||||
struct str_list *sl;
|
||||
|
||||
if (!(dl = _create_layer(dm->mem, "real", lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_vanilla;
|
||||
_clear_flag(dl, VISIBLE);
|
||||
|
||||
if (!hash_insert(dm->layers, dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
real_name = dl->name;
|
||||
|
||||
if (!(dl = _create_layer(dm->mem, NULL, lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_origin;
|
||||
_set_flag(dl, VISIBLE);
|
||||
|
||||
/* add the dependency on the real device */
|
||||
if (!(sl = pool_alloc(dm->mem, sizeof(*sl)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(sl->str = pool_strdup(dm->mem, real_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_add(&dl->pre_create, &sl->list);
|
||||
|
||||
if (!hash_insert(dm->layers,dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _expand_snapshot(struct dev_manager *dm, struct logical_volume *lv,
|
||||
struct snapshot *s)
|
||||
{
|
||||
/*
|
||||
* snapshot(org, cow)
|
||||
* cow
|
||||
*/
|
||||
struct dev_layer *dl;
|
||||
char *cow_name;
|
||||
struct str_list *sl;
|
||||
|
||||
if (!(dl = _create_layer(dm->mem, "cow", lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_vanilla;
|
||||
_clear_flag(dl, VISIBLE);
|
||||
|
||||
/* insert the cow layer */
|
||||
if (!hash_insert(dm->layers, dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
cow_name = dl->name;
|
||||
|
||||
if (!(dl = _create_layer(dm->mem, NULL, lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_snapshot;
|
||||
_set_flag(dl, VISIBLE);
|
||||
|
||||
/* add the dependency on the real device */
|
||||
if (!(sl = pool_alloc(dm->mem, sizeof(*sl)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(sl->str = pool_strdup(dm->mem, cow_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_add(&dl->pre_create, &sl->list);
|
||||
|
||||
/* add the dependency on the org device */
|
||||
if (!(sl = pool_alloc(dm->mem, sizeof(*sl)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(sl->str = _build_name(dm->mem, dm->vg_name,
|
||||
s->origin->name, "real"))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_add(&dl->pre_create, &sl->list);
|
||||
|
||||
/* insert the snapshot layer */
|
||||
if (!hash_insert(dm->layers,dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts the appropriate dev_layers for a logical volume.
|
||||
*/
|
||||
@ -609,135 +763,13 @@ static int _expand_lv(struct dev_manager *dm, struct logical_volume *lv)
|
||||
* FIXME: this doesn't cope with recursive snapshots yet.
|
||||
* FIXME: split this function up.
|
||||
*/
|
||||
if ((s = find_cow(lv))) {
|
||||
/*
|
||||
* snapshot(org, cow)
|
||||
* cow
|
||||
*/
|
||||
struct dev_layer *dl;
|
||||
char *cow_name;
|
||||
struct str_list *sl;
|
||||
if ((s = find_cow(lv)))
|
||||
return _expand_snapshot(dm, lv, s);
|
||||
|
||||
if (!(dl = _create_layer(dm->mem, "cow", lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_vanilla;
|
||||
_clear_flag(dl, VISIBLE);
|
||||
else if (lv_is_origin(lv))
|
||||
return _expand_origin(dm, lv);
|
||||
|
||||
/* insert the cow layer */
|
||||
if (!hash_insert(dm->layers, dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
cow_name = dl->name;
|
||||
|
||||
if (!(dl = _create_layer(dm->mem, NULL, lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_snapshot;
|
||||
_set_flag(dl, VISIBLE);
|
||||
|
||||
/* add the dependency on the real device */
|
||||
if (!(sl = pool_alloc(dm->mem, sizeof(*sl)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(sl->str = pool_strdup(dm->mem, cow_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_add(&dl->pre_create, &sl->list);
|
||||
|
||||
/* add the dependency on the org device */
|
||||
if (!(sl = pool_alloc(dm->mem, sizeof(*sl)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(sl->str = _build_name(dm->mem, dm->vg_name,
|
||||
s->origin->name, "real"))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_add(&dl->pre_create, &sl->list);
|
||||
|
||||
/* insert the snapshot layer */
|
||||
if (!hash_insert(dm->layers,dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else if (lv_is_origin(lv)) {
|
||||
/*
|
||||
* origin(org)
|
||||
* org
|
||||
*/
|
||||
struct dev_layer *dl;
|
||||
char *real_name;
|
||||
struct str_list *sl;
|
||||
|
||||
if (!(dl = _create_layer(dm->mem, "real", lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_vanilla;
|
||||
_clear_flag(dl, VISIBLE);
|
||||
|
||||
if (!hash_insert(dm->layers, dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
real_name = dl->name;
|
||||
|
||||
if (!(dl = _create_layer(dm->mem, NULL, lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_origin;
|
||||
_set_flag(dl, VISIBLE);
|
||||
|
||||
/* add the dependency on the real device */
|
||||
if (!(sl = pool_alloc(dm->mem, sizeof(*sl)))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(sl->str = pool_strdup(dm->mem, real_name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
list_add(&dl->pre_create, &sl->list);
|
||||
|
||||
if (!hash_insert(dm->layers,dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
* only one layer.
|
||||
*/
|
||||
struct dev_layer *dl;
|
||||
if (!(dl = _create_layer(dm->mem, NULL, lv))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_vanilla;
|
||||
_set_flag(dl, VISIBLE);
|
||||
|
||||
if (!hash_insert(dm->layers, dl->name, dl)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return _expand_vanilla(dm, lv);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1004,8 +1036,6 @@ static int _execute(struct dev_manager *dm, struct logical_volume *lv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
{
|
||||
if (!_execute(dm, lv, _create_rec)) {
|
||||
@ -1025,3 +1055,97 @@ int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ATM we decide which vg a layer belongs to by
|
||||
* looking at the beginning of the device
|
||||
* name.
|
||||
*/
|
||||
static int _belong_to_vg(const char *vg, const char *name)
|
||||
{
|
||||
/*
|
||||
* FIXME: broken for vg's with '-'s in.
|
||||
*/
|
||||
return !strncmp(vg, name, strlen(vg));
|
||||
}
|
||||
|
||||
static int _add_existing_layer(struct dev_manager *dm, const char *name)
|
||||
{
|
||||
struct dev_layer *new;
|
||||
char *copy;
|
||||
|
||||
if (!(copy = pool_strdup(dm->mem, name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(new = _create_dev(dm->mem, copy, NULL))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_info(new->name, &new->info)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hash_insert(dm->layers, new->name, new)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _scan_existing_devices(struct dev_manager *dm)
|
||||
{
|
||||
const char *dev_dir = dm_dir();
|
||||
|
||||
int i, count, r = 1;
|
||||
struct dirent **dirent;
|
||||
const char *name;
|
||||
|
||||
count = scandir(dev_dir, &dirent, NULL, alphasort);
|
||||
if (!count)
|
||||
return 1;
|
||||
|
||||
if (count < 0) {
|
||||
log_err("Couldn't scan device-mapper directory '%s'.",
|
||||
dev_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan the devices.
|
||||
*/
|
||||
for (i = 0; i < count; i++) {
|
||||
name = dirent[i]->d_name;
|
||||
|
||||
/*
|
||||
* Ignore dot files.
|
||||
*/
|
||||
if (name[0] == '.')
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Does this layer belong to us ?
|
||||
*/
|
||||
if (_belong_to_vg(dm->vg_name, name) &&
|
||||
!_add_existing_layer(dm, name)) {
|
||||
stack;
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the directory entries.
|
||||
*/
|
||||
for (i = 0; i < count; i++)
|
||||
free(dirent[i]);
|
||||
free(dirent);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user