From 6d94578955eb2b1658e1ab3694e649cf212f8e8a Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Thu, 21 Feb 2002 19:04:37 +0000 Subject: [PATCH] o Convert lv->id back to lv_number when writing back to disk o Use first unused lv_number when creating new LV o Use lv_number for refs to snapshots o Update persistent minor logic after the lvcreate restructure o Reset all parameters before use in lvcreate. --- lib/format1/format1.c | 22 ++++++++++++++++++++++ lib/format1/import-export.c | 33 +++++++++++++++------------------ tools/lvchange.c | 2 +- tools/lvcreate.c | 32 ++++++++++++++++++-------------- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/lib/format1/format1.c b/lib/format1/format1.c index 93d8b8df4..51d9a0afb 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -418,10 +418,32 @@ static int _pv_setup(struct format_instance *fi, struct physical_volume *pv, return 1; } +static int _find_free_lvnum(struct logical_volume *lv) +{ + int lvnum_used[MAX_LV]; + int i = 0; + struct list *lvh; + struct lv_list *lvl; + + memset(&lvnum_used, 0, sizeof(lvnum_used)); + + list_iterate(lvh, &lv->vg->lvs) { + lvl = list_item(lvh, struct lv_list); + lvnum_used[lvnum_from_id(&lvl->lv->id)] = 1; + } + + while (lvnum_used[i]) + i++; + + return i; +} + static int _lv_setup(struct format_instance *fi, struct logical_volume *lv) { uint64_t max_size = UINT_MAX; + id_from_lvnum(&lv->id, _find_free_lvnum(lv)); + if (lv->le_count > MAX_LE_TOTAL) { log_error("logical volumes cannot contain more than " "%d extents.", MAX_LE_TOTAL); diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c index 90d051509..a677aebb0 100644 --- a/lib/format1/import-export.c +++ b/lib/format1/import-export.c @@ -477,7 +477,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg, struct list *lvh, *sh; struct lv_list *ll; struct lvd_list *lvdl; - int lv_num = 0, len; + int lv_num, len; struct hash_table *lvd_hash; if (!(lvd_hash = hash_create(32))) { @@ -504,9 +504,8 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg, export_lv(&lvdl->lvd, vg, ll->lv, dev_dir); - /* this isn't a real dev, more of an index for - * snapshots to refer to, *HACK* */ - lvdl->lvd.lv_dev = MKDEV(0, lv_num); + lv_num = lvnum_from_id(&ll->lv->id); + lvdl->lvd.lv_number = lv_num; if (!hash_insert(lvd_hash, ll->lv->name, &lvdl->lvd)) { @@ -521,7 +520,6 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg, list_add(&dl->lvds, &lvdl->list); dl->pvd.lv_cur++; - lv_num++; } /* @@ -547,7 +545,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg, org->lv_access |= LV_SNAPSHOT_ORG; cow->lv_access |= LV_SNAPSHOT; - cow->lv_snapshot_minor = MINOR(org->lv_dev); + cow->lv_snapshot_minor = org->lv_number; } r = 1; @@ -567,10 +565,10 @@ int import_snapshots(struct pool *mem, struct volume_group *vg, struct list *pvdh, *lvdh; struct disk_list *dl; struct lv_disk *lvd; - int minor; + int lvnum; struct logical_volume *org, *cow; - /* build an array of minor->lv */ + /* build an index of lv numbers */ memset(lvs, 0, sizeof(lvs)); list_iterate (pvdh, pvds) { dl = list_item(pvdh, struct disk_list); @@ -578,16 +576,16 @@ int import_snapshots(struct pool *mem, struct volume_group *vg, list_iterate (lvdh, &dl->lvds) { lvd = &(list_item(lvdh, struct lvd_list)->lvd); - minor = MINOR(lvd->lv_dev); + lvnum = lvd->lv_number; - if (minor > MAX_LV) { - log_err("Logical volume minor number " + if (lvnum > MAX_LV) { + log_err("Logical volume number " "out of bounds."); return 0; } - if (!lvs[minor] && - !(lvs[minor] = find_lv(vg, lvd->lv_name))) { + if (!lvs[lvnum] && + !(lvs[lvnum] = find_lv(vg, lvd->lv_name))) { log_err("Couldn't find logical volume '%s'.", lvd->lv_name); return 0; @@ -607,8 +605,8 @@ int import_snapshots(struct pool *mem, struct volume_group *vg, if (!(lvd->lv_access & LV_SNAPSHOT)) continue; - minor = MINOR(lvd->lv_dev); - cow = lvs[minor]; + lvnum = lvd->lv_number; + cow = lvs[lvnum]; if (!(org = lvs[lvd->lv_snapshot_minor])) { log_err("Couldn't find origin logical volume " "for snapshot '%s'.", lvd->lv_name); @@ -654,9 +652,8 @@ int export_uuids(struct disk_list *dl, struct volume_group *vg) } /* - * This calculates the nasty pv_number and - * lv_number fields used by LVM1. Very - * inefficient code. + * This calculates the nasty pv_number field + * used by LVM1. */ void export_numbers(struct list *pvds, struct volume_group *vg) { diff --git a/tools/lvchange.c b/tools/lvchange.c index 927799f29..25b2d4c5d 100644 --- a/tools/lvchange.c +++ b/tools/lvchange.c @@ -349,7 +349,7 @@ static int lvchange_persistent(struct cmd_context *cmd, lv->minor = -1; log_verbose("Disabling persistent minor for \"%s\"", lv->name); } else { - if (lv_active(lv)) { + if (lv_active(lv) > 0) { log_error("Cannot change minor number when active"); return 0; } diff --git a/tools/lvcreate.c b/tools/lvcreate.c index 05678521f..140525477 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -14,6 +14,7 @@ struct lvcreate_params { int snapshot; int zero; int contiguous; + int minor; char *origin; char *vg_name; @@ -227,20 +228,23 @@ static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd, else lp->permission = LVM_READ | LVM_WRITE; + lp->minor = arg_int_value(cmd, minor_ARG, -1); -#if 0 - /* persistent minor */ + /* Persistent minor */ if (arg_count(cmd, persistent_ARG)) { - if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "n")) - lv->status &= ~FIXED_MINOR; - else if (!arg_count(cmd, minor_ARG)) { - log_error("Please specify minor number with " - "--minor when using -My"); - return 0; + if (!strcmp(arg_str_value(cmd, persistent_ARG, "n"), "y")) { + if (lp->minor == -1) { + log_error("Please specify minor number with " + "--minor when using -My"); + return 0; + } + } else { + if (lp->minor != -1) { + log_error("--minor not possible with -Mn"); + return 0; + } } - lv->status |= FIXED_MINOR; } -#endif lp->pv_count = argc; lp->pvs = argv; @@ -252,7 +256,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp, struct logical_volume **plv) { uint32_t size_rest; - uint32_t status; + uint32_t status = 0; struct volume_group *vg; struct logical_volume *lv, *org; struct list *pvh; @@ -362,13 +366,11 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp, lv->read_ahead = lp->read_ahead; } -#if 0 if (lp->minor >= 0) { - lv->status |= FIXED_MINOR; lv->minor = lp->minor; + lv->status |= FIXED_MINOR; log_verbose("Setting minor number to %d", lv->minor); } -#endif /* store vg on disk(s) */ if (!cmd->fid->ops->vg_write(cmd->fid, vg)) @@ -430,6 +432,8 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv) struct lvcreate_params lp; struct logical_volume *lv; + memset(&lp, 0, sizeof(lp)); + if (!_read_params(&lp, cmd, argc, argv)) return -EINVALID_CMD_LINE;