summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/activate/dev_manager.c13
-rw-r--r--lib/config/defaults.h2
-rw-r--r--lib/display/display.c5
-rw-r--r--lib/format1/import-export.c7
-rw-r--r--lib/format_text/export.c2
-rw-r--r--lib/format_text/import_vsn1.c8
-rw-r--r--lib/metadata/lv_manip.c1
-rw-r--r--lib/metadata/metadata.h1
-rw-r--r--lib/report/columns.h5
-rw-r--r--tools/args.h3
-rw-r--r--tools/commands.h10
-rw-r--r--tools/lvchange.c33
-rw-r--r--tools/lvcreate.c16
-rw-r--r--tools/lvm.c17
-rw-r--r--tools/tools.h1
15 files changed, 98 insertions, 26 deletions
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 6e8e851d..e4ba73f2 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -445,8 +445,19 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
}
/*
- * Do we want a specific minor number ?
+ * Do we want a specific device number ?
*/
+ if (dl->lv->major >= 0 && _get_flag(dl, VISIBLE)) {
+ if (!dm_task_set_major(dmt, dl->lv->major)) {
+ log_error("Failed to set major number for %s to %d "
+ "during activation.", dl->name,
+ dl->lv->major);
+ goto out;
+ } else
+ log_very_verbose("Set major number for %s to %d.",
+ dl->name, dl->lv->major);
+ }
+
if (dl->lv->minor >= 0 && _get_flag(dl, VISIBLE)) {
if (!dm_task_set_minor(dmt, dl->lv->minor)) {
log_error("Failed to set minor number for %s to %d "
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 7961645e..5f643c34 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -71,7 +71,7 @@
#define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
#define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
-#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_minor,origin,snap_percent,lv_uuid"
+#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,origin,snap_percent,lv_uuid"
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
diff --git a/lib/display/display.c b/lib/display/display.c
index c860a32f..7853faef 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -461,8 +461,11 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
log_print("Allocation %s", get_alloc_string(lv->alloc));
log_print("Read ahead sectors %u", lv->read_ahead);
- if (lv->status & FIXED_MINOR)
+ if (lv->status & FIXED_MINOR) {
+ if (lv->major >= 0)
+ log_print("Persistent major %d", lv->major);
log_print("Persistent minor %d", lv->minor);
+ }
if (inkernel)
log_print("Block device %d:%d", info.major,
diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c
index 0fb5f3d7..3d0bc77d 100644
--- a/lib/format1/import-export.c
+++ b/lib/format1/import-export.c
@@ -288,8 +288,11 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
if (lvd->lv_status & LV_PERSISTENT_MINOR) {
lv->status |= FIXED_MINOR;
lv->minor = MINOR(lvd->lv_dev);
- } else
+ lv->major = MAJOR(lvd->lv_dev);
+ } else {
+ lv->major = -1;
lv->minor = -1;
+ }
if (lvd->lv_access & LV_READ)
lv->status |= LVM_READ;
@@ -335,7 +338,7 @@ static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
if (lv->status & FIXED_MINOR) {
lvd->lv_status |= LV_PERSISTENT_MINOR;
- lvd->lv_dev = MKDEV(0, lv->minor);
+ lvd->lv_dev = MKDEV(lv->major, lv->minor);
}
lvd->lv_read_ahead = lv->read_ahead;
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index 50b36a34..66609d39 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -547,6 +547,8 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
get_alloc_string(lv->alloc));
if (lv->read_ahead)
_outf(f, "read_ahead = %u", lv->read_ahead);
+ if (lv->major >= 0)
+ _outf(f, "major = %d", lv->major);
if (lv->minor >= 0)
_outf(f, "minor = %d", lv->minor);
_outf(f, "segment_count = %u", _count_segments(lv));
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index bf1e0b5a..c10d765f 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -532,9 +532,15 @@ static int _read_lv(struct format_instance *fid, struct pool *mem,
if ((lv->status & FIXED_MINOR) &&
!_read_int32(lvn, "minor", &lv->minor)) {
log_error("Couldn't read minor number for logical "
- "volume.");
+ "volume %s.", lv->name);
return 0;
}
+ lv->major = -1;
+ if ((lv->status & FIXED_MINOR) &&
+ !_read_int32(lvn, "major", &lv->major)) {
+ log_error("Couldn't read major number for logical "
+ "volume %s.", lv->name);
+ }
vg->lv_count++;
list_add(&vg->lvs, &lvl->list);
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 3fc8a712..120ea4ae 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -425,6 +425,7 @@ struct logical_volume *lv_create(struct format_instance *fi,
lv->status = status;
lv->alloc = alloc;
lv->read_ahead = 0;
+ lv->major = -1;
lv->minor = -1;
lv->size = (uint64_t) extents *vg->extent_size;
lv->le_count = extents;
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index a99c7c37..7c0c836d 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -196,6 +196,7 @@ struct logical_volume {
uint32_t status;
alloc_policy_t alloc;
uint32_t read_ahead;
+ int32_t major;
int32_t minor;
uint64_t size;
diff --git a/lib/report/columns.h b/lib/report/columns.h
index b2eb3cad..3aa89670 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -7,9 +7,12 @@
/* Report type, Containing struct, Field type, Report heading,
* Data field with struct to pass to display function, Minimum display width,
* Display Fn, Unique format identifier */
+
+/* *INDENT-OFF* */
FIELD(LVS, lv, STR, "LV UUID", lvid.id[1], 38, uuid, "lv_uuid")
FIELD(LVS, lv, STR, "LV", name, 4, string, "lv_name")
FIELD(LVS, lv, STR, "Attr", lvid, 4, lvstatus, "lv_attr")
+FIELD(LVS, lv, NUM, "Maj", major, 3, int32, "lv_major")
FIELD(LVS, lv, NUM, "Min", minor, 3, int32, "lv_minor")
FIELD(LVS, lv, NUM, "LSize", size, 5, size64, "lv_size")
FIELD(LVS, lv, NUM, "#Seg", lvid, 4, lvsegcount, "seg_count")
@@ -49,4 +52,4 @@ FIELD(SEGS, seg, NUM, "Stripe", stripe_size, 6, size32, "stripesize")
FIELD(SEGS, seg, NUM, "Chunk", chunk_size, 5, size32, "chunksize")
FIELD(SEGS, seg, NUM, "Start", list, 5, segstart, "seg_start")
FIELD(SEGS, seg, NUM, "SSize", list, 5, segsize, "seg_size")
-
+/* *INDENT-ON* */
diff --git a/tools/args.h b/tools/args.h
index 32631901..df6c4660 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -8,6 +8,7 @@
* Put all long args that don't have a
* corresponding short option first ...
*/
+/* *INDENT-OFF* */
arg(version_ARG, '\0', "version", NULL)
arg(quiet_ARG, '\0', "quiet", NULL)
arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", size_mb_arg)
@@ -61,6 +62,7 @@ arg(list_ARG, 'l', "list", NULL)
arg(size_ARG, 'L', "size", size_mb_arg)
arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign)
arg(persistent_ARG, 'M', "persistent", yes_no_arg)
+arg(major_ARG, 'j', "major", major_arg)
arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_arg)
arg(minor_ARG, 'm', "minor", minor_arg)
arg(maps_ARG, 'm', "maps", NULL)
@@ -94,3 +96,4 @@ arg(zero_ARG, 'Z', "zero", yes_no_arg)
/* this should always be last */
arg(ARG_COUNT, '-', "", NULL)
+/* *INDENT-ON* */
diff --git a/tools/commands.h b/tools/commands.h
index 4d8f9fd4..a4bd1bcc 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -56,7 +56,7 @@ xx(lvchange,
"\t[-d|--debug]\n"
"\t[-h|--help]\n"
"\t[--ignorelockingfailure]\n"
- "\t[-M|--persistent y|n] [--minor minor]\n"
+ "\t[-M|--persistent y|n] [--major major] [--minor minor]\n"
"\t[-P|--partial] " "\n"
"\t[-p|--permission r|rw]\n"
"\t[-r|--readahead ReadAheadSectors]\n"
@@ -66,7 +66,7 @@ xx(lvchange,
"\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
autobackup_ARG, available_ARG, contiguous_ARG,
- ignorelockingfailure_ARG, minor_ARG, partial_ARG, permission_ARG,
+ ignorelockingfailure_ARG, major_ARG, minor_ARG, partial_ARG, permission_ARG,
persistent_ARG, readahead_ARG, test_ARG)
xx(lvcreate,
@@ -79,7 +79,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[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[-p|--permission {r|rw}]\n"
"\t[-r|--readahead ReadAheadSectors]\n"
@@ -98,7 +98,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[-M|--persistent {y|n}] [--major major] [--minor minor]\n"
"\t[-n|--name LogicalVolumeName]\n"
"\t[-p|--permission {r|rw}]\n"
"\t[-r|--readahead ReadAheadSectors]\n"
@@ -107,7 +107,7 @@ xx(lvcreate,
"\t[--version]\n"
"\tOriginalLogicalVolume[Path] [PhysicalVolumePath...]\n\n",
- autobackup_ARG, chunksize_ARG, contiguous_ARG, extents_ARG, minor_ARG,
+ autobackup_ARG, chunksize_ARG, contiguous_ARG, extents_ARG, major_ARG, minor_ARG,
name_ARG, permission_ARG, persistent_ARG, readahead_ARG, size_ARG,
snapshot_ARG, stripes_ARG, stripesize_ARG, test_ARG, zero_ARG)
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 00010c04..b35c9beb 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -80,10 +80,6 @@ static int lvchange_availability(struct cmd_context *cmd,
if (strcmp(arg_str_value(cmd, available_ARG, "n"), "n"))
activate = 1;
- if (arg_count(cmd, minor_ARG)) {
- lv->minor = arg_int_value(cmd, minor_ARG, -1);
- }
-
if (activate) {
/* FIXME Tighter locking if lv_is_origin() */
log_verbose("Activating logical volume \"%s\"", lv->name);
@@ -218,12 +214,18 @@ static int lvchange_persistent(struct cmd_context *cmd,
}
lv->status &= ~FIXED_MINOR;
lv->minor = -1;
- log_verbose("Disabling persistent minor for \"%s\"", lv->name);
+ lv->major = -1;
+ log_verbose("Disabling persistent device number for \"%s\"",
+ lv->name);
} else {
- if (!arg_count(cmd, minor_ARG)) {
+ if (!arg_count(cmd, minor_ARG) && lv->minor < 0) {
log_error("Minor number must be specified with -My");
return 0;
}
+ if (!arg_count(cmd, major_ARG) && lv->major < 0) {
+ log_error("Major number must be specified with -My");
+ return 0;
+ }
log_verbose("Ensuring %s is inactive. Reactivate with -ay.",
lv->name);
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_DEACTIVATE)) {
@@ -231,9 +233,10 @@ static int lvchange_persistent(struct cmd_context *cmd,
return 0;
}
lv->status |= FIXED_MINOR;
- lv->minor = arg_int_value(cmd, minor_ARG, -1);
- log_verbose("Setting persistent minor number to %d for \"%s\"",
- lv->minor, lv->name);
+ lv->minor = arg_int_value(cmd, minor_ARG, lv->minor);
+ lv->major = arg_int_value(cmd, major_ARG, lv->major);
+ log_verbose("Setting persistent device number to (%d, %d) "
+ "for \"%s\"", lv->major, lv->minor, lv->name);
}
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_SUSPEND | LCK_HOLD)) {
@@ -333,8 +336,10 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
{
if (!arg_count(cmd, available_ARG) && !arg_count(cmd, contiguous_ARG)
&& !arg_count(cmd, permission_ARG) && !arg_count(cmd, readahead_ARG)
- && !arg_count(cmd, minor_ARG) && !arg_count(cmd, persistent_ARG)) {
- log_error("One or more of -a, -C, -m, -M, -p or -r required");
+ && !arg_count(cmd, minor_ARG) && !arg_count(cmd, major_ARG)
+ && !arg_count(cmd, persistent_ARG)) {
+ log_error
+ ("One or more of -a, -C, -j, -m, -M, -p or -r required");
return EINVALID_CMD_LINE;
}
@@ -350,6 +355,12 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
+ if ((arg_count(cmd, minor_ARG) || arg_count(cmd, major_ARG)) &&
+ !arg_count(cmd, persistent_ARG)) {
+ log_error("--major and --minor require -My");
+ return EINVALID_CMD_LINE;
+ }
+
if (arg_count(cmd, minor_ARG) && argc != 1) {
log_error("Only give one logical volume when specifying minor");
return EINVALID_CMD_LINE;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 1b92fc7f..83fea1f5 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -14,6 +14,7 @@ struct lvcreate_params {
int snapshot;
int zero;
int contiguous;
+ int major;
int minor;
char *origin;
@@ -258,6 +259,7 @@ static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd,
lp->permission = LVM_READ | LVM_WRITE;
lp->minor = arg_int_value(cmd, minor_ARG, -1);
+ lp->major = arg_int_value(cmd, major_ARG, -1);
/* Persistent minor */
if (arg_count(cmd, persistent_ARG)) {
@@ -267,9 +269,15 @@ static int _read_params(struct lvcreate_params *lp, struct cmd_context *cmd,
"--minor when using -My");
return 0;
}
+ if (lp->major == -1) {
+ log_error("Please specify major number with "
+ "--major when using -My");
+ return 0;
+ }
} else {
- if (lp->minor != -1) {
- log_error("--minor not possible with -Mn");
+ if ((lp->minor != -1) || (lp->major != -1)) {
+ log_error
+ ("--major and --minor incompatible with -Mn");
return 0;
}
}
@@ -432,9 +440,11 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
}
if (lp->minor >= 0) {
+ lv->major = lp->major;
lv->minor = lp->minor;
lv->status |= FIXED_MINOR;
- log_verbose("Setting minor number to %d", lv->minor);
+ log_verbose("Setting device number to (%d, %d)", lv->major,
+ lv->minor);
}
if (!archive(vg))
diff --git a/tools/lvm.c b/tools/lvm.c
index b94e98a0..302c6aa4 100644
--- a/tools/lvm.c
+++ b/tools/lvm.c
@@ -213,6 +213,23 @@ int minor_arg(struct cmd_context *cmd, struct arg *a)
return 1;
}
+int major_arg(struct cmd_context *cmd, 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("Major number outside range 0-255");
+ return 0;
+ }
+
+ /* FIXME Also Check against /proc/devices */
+
+ return 1;
+}
+
int string_arg(struct cmd_context *cmd, struct arg *a)
{
return 1;
diff --git a/tools/tools.h b/tools/tools.h
index 7f131b2d..873bad48 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -101,6 +101,7 @@ int size_kb_arg(struct cmd_context *cmd, struct arg *a);
int size_mb_arg(struct cmd_context *cmd, struct arg *a);
int int_arg(struct cmd_context *cmd, struct arg *a);
int int_arg_with_sign(struct cmd_context *cmd, struct arg *a);
+int major_arg(struct cmd_context *cmd, struct arg *a);
int minor_arg(struct cmd_context *cmd, struct arg *a);
int string_arg(struct cmd_context *cmd, struct arg *a);
int permission_arg(struct cmd_context *cmd, struct arg *a);