[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Sync() and Shutdown() system call
Hello every1!
Here is a patch for a Sync and a Shutdown system call, relative to
MiNT 1.11 h2.
For Sync(), the FILESYS structure had to be extended by a function which
does the sync... (a patch for the minixfs will follow).
And MiNT now spawn off a system update daemon, whose update time can
be set in mint.cnf.
The shutdown() call has two modes, one to set the system to a halt,
the other to reboot. Of course, Sync() is called interally after terminating
all processes.
ok, here is the patch:
diff -uw old/debug.c ./debug.c
--- old/debug.c Tue Nov 1 22:23:10 1994
+++ ./debug.c Tue Nov 1 22:23:46 1994
@@ -523,6 +523,71 @@
}
+/* uk: a normal halt() function without an error message. This function
+ * may only be called if all processes are shut down and the file
+ * systems are synced.
+ */
+
+static const char *haltmsg[MAXLANG] = {
+"System halted.\r\n",
+"System angehalten.\r\n", /* German */
+"System halted.\r\n", /* French */
+"System halted.\r\n", /* UK */
+"System halted.\r\n", /* Spanish */
+"System halted.\r\n" /* Italian */
+};
+
+
+EXITING
+void halt()
+{
+ long r;
+ long key;
+ int scan;
+ extern long tosssp; /* in main.c */
+#ifdef PROFILING
+ extern EXITING _exit P_((int)) NORETURN;
+#endif
+ restr_intr(); /* restore interrupts to normal */
+#ifdef DEBUG_INFO
+ debug_ws("halt() called, system halting...\r\n");
+#else
+ debug_ws(haltmsg[gl_lang]);
+#endif
+ sys_q[READY_Q] = 0; /* prevent context switches */
+
+ for(;;) {
+ /* get a key; if ctl-alt then do it, else halt */
+ key = Bconin(out_device);
+ if ((key & 0x0c000000L) == 0x0c000000L) {
+ scan = (int) ((key >> 16) & 0xff);
+ do_func_key(scan);
+ }
+ else {
+ break;
+ }
+ }
+ for(;;) {
+ debug_ws(haltmsg[gl_lang]);
+ r = Bconin(2);
+
+ if ((r & 0x0ff) == 'x') {
+ extern int no_mem_prot;
+ if (!no_mem_prot)
+ restr_mmu();
+ restr_screen();
+ (void)Super((void *)tosssp); /* gratuitous (void *) for Lattice */
+#ifdef PROFILING
+ _exit(0);
+#else
+ Pterm0();
+#endif
+ }
+ }
+}
+
+
+
static const char *rebootmsg[MAXLANG] = {
"FATAL ERROR. You must reboot the system.\r\n",
"FATALER FEHLER. Das System mu? neu gestartet werden.\r\n", /* German */
@@ -565,9 +630,17 @@
debug_ws(rebootmsg[gl_lang]);
r = Bconin(2);
- if ( (r & 0x0ff) == 'x' ) {
+ if ( ((r & 0x0ff) == 'x') || ((r & 0xff) == 's') ) {
extern int no_mem_prot;
close_filesys();
+
+ /* if the user pressed 's', try to sync before halting the system */
+ if ((r & 0xff) == 's')
+ {
+ debug_ws("Syncing...");
+ s_ync();
+ debug_ws("done.\r\n");
+ }
if (!no_mem_prot)
restr_mmu();
restr_screen();
@@ -595,7 +668,7 @@
switch (scan) {
case DEL:
- reboot();
+ s_hutdown(1);
break;
case UNDO:
killgroup(con_tty.pgrp, SIGQUIT, 1);
diff -uw old/dos.c ./dos.c
--- old/dos.c Tue Nov 1 22:23:10 1994
+++ ./dos.c Tue Nov 1 22:26:42 1994
@@ -8,7 +8,7 @@
#include "mint.h"
-#define DOS_MAX 0x150
+#define DOS_MAX 0x160
Func dos_tab[DOS_MAX];
short dos_max = DOS_MAX;
@@ -829,6 +829,91 @@
return 0;
}
+/* uk: shutdown function
+ * if the parameter is nonzero, reboot the machine, otherwise
+ * halt it after syncing the file systems.
+ */
+
+/* this is mostly from main.c:
+ * shut down processes; this involves waking them all up, and sending
+ * them SIGTERM to give them a chance to clean up after themselves
+ */
+
+static void
+shutmedown(p)
+ PROC *p;
+{
+ wake(WAIT_Q, (long)s_hutdown);
+ p->wait_cond = 0;
+}
+
+long ARGS_ON_STACK
+s_hutdown(long restart)
+{
+ /* only root may shut down the system */
+ if ((curproc->euid == 0) || (curproc->ruid == 0))
+ {
+ PROC *p;
+ int proc_left = 0;
+
+ DEBUG(("Shutting processes down..."));
+ DEBUG(("This is pid %d", curproc->pid));
+ curproc->sighandle[SIGCHLD] = SIG_IGN;
+ for (p = proclist; p; p = p->gl_next) {
+ if (p->pid == 0) continue;
+ if (p == curproc) continue; /* curproc is trapped in this code */
+ if (p->wait_q != ZOMBIE_Q && p->wait_q != TSR_Q) {
+ if (p->wait_q != READY_Q) {
+ short sr = spl7();
+ rm_q(p->wait_q, p);
+ add_q(READY_Q, p);
+ spl(sr);
+ }
+ DEBUG(("Posting SIGTERM for pid %d", p->pid));
+ post_sig(p, SIGTERM);
+ proc_left++;
+ }
+ }
+
+ if (proc_left) {
+ /* sleep a little while, to give the other processes a chance to
+ shut down
+ */
+
+ if (addtimeout(1000, shutmedown))
+ do {
+ DEBUG(("Sleeping..."));
+ sleep(WAIT_Q, (long)s_hutdown);
+ } while (curproc->wait_cond == (long)s_hutdown);
+
+ DEBUG(("Killing all processes..."));
+ for (p = proclist; p; p = p->gl_next)
+ {
+ if ((p->pid == 0) || (p == curproc))
+ continue;
+ DEBUG(("Posting SIGKILL for pid %d", p->pid));
+ post_sig(p, SIGKILL);
+ }
+ }
+ sys_q[READY_Q] = 0;
+ DEBUG(("Syncing file systems..."));
+ close_filesys();
+ s_ync(); /* additional sync() */
+ if (restart)
+ {
+ DEBUG(("Rebooting..."));
+ reboot();
+ }
+ else
+ {
+ DEBUG(("Halting system..."));
+ halt();
+ }
+ }
+ return EACCDN;
+}
+
+
/*
* routine for initializing DOS
*
@@ -975,4 +1060,6 @@
dos_tab[0x14a] = s_cookie;
dos_tab[0x14e] = p_setreuid;
dos_tab[0x14f] = p_setregid;
+ dos_tab[0x150] = s_ync;
+ dos_tab[0x151] = s_hutdown;
}
diff -uw old/file.h ./file.h
--- old/file.h Tue Nov 1 22:23:10 1994
+++ ./file.h Tue Nov 1 22:28:12 1994
@@ -186,6 +186,7 @@
#define FS_LONGPATH 0x08 /* file system understands "size" argument to
"getname" */
#define FS_NO_C_CACHE 0x10 /* don't cache cookies for this filesystem */
+#define FS_DO_SYNC 0x20 /* file system has a sync function */
long ARGS_ON_STACK (*root) P_((int drv, fcookie *fc));
long ARGS_ON_STACK (*lookup) P_((fcookie *dir, const char *name, fcookie *fc));
long ARGS_ON_STACK (*creat) P_((fcookie *dir, const char *name, unsigned mode,
@@ -218,6 +219,7 @@
long ARGS_ON_STACK (*dskchng) P_((int drv));
long ARGS_ON_STACK (*release) P_((fcookie *));
long ARGS_ON_STACK (*dupcookie) P_((fcookie *new, fcookie *old));
+ long ARGS_ON_STACK (*sync) P_((void));
} FILESYS;
/*
diff -uw old/filesys.c ./filesys.c
--- old/filesys.c Tue Nov 1 22:23:10 1994
+++ ./filesys.c Tue Nov 1 22:23:54 1994
@@ -124,6 +124,26 @@
unifs_init();
}
+
+/* uk: go through the list of file systems and call their sync() function
+ * if they wish to.
+ */
+long
+s_ync()
+{
+ FILESYS *fs;
+
+ TRACE(("Syncing file systems..."));
+ for (fs = active_fs; fs; fs = fs->next)
+ {
+ if (fs->fsflags & FS_DO_SYNC)
+ (*fs->sync)();
+ }
+ TRACE(("Syncing done."));
+ return 0;
+}
+
+
/*
* load file systems from disk
* this routine is called after process 0 is set up, but before any user
diff -uw old/main.c ./main.c
--- old/main.c Tue Nov 1 22:23:10 1994
+++ ./main.c Tue Nov 1 22:23:58 1994
@@ -184,6 +184,8 @@
extern Func bios_tab[], dos_tab[];
+extern long sync_time;
+
/* kernel info that is passed to loaded file systems and device drivers */
struct kerinfo kernelinfo = {
@@ -565,6 +567,8 @@
sleep(WAIT_Q, (long)shutdown);
} while (curproc->wait_cond == (long)shutdown);
}
+ /* uk: do an additional sync for the file systems */
+ s_ync();
}
#ifndef MULTITOS
@@ -596,6 +600,8 @@
long yn;
FILEPTR *f;
+ extern void start_sysupdate();
+
#if defined(__GNUC__) || defined(__MINT__)
UNUSED(envp);
#endif
@@ -872,6 +878,9 @@
/* load the configuration file */
load_config();
+/* start system update daemon */
+ start_sysupdate();
+
*((long *)0x4c2L) |= PSEUDODRVS;
if (init_env == 0)
@@ -1173,6 +1182,7 @@
* DEBUG_DEVNO=n -- set debug device number to (decimal number) n
* HARDSCROLL=n -- set hard-scroll size to n, range 0-99.
* SLICES=nnn -- set multitasking granularity
+ * UPDATE=n -- set the sync time in seconds for the system update daemon
* echo message -- print a message on the screen
* alias drive path -- make a fake drive pointing at a path
* cd dir -- change directory/drive
@@ -1324,6 +1334,14 @@
if (!strcmp(name, "PSEUDODRIVES")) {
FORCE("PSEUDODRIVES= no longer supported");
return;
+ }
+
+ /* uk: set update time for system update daemon */
+ if (!strcmp(name, "UPDATE")) {
+ extern long sync_time;
+
+ sync_time = atol(val);
+ return;
}
FORCE("Unknown variable `%s'", name);
}
diff -uw old/makefile ./makefile
--- old/makefile Tue Nov 1 22:23:12 1994
+++ ./makefile Tue Nov 1 22:32:24 1994
@@ -61,12 +61,14 @@
COBJS = bios.o xbios.o console.o dos.o dosdir.o dosfile.o dosmem.o dossig.o \
filesys.o main.o mem.o proc.o signal.o timeout.o tty.o util.o \
biosfs.o pipefs.o procfs.o tosfs.o debug.o rendez.o cookie.o \
- unifs.o shmfs.o fasttext.o welcome.o nalloc2.o memprot.o realloc.o
+ unifs.o shmfs.o fasttext.o welcome.o nalloc2.o memprot.o realloc.o \
+ update.o
COBJS030 = bios.o0 xbios.o0 console.o0 dos.o0 dosdir.o0 dosfile.o0 dosmem.o0 dossig.o0 \
filesys.o0 main.o0 mem.o0 proc.o0 signal.o0 timeout.o0 tty.o0 util.o0 \
biosfs.o0 pipefs.o0 procfs.o0 tosfs.o0 debug.o0 rendez.o0 cookie.o0 \
- unifs.o0 shmfs.o0 fasttext.o0 welcome.o0 nalloc2.o0 memprot.o realloc.o0
+ unifs.o0 shmfs.o0 fasttext.o0 welcome.o0 nalloc2.o0 memprot.o realloc.o0 \
+ update.o0
CFILES = bios.c xbios.c console.c dos.c dosdir.c dosfile.c dosmem.c dossig.c \
filesys.c main.c mem.c proc.c signal.c timeout.c tty.c util.c \
diff -uw old/proto.h ./proto.h
--- old/proto.h Tue Nov 1 22:23:18 1994
+++ ./proto.h Tue Nov 1 22:24:04 1994
@@ -107,6 +107,7 @@
long ARGS_ON_STACK s_ysconf P_((int which));
long ARGS_ON_STACK s_alert P_((char *msg));
long ARGS_ON_STACK s_uptime P_((unsigned long *cur_uptim, unsigned long loadave[3]));
+long ARGS_ON_STACK s_hutdown P_((long restart));
void init_dos P_((void));
/* dosdir.c */
@@ -200,6 +201,7 @@
void load_filesys P_((void));
void load_devdriver P_((void));
void close_filesys P_((void));
+long s_ync P_((void));
void ARGS_ON_STACK changedrv P_((unsigned drv));
int disk_changed P_((int drv));
long relpath2cookie
@@ -398,6 +400,7 @@
void ARGS_ON_STACK FORCE P_((const char *s, ...));
void PAUSE P_((void));
EXITING void ARGS_ON_STACK FATAL P_((const char *s, ...)) NORETURN;
+EXITING void halt P_((void)) NORETURN;
EXITING void HALT P_((void)) NORETURN;
void DUMPLOG P_((void));
void do_func_key P_((int));
I hope you will like it. Unfortunately, the keyboard drivers of newer
TOSes do a warmboot by themselves when ctrl-alt-del is pressed, so
MiNT has NO chance to sync the file system, sorry.
Regards,
Ulrich
--
+---------------+----------------------------+-----------------------+
| Ulrich Kuehn | Internet: | Life is uncertain -- |
| Cand.Math.Inf | kuehn@math.uni-muenster.de | eat the dessert first |
+---------------+----------------------------+-----------------------+