mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-25 01:34:38 +03:00
o Removed old files
o rewrote activate.c to use dev-manager, I'm sure these two will merge at some point. o Rename is broken ATM o dev-manager puts the calls through to fs.c for layers that have the 'visible' flag set.
This commit is contained in:
parent
c885633e02
commit
a5bca5e240
@ -6,14 +6,13 @@
|
||||
|
||||
#include "metadata.h"
|
||||
#include "activate.h"
|
||||
#include "ll-activate.h"
|
||||
#include "display.h"
|
||||
#include "log.h"
|
||||
#include "fs.h"
|
||||
#include "lvm-string.h"
|
||||
#include "names.h"
|
||||
#include "pool.h"
|
||||
#include "toolcontext.h"
|
||||
#include "dev_manager.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <linux/kdev_t.h>
|
||||
@ -47,25 +46,31 @@ int driver_version(char *version, size_t size)
|
||||
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _query(struct logical_volume *lv, int (*fn)(const char *))
|
||||
/*
|
||||
* Returns 1 if info structure populated, else 0 on failure.
|
||||
*/
|
||||
int lv_info(struct logical_volume *lv, struct dm_info *info)
|
||||
{
|
||||
char buffer[128];
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||
lv->vg->name, lv->name)) {
|
||||
if (!(dm = dev_manager_create(lv->vg->name))) {
|
||||
stack;
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fn(buffer);
|
||||
}
|
||||
if (!(r = dev_manager_info(dm, lv, info)))
|
||||
stack;
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* These three functions return the number of LVs in the state,
|
||||
@ -73,236 +78,94 @@ static int _query(struct logical_volume *lv, int (*fn)(const char *))
|
||||
*/
|
||||
int lv_active(struct logical_volume *lv)
|
||||
{
|
||||
return _query(lv, device_active);
|
||||
struct dm_info info;
|
||||
|
||||
if (!lv_info(lv, &info)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return info.exists;
|
||||
}
|
||||
|
||||
int lv_suspended(struct logical_volume *lv)
|
||||
{
|
||||
return _query(lv, device_suspended);
|
||||
struct dm_info info;
|
||||
|
||||
if (!lv_info(lv, &info)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return info.suspended;
|
||||
}
|
||||
|
||||
int lv_open_count(struct logical_volume *lv)
|
||||
{
|
||||
return _query(lv, device_open_count);
|
||||
}
|
||||
struct dm_info info;
|
||||
|
||||
|
||||
/*
|
||||
* Returns 1 if info structure populated, else 0 on failure.
|
||||
*/
|
||||
int lv_info(struct logical_volume *lv, struct dm_info *info)
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||
lv->vg->name, lv->name)) {
|
||||
if (!lv_info(lv, &info)) {
|
||||
stack;
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
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_named(struct logical_volume *lv, const char *name)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Activation of '%s'.", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a task.
|
||||
*/
|
||||
if (!(dmt = setup_dm_task(name, DM_DEVICE_CREATE))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate it.
|
||||
*/
|
||||
if (!device_populate_lv(dmt, lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
log_verbose("Logical volume %s%s activated", lv->name,
|
||||
r == 1 ? "" : " not");
|
||||
return r;
|
||||
return info.open_count;
|
||||
}
|
||||
|
||||
int lv_activate(struct logical_volume *lv)
|
||||
{
|
||||
char buffer[128];
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
/*
|
||||
* Decide what we're going to call this device.
|
||||
*/
|
||||
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||
lv->vg->name, lv->name)) {
|
||||
if (!(dm = dev_manager_create(lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_lv_activate_named(lv, buffer) ||
|
||||
!fs_add_lv(lv, lv->minor)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
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))
|
||||
if (!(r = dev_manager_activate(dm, lv)))
|
||||
stack;
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
log_verbose("Logical volume %s%s re-activated", lv->name,
|
||||
r == 1 ? "" : " not");
|
||||
dev_manager_destroy(dm);
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_reactivate(struct logical_volume *lv)
|
||||
{
|
||||
int r;
|
||||
char buffer[128];
|
||||
struct dev_manager *dm;
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Reactivation of '%s'.", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decide what we're going to call this device.
|
||||
*/
|
||||
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||
lv->vg->name, lv->name)) {
|
||||
if (!(dm = dev_manager_create(lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Suspend the device if it isn't already.
|
||||
*/
|
||||
if (!device_suspended(buffer) && !device_suspend(buffer)) {
|
||||
if (!(r = dev_manager_reactivate(dm, lv)))
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = _reload(buffer, lv);
|
||||
|
||||
if (!device_resume(buffer)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_manager_destroy(dm);
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_deactivate(struct logical_volume *lv)
|
||||
{
|
||||
char buffer[128];
|
||||
int r;
|
||||
struct dev_manager *dm;
|
||||
|
||||
log_very_verbose("Deactivating %s", lv->name);
|
||||
if (test_mode()) {
|
||||
_skip("Deactivating '%s'.", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||
lv->vg->name, lv->name)) {
|
||||
if (!(dm = dev_manager_create(lv->vg->name))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!device_deactivate(buffer)) {
|
||||
if (!(r = dev_manager_deactivate(dm, lv)))
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fs_del_lv(lv);
|
||||
|
||||
return 1;
|
||||
dev_manager_destroy(dm);
|
||||
return r;
|
||||
}
|
||||
|
||||
int lv_suspend(struct logical_volume *lv)
|
||||
{
|
||||
#if 0
|
||||
char buffer[128];
|
||||
|
||||
log_very_verbose("Suspending %s", lv->name);
|
||||
@ -325,10 +188,15 @@ int lv_suspend(struct logical_volume *lv)
|
||||
fs_del_lv(lv);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
log_err("lv_suspend not implemented.");
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int lv_rename(const char *old_name, struct logical_volume *lv)
|
||||
{
|
||||
#if 0
|
||||
int r = 0;
|
||||
char new_name[PATH_MAX];
|
||||
struct dm_task *dmt;
|
||||
@ -366,6 +234,10 @@ int lv_rename(const char *old_name, struct logical_volume *lv)
|
||||
end:
|
||||
dm_task_destroy(dmt);
|
||||
return r;
|
||||
#else
|
||||
log_err("lv_rename not implemented yet.");
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -374,6 +246,7 @@ int lv_rename(const char *old_name, struct logical_volume *lv)
|
||||
*/
|
||||
int lv_setup_cow_store(struct logical_volume *lv)
|
||||
{
|
||||
#if 0
|
||||
char buffer[128];
|
||||
char path[PATH_MAX];
|
||||
struct device *dev;
|
||||
@ -412,6 +285,9 @@ int lv_setup_cow_store(struct logical_volume *lv)
|
||||
dev_close(dev);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -472,7 +348,7 @@ int lvs_in_vg_opened(struct volume_group *vg)
|
||||
}
|
||||
|
||||
/* FIXME Currently lvid is "vgname/lv_uuid". Needs to be vg_uuid/lv_uuid. */
|
||||
static struct logical_volume *_lv_from_lvid(struct cmd_context *cmd,
|
||||
static struct logical_volume *_lv_from_lvid(struct cmd_context *cmd,
|
||||
const char *lvid)
|
||||
{
|
||||
struct lv_list *lvl;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "hash.h"
|
||||
#include "log.h"
|
||||
#include "lvm-string.h"
|
||||
#include "fs.h"
|
||||
|
||||
#include <libdevmapper.h>
|
||||
|
||||
@ -22,6 +23,7 @@ enum {
|
||||
struct dev_layer {
|
||||
char *name;
|
||||
int mark;
|
||||
int visible;
|
||||
|
||||
/*
|
||||
* Setup the dm_task.
|
||||
@ -99,10 +101,9 @@ static char *_build_name(struct pool *mem, const char *vg,
|
||||
}
|
||||
|
||||
out = r;
|
||||
_quote_colons(&out, vg);
|
||||
_quote_colons(&out, lv);
|
||||
_quote_colons(&out, layer);
|
||||
*out = '\0';
|
||||
_quote_colons(&out, vg); *out++ = ':';
|
||||
_quote_colons(&out, lv); *out++ = ':';
|
||||
_quote_colons(&out, layer); *out = '\0';
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -148,6 +149,9 @@ static int _load(struct dev_layer *dl, int task)
|
||||
log_err("Couldn't create device '%s'.", dl->name);
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
if (dl->visible)
|
||||
fs_add_lv(dl->lv, dl->name);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -166,6 +170,10 @@ static int _remove(struct dev_layer *dl)
|
||||
log_err("Couldn't remove device '%s'", dl->name);
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
if (dl->visible)
|
||||
fs_del_lv(dl->lv);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -194,7 +202,13 @@ static int _suspend(struct dev_layer *dl)
|
||||
if (dl->info.suspended)
|
||||
return 1;
|
||||
|
||||
return _suspend_or_resume(dl->name, 1);
|
||||
if (!_suspend_or_resume(dl->name, 1)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dl->info.suspended = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _resume(struct dev_layer *dl)
|
||||
@ -202,7 +216,13 @@ static int _resume(struct dev_layer *dl)
|
||||
if (!dl->info.suspended)
|
||||
return 1;
|
||||
|
||||
return _suspend_or_resume(dl->name, 0);
|
||||
if (!_suspend_or_resume(dl->name, 0)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dl->info.suspended = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _info(const char *name, struct dm_info *info)
|
||||
@ -465,6 +485,8 @@ _create_layer(struct pool *mem, const char *layer,
|
||||
|
||||
dl->type = type;
|
||||
dl->lv = lv;
|
||||
list_init(&dl->pre_create);
|
||||
list_init(&dl->pre_active);
|
||||
|
||||
return dl;
|
||||
}
|
||||
@ -526,6 +548,7 @@ static int _expand_lv(struct dev_manager *dm, struct logical_volume *lv)
|
||||
return 0;
|
||||
}
|
||||
dl->populate = _populate_vanilla;
|
||||
dl->visible = 1;
|
||||
|
||||
if (!hash_insert(dm->layers, dl->name, dl)) {
|
||||
stack;
|
||||
@ -664,7 +687,7 @@ int _remove_rec(struct dev_manager *dm, struct dev_layer *dl)
|
||||
}
|
||||
}
|
||||
|
||||
if (dl->info.exists && !_remove(dl)) {
|
||||
if (dl->info.exists && (!_resume(dl) || !_remove(dl))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@ -703,40 +726,6 @@ static int _mark_dependants(struct dev_manager *dm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The guts of the activation unit, this examines the device
|
||||
* layers in the manager, and tries to issue the correct
|
||||
* instructions to activate them in order.
|
||||
*/
|
||||
static int _execute(struct dev_manager *dm,
|
||||
int (*cmd)(struct dev_manager *dm, struct dev_layer *dl))
|
||||
{
|
||||
struct hash_node *hn;
|
||||
struct dev_layer *dl;
|
||||
|
||||
/*
|
||||
* We need to make a list of top level devices, ie. those
|
||||
* that have no entries in 'pre_create'.
|
||||
*/
|
||||
if (!_mark_dependants(dm)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now only top level devices will be unmarked.
|
||||
*/
|
||||
hash_iterate (hn, dm->layers) {
|
||||
dl = hash_get_data(dm->layers, hn);
|
||||
|
||||
if (!dl->mark)
|
||||
cmd(dm, dl);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Remove all layers from the hash table that do not have their
|
||||
* mark flag set.
|
||||
@ -786,14 +775,50 @@ static int _select_lv(struct dev_manager *dm, struct logical_volume *lv)
|
||||
_prune_unmarked(dm);
|
||||
return 1;
|
||||
}
|
||||
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
|
||||
/*
|
||||
* The guts of the activation unit, this examines the device
|
||||
* layers in the manager, and tries to issue the correct
|
||||
* instructions to activate them in order.
|
||||
*/
|
||||
static int _execute(struct dev_manager *dm, struct logical_volume *lv,
|
||||
int (*cmd)(struct dev_manager *dm, struct dev_layer *dl))
|
||||
{
|
||||
struct hash_node *hn;
|
||||
struct dev_layer *dl;
|
||||
|
||||
if (!_select_lv(dm, lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_execute(dm, _create_rec)) {
|
||||
/*
|
||||
* We need to make a list of top level devices, ie. those
|
||||
* that have no entries in 'pre_create'.
|
||||
*/
|
||||
if (!_mark_dependants(dm)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now only top level devices will be unmarked.
|
||||
*/
|
||||
hash_iterate (hn, dm->layers) {
|
||||
dl = hash_get_data(dm->layers, hn);
|
||||
|
||||
if (!dl->mark)
|
||||
cmd(dm, dl);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
{
|
||||
if (!_execute(dm, lv, _create_rec)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@ -803,12 +828,7 @@ int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
|
||||
int dev_manager_reactivate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
{
|
||||
if (!_select_lv(dm, lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_execute(dm, _create_rec)) {
|
||||
if (!_execute(dm, lv, _create_rec)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@ -818,12 +838,7 @@ int dev_manager_reactivate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
|
||||
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv)
|
||||
{
|
||||
if (!_select_lv(dm, lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!_execute(dm, _remove_rec)) {
|
||||
if (!_execute(dm, lv, _remove_rec)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
#include "fs.h"
|
||||
#include "log.h"
|
||||
#include "names.h"
|
||||
#include "toolcontext.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -29,9 +29,10 @@ static int _mk_dir(struct volume_group *vg)
|
||||
{
|
||||
char vg_path[PATH_MAX];
|
||||
|
||||
if (!build_vg_path(vg_path, sizeof(vg_path),
|
||||
vg->cmd->dev_dir, vg->name)) {
|
||||
log_error("Couldn't construct name of volume group directory.");
|
||||
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s/%s",
|
||||
vg->cmd->dev_dir, vg->name) == -1) {
|
||||
log_error("Couldn't construct name of volume "
|
||||
"group directory.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -45,10 +46,10 @@ static int _rm_dir(struct volume_group *vg)
|
||||
{
|
||||
char vg_path[PATH_MAX];
|
||||
|
||||
if (!build_vg_path(vg_path, sizeof(vg_path),
|
||||
vg->cmd->dev_dir, vg->name)) {
|
||||
log_error("Couldn't construct name of volume group dir for %s",
|
||||
vg->name);
|
||||
if (lvm_snprintf(vg_path, sizeof(vg_path), "%s/%s",
|
||||
vg->cmd->dev_dir, vg->name) == -1) {
|
||||
log_error("Couldn't construct name of volume "
|
||||
"group directory.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -58,41 +59,41 @@ static int _rm_dir(struct volume_group *vg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _mk_link(struct logical_volume *lv)
|
||||
static int _mk_link(struct logical_volume *lv, const char *dev)
|
||||
{
|
||||
char lv_path[PATH_MAX], link_path[PATH_MAX];
|
||||
struct stat buf;
|
||||
|
||||
if (!build_dm_path(lv_path, sizeof(lv_path), "",
|
||||
lv->vg->name, lv->name)) {
|
||||
log_error("Couldn't create destination pathname for "
|
||||
"logical volume link for %s", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!build_lv_link_path(link_path, sizeof(link_path),
|
||||
lv->vg->cmd->dev_dir,
|
||||
lv->vg->name, lv->name)) {
|
||||
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s/%s/%s",
|
||||
lv->vg->cmd->dev_dir, lv->vg->name, lv->name) == -1) {
|
||||
log_error("Couldn't create source pathname for "
|
||||
"logical volume link %s", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lstat(link_path, &buf)) {
|
||||
if (lvm_snprintf(link_path, sizeof(link_path), "%s/%s",
|
||||
dm_dir(), dev) == -1) {
|
||||
log_error("Couldn't create destination pathname for "
|
||||
"logical volume link for %s", lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lstat(lv_path, &buf)) {
|
||||
if (!S_ISLNK(buf.st_mode)) {
|
||||
log_error("Symbolic link %s not created: file exists",
|
||||
link_path);
|
||||
return 0;
|
||||
}
|
||||
if (unlink(link_path) < 0) {
|
||||
log_sys_error("unlink", link_path);
|
||||
|
||||
if (unlink(lv_path) < 0) {
|
||||
log_sys_error("unlink", lv_path);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
log_very_verbose("Linking %s to %s", link_path, lv_path);
|
||||
if (symlink(lv_path, link_path) < 0) {
|
||||
log_sys_error("symlink", link_path);
|
||||
if (symlink(link_path, lv_path) < 0) {
|
||||
log_sys_error("symlink", lv_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -102,36 +103,32 @@ static int _mk_link(struct logical_volume *lv)
|
||||
static int _rm_link(struct logical_volume *lv, const char *lv_name)
|
||||
{
|
||||
struct stat buf;
|
||||
char link_path[PATH_MAX];
|
||||
char lv_path[PATH_MAX];
|
||||
|
||||
if (!lv_name)
|
||||
lv_name = lv->name;
|
||||
|
||||
if (!build_lv_link_path(link_path, sizeof(link_path),
|
||||
lv->vg->cmd->dev_dir,
|
||||
lv->vg->name, lv->name)) {
|
||||
if (lvm_snprintf(lv_path, sizeof(lv_path), "%s/%s/%s",
|
||||
lv->vg->cmd->dev_dir, lv->vg->name, lv_name) == -1) {
|
||||
log_error("Couldn't determine link pathname.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_very_verbose("Removing link %s", link_path);
|
||||
if (lstat(link_path, &buf) || !S_ISLNK(buf.st_mode)) {
|
||||
log_error("%s not symbolic link - not removing",
|
||||
link_path);
|
||||
return 0;
|
||||
log_very_verbose("Removing link %s", lv_path);
|
||||
if (lstat(lv_path, &buf) || !S_ISLNK(buf.st_mode)) {
|
||||
log_error("%s not symbolic link - not removing", lv_path);
|
||||
return 0;
|
||||
}
|
||||
if (unlink(link_path) < 0) {
|
||||
log_sys_error("unlink", link_path);
|
||||
|
||||
if (unlink(lv_path) < 0) {
|
||||
log_sys_error("unlink", lv_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fs_add_lv(struct logical_volume *lv, int minor)
|
||||
int fs_add_lv(struct logical_volume *lv, const char *dev)
|
||||
{
|
||||
if (!_mk_dir(lv->vg) ||
|
||||
!_mk_link(lv)) {
|
||||
!_mk_link(lv, dev)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
@ -141,7 +138,7 @@ int fs_add_lv(struct logical_volume *lv, int minor)
|
||||
|
||||
int fs_del_lv(struct logical_volume *lv)
|
||||
{
|
||||
if (!_rm_link(lv, NULL) ||
|
||||
if (!_rm_link(lv, lv->name) ||
|
||||
!_rm_dir(lv->vg)) {
|
||||
stack;
|
||||
return 0;
|
||||
@ -150,12 +147,13 @@ int fs_del_lv(struct logical_volume *lv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int fs_rename_lv(const char *old_name, struct logical_volume *lv)
|
||||
int fs_rename_lv(struct logical_volume *lv,
|
||||
const char *dev, const char *old_name)
|
||||
{
|
||||
if (!_rm_link(lv, old_name))
|
||||
stack;
|
||||
|
||||
if (!_mk_link(lv))
|
||||
if (!_mk_link(lv, dev))
|
||||
stack;
|
||||
|
||||
return 1;
|
||||
|
@ -14,10 +14,10 @@
|
||||
* up the volume group directory in /dev and the
|
||||
* symbolic links to the dm device.
|
||||
*/
|
||||
|
||||
int fs_add_lv(struct logical_volume *lv, int minor);
|
||||
int fs_add_lv(struct logical_volume *lv, const char *dev);
|
||||
int fs_del_lv(struct logical_volume *lv);
|
||||
int fs_rename_lv(const char *old_name, struct logical_volume *lv);
|
||||
int fs_rename_lv(struct logical_volume *lv,
|
||||
const char *dev, const char *old_name);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||
*
|
||||
* This file is released under the LGPL.
|
||||
*/
|
||||
|
||||
#include "ll-activate.h"
|
||||
#include "log.h"
|
||||
|
||||
struct dm_task *setup_dm_task(const char *name, int task)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
|
||||
if (!(dmt = dm_task_create(task))) {
|
||||
stack;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dm_task_set_name(dmt, name);
|
||||
|
||||
return dmt;
|
||||
}
|
||||
|
||||
int device_info(const char *name, struct dm_info *info)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
|
||||
log_very_verbose("Getting device info for %s", name);
|
||||
if (!(dmt = setup_dm_task(name, DM_DEVICE_INFO))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dm_task_run(dmt)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!dm_task_get_info(dmt, info)) {
|
||||
stack;
|
||||
goto out;
|
||||
}
|
||||
r = 1;
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* The next three functions return -1 on error.
|
||||
*/
|
||||
int device_active(const char *name)
|
||||
{
|
||||
struct dm_info info;
|
||||
|
||||
if (!device_info(name, &info)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_very_verbose("%s is%s active", name, info.exists ? "" : " not");
|
||||
return info.exists;
|
||||
}
|
||||
|
||||
int device_suspended(const char *name)
|
||||
{
|
||||
struct dm_info info;
|
||||
|
||||
if (!device_info(name, &info)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_very_verbose("%s is%s suspended", name,
|
||||
info.suspended ? "" : " not");
|
||||
return info.suspended;
|
||||
}
|
||||
|
||||
int device_open_count(const char *name)
|
||||
{
|
||||
struct dm_info info;
|
||||
|
||||
if (!device_info(name, &info)) {
|
||||
stack;
|
||||
return -1;
|
||||
}
|
||||
|
||||
log_very_verbose("%s is open %d time(s)", name, info.open_count);
|
||||
return info.open_count;
|
||||
}
|
||||
|
||||
|
||||
int device_deactivate(const char *name)
|
||||
{
|
||||
int r;
|
||||
struct dm_task *dmt;
|
||||
|
||||
log_very_verbose("Deactivating '%s'.", name);
|
||||
|
||||
if (!(dmt = setup_dm_task(name, DM_DEVICE_REMOVE))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(r = dm_task_run(dmt)))
|
||||
stack;
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _suspend(const char *name, int sus)
|
||||
{
|
||||
int r;
|
||||
struct dm_task *dmt;
|
||||
int task = sus ? DM_DEVICE_SUSPEND : DM_DEVICE_RESUME;
|
||||
|
||||
log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name);
|
||||
if (!(dmt = setup_dm_task(name, task))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(r = dm_task_run(dmt)))
|
||||
log_err("Couldn't %s device '%s'", sus ? "suspend" : "resume",
|
||||
name);
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
return r;
|
||||
}
|
||||
|
||||
int device_suspend(const char *name)
|
||||
{
|
||||
return _suspend(name, 1);
|
||||
}
|
||||
|
||||
int device_resume(const char *name)
|
||||
{
|
||||
return _suspend(name, 0);
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||
*
|
||||
* This file is released under the LGPL.
|
||||
*/
|
||||
|
||||
#ifndef _LVM_LL_ACTIVATE_H
|
||||
#define _LVM_LL_ACTIVATE_H
|
||||
|
||||
#include "metadata.h"
|
||||
|
||||
#include <libdevmapper.h>
|
||||
|
||||
/*
|
||||
* Prepares a new dm_task.
|
||||
*/
|
||||
struct dm_task *setup_dm_task(const char *name, int task);
|
||||
|
||||
|
||||
/*
|
||||
* Query functions. 'name' is the device node name in the
|
||||
* device-mapper dir.
|
||||
*/
|
||||
int device_info(const char *name, struct dm_info *info);
|
||||
int device_active(const char *name);
|
||||
int device_suspended(const char *name);
|
||||
int device_open_count(const char *name);
|
||||
|
||||
|
||||
/*
|
||||
* Functions to manipulate an already active device.
|
||||
*/
|
||||
int device_deactivate(const char *name);
|
||||
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_populate_lv(struct dm_task *dmt, struct logical_volume *lv);
|
||||
|
||||
/*
|
||||
* Layers the origin device above an already active 'real'
|
||||
* device.
|
||||
*/
|
||||
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_populate_snapshot(struct dm_task *dmt, struct logical_volume *lv,
|
||||
const char *origin, const char *cow_device);
|
||||
|
||||
#endif
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||
*
|
||||
* This file is released under the LGPL.
|
||||
*/
|
||||
|
||||
#include "names.h"
|
||||
#include "lvm-string.h"
|
||||
#include "log.h"
|
||||
#include "limits.h"
|
||||
|
||||
#include <libdevmapper.h>
|
||||
|
||||
/*
|
||||
* The volume group name and the logical volume name are
|
||||
* seperated by a single ':', any colons in the vg name are
|
||||
* doubled up to form a pair.
|
||||
*/
|
||||
int build_dm_name(char *buffer, size_t len, const char *prefix,
|
||||
const char *vg_name, const char *lv_name)
|
||||
{
|
||||
char *out;
|
||||
const char *in;
|
||||
|
||||
for (out = buffer, in = vg_name; len && *in; len--) {
|
||||
if (*in == ':') {
|
||||
*out++ = ':';
|
||||
if (!--len)
|
||||
break;
|
||||
}
|
||||
|
||||
*out++ = *in++;
|
||||
len--;
|
||||
}
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (lvm_snprintf(out, len, ":%s%s", prefix, lv_name) == -1) {
|
||||
log_err("Couldn't build logical volume name.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int build_dm_path(char *buffer, size_t len, const char *prefix,
|
||||
const char *vg_name, const char *lv_name)
|
||||
{
|
||||
char dev_name[PATH_MAX];
|
||||
|
||||
if (!build_dm_name(dev_name, sizeof(dev_name),
|
||||
prefix, vg_name, lv_name)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lvm_snprintf(buffer, len, "%s/%s", dm_dir(), dev_name) == -1) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int build_vg_path(char *buffer, size_t len,
|
||||
const char *dev_dir, const char *vg_name)
|
||||
{
|
||||
if (lvm_snprintf(buffer, len, "%s%s", dev_dir, vg_name) == -1) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int build_lv_link_path(char *buffer, size_t len, const char *dev_dir,
|
||||
const char *vg_name, const char *lv_name)
|
||||
{
|
||||
if (lvm_snprintf(buffer, len, "%s%s/%s",
|
||||
dev_dir, vg_name, lv_name) == -1) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||
*
|
||||
* This file is released under the LGPL.
|
||||
*/
|
||||
|
||||
#ifndef _LVM_NAMES_H
|
||||
#define _LVM_NAMES_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Functions that build up useful paths to devices, sym-links
|
||||
* etc. Names are passed in as strings, rather than via the
|
||||
* appropriate metadata structures, so we can use it for renaming
|
||||
* devices.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* The name of the device-mapper device for a particular LV.
|
||||
* eg, vg0:music
|
||||
*/
|
||||
int build_dm_name(char *buffer, size_t len, const char *prefix,
|
||||
const char *vg_name, const char *lv_name);
|
||||
|
||||
/*
|
||||
* The path of the device-mapper device for a particular LV.
|
||||
* eg, /dev/device-mapper/vg0:music
|
||||
*/
|
||||
int build_dm_path(char *buffer, size_t len, const char *prefix,
|
||||
const char *vg_name, const char *lv_name);
|
||||
|
||||
/*
|
||||
* Path to the volume group directory.
|
||||
* eg, /dev/vg0
|
||||
*/
|
||||
int build_vg_path(char *buffer, size_t len,
|
||||
const char *dev_dir, const char *vg_name);
|
||||
|
||||
/*
|
||||
* Path to the symbolic link that lives in the volume group
|
||||
* directory.
|
||||
* eg, /dev/vg0/music
|
||||
*/
|
||||
int build_lv_link_path(char *buffer, size_t len,
|
||||
const char *dev_dir,
|
||||
const char *vg_name, const char *lv_name);
|
||||
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||
*
|
||||
* This file is released under the LGPL.
|
||||
*/
|
||||
|
||||
#include "table-build.c"
|
||||
|
||||
static void _print_run(FILE *fp, struct logical_volume *lv)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int build_table(struct volume_group *vg, struct logical_volume *lv,
|
||||
const char *file)
|
||||
{
|
||||
int i;
|
||||
uint64_t sector = 0;
|
||||
uint64_t pe_size = vg->extent_size;
|
||||
uint64_t dest;
|
||||
struct pe_specifier *pes;
|
||||
FILE *fp = fopen(file, "w");
|
||||
|
||||
if (!fp) {
|
||||
log_err("couldn't open '%s' to write table", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < lv->le_count; i++) {
|
||||
pes = lv->map + i;
|
||||
dest = pes->pv->pe_start + (pe_size * pes->pe);
|
||||
fprintf(fp, "%ull %ull linear %s %ull\n",
|
||||
sector, pe_size, pes->pv->dev->name, dest);
|
||||
sector += pe_size;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return 1;
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||
*
|
||||
* This file is released under the GPL.
|
||||
*/
|
||||
|
||||
#ifndef TABLE_BUILD_H
|
||||
#define TABLE_BUILD_H
|
||||
|
||||
int build_table(struct volume_group *vg, struct logical_volume *lv,
|
||||
const char *file);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user