summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/geom/class/concat/gconcat.828
-rw-r--r--sbin/geom/class/concat/geom_concat.c35
-rw-r--r--sbin/geom/class/stripe/geom_stripe.c29
-rw-r--r--sbin/geom/class/stripe/gstripe.828
-rw-r--r--sys/geom/concat/g_concat.c10
-rw-r--r--sys/geom/concat/g_concat.h11
-rw-r--r--sys/geom/mirror/g_mirror.c10
-rw-r--r--sys/geom/mirror/g_mirror.h15
-rw-r--r--sys/geom/stripe/g_stripe.c10
-rw-r--r--sys/geom/stripe/g_stripe.h11
10 files changed, 139 insertions, 48 deletions
diff --git a/sbin/geom/class/concat/gconcat.8 b/sbin/geom/class/concat/gconcat.8
index eaccceb..e7e06a7 100644
--- a/sbin/geom/class/concat/gconcat.8
+++ b/sbin/geom/class/concat/gconcat.8
@@ -35,35 +35,35 @@
.Cm create
.Op Fl v
.Ar name
-.Ar dev1
-.Ar dev2
-.Op Ar dev3 Op Ar ...
+.Ar prov
+.Ar prov
+.Op Ar prov Op Ar ...
.Nm
.Cm destroy
.Op Fl fv
.Ar name
-.Op Ar name2 Op Ar ...
+.Op Ar name Op Ar ...
.Nm
.Cm label
-.Op Fl v
+.Op Fl hv
.Ar name
-.Ar dev1
-.Ar dev2
-.Op Ar dev3 Op Ar ...
+.Ar prov
+.Ar prov
+.Op Ar prov Op Ar ...
.Nm
.Cm stop
.Op Fl fv
.Ar name
-.Op Ar name2 Op Ar ...
+.Op Ar name Op Ar ...
.Nm
.Cm clear
.Op Fl v
-.Ar dev1
-.Op Ar dev2 Op Ar ...
+.Ar prov
+.Op Ar prov Op Ar ...
.Nm
.Cm dump
-.Ar dev1
-.Op Ar dev2 Op Ar ...
+.Ar prov
+.Op Ar prov Op Ar ...
.Nm
.Cm list
.Op Ar name Op Ar ...
@@ -140,6 +140,8 @@ Additional options:
.Bl -tag -width indent
.It Fl f
Force the removal of the specified concatenated device.
+.It Fl h
+Hardcode providers' names in metadata.
.It Fl v
Be more verbose.
.El
diff --git a/sbin/geom/class/concat/geom_concat.c b/sbin/geom/class/concat/geom_concat.c
index 49e6101..c97027a 100644
--- a/sbin/geom/class/concat/geom_concat.c
+++ b/sbin/geom/class/concat/geom_concat.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <errno.h>
+#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -59,7 +60,12 @@ struct g_command class_commands[] = {
}
},
{ "dump", 0, concat_main, G_NULL_OPTS },
- { "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, concat_main, G_NULL_OPTS },
+ { "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, concat_main,
+ {
+ { 'h', "hardcode", NULL, G_TYPE_NONE },
+ G_OPT_SENTINEL
+ }
+ },
{ "stop", G_FLAG_VERBOSE, NULL,
{
{ 'f', "force", NULL, G_TYPE_NONE },
@@ -77,12 +83,12 @@ void
usage(const char *name)
{
- fprintf(stderr, "usage: %s create [-v] <name> <dev1> <dev2> [dev3 [...]]\n", name);
- fprintf(stderr, " %s destroy [-fv] <name> [name2 [...]]\n", name);
- fprintf(stderr, " %s label [-v] <name> <dev1> <dev2> [dev3 [...]]\n", name);
- fprintf(stderr, " %s stop [-fv] <name> [name2 [...]]\n", name);
- fprintf(stderr, " %s clear [-v] <dev1> [dev2 [...]]\n", name);
- fprintf(stderr, " %s dump <dev1> [dev2 [...]]\n", name);
+ fprintf(stderr, "usage: %s create [-v] <name> <prov> <prov> [prov [...]]\n", name);
+ fprintf(stderr, " %s destroy [-fv] <name> [name [...]]\n", name);
+ fprintf(stderr, " %s label [-hv] <name> <prov> <prov> [prov [...]]\n", name);
+ fprintf(stderr, " %s stop [-fv] <name> [name [...]]\n", name);
+ fprintf(stderr, " %s clear [-v] <prov> [prov [...]]\n", name);
+ fprintf(stderr, " %s dump <prov> [prov [...]]\n", name);
}
static void
@@ -116,7 +122,7 @@ concat_label(struct gctl_req *req)
const char *name;
char param[16];
unsigned i;
- int *nargs, error;
+ int *hardcode, *nargs, error;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
@@ -127,6 +133,11 @@ concat_label(struct gctl_req *req)
gctl_error(req, "Too few arguments.");
return;
}
+ hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
+ if (hardcode == NULL) {
+ gctl_error(req, "No '%s' argument.", "hardcode");
+ return;
+ }
/*
* Clear last sector first to spoil all components if device exists.
@@ -162,6 +173,13 @@ concat_label(struct gctl_req *req)
name = gctl_get_asciiparam(req, param);
md.md_no = i - 1;
+ if (!*hardcode)
+ bzero(md.md_provider, sizeof(md.md_provider));
+ else {
+ if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) == 0)
+ name += strlen(_PATH_DEV);
+ strlcpy(md.md_provider, name, sizeof(md.md_provider));
+ }
concat_metadata_encode(&md, sector);
error = g_metadata_store(name, sector, sizeof(sector));
if (error != 0) {
@@ -219,6 +237,7 @@ concat_metadata_dump(const struct g_concat_metadata *md)
printf(" Device ID: %u\n", (u_int)md->md_id);
printf(" Disk number: %u\n", (u_int)md->md_no);
printf("Total number of disks: %u\n", (u_int)md->md_all);
+ printf(" Hardcoded provider: %s\n", md->md_provider);
}
static void
diff --git a/sbin/geom/class/stripe/geom_stripe.c b/sbin/geom/class/stripe/geom_stripe.c
index 5b6a9a3..9c47ef4 100644
--- a/sbin/geom/class/stripe/geom_stripe.c
+++ b/sbin/geom/class/stripe/geom_stripe.c
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <errno.h>
+#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -69,6 +70,7 @@ struct g_command class_commands[] = {
{ "dump", 0, stripe_main, G_NULL_OPTS },
{ "label", G_FLAG_VERBOSE | G_FLAG_LOADKLD, stripe_main,
{
+ { 'h', "hardcode", NULL, G_TYPE_NONE },
{ 's', "stripesize", &stripesize, G_TYPE_NUMBER },
G_OPT_SENTINEL
}
@@ -89,12 +91,12 @@ void
usage(const char *name)
{
- fprintf(stderr, "usage: %s create [-v] [-s stripesize] <name> <dev1> <dev2> [dev3 [...]]\n", name);
- fprintf(stderr, " %s destroy [-fv] <name> [name2 [...]]\n", name);
- fprintf(stderr, " %s label [-v] [-s stripesize] <name> <dev1> <dev2> [dev3 [...]]\n", name);
- fprintf(stderr, " %s stop [-fv] <name> [name2 [...]]\n", name);
- fprintf(stderr, " %s clear [-v] <dev1> [dev2 [...]]\n", name);
- fprintf(stderr, " %s dump <dev1> [dev2 [...]]\n", name);
+ fprintf(stderr, "usage: %s create [-hv] [-s stripesize] <name> <prov> <prov> [prov [...]]\n", name);
+ fprintf(stderr, " %s destroy [-fv] <name> [name [...]]\n", name);
+ fprintf(stderr, " %s label [-hv] [-s stripesize] <name> <prov> <prov> [prov [...]]\n", name);
+ fprintf(stderr, " %s stop [-fv] <name> [name [...]]\n", name);
+ fprintf(stderr, " %s clear [-v] <prov> [prov [...]]\n", name);
+ fprintf(stderr, " %s dump <prov> [prov [...]]\n", name);
}
static void
@@ -129,7 +131,7 @@ stripe_label(struct gctl_req *req)
const char *name;
char param[16];
unsigned i;
- int *nargs, error;
+ int *hardcode, *nargs, error;
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
if (nargs == NULL) {
@@ -140,6 +142,11 @@ stripe_label(struct gctl_req *req)
gctl_error(req, "Too few arguments.");
return;
}
+ hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode));
+ if (hardcode == NULL) {
+ gctl_error(req, "No '%s' argument.", "hardcode");
+ return;
+ }
/*
* Clear last sector first to spoil all components if device exists.
@@ -181,6 +188,13 @@ stripe_label(struct gctl_req *req)
name = gctl_get_asciiparam(req, param);
md.md_no = i - 1;
+ if (!*hardcode)
+ bzero(md.md_provider, sizeof(md.md_provider));
+ else {
+ if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) == 0)
+ name += strlen(_PATH_DEV);
+ strlcpy(md.md_provider, name, sizeof(md.md_provider));
+ }
stripe_metadata_encode(&md, sector);
error = g_metadata_store(name, sector, sizeof(sector));
if (error != 0) {
@@ -239,6 +253,7 @@ stripe_metadata_dump(const struct g_stripe_metadata *md)
printf(" Disk number: %u\n", (u_int)md->md_no);
printf("Total number of disks: %u\n", (u_int)md->md_all);
printf(" Stripe size: %u\n", (u_int)md->md_stripesize);
+ printf(" Hardcoded provider: %s\n", md->md_provider);
}
static void
diff --git a/sbin/geom/class/stripe/gstripe.8 b/sbin/geom/class/stripe/gstripe.8
index fbf4bf1..ddf7d90 100644
--- a/sbin/geom/class/stripe/gstripe.8
+++ b/sbin/geom/class/stripe/gstripe.8
@@ -36,36 +36,36 @@
.Op Fl v
.Op Fl s Ar stripesize
.Ar name
-.Ar dev1
-.Ar dev2
-.Op Ar dev3 Op Ar ...
+.Ar prov
+.Ar prov
+.Op Ar prov Op Ar ...
.Nm
.Cm destroy
.Op Fl fv
.Ar name
-.Op Ar name2 Op Ar ...
+.Op Ar name Op Ar ...
.Nm
.Cm label
-.Op Fl v
+.Op Fl hv
.Op Fl s Ar stripesize
.Ar name
-.Ar dev1
-.Ar dev2
-.Op Ar dev3 Op Ar ...
+.Ar prov
+.Ar prov
+.Op Ar prov Op Ar ...
.Nm
.Cm stop
.Op Fl fv
.Ar name
-.Op Ar name2 Op Ar ...
+.Op Ar name Op Ar ...
.Nm
.Cm clear
.Op Fl v
-.Ar dev1
-.Op Ar dev2 Op Ar ...
+.Ar prov
+.Op Ar prov Op Ar ...
.Nm
.Cm dump
-.Ar dev1
-.Op Ar dev2 Op Ar ...
+.Ar prov
+.Op Ar prov Op Ar ...
.Nm
.Cm list
.Op Ar name Op Ar ...
@@ -142,6 +142,8 @@ Additional options:
.Bl -tag -width ".Fl s Ar stripesize"
.It Fl f
Force the removal of the specified striped device.
+.It Fl h
+Hardcode providers' names in metadata.
.It Fl s Ar stripesize
Specifies size of stripe block.
.It Fl v
diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c
index 480b30d..8103ea6 100644
--- a/sys/geom/concat/g_concat.c
+++ b/sys/geom/concat/g_concat.c
@@ -567,6 +567,15 @@ g_concat_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
pp->name);
return (NULL);
}
+ /*
+ * Backward compatibility:
+ * There was no md_provider field in earlier versions of metadata.
+ */
+ if (md.md_version < 3)
+ bzero(md.md_provider, sizeof(md.md_provider));
+
+ if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0)
+ return (NULL);
/*
* Let's check if device already exists.
@@ -650,6 +659,7 @@ g_concat_ctl_create(struct gctl_req *req, struct g_class *mp)
md.md_id = arc4random();
md.md_no = 0;
md.md_all = *nargs - 1;
+ bzero(md.md_provider, sizeof(md.md_provider));
/* Check all providers are valid */
for (no = 1; no < *nargs; no++) {
diff --git a/sys/geom/concat/g_concat.h b/sys/geom/concat/g_concat.h
index 2c2296f..5cf8757 100644
--- a/sys/geom/concat/g_concat.h
+++ b/sys/geom/concat/g_concat.h
@@ -34,7 +34,13 @@
#define G_CONCAT_CLASS_NAME "CONCAT"
#define G_CONCAT_MAGIC "GEOM::CONCAT"
-#define G_CONCAT_VERSION 2
+/*
+ * Version history:
+ * 1 - Initial version number.
+ * 2 - Added 'stop' command to gconcat(8).
+ * 3 - Added md_provider field to metadata and '-h' option to gconcat(8).
+ */
+#define G_CONCAT_VERSION 3
#ifdef _KERNEL
#define G_CONCAT_TYPE_MANUAL 0
@@ -86,6 +92,7 @@ struct g_concat_metadata {
uint32_t md_id; /* Unique ID. */
uint16_t md_no; /* Disk number. */
uint16_t md_all; /* Number of all disks. */
+ char md_provider[16]; /* Hardcoded provider. */
};
static __inline void
concat_metadata_encode(const struct g_concat_metadata *md, u_char *data)
@@ -97,6 +104,7 @@ concat_metadata_encode(const struct g_concat_metadata *md, u_char *data)
le32enc(data + 36, md->md_id);
le16enc(data + 40, md->md_no);
le16enc(data + 42, md->md_all);
+ bcopy(md->md_provider, data + 44, sizeof(md->md_provider));
}
static __inline void
concat_metadata_decode(const u_char *data, struct g_concat_metadata *md)
@@ -108,5 +116,6 @@ concat_metadata_decode(const u_char *data, struct g_concat_metadata *md)
md->md_id = le32dec(data + 36);
md->md_no = le16dec(data + 40);
md->md_all = le16dec(data + 42);
+ bcopy(data + 44, md->md_provider, sizeof(md->md_provider));
}
#endif /* _G_CONCAT_H_ */
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c
index 427bc44..fed14a4 100644
--- a/sys/geom/mirror/g_mirror.c
+++ b/sys/geom/mirror/g_mirror.c
@@ -382,6 +382,8 @@ g_mirror_init_disk(struct g_mirror_softc *sc, struct g_provider *pp,
disk->d_delay.frac = 0;
binuptime(&disk->d_last_used);
disk->d_flags = md->md_dflags;
+ if (md->md_provider[0] != '\0')
+ disk->d_flags |= G_MIRROR_DISK_FLAG_HARDCODED;
disk->d_sync.ds_consumer = NULL;
disk->d_sync.ds_offset = md->md_sync_offset;
disk->d_sync.ds_offset_done = md->md_sync_offset;
@@ -621,6 +623,7 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk,
md->md_mediasize = sc->sc_mediasize;
md->md_sectorsize = sc->sc_sectorsize;
md->md_mflags = (sc->sc_flags & G_MIRROR_DEVICE_FLAG_MASK);
+ bzero(md->md_provider, sizeof(md->md_provider));
if (disk == NULL) {
md->md_did = arc4random();
md->md_priority = 0;
@@ -636,6 +639,11 @@ g_mirror_fill_metadata(struct g_mirror_softc *sc, struct g_mirror_disk *disk,
md->md_sync_offset = disk->d_sync.ds_offset_done;
else
md->md_sync_offset = 0;
+ if ((disk->d_flags & G_MIRROR_DISK_FLAG_HARDCODED) != 0) {
+ strlcpy(md->md_provider,
+ disk->d_consumer->provider->name,
+ sizeof(md->md_provider));
+ }
}
}
@@ -2491,6 +2499,8 @@ g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
pp->name);
return (NULL);
}
+ if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0)
+ return (NULL);
if ((md.md_dflags & G_MIRROR_DISK_FLAG_INACTIVE) != 0) {
G_MIRROR_DEBUG(0,
"Device %s: provider %s marked as inactive, skipping.",
diff --git a/sys/geom/mirror/g_mirror.h b/sys/geom/mirror/g_mirror.h
index 5be5cda..77dc433 100644
--- a/sys/geom/mirror/g_mirror.h
+++ b/sys/geom/mirror/g_mirror.h
@@ -49,6 +49,7 @@
#define G_MIRROR_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL
#define G_MIRROR_DISK_FLAG_FORCE_SYNC 0x0000000000000004ULL
#define G_MIRROR_DISK_FLAG_INACTIVE 0x0000000000000008ULL
+#define G_MIRROR_DISK_FLAG_HARDCODED 0x0000000000000010ULL
#define G_MIRROR_DISK_FLAG_MASK (G_MIRROR_DISK_FLAG_DIRTY | \
G_MIRROR_DISK_FLAG_SYNCHRONIZING | \
G_MIRROR_DISK_FLAG_FORCE_SYNC | \
@@ -210,6 +211,7 @@ struct g_mirror_metadata {
uint64_t md_sync_offset; /* Synchronized offset. */
uint64_t md_mflags; /* Additional mirror flags. */
uint64_t md_dflags; /* Additional disk flags. */
+ char md_provider[16]; /* Hardcoded provider. */
u_char md_hash[16]; /* MD5 hash. */
};
static __inline void
@@ -232,10 +234,11 @@ mirror_metadata_encode(struct g_mirror_metadata *md, u_char *data)
le64enc(data + 67, md->md_sync_offset);
le64enc(data + 75, md->md_mflags);
le64enc(data + 83, md->md_dflags);
+ bcopy(md->md_provider, data + 91, 16);
MD5Init(&ctx);
- MD5Update(&ctx, data, 91);
+ MD5Update(&ctx, data, 107);
MD5Final(md->md_hash, &ctx);
- bcopy(md->md_hash, data + 91, 16);
+ bcopy(md->md_hash, data + 107, 16);
}
static __inline int
mirror_metadata_decode(const u_char *data, struct g_mirror_metadata *md)
@@ -257,11 +260,12 @@ mirror_metadata_decode(const u_char *data, struct g_mirror_metadata *md)
md->md_sync_offset = le64dec(data + 67);
md->md_mflags = le64dec(data + 75);
md->md_dflags = le64dec(data + 83);
- bcopy(data + 91, md->md_hash, 16);
+ bcopy(data + 91, md->md_provider, 16);
+ bcopy(data + 107, md->md_hash, 16);
MD5Init(&ctx);
- MD5Update(&ctx, data, 91);
+ MD5Update(&ctx, data, 107);
MD5Final(md->md_hash, &ctx);
- if (bcmp(md->md_hash, data + 91, 16) != 0)
+ if (bcmp(md->md_hash, data + 107, 16) != 0)
return (EINVAL);
return (0);
}
@@ -345,6 +349,7 @@ mirror_metadata_dump(const struct g_mirror_metadata *md)
printf(" INACTIVE");
}
printf("\n");
+ printf("hcprovider: %s\n", md->md_provider);
bzero(hash, sizeof(hash));
for (i = 0; i < 16; i++) {
hash[i * 2] = hex[md->md_hash[i] >> 4];
diff --git a/sys/geom/stripe/g_stripe.c b/sys/geom/stripe/g_stripe.c
index 017cf3c..a661704 100644
--- a/sys/geom/stripe/g_stripe.c
+++ b/sys/geom/stripe/g_stripe.c
@@ -898,6 +898,15 @@ g_stripe_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
pp->name);
return (NULL);
}
+ /*
+ * Backward compatibility:
+ * There was no md_provider field in earlier versions of metadata.
+ */
+ if (md.md_version < 2)
+ bzero(md.md_provider, sizeof(md.md_provider));
+
+ if (md.md_provider[0] != '\0' && strcmp(md.md_provider, pp->name) != 0)
+ return (NULL);
/*
* Let's check if device already exists.
@@ -988,6 +997,7 @@ g_stripe_ctl_create(struct gctl_req *req, struct g_class *mp)
return;
}
md.md_stripesize = *stripesize;
+ bzero(md.md_provider, sizeof(md.md_provider));
/* Check all providers are valid */
for (no = 1; no < *nargs; no++) {
diff --git a/sys/geom/stripe/g_stripe.h b/sys/geom/stripe/g_stripe.h
index 5f4edc9..5a7825b 100644
--- a/sys/geom/stripe/g_stripe.h
+++ b/sys/geom/stripe/g_stripe.h
@@ -34,7 +34,13 @@
#define G_STRIPE_CLASS_NAME "STRIPE"
#define G_STRIPE_MAGIC "GEOM::STRIPE"
-#define G_STRIPE_VERSION 1
+/*
+ * Version history:
+ * 0 - Initial version number.
+ * 1 - Added 'stop' command for gstripe(8).
+ * 2 - Added md_provider field to metadata and '-h' option for gstripe(8).
+ */
+#define G_STRIPE_VERSION 2
#ifdef _KERNEL
#define G_STRIPE_TYPE_MANUAL 0
@@ -81,6 +87,7 @@ struct g_stripe_metadata {
uint16_t md_no; /* Disk number. */
uint16_t md_all; /* Number of all disks. */
uint32_t md_stripesize; /* Stripe size. */
+ char md_provider[16]; /* Hardcoded provider. */
};
static __inline void
stripe_metadata_encode(const struct g_stripe_metadata *md, u_char *data)
@@ -93,6 +100,7 @@ stripe_metadata_encode(const struct g_stripe_metadata *md, u_char *data)
le16enc(data + 40, md->md_no);
le16enc(data + 42, md->md_all);
le32enc(data + 44, md->md_stripesize);
+ bcopy(md->md_provider, data + 48, sizeof(md->md_provider));
}
static __inline void
stripe_metadata_decode(const u_char *data, struct g_stripe_metadata *md)
@@ -105,6 +113,7 @@ stripe_metadata_decode(const u_char *data, struct g_stripe_metadata *md)
md->md_no = le16dec(data + 40);
md->md_all = le16dec(data + 42);
md->md_stripesize = le32dec(data + 44);
+ bcopy(data + 48, md->md_provider, sizeof(md->md_provider));
}
#ifndef BITCOUNT
OpenPOWER on IntegriCloud