summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2002-02-11 15:42:34 +0000
committerAlasdair Kergon <agk@redhat.com>2002-02-11 15:42:34 +0000
commit7d0e6e800e41fd13a5dc51ef05de8298b30b7432 (patch)
tree51be3b97d6a751fed2fc643ce52dac6ad91f50ec /tools
parent713599407cc26d5e60889e828b923ed06f156ca0 (diff)
downloadlvm2-7d0e6e800e41fd13a5dc51ef05de8298b30b7432.tar.gz
lvm2-7d0e6e800e41fd13a5dc51ef05de8298b30b7432.tar.xz
lvm2-7d0e6e800e41fd13a5dc51ef05de8298b30b7432.zip
o Support locking with local lock files
o Disable control-c during updates (except if blocked waiting for a lock)
Diffstat (limited to 'tools')
-rw-r--r--tools/lvcreate.c50
-rw-r--r--tools/lvm.c11
-rw-r--r--tools/lvrename.c32
-rw-r--r--tools/lvresize.c53
-rw-r--r--tools/pvchange.c16
-rw-r--r--tools/toollib.c63
-rw-r--r--tools/toollib.h6
-rw-r--r--tools/tools.h2
-rw-r--r--tools/vgcfgbackup.c2
-rw-r--r--tools/vgchange.c5
-rw-r--r--tools/vgck.c2
-rw-r--r--tools/vgcreate.c29
-rw-r--r--tools/vgdisplay.c2
-rw-r--r--tools/vgexport.c17
-rw-r--r--tools/vgextend.c33
-rw-r--r--tools/vgimport.c15
-rw-r--r--tools/vgmerge.c42
-rw-r--r--tools/vgreduce.c16
-rw-r--r--tools/vgremove.c14
-rw-r--r--tools/vgrename.c49
-rw-r--r--tools/vgscan.c3
21 files changed, 316 insertions, 146 deletions
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 979130fb..14608d48 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -118,25 +118,31 @@ int lvcreate(int argc, char **argv)
/* does VG exist? */
log_verbose("Finding volume group \"%s\"", vg_name);
+
+ if (!lock_vol(vg_name, LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for %s", vg_name);
+ return ECMD_FAILED;
+ }
+
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group \"%s\" doesn't exist", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (!(vg->status & LVM_WRITE)) {
log_error("Volume group \"%s\" is read-only", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (lv_name && find_lv_in_vg(vg, lv_name)) {
log_error("Logical volume \"%s\" already exists in "
"volume group \"%s\"", lv_name, vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (!argc)
@@ -147,27 +153,27 @@ int lvcreate(int argc, char **argv)
if (!(pvh = create_pv_list(fid->cmd->mem, vg,
argc - opt, argv + opt))) {
stack;
- return ECMD_FAILED;
+ goto error;
}
}
if (argc && argc < stripes ) {
log_error("Too few physical volumes on "
"command line for %d-way striping", stripes);
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
}
if (stripes < 1 || stripes > MAX_STRIPES) {
log_error("Number of stripes (%d) must be between %d and %d",
stripes, 1, MAX_STRIPES);
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
}
if (stripes > 1 && (stripesize < STRIPE_SIZE_MIN ||
stripesize > STRIPE_SIZE_MAX ||
stripesize & (stripesize - 1))) {
log_error("Invalid stripe size %d", stripesize);
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
}
if (stripesize > vg->extent_size) {
@@ -201,12 +207,12 @@ int lvcreate(int argc, char **argv)
}
if (!archive(vg))
- return ECMD_FAILED;
+ goto error;
if (!(lv = lv_create(fid, lv_name, status,
stripes, stripesize, extents,
vg, pvh)))
- return ECMD_FAILED;
+ goto error;
if (arg_count(readahead_ARG)) {
log_verbose("Setting read ahead sectors");
@@ -226,21 +232,21 @@ int lvcreate(int argc, char **argv)
if (!arg_count(minor_ARG)) {
log_error("Please specify minor number with "
"--minor when using -My");
- return ECMD_FAILED;
+ goto error;
}
lv->status |= FIXED_MINOR;
}
/* store vg on disk(s) */
if (!fid->ops->vg_write(fid, vg))
- return ECMD_FAILED;
+ goto error;
backup(vg);
log_print("Logical volume \"%s\" created", lv->name);
if (!lv_activate(lv))
- return ECMD_FAILED;
+ goto error;
if (zero) {
struct device *dev;
@@ -248,29 +254,39 @@ int lvcreate(int argc, char **argv)
if (!(name = pool_alloc(fid->cmd->mem, PATH_MAX))) {
log_error("Name allocation failed - device not zeroed");
- return ECMD_FAILED;
+ goto error;
}
if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", fid->cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Name too long - device not zeroed (%s)",
lv->name);
- return ECMD_FAILED;
+ goto error;
}
log_verbose("Zeroing start of logical volume \"%s\"", name);
if (!(dev = dev_cache_get(name, NULL))) {
log_error("\"%s\" not found: device not zeroed", name);
- return ECMD_FAILED;
+ goto error;
}
if (!(dev_open(dev, O_WRONLY)))
- return ECMD_FAILED;
+ goto error;
dev_zero(dev, 0, 4096);
dev_close(dev);
} else
log_print("WARNING: \"%s\" not zeroed", lv->name);
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+
return 0;
+
+ error:
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ return ECMD_FAILED;
+
+ error_cmdline:
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ return EINVALID_CMD_LINE;
}
diff --git a/tools/lvm.c b/tools/lvm.c
index c2f6f70f..a77db806 100644
--- a/tools/lvm.c
+++ b/tools/lvm.c
@@ -720,6 +720,7 @@ static char *_copy_command_line(struct pool *mem, int argc, char **argv)
static int run_command(int argc, char **argv)
{
int ret = 0;
+ int locking_type;
if (!(cmd->cmd_line = _copy_command_line(cmd->mem, argc, argv)))
return ECMD_FAILED;
@@ -739,8 +740,18 @@ static int run_command(int argc, char **argv)
_use_settings(&_current_settings);
+ locking_type = find_config_int(cmd->cf->root, "global/locking_type",
+ '/', 1);
+ if (!init_locking(locking_type, cmd->cf)) {
+ log_error("Locking type %d initialisation failed.",
+ locking_type);
+ return 0;
+ }
+
ret = the_command->fn(argc, argv);
+ fin_locking();
+
/*
* set the debug and verbose levels back
* to the global default. We have to do
diff --git a/tools/lvrename.c b/tools/lvrename.c
index 37a22f49..ed56ee1e 100644
--- a/tools/lvrename.c
+++ b/tools/lvrename.c
@@ -85,57 +85,63 @@ int lvrename(int argc, char **argv)
}
log_verbose("Checking for existing volume group \"%s\"", vg_name);
+
+ if (!lock_vol(vg_name, LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for %s", vg_name);
+ return ECMD_FAILED;
+ }
+
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group \"%s\" doesn't exist", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name);
- return ECMD_FAILED;
+ goto error;
}
if (!(vg->status & LVM_WRITE)) {
log_error("Volume group \"%s\" is read-only", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (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;
+ goto error;
}
if (!(lvl = 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;
+ goto error;
}
lv = lvl->lv;
if (!archive(lv->vg))
- return ECMD_FAILED;
+ goto error;
if ((active = lv_active(lv)) < 0) {
log_error("Unable to determine status of \"%s\"", lv->name);
- return ECMD_FAILED;
+ goto error;
}
if (active && !lv_suspend(lv)) {
log_error("Failed to suspend \"%s\"", lv->name);
- return ECMD_FAILED;
+ goto error;
}
if (!(lv->name = pool_strdup(fid->cmd->mem, lv_name_new))) {
log_error("Failed to allocate space for new name");
- return ECMD_FAILED;
+ goto error;
}
/* store it on disks */
log_verbose("Writing out updated volume group");
if (!(fid->ops->vg_write(fid, vg))) {
- return ECMD_FAILED;
+ goto error;
}
if (active) {
@@ -145,8 +151,14 @@ int lvrename(int argc, char **argv)
backup(lv->vg);
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+
log_print("Renamed \"%s\" to \"%s\" in volume group \"%s\"",
lv_name_old, lv_name_new, vg_name);
return 0;
+
+ error:
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ return ECMD_FAILED;
}
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 17aa1659..16439251 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -105,26 +105,31 @@ int lvresize(int argc, char **argv)
/* does VG exist? */
log_verbose("Finding volume group %s", vg_name);
+ if (!lock_vol(vg_name, LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for %s", vg_name);
+ return ECMD_FAILED;
+ }
+
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group %s doesn't exist", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group %s is exported", vg->name);
- return ECMD_FAILED;
+ goto error;
}
if (!(vg->status & LVM_WRITE)) {
log_error("Volume group %s is read-only", vg_name);
- return ECMD_FAILED;
+ goto error;
}
/* does LV exist? */
if (!(lvl = find_lv_in_vg(vg, lv_name))) {
log_error("Logical volume %s not found in volume group %s",
lv_name, vg_name);
- return ECMD_FAILED;
+ goto error;
}
lv = lvl->lv;
@@ -157,7 +162,7 @@ int lvresize(int argc, char **argv)
if (extents >= lv->le_count) {
log_error("Unable to reduce %s below 1 extent",
lv_name);
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
}
extents = lv->le_count - extents;
@@ -165,13 +170,13 @@ int lvresize(int argc, char **argv)
if (!extents) {
log_error("New size of 0 not permitted");
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
}
if (extents == lv->le_count) {
log_error("New size (%d extents) matches existing size "
"(%d extents)", extents, lv->le_count);
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
}
/* If extending, find stripes, stripesize & size of last segment */
@@ -190,7 +195,7 @@ int lvresize(int argc, char **argv)
(seg_stripes && seg_stripes != str && !stripes)) {
log_error("Please specify number of "
"stripes (-i) and stripesize (-I)");
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
}
seg_stripesize = sz;
@@ -245,7 +250,7 @@ int lvresize(int argc, char **argv)
if (extents == lv->le_count) {
log_error("New size (%d extents) matches existing size "
"(%d extents)", extents, lv->le_count);
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
}
if (extents < lv->le_count) {
@@ -253,7 +258,7 @@ int lvresize(int argc, char **argv)
log_error("New size given (%d extents) not larger "
"than existing size (%d extents)",
extents, lv->le_count);
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
} else
resize = LV_REDUCE;
}
@@ -263,7 +268,7 @@ int lvresize(int argc, char **argv)
log_error("New size given (%d extents) not less than "
"existing size (%d extents)", extents,
lv->le_count);
- return EINVALID_CMD_LINE;
+ goto error_cmdline;
} else
resize = LV_EXTEND;
}
@@ -290,27 +295,27 @@ int lvresize(int argc, char **argv)
" [y/n]: ", lv_name) == 'n') {
log_print("Logical volume %s NOT reduced",
lv_name);
- return ECMD_FAILED;
+ goto error;
}
}
if (!archive(vg))
- return ECMD_FAILED;
+ goto error;
if (!lv_reduce(fid, lv, lv->le_count - extents))
- return ECMD_FAILED;
+ goto error;
}
if ((resize == LV_EXTEND && argc) &&
!(pvh = create_pv_list(fid->cmd->mem, vg,
argc - opt, argv + opt))) {
stack;
- return ECMD_FAILED;
+ goto error;
}
if (resize == LV_EXTEND) {
if (!archive(vg))
- return ECMD_FAILED;
+ goto error;
if (!argc) {
/* Use full list from VG */
@@ -322,7 +327,7 @@ int lvresize(int argc, char **argv)
if (!lv_extend(fid, lv, stripes, stripesize,
extents - lv->le_count, pvh))
- return ECMD_FAILED;
+ goto error;
}
@@ -332,16 +337,26 @@ int lvresize(int argc, char **argv)
/* store vg on disk(s) */
if (!fid->ops->vg_write(fid, vg))
- return ECMD_FAILED;
+ goto error;
backup(vg);
if (active && !lv_reactivate(lv))
- return ECMD_FAILED;
+ goto error;
/********* FIXME Resume *********/
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+
log_print("Logical volume %s successfully resized", lv_name);
return 0;
+
+ error:
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ return ECMD_FAILED;
+
+ error_cmdline:
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ return EINVALID_CMD_LINE;
}
diff --git a/tools/pvchange.c b/tools/pvchange.c
index d6d3ac09..371cddbb 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -94,23 +94,33 @@ int pvchange_single(struct physical_volume *pv)
if (*pv->vg_name) {
log_verbose("Finding volume group of physical volume \"%s\"",
pv_name);
+
+ if (!lock_vol(pv->vg_name, LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for %s", pv->vg_name);
+ return ECMD_FAILED;
+ }
+
if (!(vg = fid->ops->vg_read(fid, pv->vg_name))) {
+ lock_vol(pv->vg_name, LCK_VG | LCK_NONE);
log_error("Unable to find volume group of \"%s\"",
pv_name);
return 0;
}
if (vg->status & EXPORTED_VG) {
+ lock_vol(pv->vg_name, LCK_VG | LCK_NONE);
log_error("Volume group \"%s\" is exported", vg->name);
return ECMD_FAILED;
}
if (!(vg->status & LVM_WRITE)) {
+ lock_vol(pv->vg_name, LCK_VG | LCK_NONE);
log_error("Volume group \"%s\" is read-only", vg->name);
return ECMD_FAILED;
}
if (!(pvl = find_pv_in_vg(vg, pv_name))) {
+ lock_vol(pv->vg_name, LCK_VG | LCK_NONE);
log_error("Unable to find \"%s\" in volume group \"%s\"",
pv_name, vg->name);
return 0;
@@ -123,12 +133,16 @@ int pvchange_single(struct physical_volume *pv)
/* change allocatability for a PV */
if (allocatable && (pv->status & ALLOCATABLE_PV)) {
log_error("Physical volume \"%s\" is already allocatable", pv_name);
+ if (*pv->vg_name)
+ lock_vol(pv->vg_name, LCK_VG | LCK_NONE);
return 0;
}
if (!allocatable && !(pv->status & ALLOCATABLE_PV)) {
log_error("Physical volume \"%s\" is already unallocatable",
pv_name);
+ if (*pv->vg_name)
+ lock_vol(pv->vg_name, LCK_VG | LCK_NONE);
return 0;
}
@@ -144,11 +158,13 @@ int pvchange_single(struct physical_volume *pv)
log_verbose("Updating physical volume \"%s\"", pv_name);
if (*pv->vg_name) {
if (!(fid->ops->vg_write(fid,vg))) {
+ lock_vol(pv->vg_name, LCK_VG | LCK_NONE);
log_error("Failed to store physical volume \"%s\" in "
"volume group \"%s\"", pv_name, vg->name);
return 0;
}
backup(vg);
+ lock_vol(pv->vg_name, LCK_VG | LCK_NONE);
} else {
if (!(fid->ops->pv_write(fid, pv))) {
log_error("Failed to store physical volume \"%s\"",
diff --git a/tools/toollib.c b/tools/toollib.c
index 95dbff74..4a466a00 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -8,43 +8,6 @@
#include <sys/stat.h>
-int dir_exists(const char *dir)
-{
- struct stat info;
-
- if (!*dir)
- return 1;
-
- if (stat(dir, &info) != -1) {
- log_error("\"%s\" exists", dir);
- return 0;
- }
-
- return 1;
-}
-
-int create_dir(const char *dir)
-{
- struct stat info;
-
- if (!*dir)
- return 1;
-
- if (stat(dir, &info) < 0) {
- log_verbose("Creating directory \"%s\"", dir);
- if (!mkdir(dir, 0777))
- return 1;
- log_sys_error("mkdir", dir);
- return 0;
- }
-
- if (S_ISDIR(info.st_mode))
- return 1;
-
- log_error("Directory \"%s\" not found", dir);
- return 0;
-}
-
int process_each_lv_in_vg(struct volume_group *vg,
int (*process_single) (struct logical_volume *lv))
{
@@ -151,7 +114,7 @@ int process_each_lv(int argc, char **argv,
return ret_max;
}
-int process_each_vg(int argc, char **argv,
+int process_each_vg(int argc, char **argv, int lock_type,
int (*process_single) (const char *vg_name))
{
int opt = 0;
@@ -161,11 +124,20 @@ int process_each_vg(int argc, char **argv,
struct list *vgh;
struct list *vgs;
+ char *vg_name;
+
if (argc) {
log_verbose("Using volume group(s) on command line");
- for (; opt < argc; opt++)
- if ((ret = process_single(argv[opt])) > ret_max)
+ for (; opt < argc; opt++) {
+ vg_name = argv[opt];
+ if (!lock_vol((void *)vg_name, LCK_VG | lock_type)) {
+ log_error("Can't lock %s: skipping", vg_name);
+ continue;
+ }
+ if ((ret = process_single(vg_name)) > ret_max)
ret_max = ret;
+ lock_vol((void *)vg_name, LCK_VG | LCK_NONE);
+ }
} else {
log_verbose("Finding all volume groups");
if (!(vgs = fid->ops->get_vgs(fid))) {
@@ -173,11 +145,16 @@ int process_each_vg(int argc, char **argv,
return ECMD_FAILED;
}
list_iterate(vgh, vgs) {
- ret =
- process_single(list_item
- (vgh, struct name_list)->name);
+ vg_name = list_item (vgh, struct name_list)->name;
+ if (!lock_vol((void *)vg_name, LCK_VG | lock_type)) {
+ log_error("Can't lock %s: skipping", vg_name);
+ continue;
+ }
+ ret = process_single(vg_name);
+
if (ret > ret_max)
ret_max = ret;
+ lock_vol((void *)vg_name, LCK_VG | LCK_NONE);
}
}
diff --git a/tools/toollib.h b/tools/toollib.h
index 98ca5e30..d43a0b9d 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -26,9 +26,7 @@ int autobackup_init(const char *backup_dir, int keep_days, int keep_number,
int autobackup);
int autobackup(struct volume_group *vg);
-int create_dir(const char *dir);
-
-int process_each_vg(int argc, char **argv,
+int process_each_vg(int argc, char **argv, int lock_type,
int (*process_single) (const char *vg_name));
int process_each_pv(int argc, char **argv, struct volume_group *vg,
@@ -45,8 +43,6 @@ int process_each_lv_in_vg(struct volume_group *vg,
int (*process_single) (struct logical_volume * lv));
int is_valid_chars(char *n);
-int dir_exists(const char *dir);
-
char *default_vgname(struct format_instance *fi);
char *extract_vgname(struct format_instance *fi, char *lv_name);
diff --git a/tools/tools.h b/tools/tools.h
index bebee43f..512b7fea 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -25,6 +25,7 @@
#include "list.h"
#include "log.h"
#include "lvm-string.h"
+#include "lvm-file.h"
#include "metadata.h"
#include "config.h"
#include "dev-cache.h"
@@ -41,6 +42,7 @@
#include "toollib.h"
#include "activate.h"
#include "archive.h"
+#include "locking.h"
#include <stdio.h>
#include <stdarg.h>
diff --git a/tools/vgcfgbackup.c b/tools/vgcfgbackup.c
index 17e37883..dbfcb63e 100644
--- a/tools/vgcfgbackup.c
+++ b/tools/vgcfgbackup.c
@@ -54,6 +54,6 @@ static int vg_backup_single(const char *vg_name)
int vgcfgbackup(int argc, char **argv)
{
- return process_each_vg(argc, argv, &vg_backup_single);
+ return process_each_vg(argc, argv, LCK_READ, &vg_backup_single);
}
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 711f5bcd..aac06152 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -44,7 +44,10 @@ int vgchange(int argc, char **argv)
return EINVALID_CMD_LINE;
}
- return process_each_vg(argc, argv, &vgchange_single);
+ return process_each_vg(argc, argv,
+ (arg_count(available_ARG)) ?
+ LCK_READ : LCK_WRITE,
+ &vgchange_single);
}
static int vgchange_single(const char *vg_name)
diff --git a/tools/vgck.c b/tools/vgck.c
index 26d0aeab..9d9343a5 100644
--- a/tools/vgck.c
+++ b/tools/vgck.c
@@ -24,7 +24,7 @@ static int vgck_single(const char *vg_name);
int vgck(int argc, char **argv)
{
- return process_each_vg(argc, argv, &vgck_single);
+ return process_each_vg(argc, argv, LCK_READ, &vgck_single);
}
static int vgck_single(const char *vg_name)
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 622cfb2d..1fdc12be 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -67,7 +67,10 @@ int vgcreate(int argc, char **argv)
vg_name += strlen(fid->cmd->dev_dir);
snprintf(vg_path, PATH_MAX, "%s%s", fid->cmd->dev_dir, vg_name);
- if (!dir_exists(vg_path)) return ECMD_FAILED;
+ if (path_exists(vg_path)) {
+ log_error("%s: already exists in filesystem", vg_path);
+ return ECMD_FAILED;
+ }
if (!is_valid_chars(vg_name)) {
log_error("New volume group name \"%s\" has invalid characters",
@@ -88,12 +91,32 @@ int vgcreate(int argc, char **argv)
log_error("Warning: Setting maxphysicalvolumes to %d",
vg->max_pv);
- if (!archive(vg))
+ if (!lock_vol("", LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for orphan PVs");
+ return ECMD_FAILED;
+ }
+
+ if (!lock_vol(vg_name, LCK_VG | LCK_WRITE | LCK_NONBLOCK)) {
+ log_error("Can't get lock for %s", vg_name);
+ lock_vol("", LCK_VG | LCK_NONE);
+ return ECMD_FAILED;
+ }
+
+ if (!archive(vg)) {
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ lock_vol("", LCK_VG | LCK_NONE);
return ECMD_FAILED;
+ }
/* Store VG on disk(s) */
- if (!fid->ops->vg_write(fid, vg))
+ if (!fid->ops->vg_write(fid, vg)) {
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ lock_vol("", LCK_VG | LCK_NONE);
return ECMD_FAILED;
+ }
+
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ lock_vol("", LCK_VG | LCK_NONE);
backup(vg);
diff --git a/tools/vgdisplay.c b/tools/vgdisplay.c
index 57e4e54c..c096d40c 100644
--- a/tools/vgdisplay.c
+++ b/tools/vgdisplay.c
@@ -45,7 +45,7 @@ int vgdisplay(int argc, char **argv)
}
**********/
- process_each_vg(argc, argv, &vgdisplay_single);
+ process_each_vg(argc, argv, LCK_READ, &vgdisplay_single);
/******** FIXME Need to count number processed
Add this to process_each_vg if arg_count(activevolumegroups_ARG) ?
diff --git a/tools/vgexport.c b/tools/vgexport.c
index e74db3c8..05fdb781 100644
--- a/tools/vgexport.c
+++ b/tools/vgexport.c
@@ -34,7 +34,7 @@ int vgexport(int argc, char **argv)
return ECMD_FAILED;
}
- return process_each_vg(argc, argv, &vgexport_single);
+ return process_each_vg(argc, argv, LCK_READ, &vgexport_single);
}
static int vgexport_single(const char *vg_name)
@@ -43,36 +43,39 @@ static int vgexport_single(const char *vg_name)
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Unable to find volume group \"%s\"", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is already exported", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (!(vg->status & LVM_WRITE)) {
log_error("Volume group \"%s\" is read-only", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (lvs_in_vg_activated(vg)) {
log_error("Volume group \"%s\" has active logical volumes",
vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (!archive(vg))
- return ECMD_FAILED;
+ goto error;
vg->status |= EXPORTED_VG;
if (!fid->ops->vg_write(fid,vg))
- return ECMD_FAILED;
+ goto error;
backup(vg);
log_print("Volume group \"%s\" successfully exported", vg->name);
return 0;
+
+ error:
+ return ECMD_FAILED;
}
diff --git a/tools/vgextend.c b/tools/vgextend.c
index 6c51c27b..b51533bd 100644
--- a/tools/vgextend.c
+++ b/tools/vgextend.c
@@ -40,25 +40,36 @@ int vgextend(int argc, char **argv)
argc--;
argv++;
+ if (!lock_vol("", LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for orphan PVs");
+ return ECMD_FAILED;
+ }
+
log_verbose("Checking for volume group \"%s\"", vg_name);
+ if (!lock_vol(vg_name, LCK_VG | LCK_WRITE | LCK_NONBLOCK)) {
+ lock_vol("", LCK_VG | LCK_NONE);
+ log_error("Can't get lock for %s", vg_name);
+ goto error;
+ }
+
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group \"%s\" not found.", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name);
- return ECMD_FAILED;
+ goto error;
}
if (!(vg->status & LVM_WRITE)) {
log_error("Volume group \"%s\" is read-only", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (!(vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" is not resizeable.", vg_name);
- return ECMD_FAILED;
+ goto error;
}
/********** FIXME
@@ -69,11 +80,11 @@ int vgextend(int argc, char **argv)
**********/
if (!archive(vg))
- return ECMD_FAILED;
+ goto error;
/* extend vg */
if (!vg_extend(fid, vg, argc, argv))
- return ECMD_FAILED;
+ goto error;
/* ret > 0 */
log_verbose("Volume group \"%s\" will be extended by %d new "
@@ -81,11 +92,19 @@ int vgextend(int argc, char **argv)
/* store vg on disk(s) */
if (!fid->ops->vg_write(fid, vg))
- return ECMD_FAILED;
+ goto error;
backup(vg);
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ lock_vol("", LCK_VG | LCK_NONE);
+
log_print("Volume group \"%s\" successfully extended", vg_name);
return 0;
+
+ error:
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+ lock_vol("", LCK_VG | LCK_NONE);
+ return ECMD_FAILED;
}
diff --git a/tools/vgimport.c b/tools/vgimport.c
index 9163eda7..e30ab252 100644
--- a/tools/vgimport.c
+++ b/tools/vgimport.c
@@ -34,7 +34,7 @@ int vgimport(int argc, char **argv)
return ECMD_FAILED;
}
- return process_each_vg(argc, argv, &vgimport_single);
+ return process_each_vg(argc, argv, LCK_WRITE, &vgimport_single);
}
static int vgimport_single(const char *vg_name)
@@ -44,30 +44,33 @@ static int vgimport_single(const char *vg_name)
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Unable to find exported volume group \"%s\"",
vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (!(vg->status & EXPORTED_VG)) {
log_error("Volume group \"%s\" is not exported", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (vg->status & PARTIAL_VG) {
log_error("Volume group \"%s\" is partially missing", vg_name);
- return ECMD_FAILED;
+ goto error;
}
if (!archive(vg))
- return ECMD_FAILED;
+ goto error;
vg->status &= ~EXPORTED_VG;
if (!fid->ops->vg_write(fid,vg))
- return ECMD_FAILED;
+ goto error;
backup(vg);
log_print("Volume group \"%s\" successfully imported", vg->name);
return 0;
+
+ error:
+ return ECMD_FAILED;
}
diff --git a/tools/vgmerge.c b/tools/vgmerge.c
index eefa4f87..9c134f0e 100644
--- a/tools/vgmerge.c
+++ b/tools/vgmerge.c
@@ -58,41 +58,55 @@ int vgmerge_single(const char *vg_name_to, const char *vg_name_from)
}
log_verbose("Checking for volume group \"%s\"", vg_name_to);
+ if (!lock_vol(vg_name_to, LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for %s", vg_name_to);
+ return ECMD_FAILED;
+ }
+
if (!(vg_to = fid->ops->vg_read(fid, vg_name_to))) {
log_error("Volume group \"%s\" doesn't exist", vg_name_to);
+ lock_vol(vg_name_to, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
if (vg_to->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_to->name);
+ lock_vol(vg_name_to, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
if (!(vg_to->status & LVM_WRITE)) {
log_error("Volume group \"%s\" is read-only", vg_to->name);
+ lock_vol(vg_name_to, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
log_verbose("Checking for volume group \"%s\"", vg_name_from);
+ if (!lock_vol(vg_name_from, LCK_VG | LCK_WRITE | LCK_NONBLOCK)) {
+ log_error("Can't get lock for %s", vg_name_from);
+ lock_vol(vg_name_to, LCK_VG | LCK_NONE);
+ return ECMD_FAILED;
+ }
+
if (!(vg_from = fid->ops->vg_read(fid, vg_name_from))) {
log_error("Volume group \"%s\" doesn't exist", vg_name_from);
- return ECMD_FAILED;
+ goto error;
}
if (vg_from->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg_from->name);
- return ECMD_FAILED;
+ goto error;
}
if (!(vg_from->status & LVM_WRITE)) {
log_error("Volume group \"%s\" is read-only", vg_from->name);
- return ECMD_FAILED;
+ goto error;
}
if ((active = lvs_in_vg_activated(vg_from))) {
log_error("Logical volumes in \"%s\" must be inactive",
vg_name_from);
- return ECMD_FAILED;
+ goto error;
}
/* Check compatibility */
@@ -100,21 +114,21 @@ int vgmerge_single(const char *vg_name_to, const char *vg_name_from)
log_error("Extent sizes differ: %d (%s) and %d (%s)",
vg_to->extent_size, vg_to->name,
vg_from->extent_size, vg_from->name);
- return ECMD_FAILED;
+ goto error;
}
if (vg_to->max_pv < vg_to->pv_count + vg_from->pv_count) {
log_error("Maximum number of physical volumes (%d) exceeded "
" for \"%s\" and \"%s\"", vg_to->max_pv, vg_to->name,
vg_from->name);
- return ECMD_FAILED;
+ goto error;
}
if (vg_to->max_lv < vg_to->lv_count + vg_from->lv_count) {
log_error("Maximum number of logical volumes (%d) exceeded "
" for \"%s\" and \"%s\"", vg_to->max_lv, vg_to->name,
vg_from->name);
- return ECMD_FAILED;
+ goto error;
}
/* Check no conflicts with LV names */
@@ -131,7 +145,7 @@ int vgmerge_single(const char *vg_name_to, const char *vg_name_from)
"in \"%s\" and \"%s\"",
name1, vg_to->name,
vg_from->name);
- return ECMD_FAILED;
+ goto error;
}
}
}
@@ -139,7 +153,7 @@ int vgmerge_single(const char *vg_name_to, const char *vg_name_from)
/* FIXME List arg: vg_show_with_pv_and_lv(vg_to); */
if (!archive(vg_from) || !archive(vg_to))
- return ECMD_FAILED;
+ goto error;
/* Merge volume groups */
while (!list_empty(&vg_from->pvs)) {
@@ -168,14 +182,22 @@ int vgmerge_single(const char *vg_name_to, const char *vg_name_from)
/* store it on disks */
log_verbose("Writing out updated volume group");
if (!(fid->ops->vg_write(fid, vg_to))) {
- return ECMD_FAILED;
+ goto error;
}
/* FIXME Remove /dev/vgfrom */
backup(vg_to);
+ lock_vol(vg_name_from, LCK_VG | LCK_NONE);
+ lock_vol(vg_name_to, LCK_VG | LCK_NONE);
+
log_print("Volume group \"%s\" successfully merged into \"%s\"",
vg_from->name, vg_to->name);
return 0;
+
+ error:
+ lock_vol(vg_name_from, LCK_VG | LCK_NONE);
+ lock_vol(vg_name_to, LCK_VG | LCK_NONE);
+ return ECMD_FAILED;
}
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
index 71153fef..98b31348 100644
--- a/tools/vgreduce.c
+++ b/tools/vgreduce.c
@@ -26,6 +26,7 @@ int vgreduce(int argc, char **argv)
{
struct volume_group *vg;
char *vg_name;
+ int ret;
if (!argc) {
log_error("Please give volume group name and "
@@ -49,29 +50,42 @@ int vgreduce(int argc, char **argv)
argc--;
log_verbose("Finding volume group \"%s\"", vg_name);
+ if (!lock_vol(vg_name, LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for %s", vg_name);
+ return ECMD_FAILED;
+ }
+
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group \"%s\" doesn't exist", vg_name);
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
if (vg->status & EXPORTED_VG) {
log_error("Volume group \"%s\" is exported", vg->name);
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
if (!(vg->status & LVM_WRITE)) {
log_error("Volume group \"%s\" is read-only", vg_name);
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
if (!(vg->status & RESIZEABLE_VG)) {
log_error("Volume group \"%s\" is not reducable", vg_name);
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
/* FIXME: Pass private structure through to all these functions */
/* and update in batch here? */
- return process_each_pv(argc, argv, vg, vgreduce_single);
+ ret = process_each_pv(argc, argv, vg, vgreduce_single);
+
+ lock_vol(vg_name, LCK_VG | LCK_NONE);
+
+ return ret;
/******* FIXME
log_error ("no empty physical volumes found in volume group \"%s\"", vg_name);
diff --git a/tools/vgremove.c b/tools/vgremove.c
index cd5d0400..2d29a4d9 100644
--- a/tools/vgremove.c
+++ b/tools/vgremove.c
@@ -24,7 +24,19 @@ static int vgremove_single(const char *vg_name);
int vgremove(int argc, char **argv)
{
- return process_each_vg(argc, argv, &vgremove_single);
+ int ret;
+
+ if (!lock_vol("", LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for orphan PVs");
+ return ECMD_FAILED;
+ }
+
+ ret = process_each_vg(argc, argv, LCK_WRITE | LCK_NONBLOCK,
+ &vgremove_single);
+
+ lock_vol("", LCK_VG | LCK_NONE);
+
+ return ret;
}
static int vgremove_single(const char *vg_name)
diff --git a/tools/vgrename.c b/tools/vgrename.c
index d3a74cd7..81b84670 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -68,17 +68,26 @@ int vgrename(int argc, char **argv)
}
log_verbose("Checking for existing volume group \"%s\"", vg_name_old);
+
+ if (!lock_vol(vg_name_old, LCK_VG | LCK_WRITE)) {
+ log_error("Can't get lock for %s", vg_name_old);
+ return ECMD_FAILED;
+ }
+
if (!(vg_old = fid->ops->vg_read(fid, vg_name_old))) {
log_error("Volume group \"%s\" doesn't exist", vg_name_old);
+ lock_vol(vg_name_old, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
if (vg_old->status & EXPORTED_VG) {
+ lock_vol(vg_name_old, LCK_VG | LCK_NONE);
log_error("Volume group \"%s\" is exported", vg_old->name);
return ECMD_FAILED;
}
if (!(vg_old->status & LVM_WRITE)) {
+ lock_vol(vg_name_old, LCK_VG | LCK_NONE);
log_error("Volume group \"%s\" is read-only", vg_old->name);
return ECMD_FAILED;
}
@@ -89,20 +98,28 @@ int vgrename(int argc, char **argv)
/***** FIXME Handle this with multiple LV renames!
if (!force_ARG) {
log_error("Use -f to force the rename");
+ lock_vol(vg_name_old, LCK_VG | LCK_NONE);
return ECMD_FAILED;
}
*****/
}
log_verbose("Checking for new volume group \"%s\"", vg_name_new);
+
+ if (!lock_vol(vg_name_new, LCK_VG | LCK_WRITE | LCK_NONBLOCK)) {
+ lock_vol(vg_name_old, LCK_VG | LCK_NONE);
+ log_error("Can't get lock for %s", vg_name_new);
+ return ECMD_FAILED;
+ }
+
if ((vg_new = fid->ops->vg_read(fid, vg_name_new))) {
log_error("New volume group \"%s\" already exists",
vg_name_new);
- return ECMD_FAILED;
+ goto error;
}
if (!archive(vg_old))
- return ECMD_FAILED;
+ goto error;
/* Change the volume group name */
strcpy(vg_old->name, vg_name_new);
@@ -116,35 +133,43 @@ int vgrename(int argc, char **argv)
/********** FIXME: Check within vg_write now
log_error("A new logical volume path exceeds "
"maximum of %d!", NAME_LEN - 2);
- return ECMD_FAILED;
+ goto error;
*************/
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)) {
- log_error("Renaming \"%s\" to \"%s\" failed: %s",
- old_path, new_path, strerror(errno));
- return ECMD_FAILED;
+ if (dir_exists(old_path)) {
+ 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));
+ goto error;
+ }
}
/* store it on disks */
log_verbose("Writing out updated volume group");
if (!(fid->ops->vg_write(fid, vg_old))) {
- return ECMD_FAILED;
+ goto error;
}
-/******* FIXME Any LV things to update? */
+/******* FIXME Rename any active LVs! *****/
backup(vg_old);
+ lock_vol(vg_name_new, LCK_VG | LCK_NONE);
+ lock_vol(vg_name_old, LCK_VG | LCK_NONE);
+
log_print("Volume group \"%s\" successfully renamed to \"%s\"",
vg_name_old, vg_name_new);
- /* FIXME: Deallocations */
-
return 0;
+
+ error:
+ lock_vol(vg_name_new, LCK_VG | LCK_NONE);
+ lock_vol(vg_name_old, LCK_VG | LCK_NONE);
+ return ECMD_FAILED;
}
/* FIXME: Moved into vg_write now */
diff --git a/tools/vgscan.c b/tools/vgscan.c
index d5f541d8..bdb43978 100644
--- a/tools/vgscan.c
+++ b/tools/vgscan.c
@@ -37,7 +37,7 @@ int vgscan(int argc, char **argv)
log_print("Reading all physical volumes. This may take a while...");
- return process_each_vg(argc, argv, &vgscan_single);
+ return process_each_vg(argc, argv, LCK_READ, &vgscan_single);
}
static int vgscan_single(const char *vg_name)
@@ -45,6 +45,7 @@ static int vgscan_single(const char *vg_name)
struct volume_group *vg;
log_verbose("Checking for volume group \"%s\"", vg_name);
+
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
log_error("Volume group \"%s\" not found", vg_name);
return ECMD_FAILED;