Introduce a mechanism to suspend/resume system processes. Suspend syncer

and bufdaemon prior to disk sync during system shutdown.
This commit is contained in:
Luoqi Chen 2000-01-07 08:36:44 +00:00
parent e960abaf96
commit 5e95083920
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55539
6 changed files with 128 additions and 26 deletions

View File

@ -30,6 +30,7 @@
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/kthread.h>
#include <sys/signalvar.h>
#include <sys/unistd.h>
#include <sys/wait.h>
@ -97,3 +98,42 @@ kthread_exit(int ecode)
exit1(curproc, W_EXITCODE(ecode, 0));
}
/*
* Advise a kernel process to suspend (or resume) in its main loop.
* Participation is voluntary.
*/
int
suspend_kproc(struct proc *p, int timo)
{
/*
* Make sure this is indeed a system process and we can safely
* use the p_siglist field.
*/
if ((p->p_flag & P_SYSTEM) == 0)
return (EINVAL);
SIGADDSET(p->p_siglist, SIGSTOP);
return tsleep((caddr_t)&p->p_siglist, PPAUSE, "suspkp", timo);
}
int
resume_kproc(struct proc *p)
{
/*
* Make sure this is indeed a system process and we can safely
* use the p_siglist field.
*/
if ((p->p_flag & P_SYSTEM) == 0)
return (EINVAL);
SIGDELSET(p->p_siglist, SIGSTOP);
wakeup((caddr_t)&p->p_siglist);
return (0);
}
void
kproc_suspend_loop(struct proc *p)
{
while (SIGISMEMBER(p->p_siglist, SIGSTOP)) {
wakeup((caddr_t)&p->p_siglist);
tsleep((caddr_t)&p->p_siglist, PPAUSE, "kpsusp", 0);
}
}

View File

@ -52,6 +52,7 @@
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/mount.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
@ -571,3 +572,34 @@ poweroff_wait(void *junk, int howto)
return;
DELAY(poweroff_delay * 1000);
}
/*
* Some system processes (e.g. syncer) need to be stopped at appropriate
* points in their main loops prior to a system shutdown, so that they
* won't interfere with the shutdown process (e.g. by holding a disk buf
* to cause sync to fail). For each of these system processes, register
* shutdown_kproc() as a handler for one of shutdown events.
*/
static int kproc_shutdown_wait = 60;
SYSCTL_INT(_kern_shutdown, OID_AUTO, kproc_shutdown_wait, CTLFLAG_RW,
&kproc_shutdown_wait, 0, "");
void
shutdown_kproc(void *arg, int howto)
{
struct proc *p;
int error;
if (panicstr)
return;
p = (struct proc *)arg;
printf("Waiting (max %d seconds) for system process `%s' to stop...",
kproc_shutdown_wait * hz, p->p_comm);
error = suspend_kproc(p, kproc_shutdown_wait);
if (error == EWOULDBLOCK)
printf("timed out\n");
else
printf("stopped\n");
}

View File

@ -29,13 +29,20 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
#include <sys/kthread.h>
#include <sys/vnode.h>
#include <sys/vmmeter.h>
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/eventhandler.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/resourcevar.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_kern.h>
@ -44,11 +51,6 @@
#include <vm/vm_object.h>
#include <vm/vm_extern.h>
#include <vm/vm_map.h>
#include <sys/buf.h>
#include <sys/mount.h>
#include <sys/malloc.h>
#include <sys/resourcevar.h>
#include <sys/conf.h>
static MALLOC_DEFINE(M_BIOBUF, "BIO buffer", "BIO buffer");
@ -1666,6 +1668,13 @@ static void
buf_daemon()
{
int s;
/*
* This process needs to be suspended prior to shutdown sync.
*/
EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc, bufdaemonproc,
SHUTDOWN_PRI_LAST);
/*
* This process is allowed to take the buffer cache to the limit
*/
@ -1676,7 +1685,9 @@ buf_daemon()
bd_flushto = hidirtybuffers; /* dynamically adjusted */
bd_flushinc = 1;
while (TRUE) {
for (;;) {
kproc_suspend_loop(bufdaemonproc);
bd_request = 0;
/*

View File

@ -46,20 +46,23 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/dirent.h>
#include <sys/domain.h>
#include <sys/eventhandler.h>
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/socket.h>
#include <sys/vnode.h>
#include <sys/stat.h>
#include <sys/buf.h>
#include <sys/domain.h>
#include <sys/dirent.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <sys/conf.h>
#include <sys/vnode.h>
#include <machine/limits.h>
@ -72,7 +75,6 @@
#include <vm/vm_pager.h>
#include <vm/vnode_pager.h>
#include <vm/vm_zone.h>
#include <sys/sysctl.h>
static MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure");
@ -975,9 +977,14 @@ sched_sync(void)
int s;
struct proc *p = updateproc;
EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc, p,
SHUTDOWN_PRI_LAST);
p->p_flag |= P_BUFEXHAUST;
for (;;) {
kproc_suspend_loop(p);
starttime = time_second;
/*

View File

@ -46,20 +46,23 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/dirent.h>
#include <sys/domain.h>
#include <sys/eventhandler.h>
#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/kthread.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <sys/socket.h>
#include <sys/vnode.h>
#include <sys/stat.h>
#include <sys/buf.h>
#include <sys/domain.h>
#include <sys/dirent.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <sys/conf.h>
#include <sys/vnode.h>
#include <machine/limits.h>
@ -72,7 +75,6 @@
#include <vm/vm_pager.h>
#include <vm/vnode_pager.h>
#include <vm/vm_zone.h>
#include <sys/sysctl.h>
static MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure");
@ -975,9 +977,14 @@ sched_sync(void)
int s;
struct proc *p = updateproc;
EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc, p,
SHUTDOWN_PRI_LAST);
p->p_flag |= P_BUFEXHAUST;
for (;;) {
kproc_suspend_loop(p);
starttime = time_second;
/*

View File

@ -47,4 +47,9 @@ int kthread_create __P((void (*)(void *), void *, struct proc **,
const char *, ...)) __printflike(4, 5);
void kthread_exit __P((int)) __dead2;
int suspend_kproc __P((struct proc *, int));
int resume_kproc __P((struct proc *));
void kproc_suspend_loop __P((struct proc *));
void shutdown_kproc __P((void *, int));
#endif