Author: hrs Date: Thu Jun 27 06:57:09 2013 New Revision: 252291 URL: http://svnweb.freebsd.org/changeset/base/252291
Log: MFC 230423, 230612, 232964, 252033, 252036, 252051: - Replace the beerware license on mdconfig(8) with standard 2-clause BSD. - Rewrite option parsing in mdconfig(8). This makes it more user-friendly by removing the ordering requirements and adding more descriptive error messages; it also makes it more readable and maintainable. - Add "-f file" support to listing mode (-l). When a -f option is specified, only md(4) devices which have the specified file as backing store are displayed. - Use MD_NAME instead of "md". - Use _PATH_DEV instead of "/dev/". - Return -1 when the specified backing store file is not found in the md device list. Modified: stable/9/sbin/mdconfig/mdconfig.8 stable/9/sbin/mdconfig/mdconfig.c Directory Properties: stable/9/sbin/mdconfig/ (props changed) Modified: stable/9/sbin/mdconfig/mdconfig.8 ============================================================================== --- stable/9/sbin/mdconfig/mdconfig.8 Thu Jun 27 06:37:24 2013 (r252290) +++ stable/9/sbin/mdconfig/mdconfig.8 Thu Jun 27 06:57:09 2013 (r252291) @@ -41,7 +41,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 3, 2012 +.Dd June 20, 2013 .Dt MDCONFIG 8 .Os .Sh NAME @@ -67,6 +67,7 @@ .Fl l .Op Fl n .Op Fl v +.Op Fl f Ar file .Op Fl u Ar unit .Nm .Ar file @@ -124,6 +125,19 @@ List configured devices. If given with .Fl u , display details about that particular device. +If given with +.Fl f Ar file , +display +.Xr md 4 +device names of which +.Ar file +is used as the backing store. +If both of +.Fl u +and +.Fl f +options are specified, +display devices which match the two conditions. If the .Fl v option is specified, show all details. Modified: stable/9/sbin/mdconfig/mdconfig.c ============================================================================== --- stable/9/sbin/mdconfig/mdconfig.c Thu Jun 27 06:37:24 2013 (r252290) +++ stable/9/sbin/mdconfig/mdconfig.c Thu Jun 27 06:57:09 2013 (r252291) @@ -1,14 +1,35 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <p...@freebsd.org> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- +/*- + * Copyright (c) 2000-2004 Poul-Henning Kamp <p...@freebsd.org> + * Copyright (c) 2012 The FreeBSD Foundation + * All rights reserved. * - * $FreeBSD$ + * Portions of this software were developed by Edward Tomasz Napierala + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ */ + #include <sys/param.h> #include <sys/devicestat.h> #include <sys/ioctl.h> @@ -26,22 +47,22 @@ #include <inttypes.h> #include <libgeom.h> #include <libutil.h> +#include <paths.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> - static struct md_ioctl mdio; static enum {UNSET, ATTACH, DETACH, LIST} action = UNSET; static int nflag; static void usage(void); static void md_set_file(const char *); -static int md_find(char *, const char *); -static int md_query(char *name); -static int md_list(char *units, int opt); +static int md_find(const char *, const char *); +static int md_query(const char *, const int, const char *); +static int md_list(const char *, int, const char *); static char *geom_config_get(struct gconf *g, const char *name); static void md_prthumanval(char *length); @@ -55,12 +76,13 @@ static void md_prthumanval(char *length) static void usage(void) { + fprintf(stderr, "usage: mdconfig -a -t type [-n] [-o [no]option] ... [-f file]\n" " [-s size] [-S sectorsize] [-u unit]\n" " [-x sectors/track] [-y heads/cylinder]\n" " mdconfig -d -u unit [-o [no]force]\n" -" mdconfig -l [-v] [-n] [-u unit]\n" +" mdconfig -l [-v] [-n] [-f file] [-u unit]\n" " mdconfig file\n"); fprintf(stderr, "\t\ttype = {malloc, vnode, swap}\n"); fprintf(stderr, "\t\toption = {cluster, compress, reserve}\n"); @@ -75,8 +97,7 @@ main(int argc, char **argv) { int ch, fd, i, vflag; char *p; - int cmdline = 0; - char *mdunit = NULL; + char *fflag = NULL, *tflag = NULL, *uflag = NULL; bzero(&mdio, sizeof(mdio)); mdio.md_file = malloc(PATH_MAX); @@ -84,76 +105,59 @@ main(int argc, char **argv) err(1, "could not allocate memory"); vflag = 0; bzero(mdio.md_file, PATH_MAX); + + if (argc == 1) + usage(); + while ((ch = getopt(argc, argv, "ab:df:lno:s:S:t:u:vx:y:")) != -1) { switch (ch) { case 'a': - if (cmdline != 0) - usage(); + if (action != UNSET && action != ATTACH) + errx(1, + "-a is mutually exclusive with -d and -l"); action = ATTACH; - cmdline = 1; break; case 'd': - if (cmdline != 0) - usage(); + if (action != UNSET && action != DETACH) + errx(1, + "-d is mutually exclusive with -a and -l"); action = DETACH; - mdio.md_options = MD_AUTOUNIT; - cmdline = 3; + mdio.md_options |= MD_AUTOUNIT; break; case 'l': - if (cmdline != 0) - usage(); + if (action != UNSET && action != LIST) + errx(1, + "-l is mutually exclusive with -a and -d"); action = LIST; - mdio.md_options = MD_AUTOUNIT; - cmdline = 3; + mdio.md_options |= MD_AUTOUNIT; break; case 'n': nflag = 1; break; case 't': - if (cmdline != 1) - usage(); + if (tflag != NULL) + errx(1, "-t can be passed only once"); + tflag = optarg; if (!strcmp(optarg, "malloc")) { mdio.md_type = MD_MALLOC; - mdio.md_options = MD_AUTOUNIT | MD_COMPRESS; + mdio.md_options |= MD_AUTOUNIT | MD_COMPRESS; + } else if (!strcmp(optarg, "preload")) { + mdio.md_type = MD_PRELOAD; } else if (!strcmp(optarg, "vnode")) { mdio.md_type = MD_VNODE; - mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; + mdio.md_options |= MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; } else if (!strcmp(optarg, "swap")) { mdio.md_type = MD_SWAP; - mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; - } else { - usage(); - } - cmdline=2; + mdio.md_options |= MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; + } else + errx(1, "unknown type: %s", optarg); break; case 'f': - if (cmdline == 0) { - action = ATTACH; - cmdline = 1; - } - if (cmdline == 1) { - /* Imply ``-t vnode'' */ - mdio.md_type = MD_VNODE; - mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; - cmdline = 2; - } - if (cmdline != 2) - usage(); - md_set_file(optarg); + if (fflag != NULL) + errx(1, "-f can be passed only once"); + fflag = optarg; break; case 'o': - if (action == DETACH) { - if (!strcmp(optarg, "force")) - mdio.md_options |= MD_FORCE; - else if (!strcmp(optarg, "noforce")) - mdio.md_options &= ~MD_FORCE; - else - errx(1, "Unknown option: %s.", optarg); - break; - } - - if (cmdline != 2) - usage(); if (!strcmp(optarg, "async")) mdio.md_options |= MD_ASYNC; else if (!strcmp(optarg, "noasync")) @@ -179,27 +183,12 @@ main(int argc, char **argv) else if (!strcmp(optarg, "noreserve")) mdio.md_options &= ~MD_RESERVE; else - errx(1, "Unknown option: %s.", optarg); + errx(1, "unknown option: %s", optarg); break; case 'S': - if (cmdline != 2) - usage(); mdio.md_sectorsize = strtoul(optarg, &p, 0); break; case 's': - if (cmdline == 0) { - /* Imply ``-a'' */ - action = ATTACH; - cmdline = 1; - } - if (cmdline == 1) { - /* Imply ``-t swap'' */ - mdio.md_type = MD_SWAP; - mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; - cmdline = 2; - } - if (cmdline != 2) - usage(); mdio.md_mediasize = (off_t)strtoumax(optarg, &p, 0); if (p == NULL || *p == '\0') mdio.md_mediasize *= DEV_BSIZE; @@ -215,34 +204,22 @@ main(int argc, char **argv) mdio.md_mediasize <<= 30; mdio.md_mediasize <<= 10; } else - errx(1, "Unknown suffix on -s argument"); + errx(1, "unknown suffix on -s argument"); break; case 'u': - if (cmdline != 2 && cmdline != 3) - usage(); - if (!strncmp(optarg, "/dev/", 5)) - optarg += 5; + if (!strncmp(optarg, _PATH_DEV, sizeof(_PATH_DEV) - 1)) + optarg += sizeof(_PATH_DEV) - 1; if (!strncmp(optarg, MD_NAME, sizeof(MD_NAME) - 1)) optarg += sizeof(MD_NAME) - 1; - mdio.md_unit = strtoul(optarg, &p, 0); - if (mdio.md_unit == (unsigned)ULONG_MAX || *p != '\0') - errx(1, "bad unit: %s", optarg); - mdunit = optarg; - mdio.md_options &= ~MD_AUTOUNIT; + uflag = optarg; break; case 'v': - if (cmdline != 3) - usage(); vflag = OPT_VERBOSE; break; case 'x': - if (cmdline != 2) - usage(); mdio.md_fwsectors = strtoul(optarg, &p, 0); break; case 'y': - if (cmdline != 2) - usage(); mdio.md_fwheads = strtoul(optarg, &p, 0); break; default: @@ -252,14 +229,88 @@ main(int argc, char **argv) argc -= optind; argv += optind; - if (action == UNSET) { - if (argc != 1) - usage(); + + if (action == UNSET) action = ATTACH; - mdio.md_type = MD_VNODE; - mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; - cmdline = 2; - md_set_file(*argv); + + if (action == ATTACH) { + if (tflag == NULL) { + /* + * Try to infer the type based on other arguments. + */ + if (fflag != NULL || argc > 0) { + /* Imply ``-t vnode'' */ + mdio.md_type = MD_VNODE; + mdio.md_options |= MD_CLUSTER | MD_AUTOUNIT | + MD_COMPRESS; + } else if (mdio.md_mediasize != 0) { + /* Imply ``-t swap'' */ + mdio.md_type = MD_SWAP; + mdio.md_options |= MD_CLUSTER | MD_AUTOUNIT | + MD_COMPRESS; + } else + errx(1, "unable to determine type"); + } + + if ((fflag != NULL || argc > 0) && mdio.md_type != MD_VNODE) + errx(1, "only -t vnode can be used with file name"); + + if (mdio.md_type == MD_VNODE) { + if (fflag != NULL) { + if (argc != 0) + usage(); + md_set_file(fflag); + } else { + if (argc != 1) + usage(); + md_set_file(*argv); + } + + if ((mdio.md_options & MD_READONLY) == 0 && + access(mdio.md_file, W_OK) < 0 && + (errno == EACCES || errno == EPERM || + errno == EROFS)) { + warnx("WARNING: opening backing store: %s " + "readonly", mdio.md_file); + mdio.md_options |= MD_READONLY; + } + } + + if ((mdio.md_type == MD_MALLOC || mdio.md_type == MD_SWAP) && + mdio.md_mediasize == 0) + errx(1, "must specify -s for -t malloc or -t swap"); + if (mdio.md_type == MD_VNODE && mdio.md_file[0] == '\0') + errx(1, "must specify -f for -t vnode"); + } else { + if (mdio.md_sectorsize != 0) + errx(1, "-S can only be used with -a"); + if (mdio.md_mediasize != 0) + errx(1, "-s can only be used with -a"); + if (mdio.md_fwsectors != 0) + errx(1, "-x can only be used with -a"); + if (mdio.md_fwheads != 0) + errx(1, "-y can only be used with -a"); + if (fflag != NULL && action != LIST) + errx(1, "-f can only be used with -a and -l"); + if (tflag != NULL) + errx(1, "-t can only be used with -a"); + if (argc > 0) + errx(1, "file can only be used with -a"); + if (action != DETACH && (mdio.md_options & ~MD_AUTOUNIT) != 0) + errx(1, "-o can only be used with -a and -d"); + if (action == DETACH && + (mdio.md_options & ~(MD_FORCE | MD_AUTOUNIT)) != 0) + errx(1, "only -o [no]force can be used with -d"); + } + + if (action != LIST && vflag == OPT_VERBOSE) + errx(1, "-v can only be used with -l"); + + if (uflag != NULL) { + mdio.md_unit = strtoul(uflag, &p, 0); + if (mdio.md_unit == (unsigned)ULONG_MAX || *p != '\0') + errx(1, "bad unit: %s", uflag); + mdio.md_options &= ~MD_AUTOUNIT; } mdio.md_version = MDIOVERSION; @@ -267,53 +318,35 @@ main(int argc, char **argv) if (!kld_isloaded("g_md") && kld_load("geom_md") == -1) err(1, "failed to load geom_md module"); - fd = open("/dev/" MDCTL_NAME, O_RDWR, 0); + fd = open(_PATH_DEV MDCTL_NAME, O_RDWR, 0); if (fd < 0) - err(1, "open(/dev/%s)", MDCTL_NAME); - if (cmdline == 2 - && (mdio.md_type == MD_MALLOC || mdio.md_type == MD_SWAP)) - if (mdio.md_mediasize == 0) - errx(1, "must specify -s for -t malloc or -t swap"); - if (cmdline == 2 && mdio.md_type == MD_VNODE) - if (mdio.md_file[0] == '\0') - errx(1, "must specify -f for -t vnode"); - if (mdio.md_type == MD_VNODE && - (mdio.md_options & MD_READONLY) == 0) { - if (access(mdio.md_file, W_OK) < 0 && - (errno == EACCES || errno == EPERM || errno == EROFS)) { - fprintf(stderr, - "WARNING: opening backing store: %s readonly\n", - mdio.md_file); - mdio.md_options |= MD_READONLY; - } - } - if (action == LIST) { - if (mdio.md_options & MD_AUTOUNIT) { - /* - * Listing all devices. This is why we pass NULL - * together with OPT_LIST. - */ - md_list(NULL, OPT_LIST | vflag); - } else { - return (md_query(mdunit)); - } - } else if (action == ATTACH) { - if (cmdline < 2) - usage(); + err(1, "open(%s%s)", _PATH_DEV, MDCTL_NAME); + + if (action == ATTACH) { i = ioctl(fd, MDIOCATTACH, &mdio); if (i < 0) - err(1, "ioctl(/dev/%s)", MDCTL_NAME); + err(1, "ioctl(%s%s)", _PATH_DEV, MDCTL_NAME); if (mdio.md_options & MD_AUTOUNIT) printf("%s%d\n", nflag ? "" : MD_NAME, mdio.md_unit); } else if (action == DETACH) { if (mdio.md_options & MD_AUTOUNIT) - usage(); + errx(1, "-d requires -u"); i = ioctl(fd, MDIOCDETACH, &mdio); if (i < 0) - err(1, "ioctl(/dev/%s)", MDCTL_NAME); + err(1, "ioctl(%s%s)", _PATH_DEV, MDCTL_NAME); + } else if (action == LIST) { + if (mdio.md_options & MD_AUTOUNIT) { + /* + * Listing all devices. This is why we pass NULL + * together with OPT_LIST. + */ + return (md_list(NULL, OPT_LIST | vflag, fflag)); + } else + return (md_query(uflag, vflag, fflag)); + } else usage(); - close (fd); + close(fd); return (0); } @@ -344,7 +377,7 @@ md_set_file(const char *fn) * between list and query mode. */ static int -md_list(char *units, int opt) +md_list(const char *units, int opt, const char *fflag) { struct gmesh gm; struct gprovider *pp; @@ -354,7 +387,7 @@ md_list(char *units, int opt) struct ggeom *gg; struct gclass *gcl; void *sq; - int retcode, found; + int retcode, ffound, ufound; char *type, *file, *length; type = file = length = NULL; @@ -369,7 +402,7 @@ md_list(char *units, int opt) if (sq == NULL) return (-1); - found = 0; + ffound = ufound = 0; while ((gsp = geom_stats_snapshot_next(sq)) != NULL) { gid = geom_lookupid(&gm, gsp->id); if (gid == NULL) @@ -385,18 +418,25 @@ md_list(char *units, int opt) if (retcode != 1) continue; else - found = 1; + ufound = 1; } gc = &pp->lg_config; - if (nflag && strncmp(pp->lg_name, "md", 2) == 0) + type = geom_config_get(gc, "type"); + if (strcmp(type, "vnode") == 0) { + file = geom_config_get(gc, "file"); + if (fflag != NULL && + strcmp(fflag, file) != 0) + continue; + else + ffound = 1; + } + if (nflag && strncmp(pp->lg_name, MD_NAME, 2) == 0) printf("%s", pp->lg_name + 2); else printf("%s", pp->lg_name); - if (opt & OPT_VERBOSE || opt & OPT_UNIT) { - type = geom_config_get(gc, "type"); - if (strcmp(type, "vnode") == 0) - file = geom_config_get(gc, "file"); + if (opt & OPT_VERBOSE || + ((opt & OPT_UNIT) && fflag == NULL)) { length = geom_config_get(gc, "length"); printf("\t%s\t", type); if (length != NULL) @@ -417,7 +457,9 @@ md_list(char *units, int opt) printf("\n"); /* XXX: Check if it's enough to clean everything. */ geom_stats_snapshot_free(sq); - if ((opt & OPT_UNIT) && found) + if (((opt & OPT_UNIT) && (fflag == NULL) && ufound) || + ((opt & OPT_UNIT) == 0 && (fflag != NULL) && ffound) || + ((opt & OPT_UNIT) && (fflag != NULL) && ufound && ffound)) return (0); else return (-1); @@ -444,10 +486,10 @@ geom_config_get(struct gconf *g, const c * otherwise. */ static int -md_find(char *list, const char *name) +md_find(const char *list, const char *name) { int ret; - char num[16]; + char num[PATH_MAX]; char *ptr, *p, *u; ret = 0; @@ -455,10 +497,10 @@ md_find(char *list, const char *name) if (ptr == NULL) return (-1); for (p = ptr; (u = strsep(&p, ",")) != NULL;) { - if (strncmp(u, "/dev/", 5) == 0) - u += 5; + if (strncmp(u, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) + u += sizeof(_PATH_DEV) - 1; /* Just in case user specified number instead of full name */ - snprintf(num, sizeof(num), "md%s", u); + snprintf(num, sizeof(num), "%s%s", MD_NAME, u); if (strcmp(u, name) == 0 || strcmp(num, name) == 0) { ret = 1; break; @@ -484,8 +526,9 @@ md_prthumanval(char *length) (void)printf("%6s", buf); } -int -md_query(char *name) +static int +md_query(const char *name, const int opt, const char *fflag) { - return (md_list(name, OPT_UNIT)); + + return (md_list(name, opt | OPT_UNIT, fflag)); } _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"