Ejemplo n.º 1
0
/* Create a drive quick and dirty. */
char *
create_drive(char *device)
{
	struct gv_drive *d;
	struct gctl_req *req;
	const char *errstr;
	char *drivename, *dname;
	int drives, i, flags, volumes, subdisks, plexes;

	flags = plexes = subdisks = volumes = 0;
	drives = 1;
	dname = NULL;

	drivename = find_drive();
	if (drivename == NULL)
		return (NULL);

	req = gctl_get_handle();
	gctl_ro_param(req, "class", -1, "VINUM");
	gctl_ro_param(req, "verb", -1, "create");
	d = gv_alloc_drive();
	if (d == NULL)
		err(1, "unable to allocate for gv_drive object");

	strlcpy(d->name, drivename, sizeof(d->name));
	copy_device(d, device);
	gctl_ro_param(req, "drive0", sizeof(*d), d);
	gctl_ro_param(req, "flags", sizeof(int), &flags);
	gctl_ro_param(req, "drives", sizeof(int), &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);
	errstr = gctl_issue(req);
	if (errstr != NULL) {
		warnx("error creating drive: %s", errstr);
		gctl_free(req);
		return (NULL);
	} else {
		gctl_free(req);
		/* XXX: This is needed because we have to make sure the drives
		 * are created before we return. */
		/* Loop until it's in the config. */
		for (i = 0; i < 100000; i++) {
			dname = find_name("gvinumdrive", GV_TYPE_DRIVE,
			    GV_MAXDRIVENAME);
			/* If we got a different name, quit. */
			if (dname == NULL)
				continue;
			if (strcmp(dname, drivename)) {
				free(dname);
				return (drivename);
			}
			free(dname);
			dname = NULL;
			usleep(100000); /* Sleep for 0.1s */
		}
	}
	gctl_free(req);
	return (drivename);
}
Ejemplo n.º 2
0
/* Get a new drive object. */
struct gv_drive *
gv_new_drive(int max, char *token[])
{
	struct gv_drive *d;
	int j, errors;
	char *ptr;

	if (token[1] == NULL || *token[1] == '\0')
		return (NULL);
	d = gv_alloc_drive();
	if (d == NULL)
		return (NULL);
	errors = 0;
	for (j = 1; j < max; j++) {
		if (!strcmp(token[j], "state")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			d->state = gv_drivestatei(token[j]);
		} else if (!strcmp(token[j], "device")) {
			j++;
			if (j >= max) {
				errors++;
				break;
			}
			ptr = token[j];

			if (strncmp(ptr, "/dev/", 5) == 0)
				ptr += 5;
			strlcpy(d->device, ptr, sizeof(d->device));
		} else {
			/* We assume this is the drive name. */
			strlcpy(d->name, token[j], sizeof(d->name));
		}
	}

	if (strlen(d->name) == 0 || strlen(d->device) == 0)
		errors++;

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

	return (d);
}
Ejemplo n.º 3
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);
}