From befcada36a6458986782569963972ea2ed7ccbe4 Mon Sep 17 00:00:00 2001 From: Dave Wysochanski Date: Mon, 1 Dec 2008 20:14:33 +0000 Subject: [PATCH] Fix vgcreate race which could allow two parallel vgcreates to succeed, with the second vgcreate overwriting the first. Obtain lock before calling vg_create(), which checks for existence of vgname and fails if it already exists. --- WHATS_NEW | 1 + tools/vgcreate.c | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 94c887e48..e1eaade9d 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.44 - ==================================== + Fix race in vgcreate that would result in second caller overwriting first. Fix uninitialised lv_count in vgdisplay -c. Don't skip updating pvid hash when lvmcache_info struct got swapped. Add tinfo to termcap search path for pld-linux. diff --git a/tools/vgcreate.c b/tools/vgcreate.c index 62c957adb..a4670c3fe 100644 --- a/tools/vgcreate.c +++ b/tools/vgcreate.c @@ -46,11 +46,22 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) if (validate_vg_create_params(cmd, &vp_new)) return EINVALID_CMD_LINE; + if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) { + log_error("Can't get lock for orphan PVs"); + return ECMD_FAILED; + } + + if (!lock_vol(cmd, vp_new.vg_name, LCK_VG_WRITE | LCK_NONBLOCK)) { + log_error("Can't get lock for %s", vp_new.vg_name); + unlock_vg(cmd, VG_ORPHANS); + return ECMD_FAILED; + } + /* Create the new VG */ if (!(vg = vg_create(cmd, vp_new.vg_name, vp_new.extent_size, vp_new.max_pv, vp_new.max_lv, vp_new.alloc, argc - 1, argv + 1))) - return ECMD_FAILED; + goto bad; if (vp_new.max_lv != vg->max_lv) log_warn("WARNING: Setting maxlogicalvolumes to %d " @@ -63,18 +74,18 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) if (arg_count(cmd, addtag_ARG)) { if (!(tag = arg_str_value(cmd, addtag_ARG, NULL))) { log_error("Failed to get tag"); - return ECMD_FAILED; + goto bad; } if (!(vg->fid->fmt->features & FMT_TAGS)) { log_error("Volume group format does not support tags"); - return ECMD_FAILED; + goto bad; } if (!str_list_add(cmd->mem, &vg->tags, tag)) { log_error("Failed to add tag %s to volume group %s", tag, vp_new.vg_name); - return ECMD_FAILED; + goto bad; } } @@ -88,28 +99,13 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) clustered_message = "Non-clustered "; } - if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) { - log_error("Can't get lock for orphan PVs"); - return ECMD_FAILED; - } - - if (!lock_vol(cmd, vp_new.vg_name, LCK_VG_WRITE | LCK_NONBLOCK)) { - log_error("Can't get lock for %s", vp_new.vg_name); - unlock_vg(cmd, VG_ORPHANS); - return ECMD_FAILED; - } - if (!archive(vg)) { - unlock_vg(cmd, vp_new.vg_name); - unlock_vg(cmd, VG_ORPHANS); - return ECMD_FAILED; + goto bad; } /* Store VG on disk(s) */ if (!vg_write(vg) || !vg_commit(vg)) { - unlock_vg(cmd, vp_new.vg_name); - unlock_vg(cmd, VG_ORPHANS); - return ECMD_FAILED; + goto bad; } unlock_vg(cmd, vp_new.vg_name); @@ -121,4 +117,9 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) clustered_message, *clustered_message ? 'v' : 'V', vg->name); return ECMD_PROCESSED; + +bad: + unlock_vg(cmd, vp_new.vg_name); + unlock_vg(cmd, VG_ORPHANS); + return ECMD_FAILED; } -- 2.43.5