Esempio n. 1
0
/* Grow a subdisk by adding disk backed by provider. */
void
gvinum_grow(int argc, char **argv)
{
	struct gctl_req *req;
	char *drive, *sdname;
	char sdprefix[GV_MAXSDNAME];
	struct gv_drive *d;
	struct gv_sd *s;
	const char *errstr;
	int drives, volumes, plexes, subdisks, flags;

	drives = volumes = plexes = subdisks = 0;
	if (argc < 3) {
		warnx("usage:\tgrow plex drive\n");
		return;
	}

	s = gv_alloc_sd();
	if (s == NULL) {
		warn("unable to create subdisk");
		return;
	}
	d = gv_alloc_drive();
	if (d == NULL) {
		warn("unable to create drive");
		free(s);
		return;
	}
	/* Lookup device and set an appropriate drive name. */
	drive = find_drive();
	if (drive == NULL) {
		warn("unable to find an appropriate drive name");
		free(s);
		free(d);
		return;
	}
	strlcpy(d->name, drive, sizeof(d->name));
	copy_device(d, argv[2]);

	drives = 1;

	/* We try to use the plex name as basis for the subdisk name. */
	snprintf(sdprefix, sizeof(sdprefix), "%s.s", argv[1]);
	sdname = find_name(sdprefix, GV_TYPE_SD, GV_MAXSDNAME);
	if (sdname == NULL) {
		warn("unable to find an appropriate subdisk name");
		free(s);
		free(d);
		free(drive);
		return;
	}
	strlcpy(s->name, sdname, sizeof(s->name));
	free(sdname);
	strlcpy(s->plex, argv[1], sizeof(s->plex));
	strlcpy(s->drive, d->name, sizeof(s->drive));
	subdisks = 1;

	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);
	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);
	gctl_ro_param(req, "drive0", sizeof(*d), d);
	gctl_ro_param(req, "sd0", sizeof(*s), s);
	errstr = gctl_issue(req);
	free(drive);
	if (errstr != NULL) {
		warnx("unable to grow plex: %s", errstr);
		free(s);
		free(d);
		return;
	}
	gctl_free(req);
}
Esempio n. 2
0
/* Get a new subdisk object. */
struct gv_sd *
gv_new_sd(int max, char *token[])
{
	struct gv_sd *s;
	int j, errors;

	if (token[1] == NULL || *token[1] == '\0')
		return (NULL);

	s = gv_alloc_sd();
	if (s == NULL)
		return (NULL);

	errors = 0;
	for (j = 1; j < max; j++) {
		if (!strcmp(token[j], "name")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			strlcpy(s->name, token[j], sizeof(s->name));
		} else if (!strcmp(token[j], "drive")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			strlcpy(s->drive, token[j], sizeof(s->drive));
		} else if (!strcmp(token[j], "plex")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			strlcpy(s->plex, token[j], sizeof(s->plex));
		} else if (!strcmp(token[j], "state")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			s->state = gv_sdstatei(token[j]);
		} else if (!strcmp(token[j], "len") ||
		    !strcmp(token[j], "length")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			s->size = gv_sizespec(token[j]);
			if (s->size <= 0)
				s->size = -1;
		} else if (!strcmp(token[j], "driveoffset")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			s->drive_offset = gv_sizespec(token[j]);
			if (s->drive_offset != 0 &&
			    s->drive_offset < GV_DATA_START) {
				errors++;
				break;
			}
		} else if (!strcmp(token[j], "plexoffset")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			s->plex_offset = gv_sizespec(token[j]);
			if (s->plex_offset < 0) {
				errors++;
				break;
			}
		} else {
			errors++;
			break;
		}
	}

	if (strlen(s->drive) == 0)
		errors++;

	if (errors) {
		g_free(s);
		return (NULL);
	}

	return (s);
}