diff options
-rw-r--r-- | sbin/geom/class/eli/geli.8 | 15 | ||||
-rw-r--r-- | sbin/geom/class/eli/geom_eli.c | 47 |
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; |