diff options
author | Greg Lehey <grog@FreeBSD.org> | 1999-03-02 07:01:51 +0000 |
---|---|---|
committer | Greg Lehey <grog@FreeBSD.org> | 1999-03-02 07:01:51 +0000 |
commit | aa57f129907a5bc16975d9887be80b2e5dab166b (patch) | |
tree | 5693da58fe5e96f2d9f74ba80abbb465e56890af /sbin/vinum/v.c | |
parent | 04898b56e9a630deb87c570e55c330d4f293c8da (diff) | |
download | src-aa57f129907a5bc16975d9887be80b2e5dab166b.tar.gz src-aa57f129907a5bc16975d9887be80b2e5dab166b.zip |
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).
Notes
Notes:
svn path=/head/; revision=44416
Diffstat (limited to 'sbin/vinum/v.c')
-rw-r--r-- | sbin/vinum/v.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/sbin/vinum/v.c b/sbin/vinum/v.c index 6be006ee29f1..b4aac6dbf204 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 */ |