summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgrog <grog@FreeBSD.org>2000-02-29 06:19:42 +0000
committergrog <grog@FreeBSD.org>2000-02-29 06:19:42 +0000
commitdfb30d0b6332091a3952ca494a04d1e8bb43ee46 (patch)
tree87eac22706250637b9ca20a0d016cdd8a5144590
parent2aeb418d84f07de9f165bacc651d67612cdb66d3 (diff)
downloadFreeBSD-src-dfb30d0b6332091a3952ca494a04d1e8bb43ee46.zip
FreeBSD-src-dfb30d0b6332091a3952ca494a04d1e8bb43ee46.tar.gz
New function checkupdates: check whether configuration updates are
enabled and print a warning message in varous places if they are not. Fix typos in comments. Change some indents to approach style(9). initvol: If init fails, place the subdisks in a "down" state. vinum_start(): If we're starting a plex, try doing it directly. It's possible that the state of the plex differs from that of the subdisks, for example if somebody has used 'setupstate'. New functions vinum_raid4 and vinum_raid5 to create RAID-4 and RAID-5 volumes, analagous to vinum_mirror and vinum_stripe. vinum_checkparity: Don't try to check the parity of a non-parity plex, print a rude remark instead. Approved-by: jkh
-rw-r--r--sbin/vinum/commands.c362
1 files changed, 357 insertions, 5 deletions
diff --git a/sbin/vinum/commands.c b/sbin/vinum/commands.c
index f46b543..6c85063 100644
--- a/sbin/vinum/commands.c
+++ b/sbin/vinum/commands.c
@@ -54,6 +54,7 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <dev/vinum/vinumhdr.h>
+#include <dev/vinum/request.h>
#include "vext.h"
#include <sys/types.h>
#include <sys/linker.h>
@@ -159,6 +160,7 @@ vinum_create(int argc, char *argv[], char *arg0[])
perror("Can't save Vinum config");
make_devices();
listconfig();
+ checkupdates(); /* make sure we're updating */
}
/* Read vinum config from a disk */
@@ -197,6 +199,7 @@ vinum_read(int argc, char *argv[], char *arg0[])
perror("Can't save Vinum config");
make_devices();
}
+ checkupdates(); /* make sure we're updating */
}
#ifdef VINUMDEBUG
@@ -220,6 +223,7 @@ void
vinum_modify(int argc, char *argv[], char *arg0[])
{
fprintf(stderr, "Modify command is currently not implemented\n");
+ checkupdates(); /* make sure we're updating */
}
void
@@ -261,6 +265,7 @@ vinum_rm(int argc, char *argv[], char *arg0[])
fprintf(stderr, "%s removed\n", argv[index]);
}
}
+ checkupdates(); /* make sure we're updating */
}
}
@@ -290,9 +295,10 @@ vinum_resetconfig(int argc, char *argv[], char *arg0[])
start_daemon(); /* then restart the daemon */
}
}
+ checkupdates(); /* make sure we're updating */
}
-/* Initialize a plex */
+/* Initialize subdisks */
void
vinum_init(int argc, char *argv[], char *arg0[])
{
@@ -328,12 +334,13 @@ vinum_init(int argc, char *argv[], char *arg0[])
}
}
}
+ checkupdates(); /* make sure we're updating */
}
void
initvol(int volno)
{
- printf("Not implemented yet\n");
+ printf("Initializing volumes is not implemented yet\n");
}
void
@@ -468,7 +475,8 @@ initsd(int sdno, int dowait)
&&(SSize < 512))
SSize <<= DEV_BSHIFT;
if (reply.error) {
- fprintf(stderr, "Can't initialize %s: %s (%d)\n",
+ fprintf(stderr,
+ "Can't initialize %s: %s (%d)\n",
filename,
strerror(reply.error),
reply.error);
@@ -483,6 +491,22 @@ initsd(int sdno, int dowait)
ioctl(superdev, VINUM_SETSTATE, message);
}
while (reply.error == EAGAIN); /* until we're done */
+ if (reply.error) {
+ fprintf(stderr,
+ "Can't initialize %s: %s (%d)\n",
+ filename,
+ strerror(reply.error),
+ reply.error);
+ get_sd_info(&sd, sdno);
+ if (sd.state != sd_up)
+ /* Set the subdisk down */
+ message->index = sd.sdno; /* pass object number */
+ message->type = sd_object; /* and type of object */
+ message->state = object_down;
+ message->verify = vflag; /* verify what we write? */
+ message->force = 1; /* insist */
+ ioctl(superdev, VINUM_SETSTATE, message);
+ }
}
if (vflag) { /* don't trust the thing, check again */
close(sdfh);
@@ -605,6 +629,21 @@ vinum_start(int argc, char *argv[], char *arg0[])
else {
int sdno;
+ /*
+ * First, see if we can bring it up
+ * just by asking. This might happen
+ * if somebody has used setupstate on
+ * the subdisks. If we don't do this,
+ * we'll return success, but the plex
+ * won't have changed state. Note
+ * that we don't check for errors
+ * here.
+ */
+ message->index = plex.plexno; /* pass object number */
+ message->type = plex_object; /* it's a subdisk */
+ message->state = object_up;
+ message->force = 0; /* don't force it */
+ ioctl(superdev, VINUM_SETSTATE, message);
for (sdno = 0; sdno < plex.subdisks; sdno++) {
get_plex_sd_info(&sd, object, sdno);
if ((sd.state >= sd_empty)
@@ -690,6 +729,7 @@ vinum_start(int argc, char *argv[], char *arg0[])
}
}
}
+ checkupdates(); /* make sure we're updating */
}
void
@@ -699,6 +739,8 @@ vinum_stop(int argc, char *argv[], char *arg0[])
struct _ioctl_reply reply;
struct vinum_ioctl_msg *message = (struct vinum_ioctl_msg *) &reply;
+ if (checkupdates() && (!force)) /* not updating? */
+ return;
message->force = force; /* should we force the transition? */
if (argc == 0) { /* stop vinum */
int fileid = 0; /* ID of Vinum kld */
@@ -779,6 +821,7 @@ vinum_label(int argc, char *argv[], char *arg0[])
}
}
}
+ checkupdates(); /* not updating? */
}
void
@@ -1032,6 +1075,7 @@ vinum_attach(int argc, char *argv[], char *argv0[])
default: /* can't get here */
}
}
+ checkupdates(); /* make sure we're updating */
}
/* Detach a subdisk from a plex, or a plex from a volume.
@@ -1084,6 +1128,7 @@ vinum_detach(int argc, char *argv[], char *argv0[])
argv[0],
reply->msg[0] ? reply->msg : strerror(reply->error),
reply->error);
+ checkupdates(); /* make sure we're updating */
}
static void
@@ -1195,6 +1240,7 @@ vinum_rename(int argc, char *argv[], char *argv0[])
return;
}
vinum_rename_2(argv[0], argv[1]);
+ checkupdates(); /* make sure we're updating */
}
/*
@@ -1303,6 +1349,7 @@ vinum_mv(int argc, char *argv[], char *argv0[])
strerror(reply.error),
reply.error);
}
+ checkupdates(); /* make sure we're updating */
}
/*
@@ -1412,6 +1459,21 @@ vinum_setdaemon(int argc, char *argv[], char *argv0[])
default:
fprintf(stderr, "Usage: \tsetdaemon [<bitmask>]\n");
}
+ checkupdates(); /* make sure we're updating */
+}
+
+int
+checkupdates()
+{
+ int options;
+
+ if (ioctl(superdev, VINUM_GETDAEMON, &options) < 0)
+ fprintf(stderr, "Can't get daemon options: %s (%d)\n", strerror(errno), errno);
+ if (options & daemon_noupdate) {
+ fprintf(stderr, "*** Warning: configuration updates are disabled. ***\n");
+ return 1;
+ } else
+ return 0;
}
/* Save config info */
@@ -1427,6 +1489,7 @@ vinum_saveconfig(int argc, char *argv[], char *argv0[])
ioctltype = 1; /* user saveconfig */
if (ioctl(superdev, VINUM_SAVECONFIG, &ioctltype) < 0)
fprintf(stderr, "Can't save configuration: %s (%d)\n", strerror(errno), errno);
+ checkupdates(); /* make sure we're updating */
}
/*
@@ -1602,6 +1665,7 @@ vinum_concat(int argc, char *argv[], char *argv0[])
}
}
+
/*
* Create a volume with a single striped plex from
* as much space as we can get on the specified drives.
@@ -1747,6 +1811,294 @@ vinum_stripe(int argc, char *argv[], char *argv0[])
}
/*
+ * Create a volume with a single RAID-4 plex from
+ * as much space as we can get on the specified drives.
+ * If the drives aren't Vinum drives, make them so.
+ */
+void
+vinum_raid4(int argc, char *argv[], char *argv0[])
+{
+ int o; /* object number */
+ char buffer[BUFSIZE];
+ struct drive *drive; /* drive we're currently looking at */
+ struct _ioctl_reply *reply;
+ int ioctltype;
+ int error;
+ enum objecttype type;
+ off_t maxsize;
+ int fe; /* freelist entry index */
+ struct drive_freelist freelist;
+ struct ferq { /* request to pass to ioctl */
+ int driveno;
+ int fe;
+ } *ferq = (struct ferq *) &freelist;
+ u_int64_t bigchunk; /* biggest chunk in freelist */
+
+ maxsize = QUAD_MAX;
+ reply = (struct _ioctl_reply *) &buffer;
+
+ /*
+ * First, check our drives.
+ */
+ if (argc < 3) {
+ fprintf(stderr, "You need at least three drives to create a RAID-4 plex\n");
+ return;
+ }
+ if (ioctl(superdev, VINUM_STARTCONFIG, &force)) { /* can't get config? */
+ printf("Can't configure: %s (%d)\n", strerror(errno), errno);
+ return;
+ }
+ if (!objectname) /* we need a name for our object */
+ genvolname();
+ for (o = 0; o < argc; o++) {
+ if ((drive = find_drive_by_devname(argv[o])) == NULL) /* doesn't exist */
+ drive = create_drive(argv[o]); /* create it */
+ /* Now find the largest chunk available on the drive */
+ bigchunk = 0; /* ain't found nothin' yet */
+ for (fe = 0; fe < drive->freelist_entries; fe++) {
+ ferq->driveno = drive->driveno;
+ ferq->fe = fe;
+ if (ioctl(superdev, VINUM_GETFREELIST, &freelist) < 0) {
+ fprintf(stderr,
+ "Can't get free list element %d: %s\n",
+ fe,
+ strerror(errno));
+ longjmp(command_fail, -1);
+ }
+ bigchunk = bigchunk > freelist.sectors ? bigchunk : freelist.sectors; /* max it */
+ }
+ maxsize = min(maxsize, bigchunk); /* this is as much as we can do */
+ }
+
+ /* Now create the volume */
+ sprintf(buffer, "volume %s", objectname);
+ if (vflag)
+ printf("volume %s\n", objectname);
+ ioctl(superdev, VINUM_CREATE, buffer); /* create the volume */
+ if (reply->error != 0) { /* error in config */
+ if (reply->msg[0])
+ fprintf(stderr,
+ "Can't create volume %s: %s\n",
+ objectname,
+ reply->msg);
+ else
+ fprintf(stderr,
+ "Can't create volume %s: %s (%d)\n",
+ objectname,
+ strerror(reply->error),
+ reply->error);
+ longjmp(command_fail, -1); /* give up */
+ }
+ sprintf(buffer, "plex name %s.p0 org raid4 256k", objectname);
+ if (vflag)
+ printf(" plex name %s.p0 org raid4 256k\n", objectname);
+ ioctl(superdev, VINUM_CREATE, buffer);
+ if (reply->error != 0) { /* error in config */
+ if (reply->msg[0])
+ fprintf(stderr,
+ "Can't create plex %s.p0: %s\n",
+ objectname,
+ reply->msg);
+ else
+ fprintf(stderr,
+ "Can't create plex %s.p0: %s (%d)\n",
+ objectname,
+ strerror(reply->error),
+ reply->error);
+ longjmp(command_fail, -1); /* give up */
+ }
+ for (o = 0; o < argc; o++) {
+ drive = find_drive_by_devname(argv[o]); /* we know it exists... */
+ sprintf(buffer,
+ "sd name %s.p0.s%d drive %s size %lldb",
+ objectname,
+ o,
+ drive->label.name,
+ (long long) maxsize);
+ if (vflag)
+ printf(" sd name %s.p0.s%d drive %s size %lldb\n",
+ objectname,
+ o,
+ drive->label.name,
+ (long long) maxsize);
+ ioctl(superdev, VINUM_CREATE, buffer);
+ if (reply->error != 0) { /* error in config */
+ if (reply->msg[0])
+ fprintf(stderr,
+ "Can't create subdisk %s.p0.s%d: %s\n",
+ objectname,
+ o,
+ reply->msg);
+ else
+ fprintf(stderr,
+ "Can't create subdisk %s.p0.s%d: %s (%d)\n",
+ objectname,
+ o,
+ strerror(reply->error),
+ reply->error);
+ longjmp(command_fail, -1); /* give up */
+ }
+ }
+
+ /* done, save the config */
+ ioctltype = 0; /* saveconfig after update */
+ error = ioctl(superdev, VINUM_SAVECONFIG, &ioctltype); /* save the config to disk */
+ if (error != 0)
+ perror("Can't save Vinum config");
+ find_object(objectname, &type); /* find the index of the volume */
+ make_vol_dev(vol.volno, 1); /* and create the devices */
+ if (vflag) {
+ vflag--; /* XXX don't give too much detail */
+ find_object(objectname, &type); /* point to the volume */
+ vinum_lvi(vol.volno, 1); /* and print info about it */
+ }
+}
+
+/*
+ * Create a volume with a single RAID-4 plex from
+ * as much space as we can get on the specified drives.
+ * If the drives aren't Vinum drives, make them so.
+ */
+void
+vinum_raid5(int argc, char *argv[], char *argv0[])
+{
+ int o; /* object number */
+ char buffer[BUFSIZE];
+ struct drive *drive; /* drive we're currently looking at */
+ struct _ioctl_reply *reply;
+ int ioctltype;
+ int error;
+ enum objecttype type;
+ off_t maxsize;
+ int fe; /* freelist entry index */
+ struct drive_freelist freelist;
+ struct ferq { /* request to pass to ioctl */
+ int driveno;
+ int fe;
+ } *ferq = (struct ferq *) &freelist;
+ u_int64_t bigchunk; /* biggest chunk in freelist */
+
+ maxsize = QUAD_MAX;
+ reply = (struct _ioctl_reply *) &buffer;
+
+ /*
+ * First, check our drives.
+ */
+ if (argc < 3) {
+ fprintf(stderr, "You need at least three drives to create a RAID-5 plex\n");
+ return;
+ }
+ if (ioctl(superdev, VINUM_STARTCONFIG, &force)) { /* can't get config? */
+ printf("Can't configure: %s (%d)\n", strerror(errno), errno);
+ return;
+ }
+ if (!objectname) /* we need a name for our object */
+ genvolname();
+ for (o = 0; o < argc; o++) {
+ if ((drive = find_drive_by_devname(argv[o])) == NULL) /* doesn't exist */
+ drive = create_drive(argv[o]); /* create it */
+ /* Now find the largest chunk available on the drive */
+ bigchunk = 0; /* ain't found nothin' yet */
+ for (fe = 0; fe < drive->freelist_entries; fe++) {
+ ferq->driveno = drive->driveno;
+ ferq->fe = fe;
+ if (ioctl(superdev, VINUM_GETFREELIST, &freelist) < 0) {
+ fprintf(stderr,
+ "Can't get free list element %d: %s\n",
+ fe,
+ strerror(errno));
+ longjmp(command_fail, -1);
+ }
+ bigchunk = bigchunk > freelist.sectors ? bigchunk : freelist.sectors; /* max it */
+ }
+ maxsize = min(maxsize, bigchunk); /* this is as much as we can do */
+ }
+
+ /* Now create the volume */
+ sprintf(buffer, "volume %s", objectname);
+ if (vflag)
+ printf("volume %s\n", objectname);
+ ioctl(superdev, VINUM_CREATE, buffer); /* create the volume */
+ if (reply->error != 0) { /* error in config */
+ if (reply->msg[0])
+ fprintf(stderr,
+ "Can't create volume %s: %s\n",
+ objectname,
+ reply->msg);
+ else
+ fprintf(stderr,
+ "Can't create volume %s: %s (%d)\n",
+ objectname,
+ strerror(reply->error),
+ reply->error);
+ longjmp(command_fail, -1); /* give up */
+ }
+ sprintf(buffer, "plex name %s.p0 org raid5 256k", objectname);
+ if (vflag)
+ printf(" plex name %s.p0 org raid5 256k\n", objectname);
+ ioctl(superdev, VINUM_CREATE, buffer);
+ if (reply->error != 0) { /* error in config */
+ if (reply->msg[0])
+ fprintf(stderr,
+ "Can't create plex %s.p0: %s\n",
+ objectname,
+ reply->msg);
+ else
+ fprintf(stderr,
+ "Can't create plex %s.p0: %s (%d)\n",
+ objectname,
+ strerror(reply->error),
+ reply->error);
+ longjmp(command_fail, -1); /* give up */
+ }
+ for (o = 0; o < argc; o++) {
+ drive = find_drive_by_devname(argv[o]); /* we know it exists... */
+ sprintf(buffer,
+ "sd name %s.p0.s%d drive %s size %lldb",
+ objectname,
+ o,
+ drive->label.name,
+ (long long) maxsize);
+ if (vflag)
+ printf(" sd name %s.p0.s%d drive %s size %lldb\n",
+ objectname,
+ o,
+ drive->label.name,
+ (long long) maxsize);
+ ioctl(superdev, VINUM_CREATE, buffer);
+ if (reply->error != 0) { /* error in config */
+ if (reply->msg[0])
+ fprintf(stderr,
+ "Can't create subdisk %s.p0.s%d: %s\n",
+ objectname,
+ o,
+ reply->msg);
+ else
+ fprintf(stderr,
+ "Can't create subdisk %s.p0.s%d: %s (%d)\n",
+ objectname,
+ o,
+ strerror(reply->error),
+ reply->error);
+ longjmp(command_fail, -1); /* give up */
+ }
+ }
+
+ /* done, save the config */
+ ioctltype = 0; /* saveconfig after update */
+ error = ioctl(superdev, VINUM_SAVECONFIG, &ioctltype); /* save the config to disk */
+ if (error != 0)
+ perror("Can't save Vinum config");
+ find_object(objectname, &type); /* find the index of the volume */
+ make_vol_dev(vol.volno, 1); /* and create the devices */
+ if (vflag) {
+ vflag--; /* XXX don't give too much detail */
+ find_object(objectname, &type); /* point to the volume */
+ vinum_lvi(vol.volno, 1); /* and print info about it */
+ }
+}
+
+/*
* Create a volume with a two plexes from as much space
* as we can get on the specified drives. If the
* drives aren't Vinum drives, make them so.
@@ -2061,8 +2413,8 @@ vinum_checkparity(int argc, char *argv[], char *argv0[])
fprintf(stderr, "There is no plex %s\n", argv[index]);
else {
get_plex_info(&plex, object);
- if (plex.organization != plex_raid5)
- fprintf(stderr, "%s is not a RAID-5 plex\n", argv[index]);
+ if (!isparity((&plex)))
+ fprintf(stderr, "%s is not a RAID-4 or RAID-5 plex\n", argv[index]);
else {
do {
message->index = object; /* pass object number */
OpenPOWER on IntegriCloud