Ejemplo n.º 1
0
int
main(int argc, char **argv)
{
	int line, tokens;
	char buffer[BUFSIZ], *inputline, *token[GV_MAXARGS];

	/* Load the module if necessary. */
	if (modfind(GVINUMMOD) < 0) {
		if (kldload(GVINUMKLD) < 0 && modfind(GVINUMMOD) < 0)
			err(1, GVINUMKLD ": Kernel module not available");
	}

	/* Arguments given on the command line. */
	if (argc > 1) {
		argc--;
		argv++;
		parseline(argc, argv);

	/* Interactive mode. */
	} else {
		for (;;) {
			inputline = readline("gvinum -> ");
			if (inputline == NULL) {
				if (ferror(stdin)) {
					err(1, "can't read input");
				} else {
					printf("\n");
					exit(0);
				}
			} else if (*inputline) {
				add_history(inputline);
				strcpy(buffer, inputline);
				free(inputline);
				line++;		    /* count the lines */
				tokens = gv_tokenize(buffer, token, GV_MAXARGS);
				if (tokens)
					parseline(tokens, token);
			}
		}
	}
	exit(0);
}
Ejemplo n.º 2
0
void
gvinum_create(int argc, char **argv)
{
	struct gctl_req *req;
	struct gv_drive *d;
	struct gv_plex *p;
	struct gv_sd *s;
	struct gv_volume *v;
	FILE *tmp;
	int drives, errors, fd, flags, i, line, plexes, plex_in_volume;
	int sd_in_plex, status, subdisks, tokens, undeffd, volumes;
	const char *errstr;
	char buf[BUFSIZ], buf1[BUFSIZ], commandline[BUFSIZ], *ed, *sdname;
	char original[BUFSIZ], tmpfile[20], *token[GV_MAXARGS];
	char plex[GV_MAXPLEXNAME], volume[GV_MAXVOLNAME];

	tmp = NULL;
	flags = 0;
	for (i = 1; i < argc; i++) {
		/* Force flag used to ignore already created drives. */
		if (!strcmp(argv[i], "-f")) {
			flags |= GV_FLAG_F;
		/* Else it must be a file. */
		} else {
			if ((tmp = fopen(argv[1], "r")) == NULL) {
				warn("can't open '%s' for reading", argv[1]);
				return;
			}
		}	
	}

	/* We didn't get a file. */
	if (tmp == NULL) {
		snprintf(tmpfile, sizeof(tmpfile), "/tmp/gvinum.XXXXXX");
		
		if ((fd = mkstemp(tmpfile)) == -1) {
			warn("temporary file not accessible");
			return;
		}
		if ((tmp = fdopen(fd, "w")) == NULL) {
			warn("can't open '%s' for writing", tmpfile);
			return;
		}
		printconfig(tmp, "# ");
		fclose(tmp);
		
		ed = getenv("EDITOR");
		if (ed == NULL)
			ed = _PATH_VI;
		
		snprintf(commandline, sizeof(commandline), "%s %s", ed,
		    tmpfile);
		status = system(commandline);
		if (status != 0) {
			warn("couldn't exec %s; status: %d", ed, status);
			return;
		}
		
		if ((tmp = fopen(tmpfile, "r")) == NULL) {
			warn("can't open '%s' for reading", tmpfile);
			return;
		}
	}

	req = gctl_get_handle();
	gctl_ro_param(req, "class", -1, "VINUM");
	gctl_ro_param(req, "verb", -1, "create");
	gctl_ro_param(req, "flags", sizeof(int), &flags);

	drives = volumes = plexes = subdisks = 0;
	plex_in_volume = sd_in_plex = undeffd = 0;
	plex[0] = '\0';
	errors = 0;
	line = 1;
	while ((fgets(buf, BUFSIZ, tmp)) != NULL) {

		/* Skip empty lines and comments. */
		if (*buf == '\0' || *buf == '#') {
			line++;
			continue;
		}

		/* Kill off the newline. */
		buf[strlen(buf) - 1] = '\0';

		/*
		 * Copy the original input line in case we need it for error
		 * output.
		 */
		strlcpy(original, buf, sizeof(original));

		tokens = gv_tokenize(buf, token, GV_MAXARGS);
		if (tokens <= 0) {
			line++;
			continue;
		}

		/* Volume definition. */
		if (!strcmp(token[0], "volume")) {
			v = gv_new_volume(tokens, token);
			if (v == NULL) {
				warnx("line %d: invalid volume definition",
				    line);
				warnx("line %d: '%s'", line, original);
				errors++;
				line++;
				continue;
			}

			/* Reset plex count for this volume. */
			plex_in_volume = 0;

			/*
			 * Set default volume name for following plex
			 * definitions.
			 */
			strlcpy(volume, v->name, sizeof(volume));

			snprintf(buf1, sizeof(buf1), "volume%d", volumes);
			gctl_ro_param(req, buf1, sizeof(*v), v);
			volumes++;

		/* Plex definition. */
		} else if (!strcmp(token[0], "plex")) {
			p = gv_new_plex(tokens, token);
			if (p == NULL) {
				warnx("line %d: invalid plex definition", line);
				warnx("line %d: '%s'", line, original);
				errors++;
				line++;
				continue;
			}

			/* Reset subdisk count for this plex. */
			sd_in_plex = 0;

			/* Default name. */
			if (strlen(p->name) == 0) {
				snprintf(p->name, sizeof(p->name), "%s.p%d",
				    volume, plex_in_volume++);
			}

			/* Default volume. */
			if (strlen(p->volume) == 0) {
				snprintf(p->volume, sizeof(p->volume), "%s",
				    volume);
			}

			/*
			 * Set default plex name for following subdisk
			 * definitions.
			 */
			strlcpy(plex, p->name, sizeof(plex));

			snprintf(buf1, sizeof(buf1), "plex%d", plexes);
			gctl_ro_param(req, buf1, sizeof(*p), p);
			plexes++;

		/* Subdisk definition. */
		} else if (!strcmp(token[0], "sd")) {
			s = gv_new_sd(tokens, token);
			if (s == NULL) {
				warnx("line %d: invalid subdisk "
				    "definition:", line);
				warnx("line %d: '%s'", line, original);
				errors++;
				line++;
				continue;
			}

			/* Default name. */
			if (strlen(s->name) == 0) {
				if (strlen(plex) == 0) {
					sdname = find_name("gvinumsubdisk.p",
					    GV_TYPE_SD, GV_MAXSDNAME);
					snprintf(s->name, sizeof(s->name),
					    "%s.s%d", sdname, undeffd++);
					free(sdname);
				} else {
					snprintf(s->name, sizeof(s->name),
					    "%s.s%d",plex, sd_in_plex++);
				}
			}

			/* Default plex. */
			if (strlen(s->plex) == 0)
				snprintf(s->plex, sizeof(s->plex), "%s", plex);

			snprintf(buf1, sizeof(buf1), "sd%d", subdisks);
			gctl_ro_param(req, buf1, sizeof(*s), s);
			subdisks++;

		/* Subdisk definition. */
		} else if (!strcmp(token[0], "drive")) {
			d = gv_new_drive(tokens, token);
			if (d == NULL) {
				warnx("line %d: invalid drive definition:",
				    line);
				warnx("line %d: '%s'", line, original);
				errors++;
				line++;
				continue;
			}

			snprintf(buf1, sizeof(buf1), "drive%d", drives);
			gctl_ro_param(req, buf1, sizeof(*d), d);
			drives++;

		/* Everything else is bogus. */
		} else {
			warnx("line %d: invalid definition:", line);
			warnx("line %d: '%s'", line, original);
			errors++;
		}
		line++;
	}

	fclose(tmp);
	unlink(tmpfile);

	if (!errors && (volumes || plexes || subdisks || drives)) {
		gctl_ro_param(req, "volumes", sizeof(int), &volumes);
		gctl_ro_param(req, "plexes", sizeof(int), &plexes);
		gctl_ro_param(req, "subdisks", sizeof(int), &subdisks);
		gctl_ro_param(req, "drives", sizeof(int), &drives);
		errstr = gctl_issue(req);
		if (errstr != NULL)
			warnx("create failed: %s", errstr);
	}
	gctl_free(req);
}