diff options
author | iwasaki <iwasaki@FreeBSD.org> | 2000-04-08 05:19:44 +0000 |
---|---|---|
committer | iwasaki <iwasaki@FreeBSD.org> | 2000-04-08 05:19:44 +0000 |
commit | 6927b5bc642dff72a604d0dd729706a8ea68232d (patch) | |
tree | ea0c8e18b101f2d1d34697a764eb64378e58aaf8 | |
parent | 89ff8e1b55fe7a4a26573ebd73bcd7bc3aa93b67 (diff) | |
download | FreeBSD-src-6927b5bc642dff72a604d0dd729706a8ea68232d.zip FreeBSD-src-6927b5bc642dff72a604d0dd729706a8ea68232d.tar.gz |
Add restart capability by SIGHUP. On restart, working configuration
(resource and card configuration being used) is to be maintained for
consistency. Part of resource pool re-initialization would be rewrite
later using on Warner-san's hints driver API :-)
Reviewed by: nate, imp and -nomads ML in Japan.
Obtained from: http://www.freebsd.org/~iwasaki/pccard/pccardd-signal.diff
Commited at: BSD HANAMI Party 2000 in Japan
-rw-r--r-- | usr.sbin/pccard/pccardd/cardd.h | 3 | ||||
-rw-r--r-- | usr.sbin/pccard/pccardd/file.c | 160 | ||||
-rw-r--r-- | usr.sbin/pccard/pccardd/pccardd.8 | 9 | ||||
-rw-r--r-- | usr.sbin/pccard/pccardd/pccardd.c | 89 |
4 files changed, 255 insertions, 6 deletions
diff --git a/usr.sbin/pccard/pccardd/cardd.h b/usr.sbin/pccard/pccardd/cardd.h index a180ca6..36d712d 100644 --- a/usr.sbin/pccard/pccardd/cardd.h +++ b/usr.sbin/pccard/pccardd/cardd.h @@ -139,11 +139,14 @@ struct slot { EXTERN struct allocblk *pool_ioblks; /* I/O blocks in the pool */ EXTERN struct allocblk *pool_mem; /* Memory in the pool */ EXTERN int pool_irq[16]; /* IRQ allocations */ +EXTERN int irq_init[16]; /* initial IRQ allocations */ EXTERN struct driver *drivers; /* List of drivers */ EXTERN struct card *cards; EXTERN struct card *last_card; EXTERN bitstr_t *mem_avail; +EXTERN bitstr_t *mem_init; EXTERN bitstr_t *io_avail; +EXTERN bitstr_t *io_init; EXTERN int pccard_init_sleep; /* Time to sleep on init */ EXTERN int debug_level; diff --git a/usr.sbin/pccard/pccardd/file.c b/usr.sbin/pccard/pccardd/file.c index 098d2c4..2d15704 100644 --- a/usr.sbin/pccard/pccardd/file.c +++ b/usr.sbin/pccard/pccardd/file.c @@ -115,6 +115,41 @@ static void file_include(char *); static void addcmd(struct cmd **); static void parse_card(int); +static void +delete_card(struct card *cp) +{ + struct ether *etherp, *ether_next; + struct card_config *configp, *config_next; + struct cmd *cmdp, *cmd_next; + + /* free characters */ + if (cp->manuf[0] != NULL) + free(cp->manuf); + if (cp->version[0] != NULL) + free(cp->version); + + /* free structures */ + for (etherp = cp->ether; etherp; etherp = ether_next) { + ether_next = etherp->next; + free(etherp); + } + for (configp = cp->config; configp; configp = config_next) { + config_next = configp->next; + free(configp); + } + for (cmdp = cp->insert; cmdp; cmdp = cmd_next) { + cmd_next = cmdp->next; + free(cmdp->line); + free(cmdp); + } + for (cmdp = cp->remove; cmdp; cmdp = cmd_next) { + cmd_next = cmdp->next; + free(cmdp->line); + free(cmdp); + } + free(cp); +} + /* * Read a file and parse the pcmcia configuration data. * After parsing, verify the links. @@ -122,20 +157,82 @@ static void parse_card(int); void readfile(char *name) { - int i; - struct card *cp; + int i, inuse; + struct card *cp, *card_next; + struct card *genericp, *tail_gp; + struct card_config *configp; + + /* delete all card configuration data before we proceed */ + genericp = 0; + cp = cards; + cards = last_card = 0; + while (cp) { + card_next = cp->next; + + /* check whether this card is in use */ + inuse = 0; + for (configp = cp->config; configp; configp = configp->next) { + if (configp->inuse) { + inuse = 1; + break; + } + } - in = fopen(name, "r"); - if (in == 0) { - logerr(name); - die("readfile"); + /* + * don't delete entry in use for consistency. + * leave normal entry in the cards list, + * insert generic entry into the list after re-loading config files. + */ + if (inuse == 1) { + cp->next = 0; /* unchain from the cards list */ + switch (cp->deftype) { + case DT_VERS: + /* don't delete this entry for consistency */ + if (debug_level >= 1) { + logmsg("Card \"%s\"(\"%s\") is in use, " + "can't change configuration\n", + cp->manuf, cp->version); + } + /* add this to the card list */ + if (!last_card) { + cards = last_card = cp; + } else { + last_card->next = cp; + last_card = cp; + } + break; + + case DT_FUNC: + /* generic entry must be inserted to the list later */ + if (debug_level >= 1) { + logmsg("Generic entry is in use, " + "can't change configuration\n"); + } + cp->next = genericp; + genericp = cp; + break; + } + } else { + delete_card(cp); + } + + cp = card_next; } + for (i = 0; i < MAXINCLUDES; i++) { if (configfiles[i].filep) { fclose(configfiles[i].filep); configfiles[i].filep = NULL; + if (i > 0) { + free(configfiles[i].filename); + } } } + in = fopen(name, "r"); + if (in == 0) { + logerr(name); + die("readfile"); + } includes = 0; configfiles[includes].filep = in; filename = configfiles[includes].filename = name; @@ -146,6 +243,57 @@ readfile(char *name) logmsg("warning: card %s(%s) has no valid configuration\n", cp->manuf, cp->version); } + + /* insert generic entries in use into the top of generic entries */ + if (genericp) { + /* search tail of generic entries in use */ + for (tail_gp = genericp; tail_gp->next; tail_gp = tail_gp->next) + ; + + /* + * if the top of cards list is generic entry, + * insert generic entries in use before it. + */ + if (cards && cards->deftype == DT_FUNC) { + tail_gp->next = cards; + cards = genericp; + goto generic_done; + } + + /* search top of generic entries */ + for (cp = cards; cp; cp = cp->next) { + if (cp->next && cp->next->deftype == DT_FUNC) { + break; + } + } + + /* + * if we have generic entry in the cards list, + * insert generic entries in use into there. + */ + if (cp) { + tail_gp->next = cp->next; + cp->next = genericp; + goto generic_done; + } + + /* + * otherwise we don't have generic entries in + * cards list, just add them to the list. + */ + if (!last_card) { + cards = genericp; + } else { + last_card->next = genericp; + last_card = tail_gp; + } +generic_done: + } + + /* save the initial state of resource pool */ + bcopy(io_avail, io_init, bitstr_size(IOPORTS)); + bcopy(mem_avail, mem_init, bitstr_size(MEMBLKS)); + bcopy(pool_irq, irq_init, sizeof(pool_irq)); } static void diff --git a/usr.sbin/pccard/pccardd/pccardd.8 b/usr.sbin/pccard/pccardd/pccardd.8 index 28a7319..9214a04 100644 --- a/usr.sbin/pccard/pccardd/pccardd.8 +++ b/usr.sbin/pccard/pccardd/pccardd.8 @@ -119,6 +119,10 @@ parameters. This will change significantly when loadable kernel modules are supported. .Pp +SIGHUP causes +.Nm +to reload the configuration files. +.Pp The start options understood by .Nm are: @@ -150,7 +154,12 @@ interface to the card. .Sh FILES .Bl -tag -width /etc/defaults/pccard.conf -compact .It Pa /etc/defaults/pccard.conf +default configuration file .It Pa /etc/pccard.conf +user configuration file +.It Pa /var/run/pccardd.pid +process id of of the currently running +.Nm .El .Sh SEE ALSO .Xr pccard.conf 5 , diff --git a/usr.sbin/pccard/pccardd/pccardd.c b/usr.sbin/pccard/pccardd/pccardd.c index 1e90537..d476513 100644 --- a/usr.sbin/pccard/pccardd/pccardd.c +++ b/usr.sbin/pccard/pccardd/pccardd.c @@ -29,6 +29,7 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -38,6 +39,86 @@ static const char rcsid[] = #include "cardd.h" char *config_file = "/etc/defaults/pccard.conf"; +static char *pid_file = "/var/run/pccardd.pid"; + +/* SIGHUP signal handler */ +static void +restart(void) +{ + bitstr_t bit_decl(io_inuse, IOPORTS); + bitstr_t bit_decl(mem_inuse, MEMBLKS); + int irq_inuse[16]; + int i; + + bit_nclear(io_inuse, 0, IOPORTS-1); + bit_nclear(mem_inuse, 0, MEMBLKS-1); + bzero(irq_inuse, sizeof(irq_inuse)); + + /* compare the initial and current state of resource pool */ + for (i = 0; i < IOPORTS; i++) { + if (bit_test(io_init, i) == 1 && bit_test(io_avail, i) == 0) { + if (debug_level >= 1) { + logmsg("io 0x%x seems to be in use\n", i); + } + bit_set(io_inuse, i); + } + } + for (i = 0; i < MEMBLKS; i++) { + if (bit_test(mem_init, i) == 1 && bit_test(mem_avail, i) == 0) { + if (debug_level >= 1) { + logmsg("mem 0x%x seems to be in use\n", i); + } + bit_set(mem_inuse, i); + } + } + for (i = 0; i < 16; i++) { + if (irq_init[i] == 1 && pool_irq[i] == 0) { + if (debug_level >= 1) { + logmsg("irq %d seems to be in use\n", i); + } + irq_inuse[i] = 1; + } + } + + readfile(config_file); + + /* reflect used resources to managed resource pool */ + for (i = 0; i < IOPORTS; i++) { + if (bit_test(io_inuse, i) == 1) { + bit_clear(io_avail, i); + } + } + for (i = 0; i < MEMBLKS; i++) { + if (bit_test(mem_inuse, i) == 1) { + bit_clear(mem_avail, i); + } + } + for (i = 0; i < 16; i++) { + if (irq_inuse[i] == 1) { + pool_irq[i] = 0; + } + } +} + +/* SIGTERM/SIGINT signal handler */ +static void +term(int sig) +{ + logmsg("pccardd terminated: signal %d received", sig); + (void)unlink(pid_file); + exit(0); +} + +static void +write_pid() +{ + FILE *fp = fopen(pid_file, "w"); + + if (fp) { + fprintf(fp, "%d\n", getpid()); + fclose(fp); + } +} /* * mainline code for cardd @@ -90,9 +171,11 @@ main(int argc, char *argv[]) dodebug = 1; #endif io_avail = bit_alloc(IOPORTS); /* Only supports ISA ports */ + io_init = bit_alloc(IOPORTS); /* Mem allocation done in MEMUNIT units. */ mem_avail = bit_alloc(MEMBLKS); + mem_init = bit_alloc(MEMBLKS); readfile(config_file); if (doverbose) dump_config_file(); @@ -107,6 +190,12 @@ main(int argc, char *argv[]) if (daemon(0, 0)) die("fork failed"); logmsg("pccardd started", NULL); + write_pid(); + + (void)signal(SIGINT, dodebug ? term : SIG_IGN); + (void)signal(SIGTERM, term); + (void)signal(SIGHUP, (void (*)(int))restart); + for (;;) { fd_set mask; FD_ZERO(&mask); |