mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
o Split activate.c into a high level (remaining in activate.c) and low level (ll-activate.[hc]) API.
o Creation of a device from an lv now lives in activate-lv.c
This commit is contained in:
parent
7d0e6e800e
commit
6d52fb460b
@ -9,8 +9,10 @@ top_srcdir = @top_srcdir@
|
|||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
SOURCES=\
|
SOURCES=\
|
||||||
|
activate/activate-lv.c \
|
||||||
activate/activate.c \
|
activate/activate.c \
|
||||||
activate/fs.c \
|
activate/fs.c \
|
||||||
|
activate/ll-activate.c \
|
||||||
activate/names.c \
|
activate/names.c \
|
||||||
config/config.c \
|
config/config.c \
|
||||||
datastruct/bitset.c \
|
datastruct/bitset.c \
|
||||||
|
150
lib/activate/activate-lv.c
Normal file
150
lib/activate/activate-lv.c
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ll-activate.h"
|
||||||
|
#include "lvm-string.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
#include <libdevmapper.h>
|
||||||
|
#include <linux/kdev_t.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit a target for a given segment.
|
||||||
|
* FIXME: tidy this function.
|
||||||
|
*/
|
||||||
|
static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
|
||||||
|
{
|
||||||
|
char params[1024];
|
||||||
|
uint64_t esize = seg->lv->vg->extent_size;
|
||||||
|
uint32_t s, stripes = seg->stripes;
|
||||||
|
int w = 0, tw = 0, error = 0;
|
||||||
|
const char *no_space =
|
||||||
|
"Insufficient space to write target parameters.";
|
||||||
|
char *filler = "/dev/ioerror";
|
||||||
|
char *target;
|
||||||
|
|
||||||
|
if (stripes == 1) {
|
||||||
|
if (!seg->area[0].pv) {
|
||||||
|
target = "error";
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
target = "linear";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stripes > 1) {
|
||||||
|
target = "striped";
|
||||||
|
tw = lvm_snprintf(params, sizeof(params), "%u %u ",
|
||||||
|
stripes, seg->stripe_size);
|
||||||
|
|
||||||
|
if (tw < 0) {
|
||||||
|
log_err(no_space);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
w = tw;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
for (s = 0; s < stripes; s++, w += tw) {
|
||||||
|
if (!seg->area[s].pv)
|
||||||
|
tw = lvm_snprintf(
|
||||||
|
params + w, sizeof(params) - w,
|
||||||
|
"%s 0%s", filler,
|
||||||
|
s == (stripes - 1) ? "" : " ");
|
||||||
|
else
|
||||||
|
tw = lvm_snprintf(
|
||||||
|
params + w, sizeof(params) - w,
|
||||||
|
"%s %" PRIu64 "%s",
|
||||||
|
dev_name(seg->area[s].pv->dev),
|
||||||
|
(seg->area[s].pv->pe_start +
|
||||||
|
(esize * seg->area[s].pe)),
|
||||||
|
s == (stripes - 1) ? "" : " ");
|
||||||
|
|
||||||
|
if (tw < 0) {
|
||||||
|
log_err(no_space);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_very_verbose("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
|
||||||
|
esize * seg->le, esize * seg->len,
|
||||||
|
target, params);
|
||||||
|
|
||||||
|
if (!dm_task_add_target(dmt, esize * seg->le, esize * seg->len,
|
||||||
|
target, params)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _load(const char *name, struct logical_volume *lv, int task)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
#include "activate.h"
|
#include "activate.h"
|
||||||
|
#include "ll-activate.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
@ -13,8 +14,8 @@
|
|||||||
#include "names.h"
|
#include "names.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <linux/kdev_t.h>
|
|
||||||
|
|
||||||
|
#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
|
||||||
|
|
||||||
int library_version(char *version, size_t size)
|
int library_version(char *version, size_t size)
|
||||||
{
|
{
|
||||||
@ -23,33 +24,6 @@ int library_version(char *version, size_t size)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dm_task *_setup_task_with_name(struct logical_volume *lv,
|
|
||||||
const char *lv_name,
|
|
||||||
int task)
|
|
||||||
{
|
|
||||||
char name[128];
|
|
||||||
struct dm_task *dmt;
|
|
||||||
|
|
||||||
if (!(dmt = dm_task_create(task))) {
|
|
||||||
stack;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!build_dm_name(name, sizeof(name), lv->vg->name, lv_name)) {
|
|
||||||
stack;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dm_task_set_name(dmt, name);
|
|
||||||
|
|
||||||
return dmt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dm_task *_setup_task(struct logical_volume *lv, int task)
|
|
||||||
{
|
|
||||||
return _setup_task_with_name(lv, lv->name, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
int driver_version(char *version, size_t size)
|
int driver_version(char *version, size_t size)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
@ -75,48 +49,176 @@ int driver_version(char *version, size_t size)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _query(struct logical_volume *lv, int (*fn)(const char *))
|
||||||
|
{
|
||||||
|
char buffer[128];
|
||||||
|
|
||||||
|
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||||
|
lv->vg->name, lv->name)) {
|
||||||
|
stack;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fn(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lv_active(struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
return _query(lv, device_active);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lv_suspended(struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
return _query(lv, device_suspended);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lv_open_count(struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
return _query(lv, device_open_count);
|
||||||
|
}
|
||||||
|
|
||||||
int lv_info(struct logical_volume *lv, struct dm_info *info)
|
int lv_info(struct logical_volume *lv, struct dm_info *info)
|
||||||
{
|
{
|
||||||
int r = 0;
|
char buffer[128];
|
||||||
struct dm_task *dmt;
|
|
||||||
|
|
||||||
log_very_verbose("Getting device info for %s", lv->name);
|
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||||
if (!(dmt = _setup_task(lv, DM_DEVICE_INFO))) {
|
lv->vg->name, lv->name)) {
|
||||||
|
stack;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return device_info(buffer, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int lv_activate(struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
char buffer[128];
|
||||||
|
|
||||||
|
if (test_mode()) {
|
||||||
|
_skip("Activation of '%s'.", lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||||
|
lv->vg->name, lv->name)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dm_task_run(dmt)) {
|
if (!device_create_lv(buffer, lv, lv->minor)) {
|
||||||
stack;
|
stack;
|
||||||
goto out;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dm_task_get_info(dmt, info)) {
|
if (!fs_add_lv(lv, lv->minor)) {
|
||||||
stack;
|
stack;
|
||||||
goto out;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lv_reactivate(struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
char buffer[128];
|
||||||
|
|
||||||
|
if (test_mode()) {
|
||||||
|
_skip("Reactivation of '%s'.", lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||||
|
lv->vg->name, lv->name)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device_suspended(buffer) && !device_suspend(buffer)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = device_reload_lv(buffer, lv);
|
||||||
|
|
||||||
|
if (!device_resume(buffer)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
r = 1;
|
|
||||||
|
|
||||||
out:
|
|
||||||
dm_task_destroy(dmt);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lv_deactivate(struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
char buffer[128];
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device_deactivate(buffer)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_del_lv(lv);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lv_suspend(struct logical_volume *lv)
|
||||||
|
{
|
||||||
|
char buffer[128];
|
||||||
|
|
||||||
|
log_very_verbose("Suspending %s", lv->name);
|
||||||
|
if (test_mode()) {
|
||||||
|
_skip("Suspending '%s'.", lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!build_dm_name(buffer, sizeof(buffer), "",
|
||||||
|
lv->vg->name, lv->name)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device_suspend(buffer)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_del_lv(lv);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int lv_rename(const char *old_name, struct logical_volume *lv)
|
int lv_rename(const char *old_name, struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
char new_name[PATH_MAX];
|
char new_name[PATH_MAX];
|
||||||
struct dm_task *dmt;
|
struct dm_task *dmt;
|
||||||
|
|
||||||
if (test_mode())
|
if (test_mode()) {
|
||||||
|
_skip("Rename '%s' to '%s'.", old_name, lv->name);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(dmt = _setup_task_with_name(lv, old_name, DM_DEVICE_RENAME))) {
|
if (!(dmt = setup_dm_task(old_name, DM_DEVICE_RENAME))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!build_dm_name(new_name, sizeof(new_name),
|
if (!build_dm_name(new_name, sizeof(new_name), "",
|
||||||
lv->vg->name, lv->name)) {
|
lv->vg->name, lv->name)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
@ -136,259 +238,11 @@ int lv_rename(const char *old_name, struct logical_volume *lv)
|
|||||||
|
|
||||||
fs_rename_lv(old_name, lv);
|
fs_rename_lv(old_name, lv);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lv_active(struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
int r = -1;
|
|
||||||
struct dm_info info;
|
|
||||||
|
|
||||||
if (!lv_info(lv, &info)) {
|
|
||||||
stack;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_very_verbose("%s is%s active", lv->name, info.exists ? "":" not");
|
|
||||||
return info.exists;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lv_suspended(struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
int r = -1;
|
|
||||||
struct dm_info info;
|
|
||||||
|
|
||||||
if (!lv_info(lv, &info)) {
|
|
||||||
stack;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_very_verbose("%s is%s suspended", lv->name,
|
|
||||||
info.suspended ? "":" not");
|
|
||||||
return info.suspended;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lv_open_count(struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
int r = -1;
|
|
||||||
struct dm_info info;
|
|
||||||
|
|
||||||
if (!lv_info(lv, &info)) {
|
|
||||||
stack;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_very_verbose("%s is open %d time(s)", lv->name, info.open_count);
|
|
||||||
return info.open_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Emit a target for a given segment.
|
|
||||||
*/
|
|
||||||
static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
|
|
||||||
{
|
|
||||||
char params[1024];
|
|
||||||
uint64_t esize = seg->lv->vg->extent_size;
|
|
||||||
uint32_t s, stripes = seg->stripes;
|
|
||||||
int w = 0, tw = 0, error = 0;
|
|
||||||
const char *no_space =
|
|
||||||
"Insufficient space to write target parameters.";
|
|
||||||
char *filler = "/dev/ioerror";
|
|
||||||
char *target;
|
|
||||||
|
|
||||||
if (stripes == 1) {
|
|
||||||
if (!seg->area[0].pv) {
|
|
||||||
target = "error";
|
|
||||||
error = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
target = "linear";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stripes > 1) {
|
|
||||||
target = "striped";
|
|
||||||
tw = lvm_snprintf(params, sizeof(params), "%u %u ",
|
|
||||||
stripes, seg->stripe_size);
|
|
||||||
|
|
||||||
if (tw < 0) {
|
|
||||||
log_err(no_space);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
w = tw;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!error) {
|
|
||||||
for (s = 0; s < stripes; s++, w += tw) {
|
|
||||||
if (!seg->area[s].pv)
|
|
||||||
tw = lvm_snprintf(
|
|
||||||
params + w, sizeof(params) - w,
|
|
||||||
"%s 0%s", filler,
|
|
||||||
s == (stripes - 1) ? "" : " ");
|
|
||||||
else
|
|
||||||
tw = lvm_snprintf(
|
|
||||||
params + w, sizeof(params) - w,
|
|
||||||
"%s %" PRIu64 "%s",
|
|
||||||
dev_name(seg->area[s].pv->dev),
|
|
||||||
(seg->area[s].pv->pe_start +
|
|
||||||
(esize * seg->area[s].pe)),
|
|
||||||
s == (stripes - 1) ? "" : " ");
|
|
||||||
|
|
||||||
if (tw < 0) {
|
|
||||||
log_err(no_space);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log_very_verbose("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
|
|
||||||
esize * seg->le, esize * seg->len,
|
|
||||||
target, params);
|
|
||||||
|
|
||||||
if (!dm_task_add_target(dmt, esize * seg->le, esize * seg->len,
|
|
||||||
target, params)) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _load(struct logical_volume *lv, int task)
|
|
||||||
{
|
|
||||||
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_task(lv, task))) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Always display error msg */
|
|
||||||
int lv_activate(struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
if (test_mode())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
log_very_verbose("Activating %s", lv->name);
|
|
||||||
return _load(lv, DM_DEVICE_CREATE) && fs_add_lv(lv);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _suspend(struct logical_volume *lv, 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", lv->name);
|
|
||||||
if (!(dmt = _setup_task(lv, task))) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(r = dm_task_run(dmt)))
|
|
||||||
log_err("Couldn't %s device '%s'", sus ? "suspend" : "resume",
|
|
||||||
lv->name);
|
|
||||||
|
|
||||||
dm_task_destroy(dmt);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lv_suspend(struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
return _suspend(lv, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int lv_reactivate(struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (test_mode())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!lv_suspended(lv) && !_suspend(lv, 1)) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = _load(lv, DM_DEVICE_RELOAD);
|
|
||||||
|
|
||||||
if (!_suspend(lv, 0)) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int lv_deactivate(struct logical_volume *lv)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
struct dm_task *dmt;
|
|
||||||
|
|
||||||
log_very_verbose("Deactivating %s", lv->name);
|
|
||||||
if (test_mode())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!(dmt = _setup_task(lv, DM_DEVICE_REMOVE))) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(r = dm_task_run(dmt)))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
dm_task_destroy(dmt);
|
|
||||||
|
|
||||||
fs_del_lv(lv);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int activate_lvs_in_vg(struct volume_group *vg)
|
int activate_lvs_in_vg(struct volume_group *vg)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||||
*
|
*
|
||||||
* This file is released under the GPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LVM_ACTIVATE_H
|
#ifndef LVM_ACTIVATE_H
|
||||||
@ -9,25 +9,28 @@
|
|||||||
|
|
||||||
#include <libdevmapper.h>
|
#include <libdevmapper.h>
|
||||||
|
|
||||||
/* FIXME Snapshot handling? */
|
|
||||||
|
|
||||||
int driver_version(char *version, size_t size);
|
int driver_version(char *version, size_t size);
|
||||||
int library_version(char *version, size_t size);
|
int library_version(char *version, size_t size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Status functions.
|
||||||
|
*/
|
||||||
int lv_active(struct logical_volume *lv);
|
int lv_active(struct logical_volume *lv);
|
||||||
int lv_suspended(struct logical_volume *lv);
|
int lv_suspended(struct logical_volume *lv);
|
||||||
int lv_open_count(struct logical_volume *lv);
|
int lv_open_count(struct logical_volume *lv);
|
||||||
int lv_info(struct logical_volume *lv, struct dm_info *info);
|
int lv_info(struct logical_volume *lv, struct dm_info *info);
|
||||||
int lv_rename(const char *old_name, struct logical_volume *lv);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Activation proper.
|
||||||
|
*/
|
||||||
int lv_activate(struct logical_volume *lv);
|
int lv_activate(struct logical_volume *lv);
|
||||||
int lv_reactivate(struct logical_volume *lv);
|
int lv_reactivate(struct logical_volume *lv);
|
||||||
int lv_deactivate(struct logical_volume *lv);
|
int lv_deactivate(struct logical_volume *lv);
|
||||||
int lv_suspend(struct logical_volume *lv);
|
int lv_suspend(struct logical_volume *lv);
|
||||||
|
int lv_rename(const char *old_name, struct logical_volume *lv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return number of LVs in the VG that are
|
* Return number of LVs in the VG that are active.
|
||||||
* active.
|
|
||||||
*/
|
*/
|
||||||
int lvs_in_vg_activated(struct volume_group *vg);
|
int lvs_in_vg_activated(struct volume_group *vg);
|
||||||
int lvs_in_vg_opened(struct volume_group *vg);
|
int lvs_in_vg_opened(struct volume_group *vg);
|
||||||
@ -38,9 +41,8 @@ int lvs_in_vg_opened(struct volume_group *vg);
|
|||||||
int lv_update_write_access(struct logical_volume *lv);
|
int lv_update_write_access(struct logical_volume *lv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Activate all LVs in the VG. Ignore any that
|
* Activate all LVs in the VG. Ignore any that are already
|
||||||
* are already active. Return number
|
* active. Return number activated.
|
||||||
* activated.
|
|
||||||
*/
|
*/
|
||||||
int activate_lvs_in_vg(struct volume_group *vg);
|
int activate_lvs_in_vg(struct volume_group *vg);
|
||||||
|
|
||||||
|
@ -62,7 +62,8 @@ static int _mk_link(struct logical_volume *lv)
|
|||||||
char lv_path[PATH_MAX], link_path[PATH_MAX];
|
char lv_path[PATH_MAX], link_path[PATH_MAX];
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
if (!build_dm_path(lv_path, sizeof(lv_path), lv->vg->name, lv->name)) {
|
if (!build_dm_path(lv_path, sizeof(lv_path), "",
|
||||||
|
lv->vg->name, lv->name)) {
|
||||||
log_error("Couldn't create destination pathname for "
|
log_error("Couldn't create destination pathname for "
|
||||||
"logical volume link for %s", lv->name);
|
"logical volume link for %s", lv->name);
|
||||||
return 0;
|
return 0;
|
||||||
@ -126,7 +127,7 @@ static int _rm_link(struct logical_volume *lv, const char *lv_name)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fs_add_lv(struct logical_volume *lv)
|
int fs_add_lv(struct logical_volume *lv, int minor)
|
||||||
{
|
{
|
||||||
if (!_mk_dir(lv->vg) ||
|
if (!_mk_dir(lv->vg) ||
|
||||||
!_mk_link(lv)) {
|
!_mk_link(lv)) {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* symbolic links to the dm device.
|
* symbolic links to the dm device.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int fs_add_lv(struct logical_volume *lv);
|
int fs_add_lv(struct logical_volume *lv, int minor);
|
||||||
int fs_del_lv(struct logical_volume *lv);
|
int fs_del_lv(struct logical_volume *lv);
|
||||||
int fs_rename_lv(const char *old_name, struct logical_volume *lv);
|
int fs_rename_lv(const char *old_name, struct logical_volume *lv);
|
||||||
|
|
||||||
|
140
lib/activate/ll-activate.c
Normal file
140
lib/activate/ll-activate.c
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
61
lib/activate/ll-activate.h
Normal file
61
lib/activate/ll-activate.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Layers the origin device above an already active 'real'
|
||||||
|
* device.
|
||||||
|
*/
|
||||||
|
int device_create_origin(struct logical_volume *lv,
|
||||||
|
const char *real, int minor);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
#endif
|
@ -16,7 +16,7 @@
|
|||||||
* seperated by a single ':', any colons in the vg name are
|
* seperated by a single ':', any colons in the vg name are
|
||||||
* doubled up to form a pair.
|
* doubled up to form a pair.
|
||||||
*/
|
*/
|
||||||
int build_dm_name(char *buffer, size_t len,
|
int build_dm_name(char *buffer, size_t len, const char *prefix,
|
||||||
const char *vg_name, const char *lv_name)
|
const char *vg_name, const char *lv_name)
|
||||||
{
|
{
|
||||||
char *out;
|
char *out;
|
||||||
@ -36,7 +36,7 @@ int build_dm_name(char *buffer, size_t len,
|
|||||||
if (!len)
|
if (!len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (lvm_snprintf(out, len, ":%s", lv_name) == -1) {
|
if (lvm_snprintf(out, len, ":%s%s", prefix, lv_name) == -1) {
|
||||||
log_err("Couldn't build logical volume name.");
|
log_err("Couldn't build logical volume name.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -44,12 +44,13 @@ int build_dm_name(char *buffer, size_t len,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int build_dm_path(char *buffer, size_t len,
|
int build_dm_path(char *buffer, size_t len, const char *prefix,
|
||||||
const char *vg_name, const char *lv_name)
|
const char *vg_name, const char *lv_name)
|
||||||
{
|
{
|
||||||
char dev_name[PATH_MAX];
|
char dev_name[PATH_MAX];
|
||||||
|
|
||||||
if (!build_dm_name(dev_name, sizeof(dev_name), vg_name, lv_name)) {
|
if (!build_dm_name(dev_name, sizeof(dev_name),
|
||||||
|
prefix, vg_name, lv_name)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,14 @@
|
|||||||
* The name of the device-mapper device for a particular LV.
|
* The name of the device-mapper device for a particular LV.
|
||||||
* eg, vg0:music
|
* eg, vg0:music
|
||||||
*/
|
*/
|
||||||
int build_dm_name(char *buffer, size_t len,
|
int build_dm_name(char *buffer, size_t len, const char *prefix,
|
||||||
const char *vg_name, const char *lv_name);
|
const char *vg_name, const char *lv_name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The path of the device-mapper device for a particular LV.
|
* The path of the device-mapper device for a particular LV.
|
||||||
* eg, /dev/device-mapper/vg0:music
|
* eg, /dev/device-mapper/vg0:music
|
||||||
*/
|
*/
|
||||||
int build_dm_path(char *buffer, size_t len,
|
int build_dm_path(char *buffer, size_t len, const char *prefix,
|
||||||
const char *vg_name, const char *lv_name);
|
const char *vg_name, const char *lv_name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -72,7 +72,7 @@ void print_log(int level, const char *file, int line, const char *format, ...)
|
|||||||
#define log_err(x...) plog(_LOG_ERR, x)
|
#define log_err(x...) plog(_LOG_ERR, x)
|
||||||
#define log_fatal(x...) plog(_LOG_FATAL, x)
|
#define log_fatal(x...) plog(_LOG_FATAL, x)
|
||||||
|
|
||||||
#define stack log_debug( "s" ) /* Backtrace on error */
|
#define stack log_debug("<stack>") /* Backtrace on error */
|
||||||
|
|
||||||
#define log_error(fmt, args...) log_err(fmt , ## args)
|
#define log_error(fmt, args...) log_err(fmt , ## args)
|
||||||
#define log_print(fmt, args...) log_warn(fmt , ## args)
|
#define log_print(fmt, args...) log_warn(fmt , ## args)
|
||||||
|
Loading…
Reference in New Issue
Block a user