diff --git a/lib/activate/activate-lv.c b/lib/activate/activate-lv.c index 5462a3bf5..dc4d7d9de 100644 --- a/lib/activate/activate-lv.c +++ b/lib/activate/activate-lv.c @@ -9,8 +9,6 @@ #include "log.h" #include -#include - /* * Emit a target for a given segment. @@ -85,66 +83,19 @@ static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg) return 1; } -int _load(const char *name, struct logical_volume *lv, int task) +int device_populate_lv(struct dm_task *dmt, struct logical_volume *lv) { - int r = 0; - struct dm_task *dmt; struct list *segh; struct stripe_segment *seg; - log_very_verbose("Generating devmapper parameters for %s", lv->name); - if (!(dmt = setup_dm_task(name, task))) { - stack; - return 0; - } - + log_very_verbose("Generating devmapper table for %s", lv->name); list_iterate(segh, &lv->segments) { seg = list_item(segh, struct stripe_segment); if (!_emit_target(dmt, seg)) { - log_error("Unable to activate logical volume '%s'", - lv->name); - goto out; + log_error("Unable to build table for '%s'", lv->name); + return 0; } } - if (!((lv->status & LVM_WRITE) && (lv->vg->status & LVM_WRITE))) { - if (!dm_task_set_ro(dmt)) { - log_error("Failed to set %s read-only during " - "activation.", lv->name); - goto out; - } else - log_very_verbose("Activating %s read-only", lv->name); - } - - if (lv->minor >= 0) { - if (!dm_task_set_minor(dmt, MINOR(lv->minor))) { - log_error("Failed to set minor number for %s to %d " - "during activation.", lv->name, lv->minor); - goto out; - } else - log_very_verbose("Set minor number for %s to %d.", - lv->name, lv->minor); - } - - if (!(r = dm_task_run(dmt))) - stack; - - log_verbose("Logical volume %s%s activated", lv->name, - r == 1 ? "" : " not"); - - out: - dm_task_destroy(dmt); - return r; -} - -int device_create_lv(const char *name, struct logical_volume *lv, int minor) -{ - log_very_verbose("Activating %s", name); - return _load(name, lv, DM_DEVICE_CREATE); -} - -int device_reload_lv(const char *name, struct logical_volume *lv) -{ - log_very_verbose("Reactivating %s", name); - return _load(name, lv, DM_DEVICE_RELOAD); + return 1; } diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 887cfd71c..356830fef 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -14,6 +14,7 @@ #include "names.h" #include +#include #define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args) @@ -64,7 +65,7 @@ static int _query(struct logical_volume *lv, int (*fn)(const char *)) /* - * These three functions return the number of LVs in the state, + * These three functions return the number of LVs in the state, * or -1 on error. */ int lv_active(struct logical_volume *lv) @@ -99,9 +100,15 @@ int lv_info(struct logical_volume *lv, struct dm_info *info) return device_info(buffer, info); } +static inline int _read_only_lv(struct logical_volume *lv) +{ + return (lv->status & LVM_WRITE) && (lv->vg->status & LVM_WRITE); +} int lv_activate(struct logical_volume *lv) { + int r = 0; + struct dm_task *dmt; char buffer[128]; if (test_mode()) { @@ -109,23 +116,117 @@ int lv_activate(struct logical_volume *lv) return 0; } + /* + * Decide what we're going to call this device. + */ if (!build_dm_name(buffer, sizeof(buffer), "", lv->vg->name, lv->name)) { stack; return 0; } - if (!device_create_lv(buffer, lv, lv->minor)) { + /* + * Create a task. + */ + if (!(dmt = setup_dm_task(buffer, DM_DEVICE_CREATE))) { stack; return 0; } - if (!fs_add_lv(lv, lv->minor)) { + /* + * Populate it. + */ + if (!device_populate_lv(dmt, lv)) { stack; return 0; } - return 1; + /* + * Do we want a specific minor number ? + */ + if (lv->minor >= 0) { + if (!dm_task_set_minor(dmt, MINOR(lv->minor))) { + log_error("Failed to set minor number for %s to %d " + "during activation.", lv->name, lv->minor); + goto out; + } else + log_very_verbose("Set minor number for %s to %d.", + lv->name, lv->minor); + } + + /* + * Read only ? + */ + if (!_read_only_lv(lv)) { + if (!dm_task_set_ro(dmt)) { + log_error("Failed to set %s read-only during " + "activation.", lv->name); + goto out; + } else + log_very_verbose("Activating %s read-only", lv->name); + } + + /* + * Load this into the kernel. + */ + if (!(r = dm_task_run(dmt))) { + log_err("Activation failed."); + goto out; + } + + /* + * Create device nodes and symbolic links. + */ + if (!fs_add_lv(lv, lv->minor)) + stack; + + out: + dm_task_destroy(dmt); + log_verbose("Logical volume %s%s activated", lv->name, + r == 1 ? "" : " not"); + return r; +} + +static int _reload(const char *name, struct logical_volume *lv) +{ + int r = 0; + struct dm_task *dmt; + + /* + * Create a task. + */ + if (!(dmt = setup_dm_task(name, DM_DEVICE_RELOAD))) { + stack; + return 0; + } + + /* + * Populate it. + */ + if (!device_populate_lv(dmt, lv)) { + stack; + return 0; + } + + /* + * Load this into the kernel. + */ + if (!(r = dm_task_run(dmt))) { + log_err("Activation failed."); + goto out; + } + + /* + * Create device nodes and symbolic links. + */ + if (!fs_add_lv(lv, lv->minor)) + stack; + + out: + dm_task_destroy(dmt); + log_verbose("Logical volume %s%s re-activated", lv->name, + r == 1 ? "" : " not"); + return r; } int lv_reactivate(struct logical_volume *lv) @@ -138,18 +239,24 @@ int lv_reactivate(struct logical_volume *lv) return 0; } + /* + * Decide what we're going to call this device. + */ if (!build_dm_name(buffer, sizeof(buffer), "", lv->vg->name, lv->name)) { stack; return 0; } + /* + * Suspend the device if it isn't already. + */ if (!device_suspended(buffer) && !device_suspend(buffer)) { stack; return 0; } - r = device_reload_lv(buffer, lv); + r = _reload(buffer, lv); if (!device_resume(buffer)) { stack; diff --git a/lib/activate/activate.h b/lib/activate/activate.h index 91bb1725f..3ae13f602 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -13,7 +13,8 @@ int driver_version(char *version, size_t size); int library_version(char *version, size_t size); /* - * Status functions. Return count (0 upwards) or else -1 on error. + * Status functions. Return count (0 upwards) or else -1 on + * error. */ int lv_active(struct logical_volume *lv); int lv_suspended(struct logical_volume *lv); diff --git a/lib/activate/ll-activate.h b/lib/activate/ll-activate.h index 9cec02aa6..6ee642de9 100644 --- a/lib/activate/ll-activate.h +++ b/lib/activate/ll-activate.h @@ -35,27 +35,28 @@ int device_suspend(const char *name); int device_resume(const char *name); +/* + * The next three functions populate a dm_task with a suitable + * set of targets. + */ + /* * Creates a device with a mapping table as specified by the lv. */ -int device_create_lv(const char *name, struct logical_volume *lv, int minor); -int device_reload_lv(const char *name, struct logical_volume *lv); - +int device_populate_lv(struct dm_task *dmt, struct logical_volume *lv); /* * Layers the origin device above an already active 'real' * device. */ -int device_create_origin(struct logical_volume *lv, - const char *real, int minor); - +int device_populate_origin(struct dm_task *dmt, struct logical_volume *lv, + const char *real); /* * Creates a snapshot device for a given origin and exception * storage area. */ -int device_create_snapshot(struct logical_volume *lv, - const char *origin, const char *cow_device, - int minor); +int device_populate_snapshot(struct dm_task *dmt, struct logical_volume *lv, + const char *origin, const char *cow_device); #endif