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:
parent
89ff8e1b55
commit
6927b5bc64
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 ,
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user