From 677a06d5fdf48f820cbe66395586f1de43720001 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Mon, 8 Oct 2001 18:44:22 +0000 Subject: [PATCH] vgrename & vgck --- lib/Makefile.in | 1 + tools/Makefile.in | 8 +-- tools/commands.h | 5 +- tools/lvm.c | 34 ++++++++---- tools/stub.h | 10 +++- tools/toollib.c | 16 +++++- tools/toollib.h | 3 + tools/tools.h | 12 ++-- tools/vgck.c | 54 ++++++++++++++++++ tools/vgrename.c | 137 ++++++++++++++++++++++------------------------ 10 files changed, 180 insertions(+), 100 deletions(-) create mode 100644 tools/vgck.c diff --git a/lib/Makefile.in b/lib/Makefile.in index aeff92501..18cec750e 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -13,6 +13,7 @@ SOURCES=\ datastruct/hash.c \ device/dev-cache.c \ device/dev-io.c \ + filters/filter.c \ format1/disk-rep.c \ format1/format1.c \ log/log.c \ diff --git a/tools/Makefile.in b/tools/Makefile.in index ae0a1c2f0..74a69f8c4 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -23,12 +23,8 @@ VPATH = @srcdir@ SOURCES=\ lvm.c\ lvmchange.c\ - lvremove.c\ - pvcreate.c\ - pvchange.c\ - pvdisplay.c\ - pvscan.c\ - vgcreate.c\ + toollib.c\ + vgck.c\ vgrename.c TARGETS=\ diff --git a/tools/commands.h b/tools/commands.h index 17450ad43..b77ce2e3c 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -37,6 +37,7 @@ xx(help, "Display help for commands", "help \n") +/********* xx(lvactivate, "Activate logical volume on given partition(s)", "lvactivate " @@ -44,6 +45,7 @@ xx(lvactivate, "\t[-h/-?/--help]\n" "\t[-v/--verbose]\n" "Logical Volume(s)\n") +***********/ xx(lvchange, "Change the attributes of logical volume(s)", @@ -454,12 +456,13 @@ xx(vgrename, "vgrename\n" "\t[-A/--autobackup y/n]\n" "\t[-d/--debug]\n" + "\t[-f/--force]\n" "\t[-h/-?/--help]\n" "\t[-v/--verbose]\n" "\tOldVolumeGroupPath NewVolumeGroupPath /\n" "\tOldVolumeGroupName NewVolumeGroupName\n", - autobackup_ARG) + autobackup_ARG, force_ARG) xx(vgscan, "Search for all volume groups", diff --git a/tools/lvm.c b/tools/lvm.c index 49f9ed889..064163e3d 100644 --- a/tools/lvm.c +++ b/tools/lvm.c @@ -57,8 +57,10 @@ static int _array_size; static int _num_commands; static struct command *_commands; +/* Exported */ +struct io_space *ios; + static struct dev_filter *_filter; -static struct io_space *_ios; static struct config_file *_cf; static int _interactive; @@ -483,7 +485,7 @@ static void display_help() log_error("Available lvm commands:"); log_error("Use 'lvm help ' for more information"); - log_error(""); + log_error(" "); for (i = 0; i < _num_commands; i++) { struct command *com = _commands + i; @@ -554,11 +556,6 @@ struct dev_filter *active_filter(void) return _filter; } -struct io_space *active_ios(void) -{ - return _ios; -} - static void __init_log(struct config_file *cf) { const char *log_file = find_config_str(cf->root, "log/file", '/', 0); @@ -580,6 +577,10 @@ static int init(void) int ret = 0; const char *e = getenv("LVM_CONFIG_FILE"); struct stat info; + struct pool *ios_pool; + + /* FIXME: Override from config file */ + char *prefix = "/dev/"; if (!(_cf = create_config_file())) { stack; @@ -603,16 +604,27 @@ static int init(void) __init_log(_cf); } - if ((dev_cache_init)) { + if (!dev_cache_init()) { stack; goto out; } - if (!(_filter = config_filter_create(_cf->root))) { + if (!dev_cache_add_dir(prefix)) { + log_error("Failed to add %s to internal device cache", prefix); goto out; } - if (!(_ios = create_lvm_v1_format(_filter))) { + if (!(_filter = config_filter_create())) { + /* Add scan & rejects from _cf->root */ + goto out; + } + + if (!(ios_pool = pool_create(4 * 1024))) { + log_error("ios pool creation failed"); + goto out; + } + + if (!(ios = create_lvm1_format(prefix, ios_pool, _filter))) { goto out; } @@ -634,7 +646,7 @@ static void __fin_commands(void) static void fin(void) { - _ios->destroy(_ios); + ios->destroy(ios); config_filter_destroy(_filter); dev_cache_exit(); destroy_config_file(_cf); diff --git a/tools/stub.h b/tools/stub.h index 06d980ef6..10539fcc4 100644 --- a/tools/stub.h +++ b/tools/stub.h @@ -27,13 +27,18 @@ int lvmdiskscan(int argc, char **argv) {return 1;} int lvmsadc(int argc, char **argv) {return 1;} int lvmsar(int argc, char **argv) {return 1;} int lvreduce(int argc, char **argv) {return 1;} +int lvremove(int argc, char **argv) {return 1;} int lvrename(int argc, char **argv) {return 1;} int lvscan(int argc, char **argv) {return 1;} +int pvcreate(int argc, char **argv) {return 1;} +int pvchange(int argc, char **argv) {return 1;} +int pvdisplay(int argc, char **argv) {return 1;} int pvdata(int argc, char **argv) {return 1;} +int pvscan(int argc, char **argv) {return 1;} int vgcfgbackup(int argc, char **argv) {return 1;} -int vgcfgrestore(int argc, char **argv) {return 1;} int vgchange(int argc, char **argv) {return 1;} -int vgck(int argc, char **argv) {return 1;} +int vgcreate(int argc, char **argv) {return 1;} +int vgcfgrestore(int argc, char **argv) {return 1;} int vgdisplay(int argc, char **argv) {return 1;} int vgexport(int argc, char **argv) {return 1;} int vgextend(int argc, char **argv) {return 1;} @@ -44,5 +49,4 @@ int vgreduce(int argc, char **argv) {return 1;} int vgremove(int argc, char **argv) {return 1;} int vgscan(int argc, char **argv) {return 1;} int vgsplit(int argc, char **argv) {return 1;} -int init_autobackup() {return 0;} diff --git a/tools/toollib.c b/tools/toollib.c index c3ef0f3d3..b5c2d917f 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -20,6 +20,8 @@ #include "tools.h" +#include + static int _autobackup = 1; int autobackup_set() @@ -92,12 +94,9 @@ int process_each_vg(int argc, char **argv, int ret_max = 0; int ret = 0; - struct io_space *ios; struct list_head *vgh; struct name_list *vgs_list; - ios = active_ios(); - if (argc) { log_verbose("Using volume group(s) on command line"); for (; opt < argc; opt++) @@ -120,3 +119,14 @@ int process_each_vg(int argc, char **argv, return ret_max; } + +int is_valid_chars(char *n) +{ + register char c; + while ((c = *n++)) + if (!isalnum(c) && c != '.' && c != '_' && c != '-' && + c != '+') + return 0; + return 1; +} + diff --git a/tools/toollib.h b/tools/toollib.h index 3cb417fec..ed5421d3b 100644 --- a/tools/toollib.h +++ b/tools/toollib.h @@ -27,4 +27,7 @@ int do_autobackup(struct volume_group *vg); int process_each_vg(int argc, char **argv, int (*process_single) (const char *vg_name)); + +int is_valid_chars(char *n); + #endif diff --git a/tools/tools.h b/tools/tools.h index cccc210ad..91dcaa079 100644 --- a/tools/tools.h +++ b/tools/tools.h @@ -27,6 +27,10 @@ #include #include +#include "pool.h" +#include "dbg_malloc.h" +#include "list.h" +#include "log.h" #include "metadata.h" #include "config.h" #include "dev-cache.h" @@ -34,9 +38,7 @@ #include "display.h" #include "errors.h" #include "filter.h" -#include "list.h" -#include "log.h" -#include "dbg_malloc.h" +#include "format1.h" #include "toollib.h" #define CMD_LEN 256 @@ -105,5 +107,7 @@ static inline int arg_count_increment(int a) struct config_file *active_config_file(void); struct dev_filter *active_filter(void); -struct io_space *active_ios(void); + +extern struct io_space *ios; + #endif diff --git a/tools/vgck.c b/tools/vgck.c new file mode 100644 index 000000000..86cee39e6 --- /dev/null +++ b/tools/vgck.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2001 Sistina Software + * + * LVM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * LVM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LVM; see the file COPYING. If not, write to + * the Free Software Foundation, 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "tools.h" + +static int vgck_single(const char *vg_name); + +int vgck(int argc, char **argv) +{ + return process_each_vg(argc, argv, &vgck_single); +} + +static int vgck_single(const char *vg_name) +{ + struct volume_group *vg; + + log_verbose("Checking volume group %s", vg_name); + + if (!(vg = ios->vg_read(ios, vg_name))) { + log_error("Volume group %s not found", vg_name); + return ECMD_FAILED; + } + + if (vg->status & EXPORTED_VG) { + log_error("Volume group %s is exported", vg_name); + return ECMD_FAILED; + } + +/******* FIXME Must be caught and logged by vg_read + log_error("not all physical volumes of volume group %s online", + log_error("volume group %s has physical volumes with invalid version", +********/ + + /* FIXME: free */ + return 0; +} + diff --git a/tools/vgrename.c b/tools/vgrename.c index 1e0a6eba0..3924737b4 100644 --- a/tools/vgrename.c +++ b/tools/vgrename.c @@ -20,138 +20,131 @@ #include "tools.h" -char *lv_change_vgname(char *vg_name, char *lv_name); - int vgrename(int argc, char **argv) { - int l = 0; - int length = 0; - int p = 0; - - int ret = 0; - char *lv_name_ptr; - char *vg_name_old; - char *vg_name_new; - char vg_name_old_buf[NAME_LEN] = { 0, }; - char vg_name_new_buf[NAME_LEN] = { 0, }; char *prefix; + int length; + + char *vg_name_old, *vg_name_new; + + char old_path[NAME_LEN], new_path[NAME_LEN]; - struct io_space *ios; struct volume_group *vg_old, *vg_new; + struct list_head *pvh; if (argc != 2) { - log_error("command line too short"); + log_error("old and new volume group names need specifying"); return EINVALID_CMD_LINE; } - ios = active_ios(); + vg_name_old = argv[0]; + vg_name_new = argv[1]; - prefix = lvm_dir_prefix(); + prefix = ios->prefix; length = strlen(prefix); - vg_name_old = argv[0]; + /* If present, strip prefix */ + if (!strncmp(vg_name_old, prefix, length)) + vg_name_old += length; + if (!strncmp(vg_name_new, prefix, length)) + vg_name_new += length; - if (strlen(vg_name_new = argv[1]) > NAME_LEN - length - 2) { - log_error("New logical volume path exceeds maximum length " + /* Check sanity of new name */ + if (strlen(vg_name_new) > NAME_LEN - length - 2) { + log_error("New volume group path exceeds maximum length " "of %d!", NAME_LEN - length - 2); return ECMD_FAILED; } - if (vg_check_name(vg_name_new) < 0) { - return EINVALID_CMD_LINE; - } - - /* FIXME Handle prefix-related logic internally within ios functions? */ - if (strncmp(vg_name_old, prefix, length) != 0) { - sprintf(vg_name_old_buf, "%s%s", prefix, vg_name_old); - vg_name_old = vg_name_old_buf; - } - if (strncmp(vg_name_new, prefix, length) != 0) { - sprintf(vg_name_new_buf, "%s%s", prefix, vg_name_new); - vg_name_new = vg_name_new_buf; - } - - if (strcmp(vg_name_old, vg_name_new) == 0) { - log_error("volume group names must be different"); + if (!is_valid_chars(vg_name_new)) { + log_error("New volume group name %s has invalid characters", + vg_name_new); return ECMD_FAILED; } - log_verbose("Checking existing volume group %s", vg_name_old); + if (!strcmp(vg_name_old, vg_name_new)) { + log_error("Old and new volume group names must differ"); + return ECMD_FAILED; + } + + log_verbose("Checking for existing volume group %s", vg_name_old); if (!(vg_old = ios->vg_read(ios, vg_name_old))) { - log_error("volume group %s doesn't exist", vg_name_old); + log_error("Volume group %s doesn't exist", vg_name_old); return ECMD_FAILED; } + if (vg_old->status & ACTIVE) { log_error("Volume group %s still active", vg_name_old); + if (!force_ARG) { + log_error("Use -f to force the rename"); + return ECMD_FAILED; + } } - log_verbose("Checking new volume group %s", vg_name_new); + log_verbose("Checking for new volume group %s", vg_name_new); if ((vg_new = ios->vg_read(ios, vg_name_new))) { log_error("New volume group %s already exists", vg_name_new); return ECMD_FAILED; } - /* change the volume name in all structures */ + /* Change the volume group name */ strcpy(vg_old->name, vg_name_new); - /* FIXME: Are these necessary? Or can vg_write fix these implicitly? */ - for (p = 0; p < vg_old->pv_count; p++) - if (vg_old->pv[p]) - strcpy(vg_old->pv[p]->vg_name, vg_name_new); + /* FIXME Should vg_write fix these implicitly? It has to check them. */ + list_for_each(pvh, &vg_old->pvs) { + strcpy(list_entry(pvh, struct pv_list, list)->pv.vg_name, + vg_name_new); + } - for (l = 0; l < vg_old->lv_count; l++) { - if (vg_old->lv[l] && - !(lv_name_ptr = - lv_change_vgname(vg_name_new, vg_old->lv[l]->name))) { +/********** FIXME: Check within vg_write now log_error("A new logical volume path exceeds " "maximum of %d!", NAME_LEN - 2); return ECMD_FAILED; - } - strcpy(vg_old->lv[l]->name, lv_name_ptr); - } +*************/ - if (vg_remove_dir_and_group_and_nodes(vg_name_old) < 0) { - log_error("removing volume group nodes and directory of \"%s\"", - vg_name_old); + sprintf(old_path, "%s%s", prefix, vg_name_old); + sprintf(new_path, "%s%s", prefix, vg_name_new); + + log_verbose("Renaming %s to %s", old_path, new_path); + if (!(rename(old_path, new_path))) { + log_error("Renaming %s to %s failed: %s", + old_path, new_path, strerror(errno)); return ECMD_FAILED; } /* store it on disks */ - log_verbose("updating volume group name"); + log_verbose("Writing out updated volume group"); if (ios->vg_write(ios, vg_old)) { return ECMD_FAILED; } - log_verbose("creating volume group directory %s%s", prefix, - vg_name_new); - if (vg_create_dir_and_group_and_nodes(vg_old)) { - return ECMD_FAILED; - } - +/*********** if ((ret = do_autobackup(vg_name_new, vg_old))) return ECMD_FAILED; +**********/ log_print("Volume group %s successfully renamed to %s", vg_name_old, vg_name_new); - return 0; + /* FIXME: Deallocations */ -/* FIXME: Deallocations */ + return 0; } -/* FIXME: Move this out */ - +/* FIXME: Moved into vg_write now */ +/******************* char *lv_change_vgname(char *vg_name, char *lv_name) { char *lv_name_ptr = NULL; static char lv_name_buf[NAME_LEN] = { 0, }; - /* check if lv_name includes a path */ + ** check if lv_name includes a path if ((lv_name_ptr = strrchr(lv_name, '/'))) { - lv_name_ptr++; - sprintf(lv_name_buf, "%s%s/%s%c", lvm_dir_prefix(), vg_name, - lv_name_ptr, 0); - } else - strncpy(lv_name_buf, lv_name, NAME_LEN - 1); - return lv_name_buf; -} + lv_name_ptr++; + sprintf(lv_name_buf, "%s%s/%s%c", ios->prefix, vg_name, + lv_name_ptr, 0);} + else + strncpy(lv_name_buf, lv_name, NAME_LEN - 1); return lv_name_buf;} + +**********************/ +