示例#1
0
int
main(int argc, char **argv)
{
	int ch, fd, i, vflag;
	char *p;
	char *fflag = NULL, *sflag = NULL, *tflag = NULL, *uflag = NULL;

	bzero(&mdio, sizeof(mdio));
	mdio.md_file = malloc(PATH_MAX);
	mdio.md_label = malloc(PATH_MAX);
	if (mdio.md_file == NULL || mdio.md_label == NULL)
		err(1, "could not allocate memory");
	vflag = 0;
	bzero(mdio.md_file, PATH_MAX);
	bzero(mdio.md_label, PATH_MAX);

	if (argc == 1)
		usage();

	while ((ch = getopt(argc, argv, "ab:df:lno:rs:S:t:u:vx:y:L:")) != -1) {
		switch (ch) {
		case 'a':
			if (action != UNSET && action != ATTACH)
				errx(1, "-a is mutually exclusive "
				    "with -d, -r, and -l");
			action = ATTACH;
			break;
		case 'd':
			if (action != UNSET && action != DETACH)
				errx(1, "-d is mutually exclusive "
				    "with -a, -r, and -l");
			action = DETACH;
			mdio.md_options |= MD_AUTOUNIT;
			break;
		case 'r':
			if (action != UNSET && action != RESIZE)
				errx(1, "-r is mutually exclusive "
				    "with -a, -d, and -l");
			action = RESIZE;
			mdio.md_options |= MD_AUTOUNIT;
			break;
		case 'l':
			if (action != UNSET && action != LIST)
				errx(1, "-l is mutually exclusive "
				    "with -a, -r, and -d");
			action = LIST;
			mdio.md_options |= MD_AUTOUNIT;
			break;
		case 'n':
			nflag = 1;
			break;
		case 't':
			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;
			} else if (!strcmp(optarg, "vnode")) {
				mdio.md_type = MD_VNODE;
				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 if (!strcmp(optarg, "null")) {
				mdio.md_type = MD_NULL;
				mdio.md_options |= MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS;
			} else
				errx(1, "unknown type: %s", optarg);
			break;
		case 'f':
			if (fflag != NULL)
				errx(1, "-f can be passed only once");
			fflag = realpath(optarg, NULL);
			if (fflag == NULL)
				err(1, "realpath");
			break;
		case 'o':
			if (!strcmp(optarg, "async"))
				mdio.md_options |= MD_ASYNC;
			else if (!strcmp(optarg, "noasync"))
				mdio.md_options &= ~MD_ASYNC;
			else if (!strcmp(optarg, "cluster"))
				mdio.md_options |= MD_CLUSTER;
			else if (!strcmp(optarg, "nocluster"))
				mdio.md_options &= ~MD_CLUSTER;
			else if (!strcmp(optarg, "compress"))
				mdio.md_options |= MD_COMPRESS;
			else if (!strcmp(optarg, "nocompress"))
				mdio.md_options &= ~MD_COMPRESS;
			else if (!strcmp(optarg, "force"))
				mdio.md_options |= MD_FORCE;
			else if (!strcmp(optarg, "noforce"))
				mdio.md_options &= ~MD_FORCE;
			else if (!strcmp(optarg, "readonly"))
				mdio.md_options |= MD_READONLY;
			else if (!strcmp(optarg, "noreadonly"))
				mdio.md_options &= ~MD_READONLY;
			else if (!strcmp(optarg, "reserve"))
				mdio.md_options |= MD_RESERVE;
			else if (!strcmp(optarg, "noreserve"))
				mdio.md_options &= ~MD_RESERVE;
			else if (!strcmp(optarg, "verify"))
				mdio.md_options |= MD_VERIFY;
			else if (!strcmp(optarg, "noverify"))
				mdio.md_options &= ~MD_VERIFY;
			else
				errx(1, "unknown option: %s", optarg);
			break;
		case 'S':
			mdio.md_sectorsize = strtoul(optarg, &p, 0);
			break;
		case 's':
			if (sflag != NULL)
				errx(1, "-s can be passed only once");
			sflag = optarg;
			mdio.md_mediasize = (off_t)strtoumax(optarg, &p, 0);
			if (p == NULL || *p == '\0')
				mdio.md_mediasize *= DEV_BSIZE;
			else if (*p == 'b' || *p == 'B')
				; /* do nothing */
			else if (*p == 'k' || *p == 'K')
				mdio.md_mediasize <<= 10;
			else if (*p == 'm' || *p == 'M')
				mdio.md_mediasize <<= 20;
			else if (*p == 'g' || *p == 'G')
				mdio.md_mediasize <<= 30;
			else if (*p == 't' || *p == 'T') {
				mdio.md_mediasize <<= 30;
				mdio.md_mediasize <<= 10;
			} else if (*p == 'p' || *p == 'P') {
				mdio.md_mediasize <<= 30;
				mdio.md_mediasize <<= 20;
			} else
				errx(1, "unknown suffix on -s argument");
			break;
		case 'u':
			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;
			uflag = optarg;
			break;
		case 'v':
			vflag = OPT_VERBOSE;
			break;
		case 'x':
			mdio.md_fwsectors = strtoul(optarg, &p, 0);
			break;
		case 'y':
			mdio.md_fwheads = strtoul(optarg, &p, 0);
			break;
		case 'L':
			strlcpy(mdio.md_label, optarg, PATH_MAX);
			break;
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (action == UNSET)
		action = ATTACH;

	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 (sflag != NULL) {
				/* 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_type == MD_NULL) && sflag == NULL)
			errx(1, "must specify -s for -t malloc, -t swap, "
			    "or -t null");
		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 (action != RESIZE && sflag != NULL)
			errx(1, "-s can only be used with -a and -r");
		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 && action != RESIZE) &&
		    (mdio.md_options & ~MD_AUTOUNIT) != 0)
			errx(1, "-o can only be used with -a, -d, and -r");
		if (action == DETACH &&
		    (mdio.md_options & ~(MD_FORCE | MD_AUTOUNIT)) != 0)
			errx(1, "only -o [no]force can be used with -d");
		if (action == RESIZE &&
		    (mdio.md_options & ~(MD_FORCE | MD_RESERVE | MD_AUTOUNIT)) != 0)
			errx(1, "only -o [no]force and -o [no]reserve can be used with -r");
	}

	if (action == RESIZE && sflag == NULL)
		errx(1, "must specify -s for -r");

	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;

	if (!kld_isloaded("g_md") && kld_load("geom_md") == -1)
		err(1, "failed to load geom_md module");

	fd = open(_PATH_DEV MDCTL_NAME, O_RDWR, 0);
	if (fd < 0)
		err(1, "open(%s%s)", _PATH_DEV, MDCTL_NAME);

	if (action == ATTACH) {
		i = ioctl(fd, MDIOCATTACH, &mdio);
		if (i < 0)
			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)
			errx(1, "-d requires -u");
		i = ioctl(fd, MDIOCDETACH, &mdio);
		if (i < 0)
			err(1, "ioctl(%s%s)", _PATH_DEV, MDCTL_NAME);
	} else if (action == RESIZE) {
		if (mdio.md_options & MD_AUTOUNIT)
			errx(1, "-r requires -u");
		i = ioctl(fd, MDIOCRESIZE, &mdio);
		if (i < 0)
			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);
	return (0);
}
示例#2
0
int
main(int argc, char **argv)
{
	int ch, fd, i, vflag;
	char *p;
	int cmdline = 0;
	char *mdunit = NULL;

	bzero(&mdio, sizeof(mdio));
	mdio.md_file = malloc(PATH_MAX);
	if (mdio.md_file == NULL)
		err(1, "could not allocate memory");
	vflag = 0;
	bzero(mdio.md_file, PATH_MAX);
	while ((ch = getopt(argc, argv, "ab:df:lno:s:S:t:u:vx:y:")) != -1) {
		switch (ch) {
		case 'a':
			if (cmdline != 0)
				usage();
			action = ATTACH;
			cmdline = 1;
			break;
		case 'd':
			if (cmdline != 0)
				usage();
			action = DETACH;
			mdio.md_options = MD_AUTOUNIT;
			cmdline = 3;
			break;
		case 'l':
			if (cmdline != 0)
				usage();
			action = LIST;
			mdio.md_options = MD_AUTOUNIT;
			cmdline = 3;
			break;
		case 'n':
			nflag = 1;
			break;
		case 't':
			if (cmdline != 1)
				usage();
			if (!strcmp(optarg, "malloc")) {
				mdio.md_type = MD_MALLOC;
				mdio.md_options = MD_AUTOUNIT | MD_COMPRESS;
			} else if (!strcmp(optarg, "preload")) {
				mdio.md_type = MD_PRELOAD;
				mdio.md_options = 0;
			} else if (!strcmp(optarg, "vnode")) {
				mdio.md_type = MD_VNODE;
				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;
			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);
			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"))
				mdio.md_options &= ~MD_ASYNC;
			else if (!strcmp(optarg, "cluster"))
				mdio.md_options |= MD_CLUSTER;
			else if (!strcmp(optarg, "nocluster"))
				mdio.md_options &= ~MD_CLUSTER;
			else if (!strcmp(optarg, "compress"))
				mdio.md_options |= MD_COMPRESS;
			else if (!strcmp(optarg, "nocompress"))
				mdio.md_options &= ~MD_COMPRESS;
			else if (!strcmp(optarg, "force"))
				mdio.md_options |= MD_FORCE;
			else if (!strcmp(optarg, "noforce"))
				mdio.md_options &= ~MD_FORCE;
			else if (!strcmp(optarg, "readonly"))
				mdio.md_options |= MD_READONLY;
			else if (!strcmp(optarg, "noreadonly"))
				mdio.md_options &= ~MD_READONLY;
			else if (!strcmp(optarg, "reserve"))
				mdio.md_options |= MD_RESERVE;
			else if (!strcmp(optarg, "noreserve"))
				mdio.md_options &= ~MD_RESERVE;
			else
				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;
			else if (*p == 'b' || *p == 'B')
				; /* do nothing */
			else if (*p == 'k' || *p == 'K')
				mdio.md_mediasize <<= 10;
			else if (*p == 'm' || *p == 'M')
				mdio.md_mediasize <<= 20;
			else if (*p == 'g' || *p == 'G')
				mdio.md_mediasize <<= 30;
			else if (*p == 't' || *p == 'T') {
				mdio.md_mediasize <<= 30;
				mdio.md_mediasize <<= 10;
			} else
				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, 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;
			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:
			usage();
		}
	}

	argc -= optind;
	argv += optind;
	if (action == UNSET) {
		if (argc != 1)
			usage();
		action = ATTACH;
		mdio.md_type = MD_VNODE;
		mdio.md_options = MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS;
		cmdline = 2;
		md_set_file(*argv);
	}

	mdio.md_version = MDIOVERSION;

	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);
	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();
		i = ioctl(fd, MDIOCATTACH, &mdio);
		if (i < 0)
			err(1, "ioctl(/dev/%s)", 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();
		i = ioctl(fd, MDIOCDETACH, &mdio);
		if (i < 0)
			err(1, "ioctl(/dev/%s)", MDCTL_NAME);
	} else
		usage();
	close (fd);
	return (0);
}