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
This commit is contained in:
iwasaki 2000-04-08 05:19:44 +00:00
parent 89ff8e1b55
commit 6927b5bc64
4 changed files with 255 additions and 6 deletions

View File

@ -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;

View File

@ -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;
in = fopen(name, "r");
if (in == 0) {
logerr(name);
die("readfile");
/* 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;
}
}
/*
* 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

View File

@ -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 ,

View File

@ -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);