summaryrefslogtreecommitdiffstats
path: root/sbin/vinum/v.c
diff options
context:
space:
mode:
authorgrog <grog@FreeBSD.org>1999-03-02 07:01:51 +0000
committergrog <grog@FreeBSD.org>1999-03-02 07:01:51 +0000
commit581f2d2446d3fe30987191df0800b5c1daec5f7c (patch)
tree1dde9eb44267d62ba3328c41824b08ffd033a327 /sbin/vinum/v.c
parent2907a0fb2296d0c2147583f24071e6a1e8dad5d0 (diff)
downloadFreeBSD-src-581f2d2446d3fe30987191df0800b5c1daec5f7c.zip
FreeBSD-src-581f2d2446d3fe30987191df0800b5c1daec5f7c.tar.gz
Move definitions of VINUMMOD and WRONGMOD to vext.h.
Wait4 zombies. make_devices: Don't try if the /dev directory is mounted read-only. Create daemon superdevice /dev/vinum/controld. Format a couple of multiline comments conformant with style(9).
Diffstat (limited to 'sbin/vinum/v.c')
-rw-r--r--sbin/vinum/v.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/sbin/vinum/v.c b/sbin/vinum/v.c
index 6be006e..b4aac6d 100644
--- a/sbin/vinum/v.c
+++ b/sbin/vinum/v.c
@@ -45,6 +45,7 @@
#include <libutil.h>
#include <netdb.h>
#include <setjmp.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -118,14 +119,6 @@ int
main(int argc, char *argv[])
{
#if __FreeBSD__ >= 3
-#if RAID5
-#define VINUMMOD "Vinum"
-#define WRONGMOD "vinum" /* don't want this one */
-#else
-#define VINUMMOD "vinum"
-#define WRONGMOD "Vinum" /* don't want this one */
-#endif
-
if (modfind(WRONGMOD) >= 0) { /* wrong module loaded, */
fprintf(stderr, "Wrong module loaded: %s. Please start %s.\n", WRONGMOD, WRONGMOD);
exit(1);
@@ -133,14 +126,13 @@ main(int argc, char *argv[])
if (modfind(VINUMMOD) < 0) {
/* need to load the vinum module */
if (kldload(VINUMMOD) < 0 || modfind(VINUMMOD) < 0) {
- perror("vinum kernel module not available");
+ perror(VINUMMOD ": Kernel module not available");
return 1;
}
}
#endif
- superdev = open(VINUM_SUPERDEV_NAME, O_RDWR); /* open it */
-
+ superdev = open(VINUM_SUPERDEV_NAME, O_RDWR); /* open vinum superdevice */
if (superdev < 0) { /* no go */
if (errno == ENOENT) /* we don't have our node, */
make_devices(); /* create them first */
@@ -160,10 +152,12 @@ main(int argc, char *argv[])
} else {
for (;;) { /* ugh */
char *c;
+ int childstatus; /* from wait4 */
setjmp(command_fail); /* come back here on catastrophic failure */
- c = readline("vinum -> "); /* get an input */
+ while (wait4(-1, &childstatus, WNOHANG, NULL) >= 0); /* wait for all dead children */
+ c = readline(VINUMMOD " -> "); /* get an input */
if (c == NULL) { /* EOF or error */
if (ferror(stdin)) {
fprintf(stderr, "Can't read input: %s (%d)\n", strerror(errno), errno);
@@ -227,6 +221,7 @@ struct funkey {
FUNKEY(rename),
FUNKEY(replace),
FUNKEY(printconfig),
+ FUNKEY(saveconfig),
FUNKEY(start),
FUNKEY(stop),
FUNKEY(makedev),
@@ -383,6 +378,13 @@ make_devices(void)
char filename[PATH_MAX]; /* for forming file names */
+ if (access("/dev", W_OK) < 0) { /* can't access /dev to write? */
+ if (errno == EROFS) /* because it's read-only, */
+ fprintf(stderr, VINUMMOD ": /dev is mounted read-only, not rebuilding " VINUM_DIR);
+ else
+ perror(VINUMMOD ": Can't write to /dev");
+ return;
+ }
if (superdev >= 0) /* super device open */
close(superdev);
@@ -402,6 +404,11 @@ make_devices(void)
superdev = open(VINUM_SUPERDEV_NAME, O_RDWR); /* open the super device */
+ if (mknod(VINUM_DAEMON_DEV_NAME, /* daemon super device */
+ S_IRWXU | S_IFBLK, /* block device, user only */
+ VINUM_DAEMON_DEV) < 0)
+ fprintf(stderr, "Can't create %s: %s\n", VINUM_DAEMON_DEV_NAME, strerror(errno));
+
if (ioctl(superdev, VINUM_GETCONFIG, &vinum_conf) < 0) {
perror("Can't get vinum config");
return;
@@ -517,7 +524,8 @@ vinum_makedev(int argc, char *argv[], char *arg0[])
make_devices();
}
-/* Find the object "name". Return object type at type,
+/*
+ * Find the object "name". Return object type at type,
* and the index as the return value.
* If not found, return -1 and invalid_object.
*/
@@ -592,7 +600,7 @@ continue_revive(int sdno)
struct _ioctl_reply reply;
struct vinum_ioctl_msg *message = (struct vinum_ioctl_msg *) &reply;
- openlog("vinum", LOG_CONS | LOG_PERROR | LOG_PID, LOG_KERN);
+ openlog(VINUMMOD, LOG_CONS | LOG_PERROR | LOG_PID, LOG_KERN);
syslog(LOG_INFO | LOG_KERN, "reviving %s", sd.name);
for (reply.error = EAGAIN; reply.error == EAGAIN;) {
@@ -618,11 +626,13 @@ continue_revive(int sdno)
printf("Reviving %s in the background\n", sd.name);
}
-/* Check if the daemon is running,
+/*
+ * Check if the daemon is running,
* start it if it isn't. The check itself
* could take a while, so we do it as a separate
* process, which will become the daemon if one isn't
- * running already */
+ * running already
+ */
void
start_daemon(void)
{
@@ -633,12 +643,27 @@ start_daemon(void)
pid = (int) fork();
if (pid == 0) { /* We're the child, do the work */
+ /*
+ * We have a problem when stopping the subsystem:
+ * The only way to know that we're idle is when
+ * all open superdevs close. But we want the
+ * daemon to clean up for us, and since we can't
+ * count the opens, we need to have the main device
+ * closed when we stop. We solve this conundrum
+ * by getting the daemon to open a separate device.
+ */
+ close(superdev); /* this is the wrong device */
+ superdev = open(VINUM_DAEMON_DEV_NAME, O_RDWR); /* open deamon superdevice */
+ if (superdev < 0) {
+ perror("Can't open " VINUM_DAEMON_DEV_NAME);
+ exit(1);
+ }
error = daemon(0, 0); /* this will fork again, but who's counting? */
if (error != 0) {
fprintf(stderr, "Can't start daemon: %s (%d)\n", strerror(errno), errno);
exit(1);
}
- setproctitle("Vinum daemon"); /* show what we're doing */
+ setproctitle(VINUMMOD " daemon"); /* show what we're doing */
status = ioctl(superdev, VINUM_FINDDAEMON, NULL);
if (status != 0) { /* no daemon, */
ioctl(superdev, VINUM_DAEMON, &verbose); /* we should hang here */
OpenPOWER on IntegriCloud