From d9bc7ffe61693a471482dc32fa7407d7d1e240f6 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Thu, 15 Nov 2001 17:27:45 +0000 Subject: [PATCH] lvrename (without reactivation) --- lib/activate/fs.c | 10 ++-- lib/device/device.h | 4 -- lib/display/display.c | 2 +- tools/Makefile.in | 1 + tools/lvrename.c | 131 ++++++++++++++++++++++++++++++++++++++++++ tools/stub.h | 1 - tools/toollib.c | 4 +- tools/vgcreate.c | 2 +- tools/vgrename.c | 16 +++--- 9 files changed, 149 insertions(+), 22 deletions(-) create mode 100644 tools/lvrename.c diff --git a/lib/activate/fs.c b/lib/activate/fs.c index 610f068e3..e376f11b6 100644 --- a/lib/activate/fs.c +++ b/lib/activate/fs.c @@ -23,7 +23,7 @@ * This should run through /proc/mounts once only, * storing devfs mount points in a hash table. */ -static int _check_devfs(const char *dev_prefix) +static int _check_devfs(const char *dev_dir) { int r = 0, len; char dir[PATH_MAX], line[512]; @@ -33,9 +33,9 @@ static int _check_devfs(const char *dev_prefix) if (!(mounts = fopen("/proc/mounts", "r"))) goto out; - /* trim the trailing slash off the dir prefix, yuck */ - len = strlen(dev_prefix) - 1; - while(len && dev_prefix[len] == '/') + /* trim the trailing slash off dev_dir, yuck */ + len = strlen(dev_dir) - 1; + while(len && dev_dir[len] == '/') len--; while (!feof(mounts)) { @@ -43,7 +43,7 @@ static int _check_devfs(const char *dev_prefix) if (sscanf(line, "%*s %s %s %*s", dir, type) != 2) continue; - if (!strcmp(type, "devfs") && !strncmp(dir, dev_prefix, len)) { + if (!strcmp(type, "devfs") && !strncmp(dir, dev_dir, len)) { r = 1; break; } diff --git a/lib/device/device.h b/lib/device/device.h index 263a55d74..4a3338663 100644 --- a/lib/device/device.h +++ b/lib/device/device.h @@ -46,9 +46,5 @@ static inline int is_lvm_partition(const char *name) { return 1; } -#define LVM_DEFAULT_DIR_PREFIX "/dev/" -/* FIXME Allow config file override */ -static inline char *lvm_dir_prefix(void) { return LVM_DEFAULT_DIR_PREFIX; } - #endif diff --git a/lib/display/display.c b/lib/display/display.c index 43cf85a8f..42f4dfa0b 100644 --- a/lib/display/display.c +++ b/lib/display/display.c @@ -229,7 +229,7 @@ void lvdisplay_full(struct logical_volume *lv) log_print("--- Logical volume ---"); - /* FIXME prefix */ + /* FIXME Add dev_dir */ log_print("LV Name %s/%s", lv->vg->name, lv->name); log_print("VG Name %s", lv->vg->name); diff --git a/tools/Makefile.in b/tools/Makefile.in index f6b884040..0fd3bc3d0 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -29,6 +29,7 @@ SOURCES=\ lvmchange.c \ lvreduce.c \ lvremove.c \ + lvrename.c \ lvresize.c \ lvscan.c \ pvchange.c \ diff --git a/tools/lvrename.c b/tools/lvrename.c new file mode 100644 index 000000000..336e9c32d --- /dev/null +++ b/tools/lvrename.c @@ -0,0 +1,131 @@ +/* + * 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" + +int lvrename(int argc, char **argv) +{ + int maxlen; + char *lv_name_old, *lv_name_new; + char *vg_name, *vg_name_new; + char *st; + + struct volume_group *vg; + struct logical_volume *lv; + struct list *lvh; + + if (argc != 2) { + log_error("Old and new logical volume required"); + return EINVALID_CMD_LINE; + } + + lv_name_old = argv[0]; + lv_name_new = argv[1]; + + if (!(vg_name = extract_vgname(fid, lv_name_old))) { + log_error("Please provide a volume group name"); + return EINVALID_CMD_LINE; + } + + if (strchr(lv_name_new, '/') && + (vg_name_new = extract_vgname(fid, lv_name_new)) && + strcmp(vg_name, vg_name_new)) { + log_error("Logical volume names must " + "have the same volume group (%s or %s)", + vg_name, vg_name_new); + return EINVALID_CMD_LINE; + } + + if ((st = strrchr(lv_name_old, '/'))) + lv_name_old = st + 1; + + if ((st = strrchr(lv_name_new, '/'))) + lv_name_new = st + 1; + + /* Check sanity of new name */ + maxlen = NAME_LEN - strlen(vg_name) - strlen(fid->cmd->dev_dir) - 3; + if (strlen(lv_name_new) > maxlen) { + log_error("New logical volume path exceeds maximum length " + "of %d!", maxlen); + return ECMD_FAILED; + } + + if (!*lv_name_new) { + log_error("New logical volume name may not be blank"); + return ECMD_FAILED; + } + + if (!is_valid_chars(lv_name_new)) { + log_error("New logical volume name %s has invalid characters", + lv_name_new); + return EINVALID_CMD_LINE; + } + + if (!strcmp(lv_name_old, lv_name_new)) { + log_error("Old and new logical volume names must differ"); + return EINVALID_CMD_LINE; + } + + log_verbose("Checking for existing volume group %s", vg_name); + if (!(vg = fid->ops->vg_read(fid, vg_name))) { + log_error("Volume group %s doesn't exist", vg_name); + return ECMD_FAILED; + } + + if (!(vg->status & ACTIVE)) { + log_error("Volume group %s must be active before changing a " + "logical volume", vg_name); + return ECMD_FAILED; + } + + if ((lvh = find_lv_in_vg(vg, lv_name_new))) { + log_error("Logical volume %s already exists in " + "volume group %s", lv_name_new, vg_name); + return ECMD_FAILED; + } + + if (!(lvh = find_lv_in_vg(vg, lv_name_old))) { + log_error("Existing logical volume %s not found in " + "volume group %s", lv_name_old, vg_name); + return ECMD_FAILED; + } + + lv = &list_item(lvh, struct lv_list)->lv; + + if (!(lv->name = pool_strdup(fid->cmd->mem, lv_name_new))) { + log_error("Failed to allocate space for new name"); + return ECMD_FAILED; + } + + /* store it on disks */ + log_verbose("Writing out updated volume group"); + if (!(fid->ops->vg_write(fid, vg))) { + return ECMD_FAILED; + } + + /* FIXME Update symlink. lv_reactivate? */ + + /* FIXME backup */ + + log_print("Renamed %s to %s in volume group %s%s", + lv_name_old, lv_name_new, fid->cmd->dev_dir, vg_name); + + return 0; +} diff --git a/tools/stub.h b/tools/stub.h index d60eaa744..38713bd9a 100644 --- a/tools/stub.h +++ b/tools/stub.h @@ -22,7 +22,6 @@ int e2fsadm(int argc, char **argv) {return 1;} 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 lvrename(int argc, char **argv) {return 1;} int pvdata(int argc, char **argv) {return 1;} int vgcfgbackup(int argc, char **argv) {return 1;} int vgcfgrestore(int argc, char **argv) {return 1;} diff --git a/tools/toollib.c b/tools/toollib.c index 0b87f9bb2..3b2f829ae 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -262,7 +262,7 @@ char *extract_vgname(struct format_instance *fi, char *lv_name) /* Path supplied? */ if (vg_name && strchr(vg_name, '/')) { - /* Strip prefix (optional) */ + /* Strip dev_dir (optional) */ if (!strncmp(vg_name, dev_dir, strlen(dev_dir))) vg_name += strlen(dev_dir); @@ -304,7 +304,7 @@ char *default_vgname(struct format_instance *fi) if (!vg_path) return 0; - /* Strip prefix (optional) */ + /* Strip dev_dir (optional) */ if (!strncmp(vg_path, dev_dir, strlen(dev_dir))) vg_path += strlen(dev_dir); diff --git a/tools/vgcreate.c b/tools/vgcreate.c index 2b6d5c9ee..1fa2c0f58 100644 --- a/tools/vgcreate.c +++ b/tools/vgcreate.c @@ -61,7 +61,7 @@ int vgcreate(int argc, char **argv) return EINVALID_CMD_LINE; } - /* Strip prefix if present */ + /* Strip dev_dir if present */ if (!strncmp(vg_name, fid->cmd->dev_dir, strlen(fid->cmd->dev_dir))) vg_name += strlen(fid->cmd->dev_dir); diff --git a/tools/vgrename.c b/tools/vgrename.c index 37af8b0a2..b700a8d34 100644 --- a/tools/vgrename.c +++ b/tools/vgrename.c @@ -22,7 +22,7 @@ int vgrename(int argc, char **argv) { - char *prefix; + char *dev_dir; int length; char *vg_name_old, *vg_name_new; @@ -40,13 +40,13 @@ int vgrename(int argc, char **argv) vg_name_old = argv[0]; vg_name_new = argv[1]; - prefix = fid->cmd->dev_dir; - length = strlen(prefix); + dev_dir = fid->cmd->dev_dir; + length = strlen(dev_dir); - /* If present, strip prefix */ - if (!strncmp(vg_name_old, prefix, length)) + /* If present, strip dev_dir */ + if (!strncmp(vg_name_old, dev_dir, length)) vg_name_old += length; - if (!strncmp(vg_name_new, prefix, length)) + if (!strncmp(vg_name_new, dev_dir, length)) vg_name_new += length; /* Check sanity of new name */ @@ -102,8 +102,8 @@ int vgrename(int argc, char **argv) return ECMD_FAILED; *************/ - sprintf(old_path, "%s%s", prefix, vg_name_old); - sprintf(new_path, "%s%s", prefix, vg_name_new); + sprintf(old_path, "%s%s", dev_dir, vg_name_old); + sprintf(new_path, "%s%s", dev_dir, vg_name_new); log_verbose("Renaming %s to %s", old_path, new_path); if (rename(old_path, new_path)) {