1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

i) There's now a seperate field in struct logical_volume that stores the

allocation policy.  This can currently take one of three values:

   typedef enum {
        ALLOC_NEXT_FREE,
        ALLOC_STRICT,
        ALLOC_CONTIGUOUS
   } alloc_policy_t;

    Notice that 'SIMPLE' has turned into the slightly more meaningful NEXT_FREE.

ii) Put code into display.[hc] for converting one of these enums to a
    text representation and back again.

ii) Updated the text format so this also has the alloc_policy field.
This commit is contained in:
Joe Thornber 2002-07-11 14:21:49 +00:00
parent 407332cb9a
commit 097d49e73d
11 changed files with 116 additions and 63 deletions

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -11,15 +11,13 @@
#include "pool.h"
#include "dbg_malloc.h"
#include "lvm-string.h"
#include "display.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
/*
* 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);

View File

@ -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}
};

View File

@ -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.");

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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);