1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

Basic support for persistent minor numbers;

slightly different from the current LVM1 method.

  lvcreate --persistent y  --minor 10   (to specify when created)
  lvchange --persistent n  (to turn off)
  lvchange --persistent y  --minor 11   (to change)

--persistent uses a new LV status flag stored on disk
minor number is stored on disk the same way as LVM1 does
(but major number stored is 0; any LVM1 major/minor setting gets lost)

  lvchange -ay --minor 12 (to activate using minor 12, regardless of the
                           on-disk setting, which doesn't get changed)

--minor == -m
--persistent == -M
This commit is contained in:
Alasdair Kergon 2002-02-01 17:54:39 +00:00
parent dcde8bf026
commit 812c699c8d
15 changed files with 165 additions and 12 deletions

View File

@ -13,6 +13,7 @@
#include "names.h"
#include <limits.h>
#include <linux/kdev_t.h>
int library_version(char *version, size_t size)
@ -278,13 +279,23 @@ int _load(struct logical_volume *lv, int task)
}
if (!((lv->status & LVM_WRITE) && (lv->vg->status & LVM_WRITE))) {
if (!dm_task_set_ro(dmt))
if (!dm_task_set_ro(dmt)) {
log_error("Failed to set %s read-only during "
"activation.", lv->name);
else
goto out;
} else
log_very_verbose("Activating %s read-only", lv->name);
}
if (lv->minor) {
if (!dm_task_set_minor(dmt, MINOR(lv->minor))) {
log_error("Failed to set minor number for %s to %d "
"during activation.", lv->name, lv->minor);
goto out;
} else
log_very_verbose("Set minor number for %s to %d.",
lv->name, lv->minor);
}
if (!(r = dm_task_run(dmt)))
stack;

View File

@ -353,6 +353,9 @@ int lvdisplay_full(struct logical_volume *lv)
log_print("Read ahead sectors %u", lv->read_ahead);
if (lv->status & FIXED_MINOR)
log_print("Persistent minor %d", lv->minor);
/****************
#ifdef LVM_FUTURE
printf("IO Timeout (seconds) ");

View File

@ -40,6 +40,7 @@
/* logical volume */
#define LV_ACTIVE 0x01 /* lv_status */
#define LV_SPINDOWN 0x02 /* " */
#define LV_PERSISTENT_MINOR 0x04 /* " */
#define LV_READ 0x01 /* lv_access */
#define LV_WRITE 0x02 /* " */

View File

@ -16,6 +16,7 @@
#include <time.h>
#include <sys/utsname.h>
#include <linux/kdev_t.h>
static int _check_vg_name(const char *name)
{
@ -280,6 +281,12 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
if (lvd->lv_status & LV_SPINDOWN)
lv->status |= SPINDOWN_LV;
if (lvd->lv_status & LV_PERSISTENT_MINOR) {
lv->status |= FIXED_MINOR;
lv->minor = MINOR(lvd->lv_dev);
} else
lv->minor = -1;
if (lvd->lv_access & LV_READ)
lv->status |= LVM_READ;
@ -338,6 +345,11 @@ void export_lv(struct lv_disk *lvd, struct volume_group *vg,
if (lv->status & SPINDOWN_LV)
lvd->lv_status |= LV_SPINDOWN;
if (lv->status & FIXED_MINOR) {
lvd->lv_status |= LV_PERSISTENT_MINOR;
lvd->lv_dev = MKDEV(0, lv->minor);
}
lvd->lv_read_ahead = lv->read_ahead;
lvd->lv_stripes = list_item(lv->segments.n,
struct stripe_segment)->stripes;

View File

@ -351,6 +351,8 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
_out(f, "status = %s", buffer);
_out(f, "read_ahead = %u", lv->read_ahead);
if (lv->minor >= 0)
_out(f, "minor = %d", lv->minor);
_out(f, "segment_count = %u", _count_segments(lv));
_nl(f);

View File

@ -43,6 +43,7 @@ static struct flag _lv_flags[] = {
{ALLOC_CONTIGUOUS, "ALLOC_CONTIGUOUS"},
{SNAPSHOT, "SNASHOT"},
{SNAPSHOT_ORG, "SNAPSHOT_ORIGIN"},
{FIXED_MINOR, "FIXED_MINOR"},
{0, NULL}
};

View File

@ -371,6 +371,13 @@ static int _read_lv(struct pool *mem,
return 0;
}
lv->minor = -1;
if ((lv->status & FIXED_MINOR) &&
!_read_int32(lvn, "minor", &lv->minor)) {
log_error("Couldn't read 'minor' value for logical volume.");
return 0;
}
if (!_read_int32(lvn, "read_ahead", &lv->read_ahead)) {
log_err("Couldn't read 'read_ahead' value for "
"logical volume.");
@ -440,7 +447,21 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf,
goto bad;
}
if (!(vg->system_id = pool_zalloc(mem, NAME_LEN))) {
stack;
goto bad;
}
vgn = vgn->child;
if ((cn = find_config_node(vgn, "system_id", '/')) && cn->v) {
if (!cn->v->v.str) {
log_error("system_id must be a string");
goto bad;
}
strncpy(vg->system_id, cn->v->v.str, NAME_LEN);
}
if (!_read_id(&vg->id, vgn, "id")) {
log_err("Couldn't read uuid for volume group %s.",
vg->name);

View File

@ -424,6 +424,7 @@ struct logical_volume *lv_create(struct format_instance *fi,
lv->status = status;
lv->read_ahead = 0;
lv->minor = -1;
lv->size = extents * vg->extent_size;
lv->le_count = extents;
lv->vg = vg;

View File

@ -36,6 +36,7 @@
#define SPINDOWN_LV 0x00000010 /* LV */
#define BADBLOCK_ON 0x00000020 /* LV */
#define FIXED_MINOR 0x00000080 /* LV */
/* FIXME: do we really set read/write for a whole vg ? */
#define LVM_READ 0x00000100 /* LV VG */
@ -119,6 +120,7 @@ struct logical_volume {
uint32_t status;
uint32_t read_ahead;
int32_t minor;
uint64_t size;
uint32_t le_count;

View File

@ -44,6 +44,8 @@ arg(lvmpartition_ARG, 'l', "lvmpartition", NULL)
arg(list_ARG, 'l', "list", NULL)
arg(size_ARG, 'L', "size", size_arg)
arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign)
arg(persistent_ARG, 'M', "persistent", yes_no_arg)
arg(minor_ARG, 'm', "minor", minor_arg)
arg(maps_ARG, 'm', "maps", NULL)
arg(name_ARG, 'n', "name", string_arg)
arg(oldpath_ARG, 'n', "oldpath", NULL)

View File

@ -53,6 +53,7 @@ xx(lvchange,
"\t[-C/--contiguous y/n]\n"
"\t[-d/--debug]\n"
"\t[-h/-?/--help]\n"
"\t[-M/--persistent y/n] [--minor minor]\n"
"\t[-P/--partial] " "\n"
"\t[-p/--permission r/rw]\n"
"\t[-r/--readahead ReadAheadSectors]\n"
@ -60,7 +61,8 @@ xx(lvchange,
"\t[-v/--verbose]\n"
"\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
autobackup_ARG, available_ARG, contiguous_ARG, partial_ARG,
autobackup_ARG, available_ARG, contiguous_ARG,
minor_ARG, persistent_ARG, partial_ARG,
permission_ARG, readahead_ARG, test_ARG)
xx(lvcreate,
@ -73,6 +75,7 @@ xx(lvcreate,
"\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]" "\n"
"\t{-l|--extents LogicalExtentsNumber |" "\n"
"\t -L|--size LogicalVolumeSize[kKmMgGtT]} " "\n"
"\t[-M|--persistent {y|n}] [--minor minor]\n"
"\t[-n|--name LogicalVolumeName]" "\n"
"\t[-p|--permission {r|rw}] " "\n"
"\t[-r|--readahead ReadAheadSectors]" "\n"
@ -96,8 +99,9 @@ chunksize_ARG,
snapshot_ARG,
*/
autobackup_ARG, contiguous_ARG, stripes_ARG, stripesize_ARG,
autobackup_ARG, contiguous_ARG, stripes_ARG, stripesize_ARG,
extents_ARG, size_ARG, name_ARG, permission_ARG, readahead_ARG,
minor_ARG, persistent_ARG,
test_ARG, zero_ARG)
xx(lvdisplay,

View File

@ -25,12 +25,14 @@ static int lvchange_permission(struct logical_volume *lv);
static int lvchange_availability(struct logical_volume *lv);
static int lvchange_contiguous(struct logical_volume *lv);
static int lvchange_readahead(struct logical_volume *lv);
static int lvchange_persistent(struct logical_volume *lv);
int lvchange(int argc, char **argv)
{
if (!arg_count(available_ARG) && !arg_count(contiguous_ARG)
&& !arg_count(permission_ARG) && !arg_count(readahead_ARG)) {
log_error("One or more of -a, -C, -p or -r required");
&& !arg_count(permission_ARG) && !arg_count(readahead_ARG)
&& !arg_count(minor_ARG) && !arg_count(persistent_ARG)) {
log_error("One or more of -a, -C, -m, -M, -p or -r required");
return EINVALID_CMD_LINE;
}
@ -39,6 +41,11 @@ int lvchange(int argc, char **argv)
return EINVALID_CMD_LINE;
}
if (arg_count(minor_ARG) && argc != 1) {
log_error("Only give one logical volume when specifying minor");
return EINVALID_CMD_LINE;
}
return process_each_lv(argc, argv, &lvchange_single);
}
@ -49,9 +56,9 @@ static int lvchange_single(struct logical_volume *lv)
if (!(lv->vg->status & LVM_WRITE) &&
(arg_count(contiguous_ARG) || arg_count(permission_ARG) ||
arg_count(readahead_ARG))) {
log_error("Only -a permitted with read-only volume group \"%s\"",
lv->vg->name);
arg_count(readahead_ARG) || arg_count(persistent_ARG))) {
log_error("Only -a permitted with read-only volume "
"group \"%s\"", lv->vg->name);
return EINVALID_CMD_LINE;
}
@ -62,7 +69,8 @@ static int lvchange_single(struct logical_volume *lv)
}
if (lv->status & SNAPSHOT) {
log_error("Can't change snapshot logical volume \"%s\"", lv->name);
log_error("Can't change snapshot logical volume \"%s\"",
lv->name);
return ECMD_FAILED;
}
@ -90,6 +98,14 @@ static int lvchange_single(struct logical_volume *lv)
doit += lvchange_readahead(lv);
}
/* read ahead sector change */
if (arg_count(persistent_ARG)) {
if (!archived && !archive(lv->vg))
return ECMD_FAILED;
archived = 1;
doit += lvchange_persistent(lv);
}
if (doit)
log_print("Logical volume \"%s\" changed", lv->name);
@ -147,18 +163,24 @@ static int lvchange_availability(struct logical_volume *lv)
if (strcmp(arg_str_value(available_ARG, "n"), "n"))
activate = 1;
if (arg_count(minor_ARG)) {
lv->minor = arg_int_value(minor_ARG, -1);
}
if ((active = lv_active(lv)) < 0) {
log_error("Unable to determine status of \"%s\"", lv->name);
return 0;
}
if (activate && active) {
log_verbose("Logical volume \"%s\" is already active", lv->name);
log_verbose("Logical volume \"%s\" is already active",
lv->name);
return 0;
}
if (!activate && !active) {
log_verbose("Logical volume \"%s\" is already inactive", lv->name);
log_verbose("Logical volume \"%s\" is already inactive",
lv->name);
return 0;
}
@ -261,3 +283,40 @@ static int lvchange_readahead(struct logical_volume *lv)
return 1;
}
static int lvchange_persistent(struct logical_volume *lv)
{
if (!strcmp(arg_str_value(persistent_ARG, "n"), "n")) {
if (!(lv->status & FIXED_MINOR)) {
log_error("Minor number is already not persistent "
"for \"%s\"", lv->name);
return 0;
}
lv->status &= ~FIXED_MINOR;
lv->minor = -1;
log_verbose("Disabling persistent minor for \"%s\"", lv->name);
} else {
if (lv_active(lv)) {
log_error("Cannot change minor number when active");
return 0;
}
if (!arg_count(minor_ARG)) {
log_error("Minor number must be specified with -My");
return 0;
}
lv->status |= FIXED_MINOR;
lv->minor = arg_int_value(minor_ARG, -1);
log_verbose("Setting persistent minor number to %d for \"%s\"",
lv->minor, lv->name);
}
log_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
if (!fid->ops->vg_write(fid, lv->vg))
return 0;
backup(lv->vg);
return 1;
}

View File

@ -213,6 +213,24 @@ int lvcreate(int argc, char **argv)
lv->read_ahead = read_ahead;
}
if (arg_count(minor_ARG)) {
lv->status |= FIXED_MINOR;
lv->minor = arg_int_value(minor_ARG, -1);
log_verbose("Setting minor number to %d", lv->minor);
}
if (arg_count(persistent_ARG)) {
if (!strcmp(arg_str_value(persistent_ARG, "n"), "n"))
lv->status &= ~FIXED_MINOR;
else
if (!arg_count(minor_ARG)) {
log_error("Please specify minor number with "
"--minor when using -My");
return ECMD_FAILED;
}
lv->status |= FIXED_MINOR;
}
/* store vg on disk(s) */
if (!fid->ops->vg_write(fid, vg))
return ECMD_FAILED;

View File

@ -294,6 +294,21 @@ int int_arg_with_sign(struct arg *a)
return 1;
}
int minor_arg(struct arg *a)
{
char *ptr;
if (!_get_int_arg(a, &ptr) || (*ptr) || (a->sign == SIGN_MINUS))
return 0;
if (a->i_value > 255) {
log_error("Minor number outside range 0-255");
return 0;
}
return 1;
}
int string_arg(struct arg *a)
{
return 1;

View File

@ -109,6 +109,7 @@ int yes_no_arg(struct arg *a);
int size_arg(struct arg *a);
int int_arg(struct arg *a);
int int_arg_with_sign(struct arg *a);
int minor_arg(struct arg *a);
int string_arg(struct arg *a);
int permission_arg(struct arg *a);