From 99c941fc856f34931f2eadb63b0e539a0f037d1e Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Mon, 28 Nov 2005 21:00:37 +0000 Subject: [PATCH] Allow signed mirrors arguments. Move create_mirror_log() into toollib. --- tools/args.h | 2 +- tools/lvcreate.c | 72 ++++++++++-------------------------------------- tools/lvresize.c | 4 +++ tools/toollib.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++- tools/toollib.h | 6 ++++ 5 files changed, 95 insertions(+), 60 deletions(-) diff --git a/tools/args.h b/tools/args.h index 80b5b9a3d..17dc59fb5 100644 --- a/tools/args.h +++ b/tools/args.h @@ -85,7 +85,7 @@ arg(size_ARG, 'L', "size", size_mb_arg) arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign) arg(persistent_ARG, 'M', "persistent", yes_no_arg) arg(major_ARG, 'j', "major", major_arg) -arg(mirrors_ARG, 'm', "mirrors", int_arg) +arg(mirrors_ARG, 'm', "mirrors", int_arg_with_sign) arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_arg) arg(maps_ARG, 'm', "maps", NULL) arg(name_ARG, 'n', "name", string_arg) diff --git a/tools/lvcreate.c b/tools/lvcreate.c index 0f56ea359..afd9eb5a6 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -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. * @@ -291,6 +291,10 @@ static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd, lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1; if (lp->mirrors == 1) log_print("Redundant mirrors argument: default is 0"); + if (arg_sign_value(cmd, mirrors_ARG, 0) == SIGN_MINUS) { + log_error("Mirrors argument may not be negative"); + return 0; + } } if (lp->snapshot) { @@ -432,9 +436,8 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) const char *tag; int consistent = 1; struct alloc_handle *ah = NULL; - char *log_name, lv_name_buf[128]; + char lv_name_buf[128]; const char *lv_name; - size_t len; status |= lp->permission | VISIBLE_LV; @@ -584,27 +587,8 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) } if (lp->mirrors > 1) { - lp->region_size = adjusted_mirror_region_size(vg->extent_size, - lp->extents, - lp->region_size); - /* FIXME Calculate how many extents needed for the log */ - len = strlen(lv_name) + 32; - if (!(log_name = alloca(len)) || - !(generate_log_name_format(vg, lv_name, log_name, len))) { - log_error("log_name allocation failed. " - "Remove new LV and retry."); - return 0; - } - - if (!(log_lv = lv_create_empty(vg->fid, log_name, NULL, - VISIBLE_LV | LVM_READ | LVM_WRITE, - lp->alloc, 0, vg))) { - stack; - return 0; - } - if (!(ah = allocate_extents(vg, NULL, lp->segtype, lp->stripes, lp->mirrors, 1, lp->extents, NULL, 0, 0, pvh, lp->alloc, @@ -613,43 +597,15 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) return 0; } - if (!lv_add_log_segment(ah, log_lv)) { - stack; - goto error; + lp->region_size = adjusted_mirror_region_size(vg->extent_size, + lp->extents, + lp->region_size); + + if (!(log_lv = create_mirror_log(cmd, vg, ah, lp->alloc, + lv_name))) { + log_error("Failed to create mirror log."); + return 0; } - - /* store mirror log on disk(s) */ - if (!vg_write(vg)) { - stack; - goto error; - } - - backup(vg); - - if (!vg_commit(vg)) { - stack; - goto error; - } - - if (!activate_lv(cmd, log_lv)) { - log_error("Aborting. Failed to activate mirror log. " - "Remove new LVs and retry."); - goto error; - } - - if (activation() && !zero_lv(cmd, log_lv)) { - log_error("Aborting. Failed to wipe mirror log. " - "Remove new LV and retry."); - goto error; - } - - if (!deactivate_lv(cmd, log_lv)) { - log_error("Aborting. Failed to deactivate mirror log. " - "Remove new LV and retry."); - goto error; - } - - log_lv->status &= ~VISIBLE_LV; } if (!(lv = lv_create_empty(vg->fid, lv_name ? lv_name : "lvol%d", NULL, diff --git a/tools/lvresize.c b/tools/lvresize.c index 9469254f5..ce5f821a9 100644 --- a/tools/lvresize.c +++ b/tools/lvresize.c @@ -168,6 +168,10 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp) lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 1) + 1; else log_print("Mirrors not supported. Ignoring."); + if (arg_sign_value(cmd, mirrors_ARG, 0) == SIGN_MINUS) { + log_error("Mirrors argument may not be negative"); + return 0; + } } if (arg_count(cmd, stripesize_ARG)) { diff --git a/tools/toollib.c b/tools/toollib.c index aa15cd43b..f4a11554b 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -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. * @@ -14,6 +14,7 @@ */ #include "tools.h" +#include "lv_alloc.h" #include #include @@ -1074,3 +1075,71 @@ int zero_lv(struct cmd_context *cmd, struct logical_volume *lv) return 1; } +struct logical_volume *create_mirror_log(struct cmd_context *cmd, + struct volume_group *vg, + struct alloc_handle *ah, + alloc_policy_t alloc, + const char *lv_name) +{ + struct logical_volume *log_lv; + char *log_name; + size_t len; + + len = strlen(lv_name) + 32; + if (!(log_name = alloca(len)) || + !(generate_log_name_format(vg, lv_name, log_name, len))) { + log_error("log_name allocation failed. " + "Remove new LV and retry."); + return NULL; + } + + if (!(log_lv = lv_create_empty(vg->fid, log_name, NULL, + VISIBLE_LV | LVM_READ | LVM_WRITE, + alloc, 0, vg))) { + stack; + return NULL; + } + + if (!lv_add_log_segment(ah, log_lv)) { + stack; + goto error; + } + + /* store mirror log on disk(s) */ + if (!vg_write(vg)) { + stack; + goto error; + } + + backup(vg); + + if (!vg_commit(vg)) { + stack; + goto error; + } + + if (!activate_lv(cmd, log_lv)) { + log_error("Aborting. Failed to activate mirror log. " + "Remove new LVs and retry."); + goto error; + } + + if (activation() && !zero_lv(cmd, log_lv)) { + log_error("Aborting. Failed to wipe mirror log. " + "Remove new LV and retry."); + goto error; + } + + if (!deactivate_lv(cmd, log_lv)) { + log_error("Aborting. Failed to deactivate mirror log. " + "Remove new LV and retry."); + goto error; + } + + log_lv->status &= ~VISIBLE_LV; + + return log_lv; +error: + /* FIXME Attempt to clean up. */ + return NULL; +} diff --git a/tools/toollib.h b/tools/toollib.h index 9e8b3f339..9e58d7d2a 100644 --- a/tools/toollib.h +++ b/tools/toollib.h @@ -93,6 +93,12 @@ int validate_vg_name(struct cmd_context *cmd, const char *vg_name); int generate_log_name_format(struct volume_group *vg, const char *lv_name, char *buffer, size_t size); +struct logical_volume *create_mirror_log(struct cmd_context *cmd, + struct volume_group *vg, + struct alloc_handle *ah, + alloc_policy_t alloc, + const char *lv_name); + int zero_lv(struct cmd_context *cmd, struct logical_volume *lv); #endif