summaryrefslogtreecommitdiffstats
path: root/sbin/geom
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/geom')
-rw-r--r--sbin/geom/class/eli/geli.815
-rw-r--r--sbin/geom/class/eli/geom_eli.c47
2 files changed, 62 insertions, 0 deletions
diff --git a/sbin/geom/class/eli/geli.8 b/sbin/geom/class/eli/geli.8
index 6c46680..59361ec 100644
--- a/sbin/geom/class/eli/geli.8
+++ b/sbin/geom/class/eli/geli.8
@@ -134,6 +134,9 @@ utility:
.Fl s Ar oldsize
.Ar prov
.Nm
+.Cm version
+.Op Ar prov ...
+.Nm
.Cm clear
.Op Fl v
.Ar prov ...
@@ -597,6 +600,18 @@ Additional options include:
.It Fl s Ar oldsize
The size of the provider before it was resized.
.El
+.It Cm version
+If no arguments are given, the
+.Cm version
+subcommand will print the version of
+.Nm
+userland utility as well as the version of the
+.Nm ELI
+GEOM class.
+.Pp
+If GEOM providers are specified, the
+.Cm version
+subcommand will print metadata version used by each of them.
.It Cm clear
Clear metadata from the given providers.
.It Cm dump
diff --git a/sbin/geom/class/eli/geom_eli.c b/sbin/geom/class/eli/geom_eli.c
index 183b11c..f3553c5 100644
--- a/sbin/geom/class/eli/geom_eli.c
+++ b/sbin/geom/class/eli/geom_eli.c
@@ -72,6 +72,7 @@ static void eli_kill(struct gctl_req *req);
static void eli_backup(struct gctl_req *req);
static void eli_restore(struct gctl_req *req);
static void eli_resize(struct gctl_req *req);
+static void eli_version(struct gctl_req *req);
static void eli_clear(struct gctl_req *req);
static void eli_dump(struct gctl_req *req);
@@ -96,6 +97,7 @@ static int eli_backup_create(struct gctl_req *req, const char *prov,
* backup [-v] prov file
* restore [-fv] file prov
* resize [-v] -s oldsize prov
+ * version [prov ...]
* clear [-v] prov ...
* dump [-v] prov ...
*/
@@ -241,6 +243,9 @@ struct g_command class_commands[] = {
},
"[-v] -s oldsize prov"
},
+ { "version", G_FLAG_LOADKLD, eli_main, G_NULL_OPTS,
+ "[prov ...]"
+ },
{ "clear", G_FLAG_VERBOSE, eli_main, G_NULL_OPTS,
"[-v] prov ..."
},
@@ -309,6 +314,8 @@ eli_main(struct gctl_req *req, unsigned int flags)
eli_restore(req);
else if (strcmp(name, "resize") == 0)
eli_resize(req);
+ else if (strcmp(name, "version") == 0)
+ eli_version(req);
else if (strcmp(name, "dump") == 0)
eli_dump(req);
else if (strcmp(name, "clear") == 0)
@@ -1524,6 +1531,46 @@ out:
}
static void
+eli_version(struct gctl_req *req)
+{
+ struct g_eli_metadata md;
+ const char *name;
+ unsigned int version;
+ int error, i, nargs;
+
+ nargs = gctl_get_int(req, "nargs");
+
+ if (nargs == 0) {
+ unsigned int kernver;
+ ssize_t size;
+
+ size = sizeof(kernver);
+ if (sysctlbyname("kern.geom.eli.version", &kernver, &size,
+ NULL, 0) == -1) {
+ warn("Unable to obtain GELI kernel version");
+ } else {
+ printf("kernel: %u\n", kernver);
+ }
+ printf("userland: %u\n", G_ELI_VERSION);
+ return;
+ }
+
+ for (i = 0; i < nargs; i++) {
+ name = gctl_get_ascii(req, "arg%d", i);
+ error = g_metadata_read(name, (unsigned char *)&md,
+ sizeof(md), G_ELI_MAGIC);
+ if (error != 0) {
+ warn("%s: Unable to read metadata: %s.", name,
+ strerror(error));
+ gctl_error(req, "Not fully done.");
+ continue;
+ }
+ version = le32dec(&md.md_version);
+ printf("%s: %u\n", name, version);
+ }
+}
+
+static void
eli_clear(struct gctl_req *req)
{
const char *name;
OpenPOWER on IntegriCloud