1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Replacement activation code. [Don't use this yet!]

This commit is contained in:
Alasdair Kergon 2005-11-08 22:52:26 +00:00
parent 165e4a112b
commit 5f4b2acfe5
18 changed files with 696 additions and 2038 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -284,10 +284,8 @@ static int _target_present(const char *target_name)
struct dm_versions *target, *last_target;
log_very_verbose("Getting target version for %s", target_name);
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) {
stack;
return 0;
}
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
return_0;
if (!dm_task_run(dmt)) {
log_debug("Failed to get %s target version", target_name);
@ -314,7 +312,7 @@ static int _target_present(const char *target_name)
return r;
}
int target_present(const char *target_name)
int target_present(const char *target_name, int use_modprobe)
{
#ifdef MODPROBE_CMD
char module[128];
@ -324,17 +322,19 @@ int target_present(const char *target_name)
return 0;
#ifdef MODPROBE_CMD
if (_target_present(target_name))
return 1;
if (use_modprobe) {
if (_target_present(target_name))
return 1;
if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
log_error("target_present module name too long: %s", target_name);
return 0;
}
if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name)
< 0) {
log_error("target_present module name too long: %s",
target_name);
return 0;
}
if (!exec_cmd(MODPROBE_CMD, module, "", "")) {
stack;
return 0;
if (!exec_cmd(MODPROBE_CMD, module, "", ""))
return_0;
}
#endif
@ -353,17 +353,14 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, in
if (!activation())
return 0;
if (!(name = build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL))) {
stack;
return 0;
}
if (!(name = build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL)))
return_0;
log_debug("Getting device info for %s", name);
if (!dev_manager_info(lv->vg->cmd->mem, name, lv, with_mknodes,
with_open_count, &dminfo)) {
dm_pool_free(cmd->mem, name);
stack;
return 0;
return_0;
}
info->exists = dminfo.exists;
@ -372,6 +369,8 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, in
info->major = dminfo.major;
info->minor = dminfo.minor;
info->read_only = dminfo.read_only;
info->live_table = dminfo.live_table;
info->inactive_table = dminfo.inactive_table;
dm_pool_free(cmd->mem, name);
return 1;
@ -405,10 +404,8 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
if (!activation())
return 0;
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
stack;
return 0;
}
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
return_0;
if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
stack;
@ -429,18 +426,14 @@ int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv, int wa
if (!activation())
return 0;
if (!lv_info(cmd, lv, &info, 0)) {
stack;
return 0;
}
if (!lv_info(cmd, lv, &info, 0))
return_0;
if (!info.exists)
return 0;
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
stack;
return 0;
}
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
return_0;
if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
stack;
@ -474,16 +467,13 @@ static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
return info.open_count;
}
/* FIXME Need to detect and handle an lv rename */
static int _lv_activate_lv(struct logical_volume *lv)
{
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
stack;
return 0;
}
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
return_0;
if (!(r = dev_manager_activate(dm, lv)))
stack;
@ -492,15 +482,28 @@ static int _lv_activate_lv(struct logical_volume *lv)
return r;
}
static int _lv_preload(struct logical_volume *lv)
{
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
return_0;
if (!(r = dev_manager_preload(dm, lv)))
stack;
dev_manager_destroy(dm);
return r;
}
static int _lv_deactivate(struct logical_volume *lv)
{
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
stack;
return 0;
}
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
return_0;
if (!(r = dev_manager_deactivate(dm, lv)))
stack;
@ -514,10 +517,8 @@ static int _lv_suspend_lv(struct logical_volume *lv)
int r;
struct dev_manager *dm;
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name))) {
stack;
return 0;
}
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
return_0;
if (!(r = dev_manager_suspend(dm, lv)))
stack;
@ -580,14 +581,20 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
return 1;
}
if (!lv_info(cmd, lv, &info, 0)) {
stack;
return 0;
}
if (!lv_info(cmd, lv, &info, 0))
return_0;
if (!info.exists || info.suspended)
return error_if_not_suspended ? 0 : 1;
/* If VG was precommitted, preload devices for the LV */
if ((lv->vg->status & PRECOMMITTED)) {
if (!_lv_preload(lv)) {
/* FIXME Revert preloading */
return_0;
}
}
memlock_inc();
if (!_lv_suspend_lv(lv)) {
memlock_dec();
@ -626,10 +633,8 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
return 1;
}
if (!lv_info(cmd, lv, &info, 0)) {
stack;
return 0;
}
if (!lv_info(cmd, lv, &info, 0))
return_0;
if (!info.exists || !info.suspended)
return error_if_not_active ? 0 : 1;
@ -671,16 +676,14 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
return 1;
}
if (!lv_info(cmd, lv, &info, 1)) {
stack;
return 0;
}
if (!lv_info(cmd, lv, &info, 1))
return_0;
if (!info.exists)
return 1;
if (info.open_count && (lv->status & VISIBLE_LV)) {
log_error("LV %s/%s in use: not removing", lv->vg->name,
log_error("LV %s/%s in use: not deactivating", lv->vg->name,
lv->name);
return 0;
}
@ -741,12 +744,10 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
return 1;
}
if (!lv_info(cmd, lv, &info, 0)) {
stack;
return 0;
}
if (!lv_info(cmd, lv, &info, 0))
return_0;
if (info.exists && !info.suspended)
if (info.exists && !info.suspended && info.live_table)
return 1;
if (exclusive)
@ -783,10 +784,8 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
return r;
}
if (!_lv_info(cmd, lv, 1, &info, 0)) {
stack;
return 0;
}
if (!_lv_info(cmd, lv, 1, &info, 0))
return_0;
if (info.exists)
r = dev_manager_lv_mknodes(lv);

View File

@ -25,6 +25,8 @@ struct lvinfo {
int major;
int minor;
int read_only;
int live_table;
int inactive_table;
};
void set_activation(int activation);
@ -34,7 +36,7 @@ int driver_version(char *version, size_t size);
int library_version(char *version, size_t size);
int lvm1_present(struct cmd_context *cmd);
int target_present(const char *target_name);
int target_present(const char *target_name, int use_modprobe);
void activation_exit(void);

File diff suppressed because it is too large Load Diff

View File

@ -47,6 +47,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
float *percent, uint32_t *event_nr);
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_lv_mknodes(const struct logical_volume *lv);

View File

@ -23,6 +23,9 @@ int compose_areas_line(struct dev_manager *dm, struct lv_segment *seg,
char *params, size_t paramsize, int *pos,
int start_area, int areas);
int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
struct deptree_node *node, int start_area, int areas);
int build_dev_string(struct dev_manager *dm, char *dlid, char *devbuf,
size_t bufsize, const char *desc);

View File

@ -38,18 +38,13 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
}
#ifdef DEVMAPPER_SUPPORT
static int _compose_target_line(struct dev_manager *dm, struct dm_pool *mem,
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg, char *params,
size_t paramsize, const char **target, int *pos,
struct lv_segment *seg,
struct deptree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count)
{
/* error */
*target = "error";
*params = '\0';
return 1;
return dm_deptree_node_add_error_target(node, len);
}
static int _target_present(void)
@ -57,8 +52,10 @@ static int _target_present(void)
static int checked = 0;
static int present = 0;
if (!checked)
present = target_present("error");
/* Reported truncated in older kernels */
if (!checked &&
(target_present("error", 0) || target_present("erro", 0)))
present = 1;
checked = 1;
return present;
@ -74,7 +71,7 @@ static struct segtype_handler _error_ops = {
name:_name,
merge_segments:_merge_segments,
#ifdef DEVMAPPER_SUPPORT
compose_target_line:_compose_target_line,
add_target_line:_add_target_line,
target_present:_target_present,
#endif
destroy:_destroy,
@ -84,16 +81,14 @@ struct segment_type *init_error_segtype(struct cmd_context *cmd)
{
struct segment_type *segtype = dm_malloc(sizeof(*segtype));
if (!segtype) {
stack;
return NULL;
}
if (!segtype)
return_NULL;
segtype->cmd = cmd;
segtype->ops = &_error_ops;
segtype->name = "error";
segtype->private = NULL;
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL;
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
log_very_verbose("Initialised segtype: %s", segtype->name);

View File

@ -124,4 +124,8 @@ void print_log(int level, const char *file, int line, const char *format, ...)
#define log_sys_debug(x, y) \
log_debug("%s: %s failed: %s", y, x, strerror(errno))
#define return_0 do { stack; return 0; } while (0)
#define return_NULL do { stack; return NULL; } while (0)
#define goto_out do { stack; goto out; } while (0)
#endif

View File

@ -204,10 +204,8 @@ int create_mirror_layers(struct alloc_handle *ah,
MIRROR_IMAGE);
/* Already got a non-mirrored area to be converted? */
if (!first_area) {
if (first_area)
_move_lv_segments(img_lvs[0], lv);
lv->status |= MIRRORED;
}
if (!lv_add_mirror_segment(ah, lv, img_lvs, num_mirrors, segtype,
0, region_size, log_lv)) {
@ -216,6 +214,8 @@ int create_mirror_layers(struct alloc_handle *ah,
return 0;
}
lv->status |= MIRRORED;
return 1;
}

View File

@ -31,12 +31,14 @@ struct dev_manager;
#define SEG_SNAPSHOT 0x00000008
#define SEG_FORMAT1_SUPPORT 0x00000010
#define SEG_VIRTUAL 0x00000020
#define SEG_CANNOT_BE_ZEROED 0x00000040
#define seg_is_mirrored(seg) ((seg)->segtype->flags & SEG_AREAS_MIRRORED ? 1 : 0)
#define seg_is_striped(seg) ((seg)->segtype->flags & SEG_AREAS_STRIPED ? 1 : 0)
#define seg_is_snapshot(seg) ((seg)->segtype->flags & SEG_SNAPSHOT ? 1 : 0)
#define seg_is_virtual(seg) ((seg)->segtype->flags & SEG_VIRTUAL ? 1 : 0)
#define seg_can_split(seg) ((seg)->segtype->flags & SEG_CAN_SPLIT ? 1 : 0)
#define seg_cannot_be_zeroed(seg) ((seg)->segtype->flags & SEG_CANNOT_BE_ZEROED ? 1 : 0)
#define segtype_is_striped(segtype) ((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0)
#define segtype_is_mirrored(segtype) ((segtype)->flags & SEG_AREAS_MIRRORED ? 1 : 0)
@ -64,12 +66,11 @@ struct segtype_handler {
struct dm_hash_table * pv_hash);
int (*merge_segments) (struct lv_segment * seg1,
struct lv_segment * seg2);
int (*compose_target_line) (struct dev_manager * dm, struct dm_pool * mem,
struct config_tree * cft,
void **target_state,
struct lv_segment * seg, char *params,
size_t paramsize, const char **target,
int *pos, uint32_t *pvmove_mirror_count);
int (*add_target_line) (struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct deptree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count);
int (*target_percent) (void **target_state, struct dm_pool * mem,
struct config_tree * cft,
struct lv_segment * seg, char *params,

View File

@ -165,118 +165,6 @@ static struct mirror_state *_init_target(struct dm_pool *mem,
return mirr_state;
}
static int _compose_log_line(struct dev_manager *dm, struct lv_segment *seg,
char *params, size_t paramsize, int *pos,
int areas, uint32_t region_size)
{
int tw;
char devbuf[10];
const char *clustered = "";
char *dlid;
/*
* Use clustered mirror log for non-exclusive activation
* in clustered VG.
*/
if ((!(seg->lv->status & ACTIVATE_EXCL) &&
(seg->lv->vg->status & CLUSTERED)))
clustered = "cluster ";
if (!seg->log_lv)
tw = lvm_snprintf(params, paramsize, "%score 1 %u %u ",
clustered, region_size, areas);
else {
if (!(dlid = build_dlid(dm, seg->log_lv->lvid.s, NULL))) {
stack;
return 0;
}
if (!build_dev_string(dm, dlid, devbuf,
sizeof(devbuf), "log")) {
stack;
return 0;
}
/* FIXME add sync parm? */
tw = lvm_snprintf(params, paramsize, "%sdisk 2 %s %u %u ",
clustered, devbuf, region_size, areas);
}
if (tw < 0) {
stack;
return -1;
}
*pos += tw;
return 1;
}
static int _compose_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg, char *params,
size_t paramsize, const char **target, int *pos,
uint32_t *pvmove_mirror_count)
{
struct mirror_state *mirr_state;
int mirror_status = MIRR_RUNNING;
int areas = seg->area_count;
int start_area = 0u;
uint32_t region_size, region_max;
int ret;
if (!*target_state)
*target_state = _init_target(mem, cft);
mirr_state = *target_state;
/* mirror log_type #log_params [log_params]*
* #mirrors [device offset]+
*/
if (seg->status & PVMOVE) {
if (seg->extents_copied == seg->area_len) {
mirror_status = MIRR_COMPLETED;
start_area = 1;
} else if ((*pvmove_mirror_count)++) {
mirror_status = MIRR_DISABLED;
areas = 1;
}
}
if (mirror_status != MIRR_RUNNING) {
*target = "linear";
} else {
*target = "mirror";
if (!(seg->status & PVMOVE)) {
if (!seg->region_size) {
log_error("Missing region size for mirror segment.");
return 0;
}
region_size = seg->region_size;
} else {
/* Find largest power of 2 region size unit we can use */
region_max = (1 << (ffs(seg->area_len) - 1)) *
seg->lv->vg->extent_size;
region_size = mirr_state->default_region_size;
if (region_max < region_size) {
region_size = region_max;
log_verbose("Using reduced mirror region size of %u sectors",
region_size);
}
}
if ((ret = _compose_log_line(dm, seg, params, paramsize, pos,
areas, region_size)) <= 0) {
stack;
return ret;
}
}
return compose_areas_line(dm, seg, params, paramsize, pos, start_area,
areas);
}
static int _target_percent(void **target_state, struct dm_pool *mem,
struct config_tree *cft, struct lv_segment *seg,
char *params, uint64_t *total_numerator,
@ -328,13 +216,109 @@ static int _target_percent(void **target_state, struct dm_pool *mem,
return 1;
}
static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
struct deptree_node *node, uint32_t area_count, uint32_t region_size)
{
unsigned clustered = 0;
char *log_dlid = NULL;
/*
* Use clustered mirror log for non-exclusive activation
* in clustered VG.
*/
if ((!(seg->lv->status & ACTIVATE_EXCL) &&
(seg->lv->vg->status & CLUSTERED)))
clustered = 1;
if (seg->log_lv &&
!(log_dlid = build_dlid(dm, seg->log_lv->lvid.s, NULL))) {
log_error("Failed to build uuid for log LV %s.",
seg->log_lv->name);
return 0;
}
/* FIXME Add sync parm? */
return dm_deptree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count);
}
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct deptree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count)
{
struct mirror_state *mirr_state;
uint32_t area_count = seg->area_count;
int start_area = 0u;
int mirror_status = MIRR_RUNNING;
uint32_t region_size, region_max;
int r;
if (!*target_state)
*target_state = _init_target(mem, cft);
mirr_state = *target_state;
/*
* For pvmove, only have one mirror segment RUNNING at once.
* Segments before this are COMPLETED and use 2nd area.
* Segments after this are DISABLED and use 1st area.
*/
if (seg->status & PVMOVE) {
if (seg->extents_copied == seg->area_len) {
mirror_status = MIRR_COMPLETED;
start_area = 1;
} else if ((*pvmove_mirror_count)++) {
mirror_status = MIRR_DISABLED;
area_count = 1;
}
/* else MIRR_RUNNING */
}
if (mirror_status != MIRR_RUNNING) {
if (!dm_deptree_node_add_linear_target(node, len))
return_0;
goto done;
}
if (!(seg->status & PVMOVE)) {
if (!seg->region_size) {
log_error("Missing region size for mirror segment.");
return 0;
}
region_size = seg->region_size;
} else {
/* Find largest power of 2 region size unit we can use */
region_max = (1 << (ffs(seg->area_len) - 1)) *
seg->lv->vg->extent_size;
region_size = mirr_state->default_region_size;
if (region_max < region_size) {
region_size = region_max;
log_verbose("Using reduced mirror region size of %u sectors",
region_size);
}
}
if (!dm_deptree_node_add_mirror_target(node, len))
return_0;
if ((r = _add_log(dm, seg, node, area_count, region_size)) <= 0) {
stack;
return r;
}
done:
return add_areas_line(dm, seg, node, start_area, seg->area_count);
}
static int _target_present(void)
{
static int checked = 0;
static int present = 0;
if (!checked)
present = target_present("mirror");
present = target_present("mirror", 1);
checked = 1;
@ -354,7 +338,7 @@ static struct segtype_handler _mirrored_ops = {
text_import:_text_import,
text_export:_text_export,
#ifdef DEVMAPPER_SUPPORT
compose_target_line:_compose_target_line,
add_target_line:_add_target_line,
target_percent:_target_percent,
target_present:_target_present,
#endif

View File

@ -130,15 +130,15 @@ static void _quote_hyphens(char **out, const char *src)
/*
* <vg>-<lv>-<layer> or if !layer just <vg>-<lv>.
*/
char *build_dm_name(struct dm_pool *mem, const char *vg,
const char *lv, const char *layer)
char *build_dm_name(struct dm_pool *mem, const char *vgname,
const char *lvname, const char *layer)
{
size_t len = 1;
int hyphens = 1;
char *r, *out;
_count_hyphens(vg, &len, &hyphens);
_count_hyphens(lv, &len, &hyphens);
_count_hyphens(vgname, &len, &hyphens);
_count_hyphens(lvname, &len, &hyphens);
if (layer && *layer) {
_count_hyphens(layer, &len, &hyphens);
@ -148,14 +148,15 @@ char *build_dm_name(struct dm_pool *mem, const char *vg,
len += hyphens;
if (!(r = dm_pool_alloc(mem, len))) {
stack;
log_error("build_dm_name: Allocation failed for %" PRIsize_t
" for %s %s %s.", len, vgname, lvname, layer);
return NULL;
}
out = r;
_quote_hyphens(&out, vg);
_quote_hyphens(&out, vgname);
*out++ = '-';
_quote_hyphens(&out, lv);
_quote_hyphens(&out, lvname);
if (layer && *layer) {
*out++ = '-';
@ -174,6 +175,7 @@ static char *_unquote(char *component)
{
char *c = component;
char *o = c;
char *r;
while (*c) {
if (*(c + 1)) {
@ -189,8 +191,10 @@ static char *_unquote(char *component)
c++;
}
r = (*c) ? c + 1 : c;
*o = '\0';
return (c + 1);
return r;
}
int split_dm_name(struct dm_pool *mem, const char *dmname,

View File

@ -369,24 +369,28 @@ static int _lvstatus_disp(struct report_handle *rh, struct field *field,
if (lv_info(lv->vg->cmd, lv, &info, 1) && info.exists) {
if (info.suspended)
repstr[4] = 's'; /* Suspended */
else
else if (info.live_table)
repstr[4] = 'a'; /* Active */
if (info.open_count)
repstr[5] = 'o'; /* Open */
else if (info.inactive_table)
repstr[4] = 'i'; /* Inactive with table */
else
repstr[5] = '-';
repstr[4] = 'd'; /* Inactive without table */
/* Snapshot dropped? */
if ((snap_seg = find_cow(lv)) &&
if (info.live_table && (snap_seg = find_cow(lv)) &&
(!lv_snapshot_percent(snap_seg->cow, &snap_percent) ||
snap_percent < 0 || snap_percent >= 100)) {
repstr[0] = toupper(repstr[0]);
if (info.suspended)
repstr[4] = 'S';
repstr[4] = 'S'; /* Susp Inv snapshot */
else
repstr[4] = 'I';
repstr[4] = 'I'; /* Invalid snapshot */
}
if (info.open_count)
repstr[5] = 'o'; /* Open */
else
repstr[5] = '-';
} else {
repstr[4] = '-';
repstr[5] = '-';

View File

@ -115,8 +115,8 @@ static int _target_present(void)
static int present = 0;
if (!checked)
present = target_present("snapshot") &&
target_present("snapshot-origin");
present = target_present("snapshot", 1) &&
target_present("snapshot-origin", 0);
checked = 1;

View File

@ -106,7 +106,8 @@ static int _segments_compatible(struct lv_segment *first,
unsigned s;
if ((first->area_count != second->area_count) ||
(first->stripe_size != second->stripe_size)) return 0;
(first->stripe_size != second->stripe_size))
return 0;
for (s = 0; s < first->area_count; s++) {
@ -150,32 +151,25 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
}
#ifdef DEVMAPPER_SUPPORT
static int _compose_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg, char *params,
size_t paramsize, const char **target, int *pos,
uint32_t *pvmove_mirror_count)
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct deptree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count)
{
/* linear [device offset]+
* striped #stripes stripe_size [device offset]+ */
if (seg->area_count == 1)
*target = "linear";
else if (seg->area_count > 1) {
*target = "striped";
if ((*pos = lvm_snprintf(params, paramsize, "%u %u ",
seg->area_count,
seg->stripe_size)) < 0) {
stack;
return -1;
}
} else {
log_error("Internal error: striped target with no stripes");
if (!seg->area_count) {
log_error("Internal error: striped add_target_line called "
"with no areas for %s.", seg->lv->name);
return 0;
}
if (seg->area_count == 1) {
if (!dm_deptree_node_add_linear_target(node, len))
return_0;
} else if (!dm_deptree_node_add_striped_target(node, len,
seg->stripe_size))
return_0;
return compose_areas_line(dm, seg, params, paramsize, pos, 0u,
seg->area_count);
return add_areas_line(dm, seg, node, 0u, seg->area_count);
}
static int _target_present(void)
@ -184,7 +178,8 @@ static int _target_present(void)
static int present = 0;
if (!checked)
present = target_present("linear") && target_present("striped");
present = target_present("linear", 0) &&
target_present("striped", 0);
checked = 1;
return present;
@ -204,7 +199,7 @@ static struct segtype_handler _striped_ops = {
text_export:_text_export,
merge_segments:_merge_segments,
#ifdef DEVMAPPER_SUPPORT
compose_target_line:_compose_target_line,
add_target_line:_add_target_line,
target_present:_target_present,
#endif
destroy:_destroy,

View File

@ -38,18 +38,13 @@ static int _merge_segments(struct lv_segment *seg1, struct lv_segment *seg2)
}
#ifdef DEVMAPPER_SUPPORT
static int _compose_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg, char *params,
size_t paramsize, const char **target, int *pos,
uint32_t *pvmove_mirror_count)
static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem,
struct config_tree *cft, void **target_state,
struct lv_segment *seg,
struct deptree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count)
{
/* zero */
*target = "zero";
*params = '\0';
return 1;
return dm_deptree_node_add_zero_target(node, len);
}
static int _target_present(void)
@ -58,7 +53,7 @@ static int _target_present(void)
static int present = 0;
if (!checked)
present = target_present("zero");
present = target_present("zero", 0);
checked = 1;
return present;
@ -74,7 +69,7 @@ static struct segtype_handler _zero_ops = {
name:_name,
merge_segments:_merge_segments,
#ifdef DEVMAPPER_SUPPORT
compose_target_line:_compose_target_line,
add_target_line:_add_target_line,
target_present:_target_present,
#endif
destroy:_destroy,
@ -93,7 +88,7 @@ struct segment_type *init_zero_segtype(struct cmd_context *cmd)
segtype->ops = &_zero_ops;
segtype->name = "zero";
segtype->private = NULL;
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL;
segtype->flags = SEG_CAN_SPLIT | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
log_very_verbose("Initialised segtype: %s", segtype->name);

View File

@ -55,7 +55,8 @@ changes, for example during \fBpvmove\fP (8).
.IP 4 3
fixed (m)inor
.IP 5 3
State: (a)ctive, (s)uspended, (I)nvalid snapshot, invalid (S)uspended snapshot
State: (a)ctive, (s)uspended, (I)nvalid snapshot, invalid (S)uspended snapshot,
mapped (d)evice present without tables, mapped device present with (i)nactive table
.IP 6 3
device (o)pen
.RE

View File

@ -359,7 +359,8 @@ static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd,
/*
* Should we zero the lv.
*/
lp->zero = strcmp(arg_str_value(cmd, zero_ARG, "y"), "n");
lp->zero = strcmp(arg_str_value(cmd, zero_ARG,
(lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? "n" : "y"), "n");
/*
* Alloc policy

View File

@ -20,6 +20,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
{
struct volume_group *vg;
struct lvinfo info;
struct logical_volume *origin = NULL;
vg = lv->vg;
@ -74,6 +75,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!archive(vg))
return ECMD_FAILED;
/* FIXME Snapshot commit out of sequence if it fails after here? */
if (!deactivate_lv(cmd, lv)) {
log_error("Unable to deactivate logical volume \"%s\"",
lv->name);
@ -81,6 +83,7 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
}
if (lv_is_cow(lv)) {
origin = find_cow(lv)->origin;
log_verbose("Removing snapshot %s", lv->name);
if (!vg_remove_snapshot(lv)) {
stack;
@ -103,6 +106,14 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!vg_commit(vg))
return ECMD_FAILED;
/* If no snapshots left, reload without -real. */
if (origin && !lv_is_origin(origin)) {
if (!suspend_lv(cmd, origin))
log_error("Failed to refresh %s without snapshot.", origin->name);
else if (!resume_lv(cmd, origin))
log_error("Failed to resume %s.", origin->name);
}
log_print("Logical volume \"%s\" successfully removed", lv->name);
return ECMD_PROCESSED;
}