diff --git a/lib/display/display.c b/lib/display/display.c index 3d18321d3..67d5495b0 100644 --- a/lib/display/display.c +++ b/lib/display/display.c @@ -207,16 +207,50 @@ void lvdisplay_colons(struct logical_volume *lv) /* FIXME lv->lv_number, */ inkernel ? info.open_count : 0, lv->size, lv->le_count, /* FIXME Add num allocated to struct! lv->lv_allocated_le, */ - ((lv->status & ALLOC_STRICT) + - (lv->status & ALLOC_CONTIGUOUS) * 2), lv->read_ahead, + ((lv->alloc == ALLOC_STRICT) + + (lv->alloc == ALLOC_CONTIGUOUS) * 2), lv->read_ahead, inkernel ? info.major : -1, inkernel ? info.minor : -1); return; } + +static struct { + alloc_policy_t alloc; + const char *str; +} _policies[] = { + {ALLOC_NEXT_FREE, "next free"}, + {ALLOC_STRICT, "strict"}, + {ALLOC_CONTIGUOUS, "contiguous"} +}; + +static int _num_policies = sizeof(_policies) / sizeof(*_policies); + +const char *get_alloc_string(alloc_policy_t alloc) +{ + int i; + + for (i = 0; i < _num_policies; i++) + if (_policies[i].alloc == alloc) + return _policies[i].str; + + return NULL; +} + +alloc_policy_t get_alloc_from_string(const char *str) +{ + int i; + + for (i = 0; i < _num_policies; i++) + if (!strcmp(_policies[i].str, str)) + return _policies[i].alloc; + + log_warn("Unknown allocation policy, defaulting to next free"); + return ALLOC_NEXT_FREE; +} + int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) { char *size; - uint32_t alloc; struct dm_info info; int inkernel; char uuid[64]; @@ -243,7 +277,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) lv->vg->name, lv->name); log_print("VG Name %s", lv->vg->name); -/* Not in LVM1 format +/* Not in LVM1 format log_print("LV UUID %s", uuid); **/ log_print("LV Write Access %s", @@ -252,11 +286,11 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) /* see if this LV is an origin for a snapshot */ if ((snap = find_origin(lv))) { struct list *slh, *snaplist = find_snapshots(lv); - + log_print("LV snapshot status source of"); list_iterate(slh, snaplist) { snap = list_item(slh, struct snapshot_list)->snapshot; - snap_active = lv_snapshot_percent(snap->cow, + snap_active = lv_snapshot_percent(snap->cow, &snap_percent); log_print(" %s%s/%s [%s]", lv->vg->cmd->dev_dir, lv->vg->name, @@ -272,7 +306,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) else if ((snap = find_cow(lv))) { snap_active = lv_snapshot_percent(lv, &snap_percent); log_print("LV snapshot status %s destination for %s%s/%s", - (snap_active > 0) ? "active" : "INACTIVE", + (snap_active > 0) ? "active" : "INACTIVE", lv->vg->cmd->dev_dir, lv->vg->name, snap->origin->name); } @@ -282,7 +316,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) log_print("LV Status suspended"); else log_print("LV Status %savailable", - !inkernel || (snap && (snap_active < 1)) + !inkernel || (snap && (snap_active < 1)) ? "NOT " : ""); /********* FIXME lv_number - not sure that we're going to bother with this @@ -292,7 +326,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) /* LVM1 lists the number of LVs open in this field, therefore, so do we. */ log_print("# open %u", lvs_in_vg_opened(lv->vg)); -/* We're not going to use this count ATM, 'cause it's not what LVM1 does +/* We're not going to use this count ATM, 'cause it's not what LVM1 does if (inkernel) log_print("# open %u", info.open_count); */ @@ -312,18 +346,18 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) origin = snap->origin; else origin = lv; - + size = display_size(origin->size / 2, SIZE_SHORT); log_print("LV Size %s", size); dbg_free(size); log_print("Current LE %u", origin->le_count); - + /********** FIXME allocation - is there anytime the allocated LEs will not * equal the current LEs? */ log_print("Allocated LE %u", origin->le_count); /**********/ - + list_iterate(lvseg, &lv->segments) { seg = list_item(lvseg, struct stripe_segment); @@ -349,7 +383,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) sscanf(size, "%f", &fsize); fused = fsize * ( snap_percent / 100 ); log_print("Allocated to snapshot %2.2f%% [%2.2f/%s]", - snap_percent, fused, size); + snap_percent, fused, size); dbg_free(size); /* FIXME: Think this'll make them wonder?? */ @@ -374,16 +408,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv) #endif ***************/ - /* FIXME next free == ALLOC_SIMPLE */ - alloc = lv->status & (ALLOC_STRICT | ALLOC_CONTIGUOUS); - log_print("Allocation %s%s%s%s", - !(alloc & (ALLOC_STRICT | ALLOC_CONTIGUOUS)) ? "next free" : - "", (alloc == ALLOC_STRICT) ? "strict" : "", - (alloc == ALLOC_CONTIGUOUS) ? "contiguous" : "", - (alloc == - (ALLOC_STRICT | ALLOC_CONTIGUOUS)) ? "strict/contiguous" : - ""); - + log_print("Allocation %s", get_alloc_string(lv->alloc)); log_print("Read ahead sectors %u", lv->read_ahead); if (lv->status & FIXED_MINOR) @@ -499,7 +524,7 @@ void vgdisplay_full(struct volume_group *vg) vg->status & SHARED ? "yes" : "no"); } /****** FIXME VG # - we aren't implementing this because people should - * use the UUID for this anyway + * use the UUID for this anyway log_print("VG # %u", vg->vg_number); *******/ log_print("MAX LV %u", vg->max_lv); diff --git a/lib/display/display.h b/lib/display/display.h index b6d7ee755..871dbbaba 100644 --- a/lib/display/display.h +++ b/lib/display/display.h @@ -44,4 +44,15 @@ void vgdisplay_full(struct volume_group *vg); void vgdisplay_colons(struct volume_group *vg); void vgdisplay_short(struct volume_group *vg); +/* + * Retrieve a text description of the allocation policy. Only + * extern because it's used by lvscan. + */ +const char *get_alloc_string(alloc_policy_t alloc); + +/* + * FIXME: put this somewhere more sensible. + */ +alloc_policy_t get_alloc_from_string(const char *str); + #endif diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c index f100f5058..08df47912 100644 --- a/lib/format1/import-export.c +++ b/lib/format1/import-export.c @@ -297,12 +297,12 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd) lv->status |= BADBLOCK_ON; if (lvd->lv_allocation & LV_STRICT) - lv->status |= ALLOC_STRICT; + lv->alloc = ALLOC_STRICT; if (lvd->lv_allocation & LV_CONTIGUOUS) - lv->status |= ALLOC_CONTIGUOUS; + lv->alloc = ALLOC_CONTIGUOUS; else - lv->status |= ALLOC_SIMPLE; + lv->alloc |= ALLOC_NEXT_FREE; lv->read_ahead = lvd->lv_read_ahead; lv->size = lvd->lv_size; @@ -350,10 +350,10 @@ void export_lv(struct lv_disk *lvd, struct volume_group *vg, if (lv->status & BADBLOCK_ON) lvd->lv_badblock = LV_BADBLOCK_ON; - if (lv->status & ALLOC_STRICT) + if (lv->alloc == ALLOC_STRICT) lvd->lv_allocation |= LV_STRICT; - if (lv->status & ALLOC_CONTIGUOUS) + if (lv->alloc == ALLOC_CONTIGUOUS) lvd->lv_allocation |= LV_CONTIGUOUS; } diff --git a/lib/format_text/export.c b/lib/format_text/export.c index ca08e09af..a95540686 100644 --- a/lib/format_text/export.c +++ b/lib/format_text/export.c @@ -11,15 +11,13 @@ #include "pool.h" #include "dbg_malloc.h" #include "lvm-string.h" +#include "display.h" #include #include #include -/* - * The first half of this file deals with - * exporting the vg, ie. writing it to a file. - */ + struct formatter { struct pool *mem; /* pv names allocated from here */ struct hash_table *pv_names; /* dev_name -> pv_name (eg, pv1) */ @@ -360,12 +358,15 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg) _out(f, "id = \"%s\"", buffer); - if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer))) { + if (!print_flags(lv->status, LV_FLAGS, + buffer, sizeof(buffer))) { stack; return 0; } _out(f, "status = %s", buffer); + _out(f, "allocation_policy = \"%s\"", + get_alloc_string(lv->alloc)); _out(f, "read_ahead = %u", lv->read_ahead); if (lv->minor >= 0) _out(f, "minor = %d", lv->minor); diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c index da0e82e95..e42f4f445 100644 --- a/lib/format_text/flags.c +++ b/lib/format_text/flags.c @@ -38,9 +38,6 @@ static struct flag _pv_flags[] = { static struct flag _lv_flags[] = { {LVM_READ, "READ"}, {LVM_WRITE, "WRITE"}, - {ALLOC_SIMPLE, "ALLOC_SIMPLE"}, - {ALLOC_STRICT, "ALLOC_STRICT"}, - {ALLOC_CONTIGUOUS, "ALLOC_CONTIGUOUS"}, {FIXED_MINOR, "FIXED_MINOR"}, {0, NULL} }; diff --git a/lib/format_text/import.c b/lib/format_text/import.c index cdd4b9a0a..4028d71e7 100644 --- a/lib/format_text/import.c +++ b/lib/format_text/import.c @@ -11,6 +11,7 @@ #include "uuid.h" #include "hash.h" #include "toolcontext.h" +#include "display.h" typedef int (*section_fn) (struct format_instance * fid, struct pool * mem, struct volume_group * vg, struct config_node * pvn, @@ -438,6 +439,22 @@ static int _read_lv(struct format_instance *fid, struct pool *mem, return 0; } + /* + * allocation_policy is optional since it is meaning less + * for things like mirrors and snapshots. Where it isn't + * specified we default to the next free policy. + */ + lv->alloc = ALLOC_NEXT_FREE; + if ((cn = find_config_node(lvn, "allocation_policy", '/'))) { + struct config_value *cv = cn->v; + if (!cv || !cv->v.str) { + log_err("allocation_policy must be a string."); + return 0; + } + + lv->alloc = get_alloc_from_string(cv->v.str); + } + if (!_read_int32(lvn, "read_ahead", &lv->read_ahead)) { log_error("Couldn't read 'read_ahead' value for " "logical volume."); diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index f04202cee..5a2136c66 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -302,10 +302,10 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv, if (stripes > 1) r = _alloc_striped(lv, pvms, allocated, stripes, stripe_size); - else if (lv->status & ALLOC_CONTIGUOUS) + else if (lv->alloc == ALLOC_CONTIGUOUS) r = _alloc_contiguous(lv, pvms, allocated); - else if (lv->status & ALLOC_SIMPLE) + else if (lv->alloc == ALLOC_NEXT_FREE) r = _alloc_simple(lv, pvms, allocated); else { @@ -362,6 +362,7 @@ static char *_generate_lv_name(struct volume_group *vg, struct logical_volume *lv_create(struct format_instance *fi, const char *name, uint32_t status, + alloc_policy_t alloc, uint32_t stripes, uint32_t stripe_size, uint32_t extents, @@ -422,6 +423,7 @@ struct logical_volume *lv_create(struct format_instance *fi, } lv->status = status; + lv->alloc = alloc; lv->read_ahead = 0; lv->minor = -1; lv->size = (uint64_t) extents *vg->extent_size; diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 2a8823a13..f4d25cfb5 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -46,17 +46,19 @@ #define CLUSTERED 0x00000400 /* VG */ #define SHARED 0x00000800 /* VG */ -/* FIXME: This should be an enum rather than a bitset, - remove from status - EJT */ -#define ALLOC_SIMPLE 0x00001000 /* LV */ -#define ALLOC_STRICT 0x00002000 /* LV */ -#define ALLOC_CONTIGUOUS 0x00004000 /* LV */ - #define FMT_SEGMENTS 0x00000001 /* Arbitrary segment parameters? */ #define FMT_TEXT_NAME "text" #define FMT_LVM1_NAME "lvm1" + +typedef enum { + ALLOC_NEXT_FREE, + ALLOC_STRICT, + ALLOC_CONTIGUOUS + +} alloc_policy_t; + struct physical_volume { struct id id; struct device *dev; @@ -147,6 +149,7 @@ struct logical_volume { struct volume_group *vg; uint32_t status; + alloc_policy_t alloc; uint32_t read_ahead; int32_t minor; @@ -320,6 +323,7 @@ int vg_extend(struct format_instance *fi, struct logical_volume *lv_create(struct format_instance *fi, const char *name, uint32_t status, + alloc_policy_t alloc, uint32_t stripes, uint32_t stripe_size, uint32_t extents, diff --git a/tools/lvchange.c b/tools/lvchange.c index 8f9b50ca2..b477a3b10 100644 --- a/tools/lvchange.c +++ b/tools/lvchange.c @@ -212,39 +212,37 @@ static int lvchange_availability(struct cmd_context *cmd, static int lvchange_contiguous(struct cmd_context *cmd, struct logical_volume *lv) { - int lv_allocation = 0; + int want_contiguous = 0; if (strcmp(arg_str_value(cmd, contiguous_ARG, "n"), "n")) - lv_allocation |= ALLOC_CONTIGUOUS; + want_contiguous = 1; - if ((lv_allocation & ALLOC_CONTIGUOUS) && - (lv->status & ALLOC_CONTIGUOUS)) { + if (want_contiguous && lv->alloc == ALLOC_CONTIGUOUS) { log_error("Allocation policy of logical volume \"%s\" is " "already contiguous", lv->name); return 0; } - if (!(lv_allocation & ALLOC_CONTIGUOUS) && - !(lv->status & ALLOC_CONTIGUOUS)) { + if (!want_contiguous && lv->alloc != ALLOC_CONTIGUOUS) { log_error ("Allocation policy of logical volume \"%s\" is already" " not contiguous", lv->name); return 0; } -/******** FIXME lv_check_contiguous? +/******** FIXME lv_check_contiguous? if ((lv_allocation & ALLOC_CONTIGUOUS) && (ret = lv_check_contiguous(vg, lv_index + 1)) == FALSE) { log_error("No contiguous logical volume \"%s\"", lv->name); return 0; *********/ - if (lv_allocation & ALLOC_CONTIGUOUS) { - lv->status |= ALLOC_CONTIGUOUS; + if (want_contiguous) { + lv->alloc = ALLOC_CONTIGUOUS; log_verbose("Setting contiguous allocation policy for \"%s\"", lv->name); } else { - lv->status &= ~ALLOC_CONTIGUOUS; + lv->alloc = ALLOC_NEXT_FREE; log_verbose("Removing contiguous allocation policy for \"%s\"", lv->name); } @@ -279,7 +277,7 @@ static int lvchange_readahead(struct cmd_context *cmd, read_ahead = arg_int_value(cmd, readahead_ARG, 0); -/******* FIXME Ranges? +/******* FIXME Ranges? if (read_ahead < LVM_MIN_READ_AHEAD || read_ahead > LVM_MAX_READ_AHEAD) { log_error("read ahead sector argument is invalid"); return 0; diff --git a/tools/lvcreate.c b/tools/lvcreate.c index c05bd7936..08d7c6029 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -294,14 +294,13 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) { uint32_t size_rest; uint32_t status = 0; + alloc_policy_t alloc = ALLOC_NEXT_FREE; struct volume_group *vg; struct logical_volume *lv, *org; struct list *pvh; if (lp->contiguous) - status |= ALLOC_CONTIGUOUS; - else - status |= ALLOC_SIMPLE; + alloc = ALLOC_CONTIGUOUS; status |= lp->permission; @@ -379,7 +378,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp) return 0; } - if (!(lv = lv_create(vg->fid, lp->lv_name, status, + if (!(lv = lv_create(vg->fid, lp->lv_name, status, alloc, lp->stripes, lp->stripe_size, lp->extents, vg, pvh))) return 0; diff --git a/tools/lvscan.c b/tools/lvscan.c index a571e6c45..044e2e6ba 100644 --- a/tools/lvscan.c +++ b/tools/lvscan.c @@ -86,10 +86,9 @@ static int lvscan_single(struct cmd_context *cmd, struct logical_volume *lv) ***********/ dummy = display_size(lv->size / 2, SIZE_SHORT); - log_print("%s%s '%s%s/%s' [%s]%s%s", active_str, snapshot_str, + log_print("%s%s '%s%s/%s' [%s]%s", active_str, snapshot_str, cmd->dev_dir, lv->vg->name, lv->name, dummy, - (lv->status & ALLOC_STRICT) ? " strict" : "", - (lv->status & ALLOC_CONTIGUOUS) ? " contiguous" : ""); + get_alloc_string(lv->alloc)); dbg_free(dummy);