New RS and new signal handling for system processes.

UPDATING INFO:
20100317:
        /usr/src/etc/system.conf updated to ignore default kernel calls: copy
        it (or merge it) to /etc/system.conf.
        The hello driver (/dev/hello) added to the distribution:
        # cd /usr/src/commands/scripts && make clean install
        # cd /dev && MAKEDEV hello

KERNEL CHANGES:
- Generic signal handling support. The kernel no longer assumes PM as a signal
manager for every process. The signal manager of a given process can now be
specified in its privilege slot. When a signal has to be delivered, the kernel
performs the lookup and forwards the signal to the appropriate signal manager.
PM is the default signal manager for user processes, RS is the default signal
manager for system processes. To enable ptrace()ing for system processes, it
is sufficient to change the default signal manager to PM. This will temporarily
disable crash recovery, though.
- sys_exit() is now split into sys_exit() (i.e. exit() for system processes,
which generates a self-termination signal), and sys_clear() (i.e. used by PM
to ask the kernel to clear a process slot when a process exits).
- Added a new kernel call (i.e. sys_update()) to swap two process slots and
implement live update.

PM CHANGES:
- Posix signal handling is no longer allowed for system processes. System
signals are split into two fixed categories: termination and non-termination
signals. When a non-termination signaled is processed, PM transforms the signal
into an IPC message and delivers the message to the system process. When a
termination signal is processed, PM terminates the process.
- PM no longer assumes itself as the signal manager for system processes. It now
makes sure that every system signal goes through the kernel before being
actually processes. The kernel will then dispatch the signal to the appropriate
signal manager which may or may not be PM.

SYSLIB CHANGES:
- Simplified SEF init and LU callbacks.
- Added additional predefined SEF callbacks to debug crash recovery and
live update.
- Fixed a temporary ack in the SEF init protocol. SEF init reply is now
completely synchronous.
- Added SEF signal event type to provide a uniform interface for system
processes to deal with signals. A sef_cb_signal_handler() callback is
available for system processes to handle every received signal. A
sef_cb_signal_manager() callback is used by signal managers to process
system signals on behalf of the kernel.
- Fixed a few bugs with memory mapping and DS.

VM CHANGES:
- Page faults and memory requests coming from the kernel are now implemented
using signals.
- Added a new VM call to swap two process slots and implement live update.
- The call is used by RS at update time and in turn invokes the kernel call
sys_update().

RS CHANGES:
- RS has been reworked with a better functional decomposition.
- Better kernel call masks. com.h now defines the set of very basic kernel calls
every system service is allowed to use. This makes system.conf simpler and
easier to maintain. In addition, this guarantees a higher level of isolation
for system libraries that use one or more kernel calls internally (e.g. printf).
- RS is the default signal manager for system processes. By default, RS
intercepts every signal delivered to every system process. This makes crash
recovery possible before bringing PM and friends in the loop.
- RS now supports fast rollback when something goes wrong while initializing
the new version during a live update.
- Live update is now implemented by keeping the two versions side-by-side and
swapping the process slots when the old version is ready to update.
- Crash recovery is now implemented by keeping the two versions side-by-side
and cleaning up the old version only when the recovery process is complete.

DS CHANGES:
- Fixed a bug when the process doing ds_publish() or ds_delete() is not known
by DS.
- Fixed the completely broken support for strings. String publishing is now
implemented in the system library and simply wraps publishing of memory ranges.
Ideally, we should adopt a similar approach for other data types as well.
- Test suite fixed.

DRIVER CHANGES:
- The hello driver has been added to the Minix distribution to demonstrate basic
live update and crash recovery functionalities.
- Other drivers have been adapted to conform the new SEF interface.
This commit is contained in:
Cristiano Giuffrida 2010-03-17 01:15:29 +00:00
parent 7685e98304
commit cb176df60f
148 changed files with 4600 additions and 3308 deletions

View file

@ -673,10 +673,13 @@ int main(int argc, char **argv)
int i;
network_t *np;
struct sigaction sa;
ssize_t r= -1;
buf_t *bp= nil;
ssize_t r;
buf_t *bp;
static struct timeval eventtv;
main:
r = -1;
bp = nil;
program= argv[0];
start= now= time(nil);
@ -1403,6 +1406,9 @@ int main(int argc, char **argv)
}
}
}
if (debug >= 1) printf("Nothing more to do! Bailing out...\n");
if (debug >= 1) printf("Nothing more to do! Starting over...\n");
sleep(2);
goto main;
return 0;
}

View file

@ -190,6 +190,9 @@ do
16,0)
des="pseudo random number generator" dev=urandom
;;
17,0)
des="hello" dev=hello
;;
BAD,BAD)
des= dev=
;;

View file

@ -23,7 +23,7 @@ case $#:$1 in
ttypa ttypb ttypc ttypd ttype ttypf \
ttyq0 ttyq1 ttyq2 ttyq3 ttyq4 ttyq5 ttyq6 ttyq7 ttyq8 ttyq9 \
ttyqa ttyqb ttyqc ttyqd ttyqe ttyqf \
eth klog random filter
eth klog random filter hello
;;
0:|1:-\?)
cat >&2 <<EOF
@ -48,6 +48,7 @@ Where key is one of the following:
kbd # Make /dev/kbd
kbdaux # Make /dev/kbdaux
filter # Make /dev/filter
hello # Make /dev/hello
video # Make /dev/video
std # All standard devices
EOF
@ -259,6 +260,11 @@ do
$e mknod filter b 11 0
$e chmod 644 filter
;;
hello)
# hello driver
$e mknod hello c 17 0
$e chmod 644 hello
;;
*)
echo "$0: don't know about $dev" >&2
ex=1

View file

@ -2,4 +2,4 @@
if [ $# -gt 0 ]
then ARGS="-args $@"
fi
/bin/service up /sbin/readclock.drv -config /etc/system.conf -script /etc/rs.single $ARGS
/bin/service up /sbin/readclock.drv -config /etc/system.conf -period 5HZ -script /etc/rs.single $ARGS

View file

@ -1,27 +1,3 @@
20100316:
/usr/man/man9 is required
# mkdir /usr/man/man9
20100308:
Include directory reorganization:
# mv /usr/include/ibm /usr/include/i386
# ln -s /usr/include/i386 /usr/include/machine
Install(1) updates:
# cd commands/simple && make /bin/install
20100303:
Gas2ack updates: Run 'make install' in commands/i386/gas2ack
20100215:
Make(1) has been replaced: Run 'make install' in commands/make
Mkdep updates: Copy commands/scripts/mkdep.sh to /usr/bin/mkdep
Make(1) needs mkfiles: Copy files in etc/mk to /etc/mk
ACK update: Copy commands/i386/acd.descr to /usr/lib/descr
End.a renamed:
-Copy /usr/lib/i86/end.a to /usr/lib/i86/libend.a
-Copy /usr/lib/i386/end.a to /usr/lib/i386/libend.a
-Copy /usr/gnu/lib/end.a to /usr/gnu/lib/libend.a
Asmconv updates: Run 'make install' in commands/i386/asmconv
20091212:
/etc/drivers.conf has been renamed to /etc/system.conf.
user "service" has been added to password file /etc/passwd.
20060818:
You need flex in your $PATH, which has become part of the base
system. This needs bigger binaries.
@ -64,3 +40,34 @@
20091006 (r5422):
OSS requires an improved make to be compiled; run "make install"
in /usr/src/commands/make before running "make world".
20091212:
/etc/drivers.conf has been renamed to /etc/system.conf.
user "service" has been added to password file /etc/passwd.
20100215:
Make(1) has been replaced: Run 'make install' in commands/make
Mkdep updates: Copy commands/scripts/mkdep.sh to /usr/bin/mkdep
Make(1) needs mkfiles: Copy files in etc/mk to /etc/mk
ACK update: Copy commands/i386/acd.descr to /usr/lib/descr
End.a renamed:
-Copy /usr/lib/i86/end.a to /usr/lib/i86/libend.a
-Copy /usr/lib/i386/end.a to /usr/lib/i386/libend.a
-Copy /usr/gnu/lib/end.a to /usr/gnu/lib/libend.a
Asmconv updates: Run 'make install' in commands/i386/asmconv
20100303:
Gas2ack updates: Run 'make install' in commands/i386/gas2ack
20100308:
Include directory reorganization:
# mv /usr/include/ibm /usr/include/i386
# ln -s /usr/include/i386 /usr/include/machine
Install(1) updates:
# cd commands/simple && make /bin/install
20100316:
/usr/man/man9 is required
# mkdir /usr/man/man9
20100317:
/usr/src/etc/system.conf updated to ignore default kernel calls: copy
it (or merge it) to /etc/system.conf.
The hello driver (/dev/hello) added to the distribution:
# cd /usr/src/commands/scripts && make clean install
# cd /dev && MAKEDEV hello

View file

@ -32,6 +32,7 @@ all install depend clean:
cd ./log && $(MAKE) $@
cd ./bios_wini && $(MAKE) $@
cd ./filter && $(MAKE) $@
cd ./hello && $(MAKE) $@
cd ./random && $(MAKE) $@
cd ./readclock && $(MAKE) $@
cd ./dp8390 && $(MAKE) $@

View file

@ -16,6 +16,7 @@ Driver for the AMD Device Exclusion Vector (DEV)
#include <string.h>
#include <unistd.h>
#include <machine/vm.h>
#include <signal.h>
#include <minix/com.h>
#include <minix/const.h>
#include <minix/ipc.h>
@ -57,12 +58,12 @@ static void init_map(unsigned int ix);
static int do_add4pci(message *m);
static void add_range(u32_t busaddr, u32_t size);
static void del_range(u32_t busaddr, u32_t size);
static void do_pm_notify(message *m);
static void report_exceptions(void);
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
int main(void)
{
@ -79,13 +80,7 @@ int main(void)
r= sef_receive(ANY, &m);
if (r != OK)
panic("sef_receive failed: %d", r);
if (is_notify(m.m_type)) {
if (_ENDPOINT_P(m.m_source) == PM_PROC_NR) {
do_pm_notify(&m);
continue;
}
}
else if (m.m_type == IOMMU_MAP) {
if (m.m_type == IOMMU_MAP) {
r= do_add4pci(&m);
m.m_type= r;
send(m.m_source, &m);
@ -109,6 +104,9 @@ PRIVATE void sef_local_startup()
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -156,6 +154,47 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
int r;
endpoint_t proc_e;
phys_bytes base, size;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (;;)
{
r= getdma(&proc_e, &base, &size);
if (r == -1)
{
if (errno != -EAGAIN)
{
printf(
"amddev: getdma failed: %d\n",
errno);
}
break;
}
printf(
"amddev: deleting 0x%x@0x%x for proc %d\n",
size, base, proc_e);
del_range(base, size);
r= deldma(proc_e, base, size);
if (r == -1)
{
printf("amddev: deldma failed: %d\n",
errno);
break;
}
}
}
/* Returns 0 if no device found, or 1 if a device is found. */
static int find_dev(devindp, capaddrp)
int *devindp;
@ -419,47 +458,6 @@ static void del_range(u32_t busaddr, u32_t size)
}
}
static void do_pm_notify(message *m)
{
int r;
endpoint_t proc_e;
phys_bytes base, size;
if (m->m_source != PM_PROC_NR)
{
printf("amddev`do_pm_notify: notify not from PM (from %d)\n",
m->m_source);
return;
}
for (;;)
{
r= getdma(&proc_e, &base, &size);
if (r == -1)
{
if (errno != -EAGAIN)
{
printf(
"amddev`do_pm_notify: getdma failed: %d\n",
errno);
}
break;
}
printf(
"amddev`do_pm_notify: deleting 0x%x@0x%x for proc %d\n",
size, base, proc_e);
del_range(base, size);
r= deldma(proc_e, base, size);
if (r == -1)
{
printf("amddev`do_pm_notify: deldma failed: %d\n",
errno);
break;
}
}
}
static void report_exceptions(void)
{
u32_t status;

View file

@ -202,7 +202,6 @@ PRIVATE struct driver w_dtab = {
w_transfer, /* do the I/O */
nop_cleanup, /* nothing to clean up */
w_geometry, /* tell the geometry of the disk */
nop_signal, /* no cleanup needed on shutdown */
nop_alarm, /* ignore leftover alarms */
nop_cancel, /* ignore CANCELs */
nop_select, /* ignore selects */
@ -213,7 +212,7 @@ PRIVATE struct driver w_dtab = {
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
@ -257,9 +256,6 @@ PRIVATE void sef_local_startup()
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the at_wini driver. */
struct sigaction sa;
/* Install signal handlers. Ask PM to transform signal into message. */
system_hz = sys_hz();
init_buffer();
@ -267,14 +263,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
w_identify_wakeup_ticks = WAKEUP_TICKS;
wakeup_ticks = WAKEUP_TICKS;
sa.sa_handler = SIG_MESS;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGTERM,&sa,NULL)<0) panic("sigaction failed: %d", errno);
/* Set special disk parameters. */
init_params();
signal(SIGTERM, SIG_IGN);
return(OK);
}

View file

@ -19,7 +19,7 @@ EXTERN int w_command;
/*===========================================================================*
* sef_cb_lu_prepare *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare(int state)
PUBLIC int sef_cb_lu_prepare(int state)
{
int is_ready;
@ -43,9 +43,7 @@ PUBLIC void sef_cb_lu_prepare(int state)
}
/* Tell SEF if we are ready. */
if(is_ready) {
sef_lu_ready(OK);
}
return is_ready ? OK : ENOTREADY;
}
/*===========================================================================*

View file

@ -6,7 +6,6 @@
#include "../drivers.h"
#include <signal.h>
#include <sys/mman.h>
#include <minix/ds.h>
#include <minix/vm.h>
@ -1122,33 +1121,6 @@ PRIVATE void atl2_getname(message *m, int instance)
printf("ATL2: unable to send reply (%d)\n", r);
}
/*===========================================================================*
* atl2_shutdown *
*===========================================================================*/
PRIVATE void atl2_shutdown(void)
{
/* Shut down this driver. Stop the device, and deallocate resources
* as proof of concept.
*/
int r;
atl2_stop();
if ((r = sys_irqrmpolicy(&state.hook_id)) != OK)
panic("unable to deregister IRQ: %d", r);
free_contig(state.txd_base, ATL2_TXD_BUFSIZE);
free_contig(state.txs_base, ATL2_TXS_COUNT * sizeof(u32_t));
free_contig(state.rxd_base_u,
state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE);
vm_unmap_phys(SELF, state.base, ATL2_MMAP_SIZE);
/* We cannot free the PCI device at this time. */
exit(0);
}
/*===========================================================================*
* atl2_dump_link *
*===========================================================================*/
@ -1275,6 +1247,36 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
/* In case of a termination signal, shut down this driver.
* Stop the device, and deallocate resources as proof of concept.
*/
int r;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
atl2_stop();
if ((r = sys_irqrmpolicy(&state.hook_id)) != OK)
panic("unable to deregister IRQ: %d", r);
free_contig(state.txd_base, ATL2_TXD_BUFSIZE);
free_contig(state.txs_base, ATL2_TXS_COUNT * sizeof(u32_t));
free_contig(state.rxd_base_u,
state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE);
vm_unmap_phys(SELF, state.base, ATL2_MMAP_SIZE);
/* We cannot free the PCI device at this time. */
exit(0);
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
@ -1289,6 +1291,9 @@ PRIVATE void sef_local_startup(void)
/* No support for live update yet. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -1319,14 +1324,6 @@ int main(int argc, char **argv)
break;
case PM_PROC_NR: /* signal */
if (getsigset(&set) != 0) break;
if (sigismember(&set, SIGTERM))
atl2_shutdown();
break;
case TTY_PROC_NR: /* function key */
atl2_dump();

View file

@ -53,7 +53,6 @@ FORWARD _PROTOTYPE( int msg_ioctl, (message *m_ptr) );
FORWARD _PROTOTYPE( void msg_write, (message *m_ptr) );
FORWARD _PROTOTYPE( void msg_read, (message *m_ptr) );
FORWARD _PROTOTYPE( void msg_hardware, (void) );
FORWARD _PROTOTYPE( void msg_sig_stop, (void) );
FORWARD _PROTOTYPE( void msg_status, (message *m_ptr) );
FORWARD _PROTOTYPE( int init_driver, (void) );
FORWARD _PROTOTYPE( int open_sub_dev, (int sub_dev_nr, int operation) );
@ -78,7 +77,8 @@ PRIVATE int device_available = 0;/*todo*/
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
PUBLIC int is_status_msg_expected = FALSE;
@ -104,9 +104,6 @@ PUBLIC void main(void)
case HARDWARE:
msg_hardware();
break;
case PM_PROC_NR:
msg_sig_stop();
break;
default:
dprint("%s: %d uncaught notify!\n",
drv.DriverName, mess.m_type);
@ -191,6 +188,9 @@ PRIVATE void sef_local_startup()
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -248,10 +248,38 @@ PRIVATE int init_driver(void) {
error("%s: init driver couldn't set IRQ policy", drv.DriverName, i);
return EIO;
}
irq_hook_set = TRUE; /* now msg_sig_stop knows it must unregister policy*/
irq_hook_set = TRUE; /* now signal handler knows it must unregister policy*/
return OK;
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
int i;
char irq;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (i = 0; i < drv.NrOfSubDevices; i++) {
drv_stop(i); /* stop all sub devices */
}
if (irq_hook_set) {
if (sys_irqdisable(&irq_hook_id) != OK) {
error("Could not disable IRQ\n");
}
/* get irq from device driver*/
if (drv_get_irq(&irq) != OK) {
error("Msg SIG_STOP Couldn't get IRQ");
}
/* remove the policy */
if (sys_irqrmpolicy(&irq_hook_id) != OK) {
error("%s: Could not disable IRQ\n",drv.DriverName);
}
}
}
PRIVATE int msg_open (int minor_dev_nr) {
int r, read_chan, write_chan, io_ctl;
@ -627,29 +655,6 @@ PRIVATE void msg_status(message *m_ptr)
is_status_msg_expected = FALSE;
}
PRIVATE void msg_sig_stop(void)
{
int i; char irq;
for (i = 0; i < drv.NrOfSubDevices; i++) {
drv_stop(i); /* stop all sub devices */
}
if (irq_hook_set) {
if (sys_irqdisable(&irq_hook_id) != OK) {
error("Could not disable IRQ\n");
}
/* get irq from device driver*/
if (drv_get_irq(&irq) != OK) {
error("Msg SIG_STOP Couldn't get IRQ");
}
/* remove the policy */
if (sys_irqrmpolicy(&irq_hook_id) != OK) {
error("%s: Could not disable IRQ\n",drv.DriverName);
}
}
}
/* handle interrupt for specified sub device; DmaMode == DEV_WRITE_S*/
PRIVATE void handle_int_write(int sub_dev_nr)
{

View file

@ -44,7 +44,7 @@ PRIVATE void load_state_info(void)
/*===========================================================================*
* sef_cb_lu_prepare *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare(int state)
PUBLIC int sef_cb_lu_prepare(int state)
{
int is_ready;
@ -75,9 +75,7 @@ PUBLIC void sef_cb_lu_prepare(int state)
}
/* Tell SEF if we are ready. */
if(is_ready) {
sef_lu_ready(OK);
}
return is_ready ? OK : ENOTREADY;
}
/*===========================================================================*

View file

@ -80,7 +80,6 @@ PRIVATE struct driver w_dtab = {
w_transfer, /* do the I/O */
nop_cleanup, /* no cleanup needed */
w_geometry, /* tell the geometry of the disk */
nop_signal, /* no cleanup needed on shutdown */
nop_alarm, /* ignore leftover alarms */
nop_cancel, /* ignore CANCELs */
nop_select, /* ignore selects */

View file

@ -64,25 +64,10 @@ static char str_DevName[] = "dec21140A:eth#?";
PRIVATE dpeth_t de_table[DE_PORT_NR];
PRIVATE const char *progname;
int sef_cb_init(int type, sef_init_info_t *info)
{
int r;
int fkeys, sfkeys;
endpoint_t tasknr;
/* Request function key for debug dumps */
fkeys = sfkeys = 0; bit_set(sfkeys, DE_FKEY);
if ((fkey_map(&fkeys, &sfkeys)) != OK)
printf("%s: error using Shift+F%d key(%d)\n", str_DevName, DE_FKEY, errno);
/* Try to notify inet that we are present (again) */
r = ds_retrieve_label_num("inet", &tasknr);
if (r == OK)
notify(tasknr);
else if(r != ESRCH)
printf("%s unable to notify inet: %d\n", str_DevName, r);
return OK;
}
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN char **env_argv;
/*===========================================================================*
* main *
@ -93,13 +78,9 @@ int main(int argc, char *argv[])
message m;
int r;
(progname=strrchr(argv[0],'/')) ? progname++ : (progname=argv[0]);
/* SEF local startup. */
env_setargs(argc, argv);
sef_setcb_init_fresh(sef_cb_init);
sef_setcb_init_restart(sef_cb_init);
sef_startup();
sef_local_startup();
while (TRUE)
{
@ -125,9 +106,6 @@ int main(int argc, char *argv[])
}
}
break;
case PM_PROC_NR:
exit(0);
break;
default:
printf("ignoring notify from %d\n", m.m_source);
break;
@ -152,6 +130,51 @@ int main(int argc, char *argv[])
}
}
/*===========================================================================*
* sef_local_startup *
*===========================================================================*/
PRIVATE void sef_local_startup()
{
/* Register init callbacks. */
sef_setcb_init_fresh(sef_cb_init_fresh);
sef_setcb_init_restart(sef_setcb_init_fresh);
/* No support for live update yet. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler_term);
/* Let SEF perform startup. */
sef_startup();
}
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the DEC 21140A driver. */
int r;
int fkeys, sfkeys;
endpoint_t tasknr;
(progname=strrchr(env_argv[0],'/')) ? progname++ : (progname=env_argv[0]);
/* Request function key for debug dumps */
fkeys = sfkeys = 0; bit_set(sfkeys, DE_FKEY);
if ((fkey_map(&fkeys, &sfkeys)) != OK)
printf("%s: error using Shift+F%d key(%d)\n", str_DevName, DE_FKEY, errno);
/* Try to notify inet that we are present (again) */
r = ds_retrieve_label_num("inet", &tasknr);
if (r == OK)
notify(tasknr);
else if(r != ESRCH)
printf("%s unable to notify inet: %d\n", str_DevName, r);
return OK;
}
PRIVATE void do_get_stat_s(message * mp)
{
int port, rc;

View file

@ -134,7 +134,6 @@ _PROTOTYPE( static void dp_reset, (dpeth_t *dep) );
_PROTOTYPE( static void dp_check_ints, (dpeth_t *dep) );
_PROTOTYPE( static void dp_recv, (dpeth_t *dep) );
_PROTOTYPE( static void dp_send, (dpeth_t *dep) );
_PROTOTYPE( static void dp8390_stop, (void) );
_PROTOTYPE( static void dp_getblock, (dpeth_t *dep, int page,
size_t offset, size_t size, void *dst) );
_PROTOTYPE( static void dp_pio8_getblock, (dpeth_t *dep, int page,
@ -232,6 +231,7 @@ PRIVATE int handle_hw_intr(void)
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN int env_argc;
EXTERN char **env_argv;
@ -257,17 +257,6 @@ int main(int argc, char *argv[])
case HARDWARE:
r = handle_hw_intr();
break;
case PM_PROC_NR:
{
sigset_t set;
if (getsigset(&set) != 0) break;
if (sigismember(&set, SIGTERM))
dp8390_stop();
break;
}
case CLOCK:
printf("dp8390: notify from CLOCK\n");
break;
@ -310,6 +299,9 @@ PRIVATE void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -350,6 +342,27 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
message mess;
int i;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (i= 0; i<DE_PORT_NR; i++)
{
if (de_table[i].de_mode != DEM_ENABLED)
continue;
mess.m_type= DL_STOP;
mess.DL_PORT= i;
do_stop(&mess);
}
}
#if 0
/*===========================================================================*
* dp8390_dump *
@ -403,24 +416,6 @@ void dp8390_dump()
}
#endif
/*===========================================================================*
* dp8390_stop *
*===========================================================================*/
static void dp8390_stop()
{
message mess;
int i;
for (i= 0; i<DE_PORT_NR; i++)
{
if (de_table[i].de_mode != DEM_ENABLED)
continue;
mess.m_type= DL_STOP;
mess.DL_PORT= i;
do_stop(&mess);
}
}
#if ENABLE_PCI
/*===========================================================================*
* pci_conf *

View file

@ -544,24 +544,6 @@ static void do_watchdog(void *message)
return;
}
PRIVATE void handle_system_signal(message *m)
{
sigset_t set;
int port;
if (getsigset(&set) != 0) return;
if (sigismember(&set, SIGTERM)) { /* Shut down */
for (port = 0; port < DE_PORT_NR; port += 1) {
if (de_table[port].de_mode == DEM_ENABLED) {
m->m_type = DL_STOP;
m->DL_PORT = port;
do_stop(m);
}
}
}
}
PRIVATE void handle_hw_intr(void)
{
dpeth_t *dep;
@ -582,6 +564,7 @@ PRIVATE void handle_hw_intr(void)
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN char **env_argv;
/*
@ -619,9 +602,6 @@ PUBLIC int main(int argc, char **argv)
/* Function key pressed */
do_dump(&m);
break;
case PM_PROC_NR:
handle_system_signal(&m);
break;
default:
/* Invalid message type */
panic(TypeErrMsg, m.m_type);
@ -669,6 +649,9 @@ PRIVATE void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -706,4 +689,24 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
int port;
message m;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (port = 0; port < DE_PORT_NR; port += 1) {
if (de_table[port].de_mode == DEM_ENABLED) {
m.m_type = DL_STOP;
m.DL_PORT = port;
do_stop(&m);
}
}
}
/** dp.c **/

View file

@ -42,7 +42,6 @@ _PROTOTYPE( PRIVATE void e1000_readv_s, (message *mp, int from_int) );
_PROTOTYPE( PRIVATE void e1000_getstat_s, (message *mp) );
_PROTOTYPE( PRIVATE void e1000_getname, (message *mp) );
_PROTOTYPE( PRIVATE void e1000_interrupt, (message *mp) );
_PROTOTYPE( PRIVATE void e1000_signal, (void) );
_PROTOTYPE( PRIVATE int e1000_link_changed, (e1000_t *e) );
_PROTOTYPE( PRIVATE void e1000_stop, (void) );
_PROTOTYPE( PRIVATE e1000_t * e1000_port, (int port) );
@ -63,6 +62,7 @@ _PROTOTYPE( PRIVATE void mess_reply, (message *req, message *reply) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN int env_argc;
EXTERN char **env_argv;
@ -94,11 +94,7 @@ int main(int argc, char *argv[])
case HARDWARE:
e1000_interrupt(&m);
break;
case PM_PROC_NR:
e1000_signal();
break;
case CLOCK:
break;
}
@ -129,6 +125,9 @@ PRIVATE void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -172,6 +171,19 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
E1000_DEBUG(3, ("e1000: got signal\n"));
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
e1000_stop();
}
/*===========================================================================*
* e1000_init *
*===========================================================================*/
@ -851,27 +863,6 @@ message *mp;
}
}
/*===========================================================================*
* e1000_signal *
*===========================================================================*/
PRIVATE void e1000_signal(void)
{
sigset_t sigset;
E1000_DEBUG(3, ("e1000: signal()\n"));
/* Try to obtain signal set from PM. */
if (getsigset(&sigset) != 0)
{
return;
}
/* Check for known signals. */
if (sigismember(&sigset, SIGTERM))
{
e1000_stop();
}
}
/*===========================================================================*
* e1000_link_changed *
*===========================================================================*/

View file

@ -76,6 +76,7 @@ static char *buf_array, *buffer; /* contiguous buffer */
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN int env_argc;
EXTERN char **env_argv;
@ -368,28 +369,6 @@ static int parse_arguments(int argc, char *argv[])
return OK;
}
/*===========================================================================*
* got_signal *
*===========================================================================*/
static void got_signal(void)
{
sigset_t set;
/* See if PM sent us a SIGTERM. */
if (getsigset(&set) != 0) return;
if (!sigismember(&set, SIGTERM)) return;
/* If so, shut down this driver. */
#if DEBUG
printf("Filter: shutdown...\n");
#endif
driver_shutdown();
exit(0);
}
/*===========================================================================*
* main *
*===========================================================================*/
@ -413,9 +392,6 @@ int main(int argc, char *argv[])
m_in.m_type, m_in.m_source);
#endif
if (is_notify(m_in.m_type) && m_in.m_source == PM_PROC_NR)
got_signal();
who_e = m_in.m_source;
proc_e = m_in.IO_ENDPT;
grant_id = (cp_grant_id_t) m_in.IO_GRANT;
@ -461,6 +437,9 @@ PRIVATE void sef_local_startup(void)
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -489,3 +468,21 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
/* If so, shut down this driver. */
#if DEBUG
printf("Filter: shutdown...\n");
#endif
driver_shutdown();
exit(0);
}

View file

@ -96,13 +96,10 @@ static void got_alarm(int sig)
*===========================================================================*/
void flt_sleep(int secs)
{
/* Sleep for the given number of seconds. Don't use sleep(), as that
* will end up calling select() to VFS. This implementation could be
* improved.
*/
u32_t system_hz;
signal(SIGALRM, got_alarm);
alarm(secs);
pause();
/* Sleep for the given number of seconds. */
system_hz = sys_hz();
tickdelay(system_hz * secs);
}

View file

@ -264,7 +264,6 @@ FORWARD _PROTOTYPE( void f_reset, (void) );
FORWARD _PROTOTYPE( int f_intr_wait, (void) );
FORWARD _PROTOTYPE( int read_id, (void) );
FORWARD _PROTOTYPE( int f_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void floppy_stop, (struct driver *dp, sigset_t *set));
FORWARD _PROTOTYPE( int test_read, (int density) );
FORWARD _PROTOTYPE( void f_geometry, (struct partition *entry) );
@ -278,7 +277,6 @@ PRIVATE struct driver f_dtab = {
f_transfer, /* do the I/O */
f_cleanup, /* cleanup before sending reply to user process */
f_geometry, /* tell the geometry of the diskette */
floppy_stop, /* floppy cleanup on shutdown */
f_expire_tmrs,/* expire all alarm timers */
nop_cancel,
nop_select,
@ -292,7 +290,8 @@ static phys_bytes floppy_buf_phys;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
PUBLIC int last_transfer_opcode;
@ -326,6 +325,9 @@ PRIVATE void sef_local_startup(void)
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -365,12 +367,25 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
if ((s=sys_irqenable(&irq_hook_id)) != OK)
panic("Couldn't enable IRQs: %d", s);
/* Ignore signals */
signal(SIGHUP, SIG_IGN);
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
int s;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
/* Stop all activity and cleanly exit with the system. */
if ((s=sys_outb(DOR, ENABLE_INT)) != OK)
panic("Sys_outb failed: %d", s);
exit(0);
}
/*===========================================================================*
* f_expire_tmrs *
*===========================================================================*/
@ -745,7 +760,7 @@ PRIVATE int dma_setup(
/* First check the DMA memory address not to exceed maximum. */
if (floppy_buf_phys != (floppy_buf_phys & DMA_ADDR_MASK)) {
printf("floppy: DMA denied because address out of range");
printf("floppy: DMA denied because address out of range\n");
return(EIO);
}
@ -834,20 +849,6 @@ PRIVATE void stop_motor(timer_t *tp)
panic("Sys_outb in stop_motor() failed: %d", s);
}
/*===========================================================================*
* floppy_stop *
*===========================================================================*/
PRIVATE void floppy_stop(struct driver *dp, sigset_t *set)
{
/* Stop all activity and cleanly exit with the system. */
int s;
if (sigismember(set, SIGTERM)) {
if ((s=sys_outb(DOR, ENABLE_INT)) != OK)
panic("Sys_outb in floppy_stop() failed: %d", s);
exit(0);
}
}
/*===========================================================================*
* seek *
*===========================================================================*/

View file

@ -22,7 +22,7 @@ EXTERN int last_transfer_opcode;
/*===========================================================================*
* sef_cb_lu_prepare *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare(int state)
PUBLIC int sef_cb_lu_prepare(int state)
{
int is_ready;
@ -43,9 +43,7 @@ PUBLIC void sef_cb_lu_prepare(int state)
}
/* Tell SEF if we are ready. */
if(is_ready) {
sef_lu_ready(OK);
}
return is_ready ? OK : ENOTREADY;
}
/*===========================================================================*

View file

@ -250,7 +250,6 @@ _PROTOTYPE( static void fxp_check_ints, (fxp_t *fp) );
_PROTOTYPE( static void fxp_watchdog_f, (timer_t *tp) );
_PROTOTYPE( static int fxp_link_changed, (fxp_t *fp) );
_PROTOTYPE( static void fxp_report_link, (fxp_t *fp) );
_PROTOTYPE( static void fxp_stop, (void));
_PROTOTYPE( static void reply, (fxp_t *fp, int err, int may_block) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
_PROTOTYPE( static u16_t eeprom_read, (fxp_t *fp, int reg) );
@ -292,6 +291,7 @@ PRIVATE void handle_hw_intr(void)
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN int env_argc;
EXTERN char **env_argv;
@ -317,17 +317,6 @@ int main(int argc, char *argv[])
case HARDWARE:
handle_hw_intr();
break;
case PM_PROC_NR:
{
sigset_t set;
if (getsigset(&set) != 0) break;
if (sigismember(&set, SIGTERM))
fxp_stop();
break;
}
case CLOCK:
fxp_expire_timers();
break;
@ -368,6 +357,9 @@ PRIVATE void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -415,6 +407,34 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
int i;
port_t port;
fxp_t *fp;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)
{
if (fp->fxp_mode != FM_ENABLED)
continue;
if (!(fp->fxp_flags & FF_ENABLED))
continue;
port= fp->fxp_base_port;
/* Reset device */
if (debug)
printf("%s: resetting device\n", fp->fxp_name);
fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);
}
exit(0);
}
/*===========================================================================*
* fxp_init *
*===========================================================================*/
@ -2604,31 +2624,6 @@ resspeed:
;
}
/*===========================================================================*
* fxp_stop *
*===========================================================================*/
static void fxp_stop()
{
int i;
port_t port;
fxp_t *fp;
for (i= 0, fp= &fxp_table[0]; i<FXP_PORT_NR; i++, fp++)
{
if (fp->fxp_mode != FM_ENABLED)
continue;
if (!(fp->fxp_flags & FF_ENABLED))
continue;
port= fp->fxp_base_port;
/* Reset device */
if (debug)
printf("%s: resetting device\n", fp->fxp_name);
fxp_outl(port, CSR_PORT, CP_CMD_SOFT_RESET);
}
exit(0);
}
/*===========================================================================*
* reply *
*===========================================================================*/

44
drivers/hello/Makefile Normal file
View file

@ -0,0 +1,44 @@
#
# Makefile for the hello driver.
#
DRIVER = hello
#
# Directories.
#
u = /usr
i = $u/include
s = $i/sys
m = $i/minix
b = $i/ibm
d = ..
#
# Build Programs, Flags and Variables.
#
CC = exec cc
CFLAGS = -I$i $(CPROFILE)
LDFLAGS = -i -L../libdriver
LIBS = -ldriver -lsys
OBJ = hello.o
# build local binary
all build: $(DRIVER)
$(DRIVER): $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
install -S 128k $(DRIVER)
# install with other drivers
install: /usr/sbin/$(DRIVER)
/usr/sbin/$(DRIVER): $(DRIVER)
install -o root -cs $? $@
# clean up local files
clean:
rm -f *.o $(DRIVER)
depend:
mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
# Include generated dependencies.
include .depend

214
drivers/hello/hello.c Normal file
View file

@ -0,0 +1,214 @@
#include "../drivers.h"
#include "../libdriver/driver.h"
#include <stdio.h>
#include <stdlib.h>
#include <minix/ds.h>
#include "hello.h"
/*
* Function prototypes for the hello driver.
*/
FORWARD _PROTOTYPE( char * hello_name, (void) );
FORWARD _PROTOTYPE( int hello_open, (struct driver *d, message *m) );
FORWARD _PROTOTYPE( int hello_close, (struct driver *d, message *m) );
FORWARD _PROTOTYPE( struct device * hello_prepare, (int device) );
FORWARD _PROTOTYPE( int hello_transfer, (int procnr, int opcode,
u64_t position, iovec_t *iov,
unsigned nr_req) );
FORWARD _PROTOTYPE( void hello_geometry, (struct partition *entry) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( int sef_cb_lu_state_save, (int) );
FORWARD _PROTOTYPE( int lu_state_restore, (void) );
/* Entry points to the hello driver. */
PRIVATE struct driver hello_tab =
{
hello_name,
hello_open,
hello_close,
nop_ioctl,
hello_prepare,
hello_transfer,
nop_cleanup,
hello_geometry,
nop_alarm,
nop_cancel,
nop_select,
nop_ioctl,
do_nop,
};
/** Represents the /dev/hello device. */
PRIVATE struct device hello_device;
/** State variable to count the number of times the device has been opened. */
PRIVATE int open_counter;
PRIVATE char * hello_name(void)
{
printf("hello_name()\n");
return "hello";
}
PRIVATE int hello_open(d, m)
struct driver *d;
message *m;
{
printf("hello_open(). Called %d time(s).\n", ++open_counter);
return OK;
}
PRIVATE int hello_close(d, m)
struct driver *d;
message *m;
{
printf("hello_close()\n");
return OK;
}
PRIVATE struct device * hello_prepare(dev)
int dev;
{
hello_device.dv_base.lo = 0;
hello_device.dv_base.hi = 0;
hello_device.dv_size.lo = strlen(HELLO_MESSAGE);
hello_device.dv_size.hi = 0;
return &hello_device;
}
PRIVATE int hello_transfer(proc_nr, opcode, position, iov, nr_req)
int proc_nr;
int opcode;
u64_t position;
iovec_t *iov;
unsigned nr_req;
{
int bytes, ret;
printf("hello_transfer()\n");
bytes = strlen(HELLO_MESSAGE) - position.lo < iov->iov_size ?
strlen(HELLO_MESSAGE) - position.lo : iov->iov_size;
if (bytes <= 0)
{
return OK;
}
switch (opcode)
{
case DEV_GATHER_S:
ret = sys_safecopyto(proc_nr, iov->iov_addr, 0,
(vir_bytes) (HELLO_MESSAGE + position.lo),
bytes, D);
iov->iov_size -= bytes;
break;
default:
return EINVAL;
}
return ret;
}
PRIVATE void hello_geometry(entry)
struct partition *entry;
{
printf("hello_geometry()\n");
entry->cylinders = 0;
entry->heads = 0;
entry->sectors = 0;
}
PRIVATE int sef_cb_lu_state_save(int state) {
/* Save the state. */
ds_publish_u32("open_counter", open_counter, DSF_OVERWRITE);
return OK;
}
PRIVATE int lu_state_restore() {
/* Restore the state. */
u32_t value;
ds_retrieve_u32("open_counter", &value);
ds_delete_u32("open_counter");
open_counter = (int) value;
return OK;
}
PRIVATE void sef_local_startup()
{
/*
* Register init callbacks. Use the same function for all event types
*/
sef_setcb_init_fresh(sef_cb_init);
sef_setcb_init_lu(sef_cb_init);
sef_setcb_init_restart(sef_cb_init);
/*
* Register live update callbacks.
*/
/* - Agree to update immediately when LU is requested in a valid state. */
sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready);
/* - Support live update starting from any standard state. */
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_standard);
/* - Register a custom routine to save the state. */
sef_setcb_lu_state_save(sef_cb_lu_state_save);
/* Let SEF perform startup. */
sef_startup();
}
PRIVATE int sef_cb_init(int type, sef_init_info_t *info)
{
/* Initialize the hello driver. */
int do_mapdriver = TRUE;
open_counter = 0;
switch(type) {
case SEF_INIT_FRESH:
printf("%s", HELLO_MESSAGE);
break;
case SEF_INIT_LU:
/* Restore the state. */
lu_state_restore();
do_mapdriver = FALSE;
printf("%sHey, I'm a new version!\n", HELLO_MESSAGE);
break;
case SEF_INIT_RESTART:
printf("%sHey, I've just been restarted!\n", HELLO_MESSAGE);
break;
}
/* Map major number to our process. */
if (do_mapdriver && mapdriver("hello", HELLO_MAJOR, STYLE_DEV, TRUE) != OK)
{
printf("hello: mapdriver() failed: %s\n",
strerror(errno));
return EINVAL;
}
/* Initialization completed successfully. */
return OK;
}
PUBLIC int main(int argc, char **argv)
{
/*
* Perform initialization.
*/
sef_local_startup();
/*
* Run the main loop.
*/
driver_task(&hello_tab, DRIVER_STD);
return OK;
}

7
drivers/hello/hello.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef __HELLO_H
#define __HELLO_H
/** The Hello, World! message. */
#define HELLO_MESSAGE "Hello, World!\n"
#endif /* __HELLO_H */

View file

@ -121,7 +121,6 @@ _PROTOTYPE( static void do_stop, (message *mp) );
_PROTOTYPE( static void do_getname, (message *mp) );
_PROTOTYPE( static void lance_dump, (void) );
_PROTOTYPE( static void lance_stop, (void) );
_PROTOTYPE( static void getAddressing, (int devind, ether_card_t *ec) );
/* probe+init LANCE cards */
@ -264,6 +263,7 @@ phys_bytes lance_buf_phys;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN char **env_argv;
/*===========================================================================*
@ -317,17 +317,6 @@ void main( int argc, char **argv )
}
}
break;
case PM_PROC_NR:
{
sigset_t set;
if (getsigset(&set) != 0) break;
if (sigismember(&set, SIGTERM))
lance_stop();
break;
}
default:
panic("illegal notify source: %d", m.m_source);
}
@ -373,6 +362,9 @@ PRIVATE void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -410,7 +402,34 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
else if (r != ESRCH)
printf("lance: ds_retrieve_label_num failed for 'inet': %d\n", r);
return(OK);
return OK;
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
message mess;
int i;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (i= 0; i<EC_PORT_NR_MAX; i++)
{
if (ec_table[i].mode != EC_ENABLED)
continue;
mess.m_type= DL_STOP;
mess.DL_PORT= i;
do_stop(&mess);
}
#if VERBOSE
printf("LANCE driver stopped.\n");
#endif
exit(0);
}
/*===========================================================================*
@ -478,31 +497,6 @@ static void lance_dump()
}
}
/*===========================================================================*
* lance_stop *
*===========================================================================*/
static void lance_stop()
{
message mess;
int i;
for (i= 0; i<EC_PORT_NR_MAX; i++)
{
if (ec_table[i].mode != EC_ENABLED)
continue;
mess.m_type= DL_STOP;
mess.DL_PORT= i;
do_stop(&mess);
}
#if VERBOSE
printf("LANCE driver stopped.\n");
#endif
exit( 0 );
}
/*===========================================================================*
* do_init *
*===========================================================================*/

View file

@ -161,14 +161,6 @@ int type; /* Driver type (DRIVER_STD or DRIVER_ASYN) */
(*dp->dr_hw_int)(dp, &mess);
}
break;
case PM_PROC_NR:
if (getsigset(&set) != 0) break;
(*dp->dr_signal)(dp, &set);
break;
case SYSTEM:
set = mess.NOTIFY_ARG;
(*dp->dr_signal)(dp, &set);
break;
case CLOCK:
(*dp->dr_alarm)(dp, &mess);
break;
@ -380,16 +372,6 @@ message *mp;
return(ENOTTY);
}
/*============================================================================*
* nop_signal *
*============================================================================*/
PUBLIC void nop_signal(dp, set)
struct driver *dp;
sigset_t *set;
{
/* Default action for signal is to ignore. */
}
/*============================================================================*
* nop_alarm *
*============================================================================*/

View file

@ -37,7 +37,6 @@ struct driver {
iovec_t *iov, unsigned nr_req) );
_PROTOTYPE( void (*dr_cleanup), (void) );
_PROTOTYPE( void (*dr_geometry), (struct partition *entry) );
_PROTOTYPE( void (*dr_signal), (struct driver *dp, sigset_t *set) );
_PROTOTYPE( void (*dr_alarm), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_cancel), (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int (*dr_select), (struct driver *dp, message *m_ptr) );
@ -63,7 +62,6 @@ _PROTOTYPE( int do_nop, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( struct device *nop_prepare, (int device) );
_PROTOTYPE( void nop_cleanup, (void) );
_PROTOTYPE( void nop_task, (void) );
_PROTOTYPE( void nop_signal, (struct driver *dp, sigset_t *set) );
_PROTOTYPE( void nop_alarm, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int nop_cancel, (struct driver *dp, message *m_ptr) );
_PROTOTYPE( int nop_select, (struct driver *dp, message *m_ptr) );

View file

@ -36,7 +36,7 @@ PRIVATE void load_state_info(void)
/*===========================================================================*
* sef_cb_lu_prepare *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare(int state)
PUBLIC int sef_cb_lu_prepare(int state)
{
int is_ready;
@ -62,9 +62,7 @@ PUBLIC void sef_cb_lu_prepare(int state)
}
/* Tell SEF if we are ready. */
if(is_ready) {
sef_lu_ready(OK);
}
return is_ready ? OK : ENOTREADY;
}
/*===========================================================================*

View file

@ -29,7 +29,6 @@ FORWARD _PROTOTYPE( int log_transfer, (int proc_nr, int opcode, u64_t position,
FORWARD _PROTOTYPE( int log_do_open, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_cancel, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( int log_select, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void log_signal, (struct driver *dp, sigset_t *set) );
FORWARD _PROTOTYPE( int log_other, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void log_geometry, (struct partition *entry) );
FORWARD _PROTOTYPE( int subread, (struct logdevice *log, int count, int proc_nr, vir_bytes user_vir, size_t) );
@ -44,7 +43,6 @@ PRIVATE struct driver log_dtab = {
log_transfer, /* do the I/O */
nop_cleanup, /* no need to clean up */
log_geometry, /* geometry */
log_signal, /* handle system signal */
nop_alarm, /* no alarm */
log_cancel, /* CANCEL request */
log_select, /* DEV_SELECT request */
@ -57,9 +55,10 @@ extern int device_caller;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
/*===========================================================================*
* main *
@ -90,6 +89,9 @@ PRIVATE void sef_local_startup()
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -118,6 +120,17 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
/* Only check for a pending message from the kernel, ignore anything else. */
if (signo != SIGKMESS) return;
do_new_kmess(SYSTEM);
}
/*===========================================================================*
* log_name *
*===========================================================================*/
@ -395,20 +408,6 @@ message *m_ptr;
return(OK);
}
/*============================================================================*
* log_signal *
*============================================================================*/
PRIVATE void log_signal(dp, set)
struct driver *dp;
sigset_t *set;
{
if (sigismember(set, SIGKMESS)) {
do_new_kmess(SYSTEM);
}
}
/*============================================================================*
* log_other *
*============================================================================*/

View file

@ -64,7 +64,6 @@ PRIVATE struct driver m_dtab = {
m_transfer, /* do the I/O */
nop_cleanup, /* no need to clean up */
m_geometry, /* memory device "geometry" */
nop_signal, /* system signals */
nop_alarm,
nop_cancel,
nop_select,
@ -121,15 +120,9 @@ PRIVATE void sef_local_startup()
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the memory driver. */
struct sigaction sa;
u32_t ramdev_size;
int i, s;
sa.sa_handler = SIG_MESS;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGTERM,&sa,NULL)<0) panic("sigaction failed: %d", errno);
/* Initialize all minor devices one by one. */
if (OK != (s=sys_getkinfo(&kinfo))) {
panic("Couldn't get kernel information: %d", s);

View file

@ -5,7 +5,7 @@ exec >/dev/log
exec 2>/dev/log
exec </dev/null
/bin/service up /bin/pci -config /etc/system.conf
/bin/service -c up /bin/pci -config /etc/system.conf
/bin/service -c up /bin/floppy -config /etc/system.conf -dev /dev/fd0
if [ X`/bin/sysenv bios_wini` = Xyes ]
then

View file

@ -207,7 +207,6 @@ _PROTOTYPE (static void or_getstat_s, (message * mp));
_PROTOTYPE (static void print_linkstatus, (t_or * orp, u16_t status));
_PROTOTYPE (static int or_get_recvd_packet, (t_or *orp, u16_t rxfid,
u8_t *databuf));
_PROTOTYPE (static void orinoco_stop, (void));
_PROTOTYPE (static void or_reset, (void));
_PROTOTYPE (static void or_watchdog_f, (timer_t *tp) );
_PROTOTYPE (static void setup_wepkey, (t_or *orp, char *wepkey0) );
@ -231,6 +230,7 @@ PRIVATE const char *progname;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN char **env_argv;
/*****************************************************************************
@ -263,17 +263,6 @@ int main(int argc, char *argv[]) {
case TTY_PROC_NR:
or_dump(&m);
break;
case PM_PROC_NR:
{
sigset_t set;
if (getsigset(&set) != 0) break;
if (sigismember(&set, SIGTERM))
orinoco_stop();
break;
}
default:
panic("orinoco: illegal notify from: %d",
m.m_source);
@ -331,6 +320,9 @@ PRIVATE void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -366,6 +358,25 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
int i;
t_or *orp;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (i= 0, orp= &or_table[0]; i<OR_PORT_NR; i++, orp++) {
if (orp->or_mode != OR_M_ENABLED)
continue;
/* TODO: send a signal to the card to shut it down */
}
exit(0);
}
/*****************************************************************************
* check_int_events *
* *
@ -432,25 +443,6 @@ static int do_hard_int(void) {
}
}
/*****************************************************************************
* orinoco_stop *
* *
* Stops the card. The signal to the card itself is not implemented yet. *
*****************************************************************************/
static void orinoco_stop () {
int i;
t_or *orp;
for (i= 0, orp= &or_table[0]; i<OR_PORT_NR; i++, orp++) {
if (orp->or_mode != OR_M_ENABLED)
continue;
/* TODO: send a signal to the card to shut it down */
}
exit(0);
}
/*****************************************************************************
* or_reset *
* *

View file

@ -55,14 +55,7 @@ int main(void)
}
if (is_notify(m.m_type)) {
switch (_ENDPOINT_P(m.m_source)) {
case PM_PROC_NR:
break;
default:
printf("PCI: got notify from %d\n",
m.m_source);
break;
}
printf("PCI: got notify from %d\n", m.m_source);
/* done, get a new message */
continue;

View file

@ -365,7 +365,7 @@ endpoint_t proc;
printf("pci:pci_reserve2: bad devind: %d\n", devind);
return EINVAL;
}
if(pcidev[devind].pd_inuse)
if(pcidev[devind].pd_inuse && pcidev[devind].pd_proc != proc)
return EBUSY;
pcidev[devind].pd_inuse= 1;
pcidev[devind].pd_proc= proc;

View file

@ -11,7 +11,7 @@ EXTERN int is_status_msg_expected;
/*===========================================================================*
* sef_cb_lu_prepare *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare(int state)
PUBLIC int sef_cb_lu_prepare(int state)
{
int is_ready;
@ -34,9 +34,7 @@ PUBLIC void sef_cb_lu_prepare(int state)
}
/* Tell SEF if we are ready. */
if(is_ready) {
sef_lu_ready(OK);
}
return is_ready ? OK : ENOTREADY;
}
/*===========================================================================*

View file

@ -111,12 +111,10 @@ FORWARD _PROTOTYPE( void prepare_output, (void) );
FORWARD _PROTOTYPE( void do_initialize, (void) );
FORWARD _PROTOTYPE( void reply, (int code,int replyee,int proc,int status));
FORWARD _PROTOTYPE( void do_printer_output, (void) );
FORWARD _PROTOTYPE( void do_signal, (void) );
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
PUBLIC int is_status_msg_expected = FALSE;
@ -140,9 +138,6 @@ PUBLIC void main(void)
case HARDWARE:
do_printer_output();
break;
case PM_PROC_NR:
do_signal();
break;
default:
reply(TASK_REPLY, pr_mess.m_source,
pr_mess.IO_ENDPT, EINVAL);
@ -171,53 +166,20 @@ PUBLIC void main(void)
*===========================================================================*/
PRIVATE void sef_local_startup()
{
/* Register init callbacks. */
sef_setcb_init_fresh(sef_cb_init_fresh);
sef_setcb_init_lu(sef_cb_init_fresh);
sef_setcb_init_restart(sef_cb_init_fresh);
/* Nothing to on initialization. */
/* Register live update callbacks. */
sef_setcb_lu_prepare(sef_cb_lu_prepare);
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler_term);
/* Let SEF perform startup. */
sef_startup();
}
/*===========================================================================*
* sef_cb_init_fresh *
*===========================================================================*/
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the printer driver. */
struct sigaction sa;
/* Install signal handlers. Ask PM to transform signal into message. */
sa.sa_handler = SIG_MESS;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGTERM,&sa,NULL)<0) panic("sigaction failed: %d", errno);
return(OK);
}
/*===========================================================================*
* do_signal *
*===========================================================================*/
PRIVATE void do_signal()
{
sigset_t sigset;
if (getsigset(&sigset) != 0) return;
/* Expect a SIGTERM signal when this server must shutdown. */
if (sigismember(&sigset, SIGTERM)) {
exit(0);
}
/* Ignore all other signals. */
}
/*===========================================================================*
* do_write *
*===========================================================================*/

View file

@ -40,7 +40,6 @@ PRIVATE struct driver r_dtab = {
r_transfer, /* do the I/O */
nop_cleanup, /* no need to clean up */
r_geometry, /* device "geometry" */
nop_signal, /* system signals */
r_random, /* get randomness from kernel (alarm) */
nop_cancel,
nop_select,

View file

@ -45,7 +45,6 @@
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <minix/type.h>
#include <minix/const.h>
#include <minix/syslib.h>
@ -229,32 +228,15 @@ void errmsg(char *s)
/* */
/***********************************************************************/
int dead;
void timeout(int sig) { dead= 1; }
void get_time(struct tm *t)
{
int osec, n;
unsigned long i;
struct sigaction sa;
/* Start a timer to keep us from getting stuck on a dead clock. */
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = timeout;
sigaction(SIGALRM, &sa, NULL);
dead = 0;
alarm(5);
do {
osec = -1;
n = 0;
do {
if (dead) {
printf("readclock: CMOS clock appears dead\n");
exit(1);
}
/* Clock update in progress? */
if (read_register(RTC_REG_A) & RTC_A_UIP) continue;

View file

@ -39,7 +39,7 @@ PRIVATE void load_state_info(void)
/*===========================================================================*
* sef_cb_lu_prepare *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare(int state)
PUBLIC int sef_cb_lu_prepare(int state)
{
int is_ready;
@ -69,9 +69,7 @@ PUBLIC void sef_cb_lu_prepare(int state)
}
/* Tell SEF if we are ready. */
if(is_ready) {
sef_lu_ready(OK);
}
return is_ready ? OK : ENOTREADY;
}
/*===========================================================================*

View file

@ -171,7 +171,6 @@ _PROTOTYPE( static void rl_getstat_s, (message *mp) );
_PROTOTYPE( static void rl_getname, (message *mp) );
_PROTOTYPE( static void reply, (re_t *rep, int err, int may_block) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
_PROTOTYPE( static void rtl8139_stop, (void) );
_PROTOTYPE( static void check_int_events, (void) );
_PROTOTYPE( static int do_hard_int, (void) );
_PROTOTYPE( static void rtl8139_dump, (message *m) );
@ -195,7 +194,8 @@ PRIVATE u32_t system_hz;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
EXTERN int env_argc;
@ -243,17 +243,6 @@ int main(int argc, char *argv[])
case TTY_PROC_NR:
rtl8139_dump(&m);
break;
case PM_PROC_NR:
{
sigset_t set;
if (getsigset(&set) != 0) break;
if (sigismember(&set, SIGTERM))
rtl8139_stop();
break;
}
default:
panic("illegal notify from: %d",
m.m_source);
@ -299,6 +288,9 @@ PRIVATE void sef_local_startup()
sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid);
sef_setcb_lu_state_dump(sef_cb_lu_state_dump);
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -351,6 +343,26 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
int i;
re_t *rep;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (i= 0, rep= &re_table[0]; i<RE_PORT_NR; i++, rep++)
{
if (rep->re_mode != REM_ENABLED)
continue;
rl_outb(rep->re_base_port, RL_CR, 0);
}
exit(0);
}
/*===========================================================================*
* check_int_events *
*===========================================================================*/
@ -370,23 +382,6 @@ static void check_int_events(void)
}
}
/*===========================================================================*
* rtl8139_stop *
*===========================================================================*/
static void rtl8139_stop()
{
int i;
re_t *rep;
for (i= 0, rep= &re_table[0]; i<RE_PORT_NR; i++, rep++)
{
if (rep->re_mode != REM_ENABLED)
continue;
rl_outb(rep->re_base_port, RL_CR, 0);
}
exit(0);
}
/*===========================================================================*
* rtl8139_dump *
*===========================================================================*/

View file

@ -259,7 +259,6 @@ _PROTOTYPE( static void rl_getstat_s, (message *mp) );
_PROTOTYPE( static void rl_getname, (message *mp) );
_PROTOTYPE( static void reply, (re_t *rep, int err, int may_block) );
_PROTOTYPE( static void mess_reply, (message *req, message *reply) );
_PROTOTYPE( static void rtl8169_stop, (void) );
_PROTOTYPE( static void check_int_events, (void) );
_PROTOTYPE( static void do_hard_int, (void) );
_PROTOTYPE( static void rtl8169_dump, (void) );
@ -280,6 +279,7 @@ u32_t system_hz;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
EXTERN int env_argc;
EXTERN char **env_argv;
@ -321,17 +321,6 @@ int main(int argc, char *argv[])
check_int_events();
}
break ;
case PM_PROC_NR:
{
sigset_t set;
if (getsigset(&set) != 0) break;
if (sigismember(&set, SIGTERM))
rtl8169_stop();
break;
}
default:
panic("illegal notify from: %d", m.m_type);
}
@ -364,6 +353,9 @@ PRIVATE void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -409,6 +401,26 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
return(OK);
}
/*===========================================================================*
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void sef_cb_signal_handler(int signo)
{
int i;
re_t *rep;
/* Only check for termination signal, ignore anything else. */
if (signo != SIGTERM) return;
for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) {
if (rep->re_mode != REM_ENABLED)
continue;
rl_outb(rep->re_base_port, RL_CR, 0);
}
exit(0);
}
static void mdio_write(U16_t port, int regaddr, int value)
{
int i;
@ -466,23 +478,6 @@ static void check_int_events(void)
}
}
/*===========================================================================*
* rtl8169_stop *
*===========================================================================*/
static void rtl8169_stop()
{
int i;
re_t *rep;
for (i = 0, rep = &re_table[0]; i < RE_PORT_NR; i++, rep++) {
if (rep->re_mode != REM_ENABLED)
continue;
rl_outb(rep->re_base_port, RL_CR, 0);
}
exit(0);
}
static void rtl8169_update_stat(re_t *rep)
{
port_t port;

View file

@ -79,7 +79,7 @@ PRIVATE int reviveProcNr;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
EXTERN _PROTOTYPE( void sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_prepare, (int state) );
EXTERN _PROTOTYPE( int sef_cb_lu_state_isvalid, (int state) );
EXTERN _PROTOTYPE( void sef_cb_lu_state_dump, (int state) );
PUBLIC int is_processing = FALSE;
@ -108,8 +108,6 @@ PUBLIC void main()
case HARDWARE:
dsp_hardware_msg();
continue; /* don't reply */
case SYSTEM:
continue; /* don't reply */
default:
r = EINVAL;
}

View file

@ -12,7 +12,7 @@ EXTERN int is_status_msg_expected;
/*===========================================================================*
* sef_cb_lu_prepare *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare(int state)
PUBLIC int sef_cb_lu_prepare(int state)
{
int is_ready;
@ -35,9 +35,7 @@ PUBLIC void sef_cb_lu_prepare(int state)
}
/* Tell SEF if we are ready. */
if(is_ready) {
sef_lu_ready(OK);
}
return is_ready ? OK : ENOTREADY;
}
/*===========================================================================*

View file

@ -1063,8 +1063,7 @@ PUBLIC void kputc(int c)
/*===========================================================================*
* do_new_kmess *
*===========================================================================*/
PUBLIC void do_new_kmess(m)
message *m;
PUBLIC void do_new_kmess()
{
/* Notification for a new kernel message. */
static struct kmessages kmess; /* kmessages structure */

View file

@ -100,7 +100,6 @@ unsigned long rs_irq_set = 0;
struct kmessages kmess;
FORWARD _PROTOTYPE( void got_signal, (void) );
FORWARD _PROTOTYPE( void tty_timed_out, (timer_t *tp) );
FORWARD _PROTOTYPE( void expire_timers, (void) );
FORWARD _PROTOTYPE( void settimer, (tty_t *tty_ptr, int enable) );
@ -144,6 +143,7 @@ PUBLIC u32_t system_hz;
/* SEF functions and variables. */
FORWARD _PROTOTYPE( void sef_local_startup, (void) );
FORWARD _PROTOTYPE( int sef_cb_init_fresh, (int type, sef_init_info_t *info) );
FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
/*===========================================================================*
* tty_task *
@ -203,16 +203,6 @@ PUBLIC int main(void)
/* run watchdogs of expired timers */
expire_timers();
break;
case PM_PROC_NR:
/* signal */
got_signal();
break;
case SYSTEM:
/* system signal */
if (sigismember((sigset_t*)&tty_mess.NOTIFY_ARG,
SIGKMESS))
do_new_kmess(&tty_mess);
break;
default:
/* do nothing */
break;
@ -328,6 +318,9 @@ PRIVATE void sef_local_startup()
/* No live update support for now. */
/* Register signal callbacks. */
sef_setcb_signal_handler(sef_cb_signal_handler);
/* Let SEF perform startup. */
sef_startup();
}
@ -355,21 +348,21 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
}
/*===========================================================================*
* got_signal *
* sef_cb_signal_handler *
*===========================================================================*/
PRIVATE void got_signal()
PRIVATE void sef_cb_signal_handler(int signo)
{
/* PM notified us that we have received a signal. If it is a SIGTERM, assume
* that the system is shutting down.
*/
sigset_t set;
if (getsigset(&set) != 0) return;
if (!sigismember(&set, SIGTERM)) return;
/* switch to primary console */
cons_stop();
/* Check for known signals, ignore anything else. */
switch(signo) {
/* There is a pending message from the kernel. */
case SIGKMESS:
do_new_kmess();
break;
/* Switch to primary console on termination. */
case SIGTERM:
cons_stop();
break;
}
}
/*===========================================================================*

View file

@ -165,7 +165,7 @@ _PROTOTYPE( void rs_interrupt, (message *m) );
/* console.c */
_PROTOTYPE( void kputc, (int c) );
_PROTOTYPE( void cons_stop, (void) );
_PROTOTYPE( void do_new_kmess, (message *m) );
_PROTOTYPE( void do_new_kmess, (void) );
_PROTOTYPE( void do_diagnostics, (message *m, int safe) );
_PROTOTYPE( void do_get_kmess, (message *m) );
_PROTOTYPE( void do_get_kmess_s, (message *m) );

View file

@ -56,12 +56,13 @@ disabled()
exec > /dev/console
echo "Arguments: $@"
service down "$1"
kill_by_name dhcpd
kill_by_name nonamed
kill_by_name syslogd
sleep 1
service restart "$1"
sleep 1
sleep 3
service up /usr/sbin/inet -script /etc/rs.inet
daemonize dhcpd
daemonize nonamed -L
daemonize syslogd

View file

@ -10,13 +10,6 @@ service floppy
IRQCTL # 19
DEVIO # 21
VDEVIO # 23
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
PROFBUF # 38
SYSCTL # 44
;
};
@ -26,14 +19,6 @@ service dp8390
IRQCTL # 19
DEVIO # 21
SDEVIO # 22
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
pci device 10ec/8029;
uid 0;
@ -45,14 +30,6 @@ service dpeth
IRQCTL # 19
DEVIO # 21
SDEVIO # 22
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
uid 0;
};
@ -63,14 +40,6 @@ service lance
UMAP # 14
IRQCTL # 19
DEVIO # 21
#SDEVIO # 22
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
pci device 1022/2000;
uid 0;
@ -82,15 +51,6 @@ service rtl8139
UMAP # 14
IRQCTL # 19
DEVIO # 21
#SDEVIO # 22
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
pci device 10ec/8139;
pci device 02ac/1012;
@ -121,15 +81,6 @@ service fxp
UMAP # 14
IRQCTL # 19
DEVIO # 21
#SDEVIO # 22
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
pci device 8086/103d;
pci device 8086/1064;
@ -143,61 +94,26 @@ service fxp
service inet
{
system
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
VSAFECOPY # 33
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
uid 0;
};
service random
{
system
UMAP # 14
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
};
service readclock.drv
{
io 70:2;
system
UMAP # 14
DEVIO # 21
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
READBIOS # 35
PROFBUF # 38
SYSCTL # 44
;
uid 0;
};
service is
{
system
TIMES # 25
GETINFO # 26
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
vm
INFO
;
@ -212,13 +128,6 @@ service pci
system
PRIVCTL # 4
DEVIO # 21
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
uid 0;
};
@ -240,15 +149,7 @@ service at_wini
DEVIO # 21
SDEVIO # 22
VDEVIO # 23
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
READBIOS # 35
PROFBUF # 38
SYSCTL # 44
;
pci class
1/1 # Mass storage / IDE
@ -261,58 +162,25 @@ service bios_wini
system
UMAP # 14
INT86 # 20
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
READBIOS # 35
PROFBUF # 38
SYSCTL # 44
;
};
service mfs
{
system
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
uid 0;
};
service isofs
{
system
UMAP # 14
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
UMAP # 14
;
uid 0;
};
service hgfs
{
system
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
ipc
SYSTEM PM VFS RS VM
;
@ -333,13 +201,6 @@ service printer
IRQCTL # 19
DEVIO # 21
VDEVIO # 23
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
};
@ -350,16 +211,7 @@ service orinoco
UMAP # 14
IRQCTL # 19
DEVIO # 21
#SDEVIO # 22
SETALARM # 24
TIMES # 25
GETINFO # 26
VM_MAP # 30
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
pci device 1260/3873;
pci device 1186/1300;
@ -372,13 +224,6 @@ service es1370
UMAP # 14
IRQCTL # 19
DEVIO # 21
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
pci device 1274/5000;
};
@ -386,16 +231,9 @@ service es1370
service es1371
{
system
SAFECOPYFROM
SAFECOPYTO
UMAP
SETGRANT
TIMES # 25
GETINFO
UMAP # 14
IRQCTL # 19
DEVIO # 21
PROFBUF # 38
SYSCTL
;
pci device 1274/1371;
};
@ -405,12 +243,6 @@ service amddev
pci device 1022/1103;
system
UMAP # 14
TIMES # 25
GETINFO # 26
SETGRANT # 34
PROFBUF # 38
REGDEV # 40
SYSCTL # 44
;
uid 0;
};
@ -419,14 +251,7 @@ service ipc
{
system
UMAP # 14
VIRCOPY # 15
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
VIRCOPY # 15
;
uid 0;
ipc
@ -456,14 +281,6 @@ service osscore
IRQCTL # 19
DEVIO # 21
SDEVIO # 22
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
pci class
4/1 # Multimedia / Audio device
@ -481,15 +298,6 @@ service rtl8169
UMAP # 14
IRQCTL # 19
DEVIO # 21
#SDEVIO # 22
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL # 44
;
pci device 10ec/8129;
pci device 10ec/8167;
@ -507,15 +315,6 @@ service rtl8169
service filter
{
system
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
SYSCTL # 44
;
ipc
SYSTEM PM VFS RS DS VM
at_wini
@ -533,13 +332,6 @@ service e1000
UMAP # 14
IRQCTL # 19
DEVIO # 21
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
SYSCTL # 44
;
pci device 8086/100e;
pci device 8086/107c;
@ -554,13 +346,6 @@ service atl2
system
UMAP # 14
IRQCTL # 19
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
SYSCTL # 44
;
pci device 1969/2048;
ipc
@ -575,15 +360,6 @@ service dec21140A
UMAP # 14
IRQCTL # 19
DEVIO # 21
#SDEVIO # 22
SETALARM # 24
TIMES # 25
GETINFO # 26
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
PROFBUF # 38
SYSCTL
;
pci device 1011/0009;
ipc
@ -591,3 +367,17 @@ service dec21140A
pci inet
;
};
service hello
{
system
IRQCTL # 19
DEVIO # 21
;
ipc
SYSTEM PM RS LOG TTY DS VM VFS
pci inet amddev
;
uid 0;
};

View file

@ -74,7 +74,7 @@ extern int errno; /* place where the error numbers go */
#define ENOSYS (_SIGN 38) /* function not implemented */
#define ENOTEMPTY (_SIGN 39) /* directory not empty */
#define ELOOP (_SIGN 40) /* too many levels of symlinks detected */
#define ERESTART (_SIGN 41) /* driver restarted */
#define ERESTART (_SIGN 41) /* service restarted */
#define EIDRM (_SIGN 43) /* Identifier removed */
#define EILSEQ (_SIGN 44) /* illegal byte sequence */

View file

@ -1,4 +1,4 @@
#define NCALLS 111 /* number of system calls allowed */
#define NCALLS 112 /* number of system calls allowed */
#define EXIT 1
#define FORK 2
@ -93,7 +93,7 @@
#define EXEC_NEWMEM 100 /* from FS or RS to PM: new memory map for
* exec
*/
#define FORK_NB 101 /* to PM: special fork call for RS */
#define SRV_FORK 101 /* to PM: special fork call for RS */
#define EXEC_RESTART 102 /* to PM: final part of exec for RS */
#define PROCSTAT 103 /* to PM */
#define GETPROCNR 104 /* to PM */
@ -109,6 +109,7 @@
* that should not be used for bus-master DMA
* any longer
*/
#define SRV_KILL 111 /* to PM: special kill call for RS */
#define TASK_REPLY 121 /* to FS: reply code from drivers, not
* really a standalone call.

View file

@ -19,6 +19,7 @@
* 0xB00 - 0xBFF Requests from VM to VFS
* 0xC00 - 0xCFF Virtual Memory (VM) requests
* 0xD00 - 0xDFF IPC server requests
* 0xE00 - 0xEFF Common system messages (e.g. system signals)
* 0x1000 - 0x10FF Notify messages
*
* Zero and negative values are widely used for OK and error responses.
@ -305,7 +306,7 @@
# define SYS_FORK (KERNEL_CALL + 0) /* sys_fork() */
# define SYS_EXEC (KERNEL_CALL + 1) /* sys_exec() */
# define SYS_EXIT (KERNEL_CALL + 2) /* sys_exit() */
# define SYS_CLEAR (KERNEL_CALL + 2) /* sys_clear() */
# define SYS_NICE (KERNEL_CALL + 3) /* sys_nice() */
# define SYS_PRIVCTL (KERNEL_CALL + 4) /* sys_privctl() */
# define SYS_TRACE (KERNEL_CALL + 5) /* sys_trace() */
@ -358,9 +359,20 @@
# define SYS_GETMCONTEXT (KERNEL_CALL + 50) /* sys_getmcontext() */
# define SYS_SETMCONTEXT (KERNEL_CALL + 51) /* sys_setmcontext() */
#define NR_SYS_CALLS 52 /* number of system calls */
# define SYS_UPDATE (KERNEL_CALL + 52) /* sys_update() */
# define SYS_EXIT (KERNEL_CALL + 53) /* sys_exit() */
/* Total */
#define NR_SYS_CALLS 54 /* number of system calls */
#define SYS_CALL_MASK_SIZE BITMAP_CHUNKS(NR_SYS_CALLS)
/* Basic kernel calls allowed to every system process. */
#define SYS_BASIC_CALLS \
SYS_EXIT, SYS_SAFECOPYFROM, SYS_SAFECOPYTO, SYS_VSAFECOPY, SYS_GETINFO, \
SYS_TIMES, SYS_SETALARM, SYS_SETGRANT, SYS_SAFEMAP, SYS_SAFEREVMAP, \
SYS_SAFEUNMAP, SYS_PROFBUF, SYS_SYSCTL
/* Field names for SYS_MEMSET. */
#define MEM_PTR m2_p1 /* base */
#define MEM_COUNT m2_l1 /* count */
@ -631,6 +643,10 @@
#define RC_FLAGS m1_i3 /* request flags */
# define RC_DELAY 1 /* delay stop if process is sending */
/* Field names for SYS_UPDATE. */
#define SYS_UPD_SRC_ENDPT m1_i1 /* source endpoint */
#define SYS_UPD_DST_ENDPT m1_i2 /* destination endpoint */
/*===========================================================================*
* Messages for the Reincarnation Server *
*===========================================================================*/
@ -689,7 +705,6 @@
# define DS_VAL m2_l1 /* data (u32, char *, etc.) */
# define DS_VAL_LEN m2_l2 /* data length */
# define DS_NR_SNAPSHOT m2_i3 /* number of snapshot */
# define DS_STRING m2_i3 /* inline string */
/*===========================================================================*
* Miscellaneous messages used by TTY *
@ -732,7 +747,7 @@
#define PM_DUMPCORE (PM_RQ_BASE + 5) /* Process is to dump core */
#define PM_EXEC (PM_RQ_BASE + 6) /* Forwarded exec call */
#define PM_FORK (PM_RQ_BASE + 7) /* Newly forked process */
#define PM_FORK_NB (PM_RQ_BASE + 8) /* Non-blocking fork */
#define PM_SRV_FORK (PM_RQ_BASE + 8) /* fork for system services */
#define PM_UNPAUSE (PM_RQ_BASE + 9) /* Interrupt process call */
#define PM_REBOOT (PM_RQ_BASE + 10) /* System reboot */
#define PM_SETGROUPS (PM_RQ_BASE + 11) /* Tell VFS about setgroups */
@ -745,7 +760,7 @@
#define PM_CORE_REPLY (PM_RS_BASE + 5)
#define PM_EXEC_REPLY (PM_RS_BASE + 6)
#define PM_FORK_REPLY (PM_RS_BASE + 7)
#define PM_FORK_NB_REPLY (PM_RS_BASE + 8)
#define PM_SRV_FORK_REPLY (PM_RS_BASE + 8)
#define PM_UNPAUSE_REPLY (PM_RS_BASE + 9)
#define PM_REBOOT_REPLY (PM_RS_BASE + 10)
#define PM_SETGROUPS_REPLY (PM_RS_BASE + 11)
@ -755,7 +770,7 @@
/* Additional parameters for PM_INIT */
# define PM_SLOT m1_i2 /* process slot number */
# define PM_PID m2_i3 /* process pid */
# define PM_PID m1_i3 /* process pid */
/* Additional parameters for PM_SETUID and PM_SETGID */
# define PM_EID m1_i2 /* effective user/group id */
@ -776,7 +791,7 @@
/* Additional parameters for PM_EXEC_REPLY and PM_CORE_REPLY */
# define PM_STATUS m1_i2 /* OK or failure */
/* Additional parameters for PM_FORK and PM_FORK_NB */
/* Additional parameters for PM_FORK and PM_SRV_FORK */
# define PM_PPROC m1_i2 /* parent process endpoint */
# define PM_CPID m1_i3 /* child pid */
@ -813,6 +828,8 @@
* Miscellaneous field names *
*===========================================================================*/
#define COMMON_RQ_BASE 0xE00
/* PM field names */
/* BRK */
#define PMBRK_ADDR m1_p1
@ -835,6 +852,10 @@
#define SEL_ERRORFDS m8_p3
#define SEL_TIMEOUT m8_p4
/* Field names for system signals (sent by a signal manager). */
#define SIGS_SIGNAL_RECEIVED (COMMON_RQ_BASE+0)
# define SIGS_SIG_NUM m2_i1
/*===========================================================================*
* Messages for VM server *
*===========================================================================*/
@ -974,8 +995,12 @@
#define VMIW_USAGE 2
#define VMIW_REGION 3
#define VM_RS_UPDATE (VM_RQ_BASE+41)
# define VM_RS_SRC_ENDPT m1_i1
# define VM_RS_DST_ENDPT m1_i2
/* Total. */
#define NR_VM_CALLS 41
#define NR_VM_CALLS 42
#define VM_CALL_MASK_SIZE BITMAP_CHUNKS(NR_VM_CALLS)
/* Basic vm calls allowed to every process. */

View file

@ -45,4 +45,6 @@ enum dev_style { STYLE_DEV, STYLE_NDEV, STYLE_TTY, STYLE_CLONE };
#define LOG_MAJOR 15 /* major device for log driver */
# define IS_KLOG_DEV 0 /* minor device for /dev/klog */
#define HELLO_MAJOR 17 /* major device for hello driver */
#endif /* _DMAP_H */

View file

@ -29,7 +29,6 @@
/* DS constants. */
#define DS_MAX_KEYLEN 80 /* Max length of a key, including '\0'. */
#define DS_MAX_STRLEN 16 /* Max length of string, including '\0'. */
/* ds.c */

View file

@ -22,7 +22,6 @@ Interface to the reincarnation server
#define RSS_REUSE 0x04 /* Try to reuse previously copied binary */
/* Common definitions. */
#define RS_SYS_CALL_MASK_SIZE 2
#define RS_NR_CONTROL 8
#define RS_NR_PCI_DEVICE 32
#define RS_NR_PCI_CLASS 4
@ -55,7 +54,7 @@ struct rs_start
struct { u16_t vid; u16_t did; } rss_pci_id[RS_NR_PCI_DEVICE];
int rss_nr_pci_class;
struct { u32_t class; u32_t mask; } rss_pci_class[RS_NR_PCI_CLASS];
u32_t rss_system[RS_SYS_CALL_MASK_SIZE];
bitchunk_t rss_system[SYS_CALL_MASK_SIZE];
struct rss_label rss_label;
char *rss_ipc;
size_t rss_ipclen;

View file

@ -4,6 +4,7 @@
#include <minix/sys_config.h>
#include <minix/types.h>
#include <minix/vm.h>
#include <stdint.h>
typedef struct {
@ -47,13 +48,6 @@ struct vscp_vec {
size_t v_bytes; /* no. of bytes */
};
/* Types on VM invocation. */
#define VMPTYPE_NONE 0
#define VMPTYPE_CHECK 1
#define VMPTYPE_COWMAP 2
#define VMPTYPE_SMAP 3
#define VMPTYPE_SUNMAP 4
/* Invalid grant number. */
#define GRANT_INVALID ((cp_grant_id_t) -1)
#define GRANT_VALID(g) ((g) > GRANT_INVALID)

View file

@ -8,6 +8,7 @@
/* SEF entry points for system processes. */
_PROTOTYPE( void sef_startup, (void) );
_PROTOTYPE( int sef_receive, (endpoint_t src, message *m_ptr) );
_PROTOTYPE( void sef_exit, (int status) );
/* SEF Debug. */
#include <stdio.h>
@ -29,30 +30,27 @@ typedef struct {
} sef_init_info_t;
/* Callback type definitions. */
typedef int(*sef_cb_init_fresh_t)(int type, sef_init_info_t *info);
typedef int(*sef_cb_init_lu_t)(int type, sef_init_info_t *info);
typedef int(*sef_cb_init_restart_t)(int type, sef_init_info_t *info);
typedef int(*sef_cb_init_t)(int type, sef_init_info_t *info);
/* Callback registration helpers. */
_PROTOTYPE( void sef_setcb_init_fresh, (sef_cb_init_fresh_t cb));
_PROTOTYPE( void sef_setcb_init_lu, (sef_cb_init_lu_t cb));
_PROTOTYPE( void sef_setcb_init_restart, (sef_cb_init_restart_t cb));
_PROTOTYPE( void sef_setcb_init_fresh, (sef_cb_init_t cb));
_PROTOTYPE( void sef_setcb_init_lu, (sef_cb_init_t cb));
_PROTOTYPE( void sef_setcb_init_restart, (sef_cb_init_t cb));
/* Predefined callback implementations. */
_PROTOTYPE( int sef_cb_init_fresh_null, (int type, sef_init_info_t *info) );
_PROTOTYPE( int sef_cb_init_lu_null, (int type, sef_init_info_t *info) );
_PROTOTYPE( int sef_cb_init_restart_null, (int type, sef_init_info_t *info) );
_PROTOTYPE( int sef_cb_init_null, (int type, sef_init_info_t *info) );
_PROTOTYPE( int sef_cb_init_restart_fail, (int type, sef_init_info_t *info) );
_PROTOTYPE( int sef_cb_init_fail, (int type, sef_init_info_t *info) );
_PROTOTYPE( int sef_cb_init_crash, (int type, sef_init_info_t *info) );
/* Macros for predefined callback implementations. */
#define SEF_CB_INIT_FRESH_NULL sef_cb_init_fresh_null
#define SEF_CB_INIT_LU_NULL sef_cb_init_lu_null
#define SEF_CB_INIT_RESTART_NULL sef_cb_init_restart_null
#define SEF_CB_INIT_FRESH_NULL sef_cb_init_null
#define SEF_CB_INIT_LU_NULL sef_cb_init_null
#define SEF_CB_INIT_RESTART_NULL sef_cb_init_null
#define SEF_CB_INIT_FRESH_DEFAULT sef_cb_init_fresh_null
#define SEF_CB_INIT_LU_DEFAULT sef_cb_init_lu_null
#define SEF_CB_INIT_RESTART_DEFAULT sef_cb_init_restart_null
#define SEF_CB_INIT_FRESH_DEFAULT sef_cb_init_null
#define SEF_CB_INIT_LU_DEFAULT sef_cb_init_null
#define SEF_CB_INIT_RESTART_DEFAULT sef_cb_init_null
/* Init types. */
#define SEF_INIT_FRESH 0 /* init fresh */
@ -79,15 +77,15 @@ _PROTOTYPE( int sef_cb_init_restart_fail, (int type, sef_init_info_t *info) );
&& (mp)->m_source == RS_PROC_NR)
/* Callback type definitions. */
typedef void(*sef_cb_ping_reply_t)(message *m_ptr);
typedef void(*sef_cb_ping_reply_t)(endpoint_t source);
/* Callback registration helpers. */
_PROTOTYPE( void sef_setcb_ping_reply, (sef_cb_ping_reply_t cb));
/* Predefined callback implementations. */
_PROTOTYPE( void sef_cb_ping_reply_null, (message *m_ptr) );
_PROTOTYPE( void sef_cb_ping_reply_null, (endpoint_t source) );
_PROTOTYPE( void sef_cb_ping_reply_pong, (message *m_ptr) );
_PROTOTYPE( void sef_cb_ping_reply_pong, (endpoint_t source) );
/* Macros for predefined callback implementations. */
#define SEF_CB_PING_REPLY_NULL sef_cb_ping_reply_null
@ -113,31 +111,30 @@ _PROTOTYPE( void sef_cb_ping_reply_pong, (message *m_ptr) );
#define IS_SEF_LU_REQUEST(mp) ((mp)->m_type == RS_LU_PREPARE \
&& (mp)->m_source == RS_PROC_NR)
/* Global helpers. */
_PROTOTYPE( void sef_lu_ready, (int result) );
/* Callback type definitions. */
typedef void(*sef_cb_lu_prepare_t)(int);
typedef int(*sef_cb_lu_prepare_t)(int);
typedef int(*sef_cb_lu_state_isvalid_t)(int);
typedef void(*sef_cb_lu_state_changed_t)(int, int);
typedef void(*sef_cb_lu_state_dump_t)(int);
typedef int(*sef_cb_lu_ready_pre_t)(int);
typedef int(*sef_cb_lu_state_save_t)(int);
/* Callback registration helpers. */
_PROTOTYPE( void sef_setcb_lu_prepare, (sef_cb_lu_prepare_t cb) );
_PROTOTYPE( void sef_setcb_lu_state_isvalid, (sef_cb_lu_state_isvalid_t cb) );
_PROTOTYPE( void sef_setcb_lu_state_changed, (sef_cb_lu_state_changed_t cb) );
_PROTOTYPE( void sef_setcb_lu_state_dump, (sef_cb_lu_state_dump_t cb) );
_PROTOTYPE( void sef_setcb_lu_ready_pre, (sef_cb_lu_ready_pre_t cb) );
_PROTOTYPE( void sef_setcb_lu_state_save, (sef_cb_lu_state_save_t cb) );
/* Predefined callback implementations. */
_PROTOTYPE( void sef_cb_lu_prepare_null, (int state) );
_PROTOTYPE( int sef_cb_lu_prepare_null, (int state) );
_PROTOTYPE( int sef_cb_lu_state_isvalid_null, (int state) );
_PROTOTYPE( void sef_cb_lu_state_changed_null, (int old_state, int state) );
_PROTOTYPE( void sef_cb_lu_state_dump_null, (int state) );
_PROTOTYPE( int sef_cb_lu_ready_pre_null, (int result) );
_PROTOTYPE( int sef_cb_lu_state_save_null, (int state) );
_PROTOTYPE( void sef_cb_lu_prepare_always_ready, (int state) );
_PROTOTYPE( int sef_cb_lu_prepare_always_ready, (int state) );
_PROTOTYPE( int sef_cb_lu_prepare_never_ready, (int state) );
_PROTOTYPE( int sef_cb_lu_prepare_crash, (int state) );
_PROTOTYPE( int sef_cb_lu_state_isvalid_standard, (int state) );
/* Macros for predefined callback implementations. */
@ -145,13 +142,13 @@ _PROTOTYPE( int sef_cb_lu_state_isvalid_standard, (int state) );
#define SEF_CB_LU_STATE_ISVALID_NULL sef_cb_lu_state_isvalid_null
#define SEF_CB_LU_STATE_CHANGED_NULL sef_cb_lu_state_changed_null
#define SEF_CB_LU_STATE_DUMP_NULL sef_cb_lu_state_dump_null
#define SEF_CB_LU_READY_PRE_NULL sef_cb_lu_ready_pre_null
#define SEF_CB_LU_STATE_SAVE_NULL sef_cb_lu_state_save_null
#define SEF_CB_LU_PREPARE_DEFAULT sef_cb_lu_prepare_null
#define SEF_CB_LU_STATE_ISVALID_DEFAULT sef_cb_lu_state_isvalid_null
#define SEF_CB_LU_STATE_CHANGED_DEFAULT sef_cb_lu_state_changed_null
#define SEF_CB_LU_STATE_DUMP_DEFAULT sef_cb_lu_state_dump_null
#define SEF_CB_LU_READY_PRE_DEFAULT sef_cb_lu_ready_pre_null
#define SEF_CB_LU_STATE_SAVE_DEFAULT sef_cb_lu_state_save_null
/* Standard live update states. */
#define SEF_LU_STATE_NULL 0 /* null state */
@ -173,5 +170,47 @@ _PROTOTYPE( int sef_cb_lu_state_isvalid_standard, (int state) );
#define sef_lu_debug_begin sef_debug_begin
#define sef_lu_debug_end sef_debug_end
/*===========================================================================*
* SEF Signal *
*===========================================================================*/
/* What to intercept. */
#define INTERCEPT_SEF_SIGNAL_REQUESTS 1
#define IS_SEF_SIGNAL_REQUEST(mp) \
(((mp)->m_type == SIGS_SIGNAL_RECEIVED && (mp)->m_source < INIT_PROC_NR) \
|| (is_notify((mp)->m_type) && (mp)->m_source == SYSTEM))
/* Callback type definitions. */
typedef void(*sef_cb_signal_handler_t)(int signo);
typedef int(*sef_cb_signal_manager_t)(endpoint_t target, int signo);
/* Callback registration helpers. */
_PROTOTYPE( void sef_setcb_signal_handler, (sef_cb_signal_handler_t cb));
_PROTOTYPE( void sef_setcb_signal_manager, (sef_cb_signal_manager_t cb));
/* Predefined callback implementations. */
_PROTOTYPE( void sef_cb_signal_handler_null, (int signo) );
_PROTOTYPE( int sef_cb_signal_manager_null, (endpoint_t target, int signo) );
_PROTOTYPE( void sef_cb_signal_handler_term, (int signo) );
_PROTOTYPE( void sef_cb_signal_handler_posix_default, (int signo) );
/* Macros for predefined callback implementations. */
#define SEF_CB_SIGNAL_HANDLER_NULL sef_cb_signal_handler_null
#define SEF_CB_SIGNAL_MANAGER_NULL sef_cb_signal_manager_null
#define SEF_CB_SIGNAL_HANDLER_DEFAULT sef_cb_signal_handler_null
#define SEF_CB_SIGNAL_MANAGER_DEFAULT sef_cb_signal_manager_null
/* Debug. */
#define SEF_SIGNAL_DEBUG_DEFAULT 0
#ifndef SEF_SIGNAL_DEBUG
#define SEF_SIGNAL_DEBUG SEF_SIGNAL_DEBUG_DEFAULT
#endif
#define sef_signal_dprint sef_dprint
#define sef_signal_debug_begin sef_debug_begin
#define sef_signal_debug_end sef_debug_end
#endif /* _SEF_H */

View file

@ -40,7 +40,8 @@ _PROTOTYPE( int sys_exec, (endpoint_t proc_ep, char *ptr,
_PROTOTYPE( int sys_fork, (endpoint_t parent, endpoint_t child, endpoint_t *,
struct mem_map *ptr, u32_t vm, vir_bytes *));
_PROTOTYPE( int sys_newmap, (endpoint_t proc_ep, struct mem_map *ptr));
_PROTOTYPE( int sys_exit, (endpoint_t proc_ep));
_PROTOTYPE( int sys_clear, (endpoint_t proc_ep));
_PROTOTYPE( int sys_exit, (void));
_PROTOTYPE( int sys_trace, (int req, endpoint_t proc_ep, long addr, long *data_p));
/* Shorthands for sys_runctl() system call. */
@ -49,6 +50,7 @@ _PROTOTYPE( int sys_trace, (int req, endpoint_t proc_ep, long addr, long *data_p
#define sys_resume(proc_ep) sys_runctl(proc_ep, RC_RESUME, 0)
_PROTOTYPE( int sys_runctl, (endpoint_t proc_ep, int action, int flags));
_PROTOTYPE( int sys_update, (endpoint_t src_ep, endpoint_t dst_ep));
_PROTOTYPE( int sys_privctl, (endpoint_t proc_ep, int req, void *p));
_PROTOTYPE( int sys_privquery_mem, (endpoint_t proc_ep,
phys_bytes physstart, phys_bytes physlen));

View file

@ -25,8 +25,16 @@ _PROTOTYPE( int vm_unmap_phys, (endpoint_t who, void *vaddr, size_t len));
_PROTOTYPE( int vm_notify_sig, (endpoint_t ep, endpoint_t ipc_ep));
_PROTOTYPE( int vm_ctl, (int what, int param));
_PROTOTYPE( int vm_set_priv, (int procnr, void *buf));
_PROTOTYPE( int vm_update, (endpoint_t src_e, endpoint_t dst_e));
_PROTOTYPE( int vm_query_exit, (int *endpt));
/* VM kernel request types. */
#define VMPTYPE_NONE 0
#define VMPTYPE_CHECK 1
#define VMPTYPE_COWMAP 2
#define VMPTYPE_SMAP 3
#define VMPTYPE_SUNMAP 4
struct vm_stats_info {
int vsi_pagesize; /* page size */
int vsi_total; /* total number of memory pages */

View file

@ -63,10 +63,26 @@ typedef unsigned long sigset_t;
/* MINIX specific signals. These signals are not used by user proceses,
* but meant to inform system processes, like the PM, about system events.
* The order here determines the order signals are processed by system
* processes in user-space. Higher-priority signals should be first.
*/
#define SIGKMESS 29 /* new kernel message */
#define SIGKPF 26 /* kernel page fault request pending */
#define SIGKMEM 27 /* kernel memory request pending */
#define SIGKMESS 28 /* new kernel message */
#define SIGKSIGSM 29 /* kernel signal pending for signal manager */
#define SIGKSIG 30 /* kernel signal pending */
#define SIGNDELAY 31 /* end of delay for signal delivery */
#define SIGKNDELAY 31 /* end of delay for signal delivery */
#define SIGK_FIRST SIGKPF /* first kernel signal */
#define SIGK_LAST SIGKNDELAY /* last kernel signal */
#define IS_SIGK(signo) (signo>=SIGK_FIRST && signo<=SIGK_LAST)
/* Termination signals for Minix system processes. */
#define SIGS_IS_LETHAL(sig) \
(sig == SIGILL || sig == SIGBUS || sig == SIGFPE || sig == SIGSEGV \
|| sig == SIGEMT || sig == SIGABRT)
#define SIGS_IS_TERMINATION(sig) (SIGS_IS_LETHAL(sig) \
|| (sig == SIGKILL || sig == SIGPIPE))
#endif
@ -79,7 +95,6 @@ typedef void _PROTOTYPE( (*__sighandler_t), (int) );
#define SIG_IGN ((__sighandler_t) 1) /* ignore signal */
#define SIG_HOLD ((__sighandler_t) 2) /* block signal */
#define SIG_CATCH ((__sighandler_t) 3) /* catch signal */
#define SIG_MESS ((__sighandler_t) 4) /* pass as message (MINIX) */
#ifdef _POSIX_SOURCE
struct sigaction {

View file

@ -91,7 +91,7 @@ void pagefault( struct proc *pr,
pr->p_nextpagefault = pagefaults;
pagefaults = pr;
mini_notify(proc_addr(HARDWARE), VM_PROC_NR);
send_sig(VM_PROC_NR, SIGKPF);
return;
}

View file

@ -9,6 +9,7 @@
#include <minix/cpufeature.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <machine/vm.h>
@ -577,7 +578,7 @@ PRIVATE void vm_suspend(struct proc *caller, struct proc *target,
/* Connect caller on vmrequest wait queue. */
if(!(caller->p_vmrequest.nextrequestor = vmrequest))
mini_notify(proc_addr(SYSTEM), VM_PROC_NR);
send_sig(VM_PROC_NR, SIGKMEM);
vmrequest = caller;
}

View file

@ -18,7 +18,8 @@
#define USE_FORK 1 /* fork a new process */
#define USE_NEWMAP 1 /* set a new memory map */
#define USE_EXEC 1 /* update process after execute */
#define USE_EXIT 1 /* clean up after process exit */
#define USE_CLEAR 1 /* clean up after process exit */
#define USE_EXIT 1 /* a system process wants to exit */
#define USE_TRACE 1 /* process information and tracing */
#define USE_GETKSIG 1 /* retrieve pending kernel signals */
#define USE_ENDKSIG 1 /* finish pending kernel signals */
@ -42,6 +43,7 @@
#define USE_PHYSCOPY 1 /* copy using physical addressing */
#define USE_MEMSET 1 /* write char to a given memory area */
#define USE_RUNCTL 1 /* control stop flags of a process */
#define USE_UPDATE 1 /* update a process into another */
#define USE_MCONTEXT 1 /* enable getting and setting of mach context*/
/* Length of program names stored in the process table. This is only used

View file

@ -56,7 +56,7 @@ PUBLIC void put_irq_handler( irq_hook_t* hook, int irq, irq_handler_t handler)
hook->id = id;
*line = hook;
irq_use |= 1 << irq; /* this does not work for irq >= 32 */
/* And as last enable the irq at the hardware.
*
* Internal this activates the line or source of the given interrupt.
@ -78,25 +78,30 @@ PUBLIC void rm_irq_handler( irq_hook_t* hook ) {
if( irq < 0 || irq >= NR_IRQ_VECTORS )
panic("invalid call to rm_irq_handler: %d", irq);
/* disable the irq. */
irq_actids[hook->irq] |= hook->id;
hw_intr_mask(hook->irq);
/* remove the hook. */
/* remove the hook */
line = &irq_handlers[irq];
while( (*line) != NULL ) {
if((*line)->id == id) {
(*line) = (*line)->next;
if((*line)->id == id) {
(*line) = (*line)->next;
if(!irq_handlers[irq])
irq_use &= ~(1 << irq);
if (irq_actids[irq] & id)
irq_actids[irq] &= ~id;
return;
}
line = &(*line)->next;
}
else {
line = &(*line)->next;
}
}
/* Disable the irq if there are no other handlers registered.
* If the irq is shared, reenable it if there is no active handler.
*/
if (irq_handlers[irq] == NULL) {
hw_intr_mask(irq);
}
else if (irq_actids[irq] == 0) {
hw_intr_unmask(irq);
}
/* When the handler is not found, normally return here. */
}
/*===========================================================================*
@ -115,6 +120,13 @@ PUBLIC void irq_handle(int irq)
hw_intr_mask(irq);
hook = irq_handlers[irq];
/* Sanity check. */
if(hook == NULL) {
printf("%s: irq_handle:no handler registered, masking the IRQ...\n",
__FILE__);
return;
}
/* Call list of handlers for an IRQ. */
while( hook != NULL ) {
/* For each handler in the list, mark it active by setting its ID bit,

View file

@ -114,6 +114,7 @@ PUBLIC void main()
priv(rp)->s_trap_mask= RSYS_T; /* allowed traps */
ipc_to_m = RSYS_M; /* allowed targets */
kcalls = RSYS_KC; /* allowed kernel calls */
priv(rp)->s_sig_mgr = RSYS_SM; /* signal manager */
}
/* Priviliges for ordinary process. */
else {

View file

@ -41,8 +41,9 @@ struct priv {
sys_map_t s_ipc_to; /* allowed destination processes */
/* allowed kernel calls */
bitchunk_t s_k_call_mask[SYS_CALL_MASK_SIZE];
bitchunk_t s_k_call_mask[SYS_CALL_MASK_SIZE];
endpoint_t s_sig_mgr; /* signal manager for system signals */
sys_map_t s_notify_pending; /* bit map with pending notifications */
irq_id_t s_int_pending; /* pending hardware interrupts */
sigset_t s_sig_pending; /* pending signals */
@ -150,4 +151,8 @@ EXTERN struct priv *ppriv_addr[NR_SYS_PROCS]; /* direct slot pointers */
#define RSYS_KC ALL_C /* root system proc */
#define DEF_SYS_KC RSYS_KC /* default sys proc */
/* signal manager */
#define RSYS_SM ROOT_SYS_PROC_NR /* root system proc */
#define DEF_SYS_SM ROOT_SYS_PROC_NR /* default sys proc */
#endif /* PRIV_H */

View file

@ -45,8 +45,8 @@ struct proc {
struct proc *p_nextready; /* pointer to next ready process */
struct proc *p_caller_q; /* head of list of procs wishing to send */
struct proc *p_q_link; /* link to next proc wishing to send */
int p_getfrom_e; /* from whom does process want to receive? */
int p_sendto_e; /* to whom does process want to send? */
endpoint_t p_getfrom_e; /* from whom does process want to receive? */
endpoint_t p_sendto_e; /* to whom does process want to send? */
sigset_t p_pending; /* bit map for pending kernel signals */

View file

@ -15,7 +15,7 @@
* set_sendto_bit: allow a process to send messages to a new target
* unset_sendto_bit: disallow a process from sending messages to a target
* send_sig: send a signal directly to a system process
* cause_sig: take action to cause a signal to occur via PM
* cause_sig: take action to cause a signal to occur via a signal mgr
* sig_delay_done: tell PM that a process is not sending
* umap_bios: map virtual address in BIOS_SEG to physical
* get_randomness: accumulate randomness in a buffer
@ -176,17 +176,19 @@ PUBLIC void system_init(void)
/* Process management. */
map(SYS_FORK, do_fork); /* a process forked a new process */
map(SYS_EXEC, do_exec); /* update process after execute */
map(SYS_EXIT, do_exit); /* clean up after process exit */
map(SYS_CLEAR, do_clear); /* clean up after process exit */
map(SYS_EXIT, do_exit); /* a system process wants to exit */
map(SYS_NICE, do_nice); /* set scheduling priority */
map(SYS_PRIVCTL, do_privctl); /* system privileges control */
map(SYS_TRACE, do_trace); /* request a trace operation */
map(SYS_SETGRANT, do_setgrant); /* get/set own parameters */
map(SYS_RUNCTL, do_runctl); /* set/clear stop flag of a process */
map(SYS_UPDATE, do_update); /* update a process into another */
/* Signal handling. */
map(SYS_KILL, do_kill); /* cause a process to be signaled */
map(SYS_GETKSIG, do_getksig); /* PM checks for pending signals */
map(SYS_ENDKSIG, do_endksig); /* PM finished processing signal */
map(SYS_GETKSIG, do_getksig); /* signal manager checks for signals */
map(SYS_ENDKSIG, do_endksig); /* signal manager finished signal */
map(SYS_SIGSEND, do_sigsend); /* start POSIX-style signal */
map(SYS_SIGRETURN, do_sigreturn); /* return from POSIX-style signal */
@ -347,27 +349,38 @@ int sig_nr; /* signal to be sent */
* - HARDWARE wanting to cause a SIGSEGV after a CPU exception
* - TTY wanting to cause SIGINT upon getting a DEL
* - FS wanting to cause SIGPIPE for a broken pipe
* Signals are handled by sending a message to PM. This function handles the
* signals and makes sure the PM gets them by sending a notification. The
* process being signaled is blocked while PM has not finished all signals
* for it.
* Signals are handled by sending a message to the signal manager assigned to
* the process. This function handles the signals and makes sure the signal
* manager gets them by sending a notification. The process being signaled
* is blocked while the signal manager has not finished all signals for it.
* Race conditions between calls to this function and the system calls that
* process pending kernel signals cannot exist. Signal related functions are
* only called when a user process causes a CPU exception and from the kernel
* process level, which runs to completion.
*/
register struct proc *rp;
endpoint_t sig_mgr;
if (proc_nr == PM_PROC_NR)
panic("cause_sig: PM gets signal");
/* Lookup signal manager. */
rp = proc_addr(proc_nr);
sig_mgr = priv(rp)->s_sig_mgr;
/* If the target is the signal manager of itself, send the signal directly. */
if(rp->p_endpoint == sig_mgr) {
if(SIGS_IS_LETHAL(sig_nr)) {
panic("cause_sig: signal manager gets lethal signal for itself");
}
sigaddset(&priv(rp)->s_sig_pending, sig_nr);
send_sig(rp->p_endpoint, SIGKSIGSM);
return;
}
/* Check if the signal is already pending. Process it otherwise. */
rp = proc_addr(proc_nr);
if (! sigismember(&rp->p_pending, sig_nr)) {
sigaddset(&rp->p_pending, sig_nr);
if (! (RTS_ISSET(rp, RTS_SIGNALED))) { /* other pending */
RTS_SET(rp, RTS_SIGNALED | RTS_SIG_PENDING);
send_sig(PM_PROC_NR, SIGKSIG);
send_sig(sig_mgr, SIGKSIG);
}
}
}
@ -385,7 +398,7 @@ struct proc *rp;
rp->p_misc_flags &= ~MF_SIG_DELAY;
cause_sig(proc_nr(rp), SIGNDELAY);
cause_sig(proc_nr(rp), SIGKNDELAY);
}
#if _MINIX_CHIP == _CHIP_INTEL

View file

@ -8,6 +8,7 @@
* into a message with type SYS_CALL that is handled in a function do_call().
*
* Changes:
* Mar 01, 2010 SYS_CLEAR and SYS_EXIT split (Cristiano Giuffrida)
* Jul 30, 2005 created SYS_INT86 to support BIOS driver (Philip Homburg)
* Jul 13, 2005 created SYS_PRIVCTL to manage services (Jorrit N. Herder)
* Jul 09, 2005 updated SYS_KILL to signal services (Jorrit N. Herder)
@ -53,9 +54,9 @@ _PROTOTYPE( int do_newmap, (struct proc * caller, message *m_ptr) );
#define do_newmap do_unused
#endif
_PROTOTYPE( int do_exit, (struct proc * caller, message *m_ptr) );
#if ! USE_EXIT
#define do_exit do_unused
_PROTOTYPE( int do_clear, (struct proc * caller, message *m_ptr) );
#if ! USE_CLEAR
#define do_clear do_unused
#endif
_PROTOTYPE( int do_trace, (struct proc * caller, message *m_ptr) );
@ -73,6 +74,16 @@ _PROTOTYPE( int do_runctl, (struct proc * caller, message *m_ptr) );
#define do_runctl do_unused
#endif
_PROTOTYPE( int do_update, (struct proc * caller, message *m_ptr) );
#if ! USE_UPDATE
#define do_update do_unused
#endif
_PROTOTYPE( int do_exit, (struct proc * caller, message *m_ptr) );
#if ! USE_EXIT
#define do_exit do_unused
#endif
_PROTOTYPE( int do_copy, (struct proc * caller, message *m_ptr) );
#define do_vircopy do_copy
#if ! (USE_VIRCOPY || USE_PHYSCOPY)

View file

@ -27,10 +27,12 @@ OBJECTS = \
do_fork.o \
do_exec.o \
do_newmap.o \
do_clear.o \
do_exit.o \
do_trace.o \
do_nice.o \
do_runctl.o \
do_update.o \
do_times.o \
do_setalarm.o \
do_stime.o \

View file

@ -19,7 +19,7 @@
PUBLIC int do_abort(struct proc * caller, message * m_ptr)
{
/* Handle sys_abort. MINIX is unable to continue. This can originate e.g.
* in the PM (normal abort or panic) or TTY (after CTRL-ALT-DEL).
* in the PM (normal abort) or TTY (after CTRL-ALT-DEL).
*/
int how = m_ptr->ABRT_HOW;

75
kernel/system/do_clear.c Normal file
View file

@ -0,0 +1,75 @@
/* The kernel call implemented in this file:
* m_type: SYS_CLEAR
*
* The parameters for this kernel call are:
* m1_i1: PR_ENDPT (endpoint of process to clean up)
*/
#include "../system.h"
#include <minix/endpoint.h>
#if USE_CLEAR
/*===========================================================================*
* do_clear *
*===========================================================================*/
PUBLIC int do_clear(struct proc * caller, message * m_ptr)
{
/* Handle sys_clear. Only the PM can request other process slots to be cleared
* when a process has exited.
* The routine to clean up a process table slot cancels outstanding timers,
* possibly removes the process from the message queues, and resets certain
* process table fields to the default values.
*/
struct proc *rc;
int exit_p;
int i;
if(!isokendpt(m_ptr->PR_ENDPT, &exit_p)) { /* get exiting process */
return EINVAL;
}
rc = proc_addr(exit_p); /* clean up */
/* Don't clear if already cleared. */
if(isemptyp(rc)) return;
/* Check the table with IRQ hooks to see if hooks should be released. */
for (i=0; i < NR_IRQ_HOOKS; i++) {
if (rc->p_endpoint == irq_hooks[i].proc_nr_e) {
rm_irq_handler(&irq_hooks[i]); /* remove interrupt handler */
irq_hooks[i].proc_nr_e = NONE; /* mark hook as free */
}
}
/* Remove the process' ability to send and receive messages */
clear_endpoint(rc);
/* Turn off any alarm timers at the clock. */
reset_timer(&priv(rc)->s_alarm_timer);
/* Make sure that the exiting process is no longer scheduled,
* and mark slot as FREE. Also mark saved fpu contents as not significant.
*/
RTS_SETFLAGS(rc, RTS_SLOT_FREE);
rc->p_misc_flags &= ~MF_FPU_INITIALIZED;
/* Release the process table slot. If this is a system process, also
* release its privilege structure. Further cleanup is not needed at
* this point. All important fields are reinitialized when the
* slots are assigned to another, new process.
*/
if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
#if 0
/* Clean up virtual memory */
if (rc->p_misc_flags & MF_VM) {
vm_map_default(rc);
}
#endif
return OK;
}
#endif /* USE_CLEAR */

View file

@ -15,8 +15,8 @@
PUBLIC int do_endksig(struct proc * caller, message * m_ptr)
{
/* Finish up after a kernel type signal, caused by a SYS_KILL message or a
* call to cause_sig by a task. This is called by the PM after processing a
* signal it got with SYS_GETKSIG.
* call to cause_sig by a task. This is called by a signal manager after
* processing a signal it got with SYS_GETKSIG.
*/
register struct proc *rp;
int proc_nr;
@ -28,9 +28,10 @@ PUBLIC int do_endksig(struct proc * caller, message * m_ptr)
return EINVAL;
rp = proc_addr(proc_nr);
if (caller->p_endpoint != priv(rp)->s_sig_mgr) return(EPERM);
if (!RTS_ISSET(rp, RTS_SIG_PENDING)) return(EINVAL);
/* PM has finished one kernel signal. Perhaps process is ready now? */
/* The signal manager has finished one kernel signal. Is the process ready? */
if (!RTS_ISSET(rp, RTS_SIGNALED)) /* new signal arrived */
RTS_UNSET(rp, RTS_SIG_PENDING); /* remove pending flag */
return(OK);

View file

@ -1,91 +1,27 @@
/* The kernel call implemented in this file:
* m_type: SYS_EXIT
*
* The parameters for this kernel call are:
* m1_i1: PR_ENDPT (slot number of exiting process)
*/
#include "../system.h"
#include <minix/endpoint.h>
#include <signal.h>
#if USE_EXIT
FORWARD _PROTOTYPE( void clear_proc, (register struct proc *rc));
/*===========================================================================*
* do_exit *
* do_exit *
*===========================================================================*/
PUBLIC int do_exit(struct proc * caller, message * m_ptr)
{
/* Handle sys_exit. A user process has exited or a system process requests
* to exit. Only the PM can request other process slots to be cleared.
* The routine to clean up a process table slot cancels outstanding timers,
* possibly removes the process from the message queues, and resets certain
* process table fields to the default values.
/* Handle sys_exit. A system process has requested to exit. Generate a
* self-termination signal.
*/
int exit_e;
int sig_nr = SIGABRT;
/* Determine what process exited. User processes are handled here. */
if (PM_PROC_NR == caller->p_endpoint) {
if (m_ptr->PR_ENDPT != SELF) { /* PM tries to exit self */
if(!isokendpt(m_ptr->PR_ENDPT, &exit_e)) /* get exiting process */
return EINVAL;
clear_proc(proc_addr(exit_e)); /* exit a user process */
return(OK); /* report back to PM */
}
}
cause_sig(caller->p_nr, sig_nr); /* send a signal to the caller */
/* The PM or some other system process requested to be exited. */
clear_proc(caller);
return(EDONTREPLY);
}
/*===========================================================================*
* clear_proc *
*===========================================================================*/
PRIVATE void clear_proc(rc)
register struct proc *rc; /* slot of process to clean up */
{
int i;
/* Don't clear if already cleared. */
if(isemptyp(rc)) return;
/* Check the table with IRQ hooks to see if hooks should be released. */
for (i=0; i < NR_IRQ_HOOKS; i++) {
if (rc->p_endpoint == irq_hooks[i].proc_nr_e) {
rm_irq_handler(&irq_hooks[i]); /* remove interrupt handler */
irq_hooks[i].proc_nr_e = NONE; /* mark hook as free */
}
}
/* Remove the process' ability to send and receive messages */
clear_endpoint(rc);
/* Turn off any alarm timers at the clock. */
reset_timer(&priv(rc)->s_alarm_timer);
/* Make sure that the exiting process is no longer scheduled,
* and mark slot as FREE. Also mark saved fpu contents as not significant.
*/
RTS_SETFLAGS(rc, RTS_SLOT_FREE);
rc->p_misc_flags &= ~MF_FPU_INITIALIZED;
/* Release the process table slot. If this is a system process, also
* release its privilege structure. Further cleanup is not needed at
* this point. All important fields are reinitialized when the
* slots are assigned to another, new process.
*/
if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
#if 0
/* Clean up virtual memory */
if (rc->p_misc_flags & MF_VM) {
vm_map_default(rc);
}
#endif
return(EDONTREPLY); /* don't reply */
}
#endif /* USE_EXIT */

View file

@ -17,21 +17,20 @@
*===========================================================================*/
PUBLIC int do_getksig(struct proc * caller, message * m_ptr)
{
/* PM is ready to accept signals and repeatedly does a kernel call to get
* one. Find a process with pending signals. If no signals are available,
* return NONE in the process number field.
* It is not sufficient to ready the process when PM is informed, because
* PM can block waiting for FS to do a core dump.
/* The signal manager is ready to accept signals and repeatedly does a kernel
* call to get one. Find a process with pending signals. If no signals are
* available, return NONE in the process number field.
*/
register struct proc *rp;
/* Find the next process with pending signals. */
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
if (RTS_ISSET(rp, RTS_SIGNALED)) {
if (caller->p_endpoint != priv(rp)->s_sig_mgr) continue;
/* store signaled process' endpoint */
m_ptr->SIG_ENDPT = rp->p_endpoint;
m_ptr->SIG_MAP = rp->p_pending; /* pending signals map */
sigemptyset(&rp->p_pending); /* ball is in PM's court */
sigemptyset(&rp->p_pending); /* clear map in the kernel */
RTS_UNSET(rp, RTS_SIGNALED); /* blocked by SIG_PENDING */
return(OK);
}

View file

@ -16,13 +16,11 @@
*===========================================================================*/
PUBLIC int do_kill(struct proc * caller, message * m_ptr)
{
/* Handle sys_kill(). Cause a signal to be sent to a process. The PM is the
* central server where all signals are processed and handler policies can
* be registered. Any request, except for PM requests, is added to the map
* of pending signals and the PM is informed about the new signal.
* Since system servers cannot use normal POSIX signal handlers (because they
* are usually blocked on a RECEIVE), they can request the PM to transform
* signals into messages. This is done by the PM with a call to sys_kill().
/* Handle sys_kill(). Cause a signal to be sent to a process. Any request
* is added to the map of pending signals and the signal manager
* associated to the process is informed about the new signal. The signal
* is then delivered using POSIX signal handlers for user processes, or
* translated into an IPC message for system services.
*/
proc_nr_t proc_nr, proc_nr_e;
int sig_nr = m_ptr->SIG_NUMBER;
@ -33,10 +31,9 @@ PUBLIC int do_kill(struct proc * caller, message * m_ptr)
if (sig_nr >= _NSIG) return(EINVAL);
if (iskerneln(proc_nr)) return(EPERM);
/* Set pending signal to be processed by the PM. */
/* Set pending signal to be processed by the signal manager. */
cause_sig(proc_nr, sig_nr);
if (sig_nr == SIGKILL)
clear_endpoint(proc_addr(proc_nr));
return(OK);
}

View file

@ -111,6 +111,9 @@ PUBLIC int do_privctl(struct proc * caller, message * m_ptr)
priv(rp)->s_k_call_mask[i] = (kcalls == NO_C ? 0 : (~0));
}
/* Set the default signal manager. */
priv(rp)->s_sig_mgr = DEF_SYS_SM;
/* Set defaults for resources: no I/O resources, no memory resources,
* no IRQs, no grant table
*/
@ -123,8 +126,9 @@ PUBLIC int do_privctl(struct proc * caller, message * m_ptr)
/* Override defaults if the caller has supplied a privilege structure. */
if (m_ptr->CTL_ARG_PTR)
{
/* Copy s_flags. */
/* Copy s_flags and signal manager. */
priv(rp)->s_flags = priv.s_flags;
priv(rp)->s_sig_mgr = priv.s_sig_mgr;
/* Copy IRQs */
if(priv.s_flags & CHECK_IRQ) {

View file

@ -19,7 +19,7 @@ PUBLIC int do_runctl(struct proc * caller, message * m_ptr)
/* Control a process's RTS_PROC_STOP flag. Used for process management.
* If the process is queued sending a message or stopped for system call
* tracing, and the RC_DELAY request flag is given, set MF_SIG_DELAY instead
* of RTS_PROC_STOP, and send a SIGNDELAY signal later when the process is done
* of RTS_PROC_STOP, and send a SIGKNDELAY signal later when the process is done
* sending (ending the delay). Used by PM for safe signal delivery.
*/
int proc_nr, action, flags, delayed;

View file

@ -13,11 +13,13 @@
#include <assert.h>
#include <minix/type.h>
#include <minix/type.h>
#include <minix/safecopies.h>
#include "../system.h"
#include <signal.h>
struct map_info_s {
int flag;
@ -161,7 +163,7 @@ PUBLIC int map_invoke_vm(struct proc * caller,
/* Connect caller on vmrequest wait queue. */
if(!(caller->p_vmrequest.nextrequestor = vmrequest))
mini_notify(proc_addr(SYSTEM), VM_PROC_NR);
send_sig(VM_PROC_NR, SIGKMEM);
vmrequest = caller;
return OK;

165
kernel/system/do_update.c Normal file
View file

@ -0,0 +1,165 @@
/* The kernel call implemented in this file:
* m_type: SYS_UPDATE
*
* The parameters for this kernel call are:
* m2_i1: SYS_UPD_SRC_ENDPT (source process endpoint)
* m2_i2: SYS_UPD_DST_ENDPT (destination process endpoint)
*/
#include "../system.h"
#include "../ipc.h"
#include <string.h>
#if USE_UPDATE
#define DEBUG 0
#define proc_is_updatable(p) \
(RTS_ISSET(p, RTS_NO_PRIV) || RTS_ISSET(p, RTS_SIG_PENDING) \
|| (RTS_ISSET(p, RTS_RECEIVING) && !RTS_ISSET(p, RTS_SENDING)))
FORWARD _PROTOTYPE(void adjust_proc_slot, (struct proc *rp,
struct proc *from_rp));
FORWARD _PROTOTYPE(void adjust_priv_slot, (struct priv *privp,
struct priv *from_privp));
FORWARD _PROTOTYPE(void swap_proc_slot_pointer, (struct proc **rpp,
struct proc *src_rp, struct proc *dst_rp));
/*===========================================================================*
* do_update *
*===========================================================================*/
PUBLIC int do_update(struct proc * caller, message * m_ptr)
{
/* Handle sys_update(). Update a process into another by swapping their process
* slots.
*/
endpoint_t src_e, dst_e;
int src_p, dst_p;
struct proc *src_rp, *dst_rp, *rp;
struct priv *src_privp, *dst_privp;
struct proc orig_src_proc;
struct proc orig_dst_proc;
struct priv orig_src_priv;
struct priv orig_dst_priv;
int r;
reg_t src_vbp, dst_vbp;
/* Lookup slots for source and destination process. */
src_e = m_ptr->SYS_UPD_SRC_ENDPT;
if(!isokendpt(src_e, &src_p)) {
return EINVAL;
}
src_rp = proc_addr(src_p);
src_privp = priv(src_rp);
if(!(src_privp->s_flags & SYS_PROC)) {
return EPERM;
}
dst_e = m_ptr->SYS_UPD_DST_ENDPT;
if(!isokendpt(dst_e, &dst_p)) {
return EINVAL;
}
dst_rp = proc_addr(dst_p);
dst_privp = priv(dst_rp);
if(!(dst_privp->s_flags & SYS_PROC)) {
return EPERM;
}
/* Check if processes are updatable. */
if(!proc_is_updatable(src_rp) || !proc_is_updatable(dst_rp)) {
return EBUSY;
}
#if DEBUG
printf("do_update: updating %d (%s, %d, %d) into %d (%s, %d, %d)\n",
src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr,
dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr);
proc_stacktrace(src_rp);
proc_stacktrace(dst_rp);
printf("do_update: curr ptproc %d\n", ptproc->p_endpoint);
#endif
/* Save existing data. */
orig_src_proc = *src_rp;
orig_src_priv = *(priv(src_rp));
orig_dst_proc = *dst_rp;
orig_dst_priv = *(priv(dst_rp));
/* Swap slots. */
*src_rp = orig_dst_proc;
*src_privp = orig_dst_priv;
*dst_rp = orig_src_proc;
*dst_privp = orig_src_priv;
/* Adjust process slots. */
adjust_proc_slot(src_rp, &orig_src_proc);
adjust_proc_slot(dst_rp, &orig_dst_proc);
/* Adjust privilege slots. */
adjust_priv_slot(priv(src_rp), &orig_src_priv);
adjust_priv_slot(priv(dst_rp), &orig_dst_priv);
/* Swap global process slot addresses. */
swap_proc_slot_pointer(&ptproc, src_rp, dst_rp);
/* Fix segments. */
alloc_segments(src_rp);
alloc_segments(dst_rp);
prot_init();
#if DEBUG
printf("do_update: updated %d (%s, %d, %d) into %d (%s, %d, %d)\n",
src_rp->p_endpoint, src_rp->p_name, src_rp->p_nr, priv(src_rp)->s_proc_nr,
dst_rp->p_endpoint, dst_rp->p_name, dst_rp->p_nr, priv(dst_rp)->s_proc_nr);
proc_stacktrace(src_rp);
proc_stacktrace(dst_rp);
printf("do_update: curr ptproc %d\n", ptproc->p_endpoint);
#endif
return OK;
}
/*===========================================================================*
* adjust_proc_slot *
*===========================================================================*/
PRIVATE void adjust_proc_slot(struct proc *rp, struct proc *from_rp)
{
/* Preserve endpoints, slot numbers, priv structure. */
rp->p_endpoint = from_rp->p_endpoint;
rp->p_nr = from_rp->p_nr;
rp->p_priv = from_rp->p_priv;
priv(rp)->s_proc_nr = from_rp->p_nr;
}
/*===========================================================================*
* adjust_priv_slot *
*===========================================================================*/
PRIVATE void adjust_priv_slot(struct priv *privp, struct priv *from_privp)
{
/* Preserve privilege ids and non-privilege stuff in the priv structure. */
privp->s_id = from_privp->s_id;
privp->s_notify_pending = from_privp->s_notify_pending;
privp->s_int_pending = from_privp->s_int_pending;
privp->s_sig_pending = from_privp->s_sig_pending;
privp->s_alarm_timer = from_privp->s_alarm_timer;
memcpy(privp->s_farmem, from_privp->s_farmem, sizeof(privp->s_farmem));
}
/*===========================================================================*
* swap_proc_slot_pointer *
*===========================================================================*/
PRIVATE void swap_proc_slot_pointer(struct proc **rpp, struct proc *src_rp,
struct proc *dst_rp)
{
if(*rpp == src_rp) {
*rpp = dst_rp;
}
else if(*rpp == dst_rp) {
*rpp = src_rp;
}
}
#endif /* USE_UPDATE */

View file

@ -48,7 +48,7 @@ const char *_sys_errlist[] = {
"Function not implemented", /* ENOSYS */
"Directory not empty", /* ENOTEMPTY */
"Too many levels of symbolic links", /* ELOOP */
"Driver restarted", /* ERESTART */
"Service restarted", /* ERESTART */
unknown, /* 42 */
"Identifier removed", /* EIDRM */
"Illegal byte sequence", /* EILSEQ */

View file

@ -33,6 +33,7 @@ SRCS+= \
_sysuname.c \
_vm_dmacalls.c \
_vm_set_priv.c \
_vm_update.c \
_vm_query_exit.c \
asynchio.c \
basename.c \

View file

@ -0,0 +1,12 @@
#include <lib.h>
#define vm_update _vm_update
#include <unistd.h>
PUBLIC int vm_update(endpoint_t src_e, endpoint_t dst_e)
{
message m;
m.VM_RS_SRC_ENDPT = src_e;
m.VM_RS_DST_ENDPT = dst_e;
return _syscall(VM_PROC_NR, VM_RS_UPDATE, &m);
}

View file

@ -74,6 +74,7 @@ SRCS+= \
vm_remap.S \
vm_unmap.S \
vm_set_priv.S \
vm_update.S \
vm_query_exit.S \
mount.S \
nanosleep.S \

View file

@ -0,0 +1,7 @@
.text
.extern __vm_update
.globl _vm_update
.balign 2
_vm_update:
jmp __vm_update

View file

@ -29,10 +29,12 @@ SRCS= \
pci_slot_name.c \
safecopies.c \
sef.c \
sef_init.c \
sef_liveupdate.c \
sef_ping.c \
sef_init.c \
sef_signal.c \
sys_abort.c \
sys_clear.c \
sys_mcontext.c \
sys_cprof.c \
sys_endsig.c \
@ -53,6 +55,7 @@ SRCS= \
sys_physcopy.c \
sys_readbios.c \
sys_runctl.c \
sys_update.c \
sys_safecopy.c \
sys_safemap.c \
sys_sysctl.c \

View file

@ -49,16 +49,8 @@ int ds_publish_u32(const char *ds_name, u32_t value, int flags)
return do_invoke_ds(DS_PUBLISH, ds_name);
}
int ds_publish_str(const char *ds_name, char *value, int flags)
{
if(strlen(value) >= DS_MAX_STRLEN)
return EINVAL;
strcpy((char *)(&m.DS_STRING), value);
m.DS_FLAGS = DSF_TYPE_STR | flags;
return do_invoke_ds(DS_PUBLISH, ds_name);
}
int ds_publish_mem(const char *ds_name, void *vaddr, size_t length, int flags)
static int ds_publish_raw(const char *ds_name, void *vaddr, size_t length,
int flags)
{
cp_grant_id_t gid;
int r;
@ -70,7 +62,7 @@ int ds_publish_mem(const char *ds_name, void *vaddr, size_t length, int flags)
m.DS_VAL = gid;
m.DS_VAL_LEN = length;
m.DS_FLAGS = DSF_TYPE_MEM | flags;
m.DS_FLAGS = flags;
r = do_invoke_ds(DS_PUBLISH, ds_name);
cpf_revoke(gid);
@ -78,6 +70,19 @@ int ds_publish_mem(const char *ds_name, void *vaddr, size_t length, int flags)
return r;
}
int ds_publish_str(const char *ds_name, char *value, int flags)
{
size_t length;
length = strlen(value) + 1;
value[length - 1] = '\0';
return ds_publish_raw(ds_name, value, length, flags | DSF_TYPE_STR);
}
int ds_publish_mem(const char *ds_name, void *vaddr, size_t length, int flags)
{
return ds_publish_raw(ds_name, vaddr, length, flags | DSF_TYPE_MEM);
}
int ds_publish_map(const char *ds_name, void *vaddr, size_t length, int flags)
{
cp_grant_id_t gid;
@ -97,7 +102,6 @@ int ds_publish_map(const char *ds_name, void *vaddr, size_t length, int flags)
m.DS_FLAGS = DSF_TYPE_MAP | flags;
r = do_invoke_ds(DS_PUBLISH, ds_name);
cpf_revoke(gid);
return r;
}
@ -136,17 +140,8 @@ int ds_retrieve_u32(const char *ds_name, u32_t *value)
return r;
}
int ds_retrieve_str(const char *ds_name, char *value, size_t len_str)
{
int r;
m.DS_FLAGS = DSF_TYPE_STR;
r = do_invoke_ds(DS_RETRIEVE, ds_name);
strncpy(value, (char *)(&m.DS_STRING), DS_MAX_STRLEN);
value[DS_MAX_STRLEN - 1] = '\0';
return r;
}
int ds_retrieve_mem(const char *ds_name, char *vaddr, size_t *length)
static int ds_retrieve_raw(const char *ds_name, char *vaddr, size_t *length,
int flags)
{
cp_grant_id_t gid;
int r;
@ -158,7 +153,7 @@ int ds_retrieve_mem(const char *ds_name, char *vaddr, size_t *length)
m.DS_VAL = gid;
m.DS_VAL_LEN = *length;
m.DS_FLAGS = DSF_TYPE_MEM;
m.DS_FLAGS = flags;
r = do_invoke_ds(DS_RETRIEVE, ds_name);
*length = m.DS_VAL_LEN;
cpf_revoke(gid);
@ -166,6 +161,20 @@ int ds_retrieve_mem(const char *ds_name, char *vaddr, size_t *length)
return r;
}
int ds_retrieve_str(const char *ds_name, char *value, size_t len_str)
{
int r;
size_t length = len_str + 1;
r = ds_retrieve_raw(ds_name, value, &length, DSF_TYPE_STR);
value[length - 1] = '\0';
return r;
}
int ds_retrieve_mem(const char *ds_name, char *vaddr, size_t *length)
{
return ds_retrieve_raw(ds_name, vaddr, length, DSF_TYPE_MEM);
}
int ds_retrieve_map(const char *ds_name, char *vaddr, size_t *length,
int nr_snapshot, int flags)
{

View file

@ -5,8 +5,8 @@
/* Self variables. */
#define SEF_SELF_NAME_MAXLEN 20
PRIVATE char sef_self_name[SEF_SELF_NAME_MAXLEN];
PRIVATE endpoint_t sef_self_endpoint;
PUBLIC char sef_self_name[SEF_SELF_NAME_MAXLEN];
PUBLIC endpoint_t sef_self_endpoint;
/* Debug. */
#define SEF_DEBUG_HEADER_MAXLEN 32
@ -22,19 +22,22 @@ PUBLIC _PROTOTYPE( char* sef_debug_header, (void) );
EXTERN _PROTOTYPE( int do_sef_rs_init, (void) );
EXTERN _PROTOTYPE( int do_sef_init_request, (message *m_ptr) );
/* SEF Ping prototypes. */
EXTERN _PROTOTYPE( int do_sef_ping_request, (message *m_ptr) );
/* SEF Live update prototypes. */
EXTERN _PROTOTYPE( void do_sef_lu_before_receive, (void) );
EXTERN _PROTOTYPE( int do_sef_lu_request, (message *m_ptr) );
/* SEF Ping prototypes. */
EXTERN _PROTOTYPE( int do_sef_ping_request, (message *m_ptr) );
/* SEF Signal prototypes. */
EXTERN _PROTOTYPE( int do_sef_signal_request, (message *m_ptr) );
/*===========================================================================*
* sef_startup *
*===========================================================================*/
PUBLIC void sef_startup()
{
/* SEF startup interface for system processes. */
/* SEF startup interface for system services. */
int r;
/* Get information about self. */
@ -63,7 +66,7 @@ PUBLIC void sef_startup()
}
}
else {
panic("unable to receive init request");
panic("got an unexpected message type %d", m.m_type);
}
}
#endif
@ -74,7 +77,7 @@ PUBLIC void sef_startup()
*===========================================================================*/
PUBLIC int sef_receive(endpoint_t src, message *m_ptr)
{
/* SEF receive() interface for system processes. */
/* SEF receive() interface for system services. */
int r;
while(TRUE) {
@ -108,6 +111,15 @@ PUBLIC int sef_receive(endpoint_t src, message *m_ptr)
}
#endif
#if INTERCEPT_SEF_SIGNAL_REQUESTS
/* Intercept SEF Signal requests. */
if(IS_SEF_SIGNAL_REQUEST(m_ptr)) {
if(do_sef_signal_request(m_ptr) == OK) {
continue;
}
}
#endif
/* If we get this far, this is not a valid SEF request, return and
* let the caller deal with that.
*/
@ -117,6 +129,46 @@ PUBLIC int sef_receive(endpoint_t src, message *m_ptr)
return r;
}
/*===========================================================================*
* sef_exit *
*===========================================================================*/
PUBLIC void sef_exit(int status)
{
/* System services use a special version of exit() that generates a
* self-termination signal.
*/
message m;
/* Ask the kernel to exit. */
sys_exit();
/* If sys_exit() fails, this is not a system service. Exit through PM. */
m.m1_i1 = status;
_syscall(PM_PROC_NR, EXIT, &m);
/* If everything else fails, hang. */
printf("Warning: system service %d couldn't exit\n", sef_self_endpoint);
for(;;) { }
}
/*===========================================================================*
* _exit *
*===========================================================================*/
PUBLIC void _exit(int status)
{
/* Make exit() an alias for sef_exit() for system services. */
sef_exit(status);
}
/*===========================================================================*
* __exit *
*===========================================================================*/
PUBLIC void __exit(int status)
{
/* Make exit() an alias for sef_exit() for system services. */
sef_exit(status);
}
/*===========================================================================*
* sef_debug_refresh_params *
*===========================================================================*/

View file

@ -4,9 +4,9 @@
/* SEF Init callbacks. */
PRIVATE struct sef_cbs {
sef_cb_init_fresh_t sef_cb_init_fresh;
sef_cb_init_lu_t sef_cb_init_lu;
sef_cb_init_restart_t sef_cb_init_restart;
sef_cb_init_t sef_cb_init_fresh;
sef_cb_init_t sef_cb_init_lu;
sef_cb_init_t sef_cb_init_restart;
} sef_cbs = {
SEF_CB_INIT_FRESH_DEFAULT,
SEF_CB_INIT_LU_DEFAULT,
@ -67,11 +67,9 @@ PUBLIC int do_sef_init_request(message *m_ptr)
break;
}
/* Report back to RS. XXX FIXME: we should use send, but this would cause
* a deadlock due to the current blocking nature of mapdriver().
*/
/* Report back to RS. */
m_ptr->RS_INIT_RESULT = r;
r = asynsend(RS_PROC_NR, m_ptr);
r = sendrec(RS_PROC_NR, m_ptr);
return r;
}
@ -79,7 +77,7 @@ PUBLIC int do_sef_init_request(message *m_ptr)
/*===========================================================================*
* sef_setcb_init_fresh *
*===========================================================================*/
PUBLIC void sef_setcb_init_fresh(sef_cb_init_fresh_t cb)
PUBLIC void sef_setcb_init_fresh(sef_cb_init_t cb)
{
assert(cb != NULL);
sef_cbs.sef_cb_init_fresh = cb;
@ -88,7 +86,7 @@ PUBLIC void sef_setcb_init_fresh(sef_cb_init_fresh_t cb)
/*===========================================================================*
* sef_setcb_init_lu *
*===========================================================================*/
PUBLIC void sef_setcb_init_lu(sef_cb_init_lu_t cb)
PUBLIC void sef_setcb_init_lu(sef_cb_init_t cb)
{
assert(cb != NULL);
sef_cbs.sef_cb_init_lu = cb;
@ -97,44 +95,36 @@ PUBLIC void sef_setcb_init_lu(sef_cb_init_lu_t cb)
/*===========================================================================*
* sef_setcb_init_restart *
*===========================================================================*/
PUBLIC void sef_setcb_init_restart(sef_cb_init_restart_t cb)
PUBLIC void sef_setcb_init_restart(sef_cb_init_t cb)
{
assert(cb != NULL);
sef_cbs.sef_cb_init_restart = cb;
}
/*===========================================================================*
* sef_cb_init_fresh_null *
* sef_cb_init_null *
*===========================================================================*/
PUBLIC int sef_cb_init_fresh_null(int UNUSED(type),
PUBLIC int sef_cb_init_null(int UNUSED(type),
sef_init_info_t *UNUSED(info))
{
return(OK);
return OK;
}
/*===========================================================================*
* sef_cb_init_lu_null *
* sef_cb_init_fail *
*===========================================================================*/
PUBLIC int sef_cb_init_lu_null(int UNUSED(type), sef_init_info_t *UNUSED(info))
PUBLIC int sef_cb_init_fail(int UNUSED(type), sef_init_info_t *UNUSED(info))
{
return(OK);
return ENOSYS;
}
/*===========================================================================*
* sef_cb_init_restart_null *
* sef_cb_init_crash *
*===========================================================================*/
PUBLIC int sef_cb_init_restart_null(int UNUSED(type),
sef_init_info_t *UNUSED(info))
PUBLIC int sef_cb_init_crash(int UNUSED(type), sef_init_info_t *UNUSED(info))
{
return(OK);
}
/*===========================================================================*
* sef_cb_init_restart_fail *
*===========================================================================*/
PUBLIC int sef_cb_init_restart_fail(int UNUSED(type),
sef_init_info_t *UNUSED(info))
{
return(ENOSYS);
panic("Simulating a crash at initialization time...");
return OK;
}

View file

@ -11,19 +11,22 @@ PRIVATE struct sef_cbs {
sef_cb_lu_state_isvalid_t sef_cb_lu_state_isvalid;
sef_cb_lu_state_changed_t sef_cb_lu_state_changed;
sef_cb_lu_state_dump_t sef_cb_lu_state_dump;
sef_cb_lu_ready_pre_t sef_cb_lu_ready_pre;
sef_cb_lu_state_save_t sef_cb_lu_state_save;
} sef_cbs = {
SEF_CB_LU_PREPARE_DEFAULT,
SEF_CB_LU_STATE_ISVALID_DEFAULT,
SEF_CB_LU_STATE_CHANGED_DEFAULT,
SEF_CB_LU_STATE_DUMP_DEFAULT,
SEF_CB_LU_READY_PRE_DEFAULT,
SEF_CB_LU_STATE_SAVE_DEFAULT,
};
/* SEF Live update prototypes for sef_receive(). */
PUBLIC _PROTOTYPE( void do_sef_lu_before_receive, (void) );
PUBLIC _PROTOTYPE( int do_sef_lu_request, (message *m_ptr) );
/* SEF Live update helpers. */
PRIVATE _PROTOTYPE( void sef_lu_ready, (int result) );
/* Debug. */
EXTERN _PROTOTYPE( char* sef_debug_header, (void) );
PRIVATE int sef_lu_debug_cycle = 0;
@ -34,6 +37,7 @@ PRIVATE int sef_lu_debug_cycle = 0;
PUBLIC void do_sef_lu_before_receive()
{
/* Handle SEF Live update before receive events. */
int r;
/* Nothing to do if we are not preparing for a live update. */
if(sef_lu_state == SEF_LU_STATE_NULL) {
@ -53,11 +57,12 @@ PUBLIC void do_sef_lu_before_receive()
/* Let the callback code handle the event.
* For SEF_LU_STATE_WORK_FREE, we're always ready, tell immediately.
*/
if(sef_lu_state == SEF_LU_STATE_WORK_FREE) {
sef_lu_ready(OK);
r = OK;
if(sef_lu_state != SEF_LU_STATE_WORK_FREE) {
r = sef_cbs.sef_cb_lu_prepare(sef_lu_state);
}
else {
sef_cbs.sef_cb_lu_prepare(sef_lu_state);
if(r == OK) {
sef_lu_ready(OK);
}
}
@ -67,19 +72,28 @@ PUBLIC void do_sef_lu_before_receive()
PUBLIC int do_sef_lu_request(message *m_ptr)
{
/* Handle a SEF Live update request. */
int old_state, is_valid_state;
int state, old_state, is_valid_state;
sef_lu_debug_cycle = 0;
old_state = sef_lu_state;
state = m_ptr->RS_LU_STATE;
/* Only accept live update requests with a valid state. */
is_valid_state = sef_cbs.sef_cb_lu_state_isvalid(m_ptr->RS_LU_STATE);
/* Deal with prepare cancel requests first. */
is_valid_state = (state == SEF_LU_STATE_NULL);
/* Otherwise only accept live update requests with a valid state. */
is_valid_state = is_valid_state || sef_cbs.sef_cb_lu_state_isvalid(state);
if(!is_valid_state) {
sef_lu_ready(EINVAL);
if(sef_cbs.sef_cb_lu_state_isvalid == SEF_CB_LU_STATE_ISVALID_NULL) {
sef_lu_ready(ENOSYS);
}
else {
sef_lu_ready(EINVAL);
}
}
else {
/* Set the new live update state. */
sef_lu_state = m_ptr->RS_LU_STATE;
sef_lu_state = state;
/* If the live update state changed, let the callback code
* handle the rest.
@ -96,10 +110,10 @@ PUBLIC int do_sef_lu_request(message *m_ptr)
/*===========================================================================*
* sef_lu_ready *
*===========================================================================*/
PUBLIC void sef_lu_ready(int result)
PRIVATE void sef_lu_ready(int result)
{
message m;
int old_state, r;
int old_state, rs_result, r;
#if SEF_LU_DEBUG
sef_lu_debug_begin();
@ -109,28 +123,33 @@ PUBLIC void sef_lu_ready(int result)
sef_lu_debug_end();
#endif
/* Let the callback code perform any pre-ready operations. */
r = sef_cbs.sef_cb_lu_ready_pre(result);
if(r != OK) {
/* Abort update if callback returned error. */
result = r;
}
else {
/* Inform RS that we're ready with the given result. */
m.m_type = RS_LU_PREPARE;
m.RS_LU_STATE = sef_lu_state;
m.RS_LU_RESULT = result;
r = sendrec(RS_PROC_NR, &m);
if ( r != OK) {
panic("sendrec failed: %d", r);
/* If result is OK, let the callback code save
* any state that must be carried over to the new version.
*/
if(result == OK) {
r = sef_cbs.sef_cb_lu_state_save(sef_lu_state);
if(r != OK) {
/* Abort update if callback returned error. */
result = r;
}
}
/* Inform RS that we're ready with the given result. */
m.m_type = RS_LU_PREPARE;
m.RS_LU_STATE = sef_lu_state;
m.RS_LU_RESULT = result;
r = sendrec(RS_PROC_NR, &m);
if ( r != OK) {
panic("sendrec failed: %d", r);
}
#if SEF_LU_DEBUG
rs_result = m.m_type == RS_LU_PREPARE ? EINTR : m.m_type;
sef_lu_debug_begin();
sef_lu_dprint("%s, cycle=%d. The %s aborted the update!\n",
sef_lu_dprint("%s, cycle=%d. The %s aborted the update with result %d!\n",
sef_debug_header(), sef_lu_debug_cycle,
(result == OK ? "server" : "client"));
(result == OK ? "server" : "client"),
(result == OK ? rs_result : result)); /* EINTR if update was canceled. */
sef_lu_debug_end();
#endif
@ -181,19 +200,20 @@ PUBLIC void sef_setcb_lu_state_dump(sef_cb_lu_state_dump_t cb)
}
/*===========================================================================*
* sef_setcb_lu_ready_pre *
* sef_setcb_lu_state_save *
*===========================================================================*/
PUBLIC void sef_setcb_lu_ready_pre(sef_cb_lu_ready_pre_t cb)
PUBLIC void sef_setcb_lu_state_save(sef_cb_lu_state_save_t cb)
{
assert(cb != NULL);
sef_cbs.sef_cb_lu_ready_pre = cb;
sef_cbs.sef_cb_lu_state_save = cb;
}
/*===========================================================================*
* sef_cb_lu_prepare_null *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare_null(int UNUSED(state))
PUBLIC int sef_cb_lu_prepare_null(int UNUSED(state))
{
return ENOTREADY;
}
/*===========================================================================*
@ -221,19 +241,44 @@ PUBLIC void sef_cb_lu_state_dump_null(int UNUSED(state))
}
/*===========================================================================*
* sef_cb_lu_ready_pre_null *
* sef_cb_lu_state_save_null *
*===========================================================================*/
PUBLIC int sef_cb_lu_ready_pre_null(int UNUSED(result))
PUBLIC int sef_cb_lu_state_save_null(int UNUSED(result))
{
return(OK);
return OK;
}
/*===========================================================================*
* sef_cb_lu_prepare_always_ready *
*===========================================================================*/
PUBLIC void sef_cb_lu_prepare_always_ready(int UNUSED(state))
PUBLIC int sef_cb_lu_prepare_always_ready(int UNUSED(state))
{
sef_lu_ready(OK);
return OK;
}
/*===========================================================================*
* sef_cb_lu_prepare_never_ready *
*===========================================================================*/
PUBLIC int sef_cb_lu_prepare_never_ready(int UNUSED(state))
{
#if SEF_LU_DEBUG
sef_lu_debug_begin();
sef_lu_dprint("%s, cycle=%d. Simulating a service never ready to update...\n",
sef_debug_header(), sef_lu_debug_cycle);
sef_lu_debug_end();
#endif
return ENOTREADY;
}
/*===========================================================================*
* sef_cb_lu_prepare_crash *
*===========================================================================*/
PUBLIC int sef_cb_lu_prepare_crash(int UNUSED(state))
{
panic("Simulating a crash at update prepare time...");
return OK;
}
/*===========================================================================*

View file

@ -31,7 +31,7 @@ PUBLIC int do_sef_ping_request(message *m_ptr)
#endif
/* Let the callback code handle the request. */
sef_cbs.sef_cb_ping_reply(m_ptr);
sef_cbs.sef_cb_ping_reply(m_ptr->m_source);
/* Return OK not to let anybody else intercept the request. */
return(OK);
@ -49,15 +49,15 @@ PUBLIC void sef_setcb_ping_reply(sef_cb_ping_reply_t cb)
/*===========================================================================*
* sef_cb_ping_reply_null *
*===========================================================================*/
PUBLIC void sef_cb_ping_reply_null(message *UNUSED(m_ptr))
PUBLIC void sef_cb_ping_reply_null(endpoint_t UNUSED(source))
{
}
/*===========================================================================*
* sef_cb_ping_reply_pong *
*===========================================================================*/
PUBLIC void sef_cb_ping_reply_pong(message *m_ptr)
PUBLIC void sef_cb_ping_reply_pong(endpoint_t source)
{
notify(m_ptr->m_source);
notify(source);
}

196
lib/libsys/sef_signal.c Normal file
View file

@ -0,0 +1,196 @@
#include "syslib.h"
#include <assert.h>
#include <signal.h>
#include <minix/sysutil.h>
/* SEF Signal callbacks. */
PRIVATE struct sef_cbs {
sef_cb_signal_handler_t sef_cb_signal_handler;
sef_cb_signal_manager_t sef_cb_signal_manager;
} sef_cbs = {
SEF_CB_SIGNAL_HANDLER_DEFAULT,
SEF_CB_SIGNAL_MANAGER_DEFAULT
};
/* SEF Signal prototypes for sef_receive(). */
PUBLIC _PROTOTYPE( int do_sef_signal_request, (message *m_ptr) );
/* Debug. */
EXTERN _PROTOTYPE( char* sef_debug_header, (void) );
/* Information about SELF. */
EXTERN endpoint_t sef_self_endpoint;
/*===========================================================================*
* process_sigmgr_signals *
*===========================================================================*/
PRIVATE void process_sigmgr_signals(void)
{
/* A signal manager has pending signals in the kernel. Process them. */
endpoint_t target;
sigset_t sigset;
int signo, r;
while (TRUE) {
/* Get an arbitrary pending signal. */
if((r=sys_getksig(&target, &sigset)) != OK)
panic("SEF", "sys_getksig failed", r);
if (target == NONE) {
/* Stop if there are no more pending signals. */
break;
} else {
/* Process every signal in the signal set. */
r = OK;
for(signo = 1; signo < _NSIG; signo++) {
if(sigismember(&sigset, signo)) {
/* Let the callback code process the signal. */
r = sef_cbs.sef_cb_signal_manager(target, signo);
/* Stop if process is gone. */
if(r == EDEADSRCDST) {
break;
}
}
}
/* Tell the kernel we are done if the target is still alive. */
if(r == OK) {
if((r=sys_endksig(target)) != OK)
panic("SEF","sys_endksig failed", r);
}
}
}
}
/*===========================================================================*
* process_sigmgr_self_signals *
*===========================================================================*/
PRIVATE void process_sigmgr_self_signals(sigset_t sigset)
{
/* A signal manager has pending signals for itself. Process them. */
int signo;
for(signo = 1; signo < _NSIG; signo++) {
if(sigismember(&sigset, signo)) {
/* Let the callback code process the signal. */
sef_cbs.sef_cb_signal_handler(signo);
}
}
}
/*===========================================================================*
* do_sef_signal_request *
*===========================================================================*/
PUBLIC int do_sef_signal_request(message *m_ptr)
{
/* Handle a SEF Signal request. */
int signo;
sigset_t sigset;
if(m_ptr->m_source == SYSTEM) {
/* Handle kernel signals. */
sigset = m_ptr->NOTIFY_ARG;
for (signo = SIGK_FIRST; signo <= SIGK_LAST; signo++) {
if (sigismember(&sigset, signo)) {
/* Let the callback code handle the kernel signal. */
sef_cbs.sef_cb_signal_handler(signo);
/* Handle SIGKSIG for a signal manager. */
if(signo == SIGKSIG) {
process_sigmgr_signals();
}
/* Handle SIGKSIGSM for a signal manager. */
else if(signo == SIGKSIGSM) {
process_sigmgr_self_signals(sigset);
}
}
}
}
else {
/* Handle system signals from a signal manager. */
signo = m_ptr->SIGS_SIG_NUM;
/* Debug. */
#if SEF_SIGNAL_DEBUG
sef_signal_debug_begin();
sef_signal_dprint("%s. Got a SEF Signal request for signal %d! About to handle signal.\n",
sef_debug_header(), signo);
sef_signal_debug_end();
#endif
/* Let the callback code handle the signal. */
sef_cbs.sef_cb_signal_handler(signo);
}
/* Return OK not to let anybody else intercept the request. */
return OK;
}
/*===========================================================================*
* sef_setcb_signal_handler *
*===========================================================================*/
PUBLIC void sef_setcb_signal_handler(sef_cb_signal_handler_t cb)
{
assert(cb != NULL);
sef_cbs.sef_cb_signal_handler = cb;
}
/*===========================================================================*
* sef_setcb_signal_manager *
*===========================================================================*/
PUBLIC void sef_setcb_signal_manager(sef_cb_signal_manager_t cb)
{
assert(cb != NULL);
sef_cbs.sef_cb_signal_manager = cb;
}
/*===========================================================================*
* sef_cb_signal_handler_null *
*===========================================================================*/
PUBLIC void sef_cb_signal_handler_null(int signo)
{
}
/*===========================================================================*
* sef_cb_signal_manager_null *
*===========================================================================*/
PUBLIC int sef_cb_signal_manager_null(endpoint_t target, int signo)
{
return OK;
}
/*===========================================================================*
* sef_cb_signal_handler_term *
*===========================================================================*/
PUBLIC void sef_cb_signal_handler_term(int signo)
{
/* Terminate in case of SIGTERM, ignore other signals. */
if(signo == SIGTERM) {
sef_exit(1);
}
}
/*===========================================================================*
* sef_cb_signal_handler_posix_default *
*===========================================================================*/
PUBLIC void sef_cb_signal_handler_posix_default(int signo)
{
switch(signo) {
/* Ignore when possible. */
case SIGCHLD:
case SIGWINCH:
case SIGCONT:
case SIGTSTP:
case SIGTTIN:
case SIGTTOU:
break;
/* Terminate in any other case unless it is a kernel signal. */
default:
if(!IS_SIGK(signo)) {
sef_exit(1);
}
break;
}
}

15
lib/libsys/sys_clear.c Normal file
View file

@ -0,0 +1,15 @@
#include "syslib.h"
/*===========================================================================*
* sys_clear *
*===========================================================================*/
PUBLIC int sys_clear(proc_ep)
endpoint_t proc_ep; /* which process has exited */
{
/* A process has exited. PM tells the kernel.
*/
message m;
m.PR_ENDPT = proc_ep;
return(_kernel_call(SYS_CLEAR, &m));
}

View file

@ -3,15 +3,10 @@
/*===========================================================================*
* sys_exit *
*===========================================================================*/
PUBLIC int sys_exit(proc_ep)
endpoint_t proc_ep; /* which process has exited */
PUBLIC int sys_exit()
{
/* A process has exited. PM tells the kernel. In addition this call can be
* used by system processes to directly exit without passing through the
* PM. This should be used with care to prevent inconsistent PM tables.
*/
/* A system process requests to exit. */
message m;
m.PR_ENDPT = proc_ep;
return(_kernel_call(SYS_EXIT, &m));
}

11
lib/libsys/sys_update.c Normal file
View file

@ -0,0 +1,11 @@
#include "syslib.h"
int sys_update(endpoint_t src_ep, endpoint_t dst_ep)
{
message m;
m.SYS_UPD_SRC_ENDPT = src_ep;
m.SYS_UPD_DST_ENDPT = dst_ep;
return _kernel_call(SYS_UPDATE, &m);
}

View file

@ -229,7 +229,7 @@ A directory with entries other than \*(lq.\*(rq and \*(lq..\*(rq
was supplied to a remove directory or rename call.
.en 40 ELOOP "Too many symbolic links"
A path name lookup involved too many symbolic links.
.en 41 ERESTART "Device driver restarted
.en 41 ERESTART "Service restarted
.en 43 EIDRM "Identifier removed
.en 44 EILSEQ "Illegal byte sequence
.en 50 EPACKSIZE "Invalid packet size

View file

@ -3,8 +3,9 @@
/* Header file including all needed system headers. */
#define _SYSTEM 1 /* get OK and negative error codes */
#define _POSIX_SOURCE 1 /* tell headers to include POSIX stuff */
#define _MINIX 1 /* tell headers to include MINIX stuff */
#define _SYSTEM 1 /* get OK and negative error codes */
#include <ansi.h>
#include <sys/types.h>

View file

@ -16,8 +16,6 @@ PRIVATE endpoint_t who_e; /* caller's proc number */
PRIVATE int callnr; /* system call number */
/* Declare some local functions. */
FORWARD _PROTOTYPE(void exit_server, (void) );
FORWARD _PROTOTYPE(void sig_handler, (void) );
FORWARD _PROTOTYPE(void get_work, (message *m_ptr) );
FORWARD _PROTOTYPE(void reply, (int whom, message *m_ptr) );
@ -47,18 +45,9 @@ PUBLIC int main(int argc, char **argv)
get_work(&m);
if (is_notify(callnr)) {
switch (_ENDPOINT_P(who_e)) {
case PM_PROC_NR:
sig_handler();
break;
default:
printf("DS: warning, got illegal notify from: %d\n",
m.m_source);
result = EINVAL;
goto send_reply;
}
/* done, get a new message */
printf("DS: warning, got illegal notify from: %d\n", m.m_source);
result = EINVAL;
goto send_reply;
}
switch (callnr) {
@ -108,7 +97,7 @@ PRIVATE void sef_local_startup()
{
/* Register init callbacks. */
sef_setcb_init_fresh(sef_cb_init_fresh);
sef_setcb_init_restart(sef_cb_init_restart_fail);
sef_setcb_init_restart(sef_cb_init_fail);
/* No live update support for now. */
@ -116,34 +105,6 @@ PRIVATE void sef_local_startup()
sef_startup();
}
/*===========================================================================*
* sig_handler *
*===========================================================================*/
PRIVATE void sig_handler()
{
/* Signal handler. */
sigset_t sigset;
/* Try to obtain signal set from PM. */
if (getsigset(&sigset) != 0) return;
/* Check for known signals. */
if (sigismember(&sigset, SIGTERM)) {
exit_server();
}
}
/*===========================================================================*
* exit_server *
*===========================================================================*/
PRIVATE void exit_server()
{
/* Shut down the information service. */
/* Done. Now exit. */
exit(0);
}
/*===========================================================================*
* get_work *
*===========================================================================*/

View file

@ -129,10 +129,13 @@ PRIVATE endpoint_t ds_getprocep(char *s)
PRIVATE int check_auth(struct data_store *p, endpoint_t ep, int perm)
{
/* Check authorization for a given type of permission. */
char *source;
if(!(p->flags & perm))
return 1;
return !strcmp(p->owner, ds_getprocname(ep));
source = ds_getprocname(ep);
return source && !strcmp(p->owner, source);
}
/*===========================================================================*
@ -237,7 +240,7 @@ PRIVATE int map_service(struct rprocpub *rpub)
/* Set attributes. */
strcpy(dsp->key, rpub->label);
dsp->u.u32 = (u32_t) rpub->endpoint;
strcpy(dsp->owner, ds_getprocname(DS_PROC_NR));
strcpy(dsp->owner, "rs");
dsp->flags = DSF_IN_USE | DSF_TYPE_LABEL;
/* Update subscribers having a matching subscription. */
@ -286,10 +289,16 @@ PUBLIC int do_publish(message *m_ptr)
{
struct data_store *dsp;
char key_name[DS_MAX_KEYLEN];
char *source;
int flags = m_ptr->DS_FLAGS;
size_t length;
int r;
/* Lookup the source. */
source = ds_getprocname(m_ptr->m_source);
if(source == NULL)
return EPERM;
/* MAP should not be overwritten. */
if((flags & DSF_TYPE_MAP) && (flags & DSF_OVERWRITE))
return EINVAL;
@ -324,9 +333,6 @@ PUBLIC int do_publish(message *m_ptr)
dsp->u.u32 = m_ptr->DS_VAL;
break;
case DSF_TYPE_STR:
strncpy(dsp->u.string, (char *)(&m_ptr->DS_STRING), DS_MAX_STRLEN);
dsp->u.string[DS_MAX_STRLEN - 1] = '\0';
break;
case DSF_TYPE_MEM:
length = m_ptr->DS_VAL_LEN;
/* Allocate a new data buffer if necessary. */
@ -351,6 +357,9 @@ PUBLIC int do_publish(message *m_ptr)
return r;
}
dsp->u.mem.length = length;
if(flags & DSF_TYPE_STR) {
((char*)dsp->u.mem.data)[length-1] = '\0';
}
break;
case DSF_TYPE_MAP:
/* Allocate buffer, the address should be aligned by CLICK_SIZE. */
@ -377,7 +386,7 @@ PUBLIC int do_publish(message *m_ptr)
/* Set attributes. */
strcpy(dsp->key, key_name);
strcpy(dsp->owner, ds_getprocname(m_ptr->m_source));
strcpy(dsp->owner, source);
dsp->flags = DSF_IN_USE | (flags & DSF_MASK_INTERNAL);
/* Update subscribers having a matching subscription. */
@ -416,8 +425,6 @@ PUBLIC int do_retrieve(message *m_ptr)
m_ptr->DS_VAL = dsp->u.u32;
break;
case DSF_TYPE_STR:
strncpy((char *)(&m_ptr->DS_STRING), dsp->u.string, DS_MAX_STRLEN);
break;
case DSF_TYPE_MEM:
length = MIN(m_ptr->DS_VAL_LEN, dsp->u.mem.length);
r = sys_safecopyto(m_ptr->m_source, (cp_grant_id_t) m_ptr->DS_VAL, 0,
@ -631,9 +638,15 @@ PUBLIC int do_delete(message *m_ptr)
{
struct data_store *dsp;
char key_name[DS_MAX_KEYLEN];
char *source;
int type = m_ptr->DS_FLAGS & DSF_MASK_TYPE;
int top, i, r;
/* Lookup the source. */
source = ds_getprocname(m_ptr->m_source);
if(source == NULL)
return EPERM;
/* Get key name. */
if((r = get_key_name(m_ptr, key_name)) != OK)
return r;
@ -643,14 +656,14 @@ PUBLIC int do_delete(message *m_ptr)
return ESRCH;
/* Only the owner can delete. */
if(strcmp(dsp->owner, ds_getprocname(m_ptr->m_source)))
if(strcmp(dsp->owner, source))
return EPERM;
switch(type) {
case DSF_TYPE_U32:
case DSF_TYPE_STR:
case DSF_TYPE_LABEL:
break;
case DSF_TYPE_STR:
case DSF_TYPE_MEM:
free(dsp->u.mem.data);
break;
@ -658,7 +671,7 @@ PUBLIC int do_delete(message *m_ptr)
/* Unmap the mapped data. */
r = sys_safeunmap(D, (vir_bytes)dsp->u.map.data);
if(r != OK)
return r;
printf("DS: sys_safeunmap failed. Grant already revoked?\n");
/* Revoke all the mapped grants. */
r = sys_saferevmap_addr((vir_bytes)dsp->u.map.data);

View file

@ -20,7 +20,6 @@ struct data_store {
union {
unsigned u32;
char string[DS_MAX_STRLEN];
struct {
void *data;
size_t length;

Some files were not shown because too many files have changed in this diff Show more