From 9c520b114a6af36d5b0f1afc94f54471d552e165 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Thu, 28 Aug 2008 18:41:51 +0000 Subject: [PATCH] Fix vgconvert logical volume id metadata validation. If volume group is downconverted to lvm1 format, check if lvid has supported format for conversion to lv_num in lvm1. --- WHATS_NEW | 1 + lib/uuid/uuid.c | 18 ++++++++++++++++++ lib/uuid/uuid.h | 1 + tools/vgconvert.c | 11 +++++++++++ 4 files changed, 31 insertions(+) diff --git a/WHATS_NEW b/WHATS_NEW index f007673dd..7524edfdf 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.40 - ================================ + Fix vgconvert logical volume id metadata validation. Fix lvmdump metadata gather option (-m) to work correctly. Fix allocation bug in text metadata format write error path. Fix vgcfgbackup to properly check filename if template is used. diff --git a/lib/uuid/uuid.c b/lib/uuid/uuid.c index 03fe5c556..da4093f7a 100644 --- a/lib/uuid/uuid.c +++ b/lib/uuid/uuid.c @@ -67,11 +67,29 @@ int lvnum_from_lvid(union lvid *lvid) lv_num *= sizeof(_c) - 1; if ((c = strchr(_c, lvid->id[1].uuid[i]))) lv_num += (int) (c - _c); + if (lv_num < 0) + lv_num = 0; } return lv_num; } +int lvid_in_restricted_range(union lvid *lvid) +{ + int i; + + for (i = 0; i < ID_LEN - 3; i++) + if (lvid->id[1].uuid[i] != '0') + return 0; + + for (i = ID_LEN - 3; i < ID_LEN; i++) + if (!isdigit(lvid->id[1].uuid[i])) + return 0; + + return 1; +} + + int id_create(struct id *id) { int randomfile; diff --git a/lib/uuid/uuid.h b/lib/uuid/uuid.h index d1b03b3bf..00296393c 100644 --- a/lib/uuid/uuid.h +++ b/lib/uuid/uuid.h @@ -34,6 +34,7 @@ union lvid { int lvid_from_lvnum(union lvid *lvid, struct id *vgid, uint32_t lv_num); int lvnum_from_lvid(union lvid *lvid); +int lvid_in_restricted_range(union lvid *lvid); void uuid_from_num(char *uuid, uint32_t num); diff --git a/tools/vgconvert.c b/tools/vgconvert.c index 6c261f3a4..0b7d978c0 100644 --- a/tools/vgconvert.c +++ b/tools/vgconvert.c @@ -81,6 +81,17 @@ static int vgconvert_single(struct cmd_context *cmd, const char *vg_name, return ECMD_FAILED; } + /* If converting to restricted lvid, check if lvid is compatible */ + if (!(vg->fid->fmt->features & FMT_RESTRICTED_LVIDS) && + cmd->fmt->features & FMT_RESTRICTED_LVIDS) + list_iterate_items(lvl, &vg->lvs) + if (!lvid_in_restricted_range(&lvl->lv->lvid)) { + log_error("Logical volume %s lvid format is" + " incompatible with requested" + " metadata format.", lvl->lv->name); + return ECMD_FAILED; + } + /* Attempt to change any LVIDs that are too big */ if (cmd->fmt->features & FMT_RESTRICTED_LVIDS) { list_iterate_items(lvl, &vg->lvs) {