377 lines
9.4 KiB
Diff
377 lines
9.4 KiB
Diff
--- README.swsusp
|
|
+++ README.swsusp 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -0,0 +1,5 @@
|
|
+ This version of sysvinit contains a patch for supporting the
|
|
+ Software suspend feature for Linux.
|
|
+ In order to really use it, you need to patch your kernel
|
|
+ with Gabor Kuti's software-suspend patch:
|
|
+ http://falcon.sch.bme.hu/~seasons/linux/
|
|
--- man/halt.8
|
|
+++ man/halt.8 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -4,7 +4,7 @@
|
|
.\"}}}
|
|
.\"{{{ Name
|
|
.SH NAME
|
|
-halt, reboot, poweroff \- stop the system.
|
|
+halt, reboot, poweroff, suspend \- stop the system.
|
|
.\"}}}
|
|
.\"{{{ Synopsis
|
|
.SH SYNOPSIS
|
|
@@ -31,12 +31,16 @@
|
|
.RB [ \-f ]
|
|
.RB [ \-i ]
|
|
.RB [ \-h ]
|
|
+.br
|
|
+.B /sbin/swsusp
|
|
+.RB [ \-w ]
|
|
+.RB [ \-d ]
|
|
.\"}}}
|
|
.\"{{{ Description
|
|
.SH DESCRIPTION
|
|
\fBHalt\fP notes that the system is being brought down in the file
|
|
-\fI/var/log/wtmp\fP, and then either tells the kernel to halt, reboot or
|
|
-poweroff the system.
|
|
+\fI/var/log/wtmp\fP, and then either tells the kernel to halt, reboot, poweroff,
|
|
+or suspend the system.
|
|
.PP
|
|
If \fBhalt\fP or \fBreboot\fP is called when the system is
|
|
\fInot\fP in runlevel \fB0\fP or \fB6\fP, in other words when it's running
|
|
--- man/inittab.5
|
|
+++ man/inittab.5 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -137,6 +137,13 @@
|
|
the external UPS is almost empty and the power is failing (provided that the
|
|
external UPS and the monitoring process are able to detect this condition).
|
|
.\"}}}
|
|
+.\"{{{ resume
|
|
+.IP \fBresume\fP
|
|
+This process will be executed when \fBinit\fP is told by the kernel that
|
|
+Software Suspend has resumed the machine. This way you may specify userland
|
|
+programs what can restore hardware states the kernel cannot (for example
|
|
+svgatextmode and hdparm).
|
|
+.\"}}}
|
|
.\"{{{ ctrlaltdel
|
|
.IP \fBctrlaltdel\fP
|
|
The process will be executed when \fBinit\fP receives the SIGINT signal.
|
|
--- man/shutdown.8
|
|
+++ man/shutdown.8 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -11,7 +11,7 @@
|
|
.B /sbin/shutdown
|
|
.RB [ \-t
|
|
.IR sec ]
|
|
-.RB [ \-arkhncfFHP ]
|
|
+.RB [ \-arkhzncfFHP ]
|
|
.I time
|
|
.RI [ warning-message ]
|
|
.\"}}}
|
|
@@ -71,6 +71,12 @@
|
|
The use of this option is discouraged, and its results are not always what
|
|
you'd expect.
|
|
.\"}}}
|
|
+.\"{{{ -z
|
|
+.IP \fB\-z\fP
|
|
+Shutdown using software suspend. Using this option will not kill processes
|
|
+but pass the control to the kernel what makes the proper steps to stop and
|
|
+save processes to swaps. 'Software\ Suspend' needs to be compiled in.
|
|
+.\"}}}
|
|
.\"{{{ -f
|
|
.IP \fB\-f\fP
|
|
Skip fsck on reboot.
|
|
--- man/swsusp.8
|
|
+++ man/swsusp.8 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -0,0 +1 @@
|
|
+.so man8/halt.8
|
|
--- src/Makefile
|
|
+++ src/Makefile 2005-10-19 13:54:38.000000000 +0200
|
|
@@ -52,7 +52,7 @@
|
|
SBIN += sulogin
|
|
USRBIN += utmpdump
|
|
MAN1 += mountpoint.1
|
|
-MAN8 += sulogin.8
|
|
+MAN8 += sulogin.8 swsusp.8
|
|
endif
|
|
|
|
BIN_OWNER = root
|
|
@@ -131,6 +131,7 @@
|
|
for i in $(USRBIN); do \
|
|
$(INSTALL) -m 755 $$i $(ROOT)/usr/bin/; \
|
|
done
|
|
+ ln -sf halt $(ROOT)/sbin/swsusp
|
|
ln -sf halt $(ROOT)/sbin/reboot
|
|
ln -sf halt $(ROOT)/sbin/poweroff
|
|
ln -sf init $(ROOT)/sbin/telinit
|
|
--- src/dowall.c
|
|
+++ src/dowall.c 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -27,6 +27,7 @@
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
#include <setjmp.h>
|
|
+#include <sched.h>
|
|
|
|
static sigjmp_buf jbuf;
|
|
|
|
@@ -214,6 +215,7 @@
|
|
if (tp != NULL) fclose(tp);
|
|
}
|
|
endutent();
|
|
+ sched_yield();
|
|
|
|
exit(0);
|
|
}
|
|
--- src/halt.c
|
|
+++ src/halt.c 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -172,6 +172,7 @@
|
|
int do_ifdown = 0;
|
|
int do_hddown = 0;
|
|
int do_poweroff = 0;
|
|
+ int do_swsusp = 0;
|
|
int c;
|
|
char *tm = NULL;
|
|
|
|
@@ -185,6 +186,7 @@
|
|
|
|
if (!strcmp(progname, "reboot")) do_reboot = 1;
|
|
if (!strcmp(progname, "poweroff")) do_poweroff = 1;
|
|
+ if (!strcmp(progname, "swsusp")) do_swsusp = 1;
|
|
|
|
/*
|
|
* Get flags
|
|
@@ -220,6 +222,14 @@
|
|
usage();
|
|
}
|
|
}
|
|
+ if(do_swsusp) { /* This implies some flags.. */
|
|
+ do_sync = 0;
|
|
+ do_ifdown = 0;
|
|
+ do_poweroff = 0;
|
|
+ do_reboot = 0;
|
|
+ do_hard = 1;
|
|
+ }
|
|
+
|
|
if (argc != optind) usage();
|
|
|
|
if (geteuid() != 0) {
|
|
@@ -264,6 +274,8 @@
|
|
|
|
if (do_reboot) {
|
|
init_reboot(BMAGIC_REBOOT);
|
|
+ } else if(do_swsusp) {
|
|
+ init_reboot(BMAGIC_SWSUSP);
|
|
} else {
|
|
/*
|
|
* Turn on hard reboot, CTRL-ALT-DEL will reboot now
|
|
--- src/init.c
|
|
+++ src/init.c 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -85,6 +85,10 @@
|
|
# define CBAUDEX 0
|
|
#endif
|
|
|
|
+#ifndef SIGRESUME
|
|
+# define SIGRESUME SIGXCPU
|
|
+#endif
|
|
+
|
|
/* Set a signal handler. */
|
|
#define SETSIG(sa, sig, fun, flags) \
|
|
do { \
|
|
@@ -143,7 +147,7 @@
|
|
/* Macro to see if this is a special action */
|
|
#define ISPOWER(i) ((i) == POWERWAIT || (i) == POWERFAIL || \
|
|
(i) == POWEROKWAIT || (i) == POWERFAILNOW || \
|
|
- (i) == CTRLALTDEL)
|
|
+ (i) == CTRLALTDEL || (i) == RESUME)
|
|
|
|
/* ascii values for the `action' field. */
|
|
struct actions {
|
|
@@ -165,6 +169,7 @@
|
|
{ "initdefault", INITDEFAULT },
|
|
{ "sysinit", SYSINIT },
|
|
{ "kbrequest", KBREQUEST },
|
|
+ { "resume", RESUME },
|
|
{ NULL, 0 },
|
|
};
|
|
|
|
@@ -1129,6 +1134,7 @@
|
|
case POWERWAIT:
|
|
case POWERFAILNOW:
|
|
case POWEROKWAIT:
|
|
+ case RESUME:
|
|
case CTRLALTDEL:
|
|
if (!(ch->flags & XECUTED)) ch->flags |= WAITING;
|
|
case KBREQUEST:
|
|
@@ -1822,6 +1828,22 @@
|
|
}
|
|
|
|
/*
|
|
+ * Start up userland hwstate restoring.
|
|
+ */
|
|
+void do_hwstate_restore(void)
|
|
+{
|
|
+ CHILD *ch;
|
|
+
|
|
+ /*
|
|
+ * Tell resume entries to start up
|
|
+ */
|
|
+ for (ch = family; ch; ch = ch->next) {
|
|
+ if (ch->action == RESUME)
|
|
+ ch->flags &= ~XECUTED;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
* Start up powerfail entries.
|
|
*/
|
|
static
|
|
@@ -2318,6 +2340,14 @@
|
|
int fd;
|
|
char c;
|
|
|
|
+ if (ISMEMBER(got_signals, SIGRESUME)) {
|
|
+#if DEBUG
|
|
+ log(L_VB, "got SIGRESUME");
|
|
+#endif
|
|
+ do_hwstate_restore();
|
|
+ DELSET(got_signals, SIGRESUME);
|
|
+ }
|
|
+
|
|
if (ISMEMBER(got_signals, SIGPWR)) {
|
|
INITDBG(L_VB, "got SIGPWR");
|
|
/* See _what_ kind of SIGPWR this is. */
|
|
@@ -2474,6 +2504,7 @@
|
|
SETSIG(sa, SIGPWR, signal_handler, 0);
|
|
SETSIG(sa, SIGWINCH, signal_handler, 0);
|
|
SETSIG(sa, SIGUSR1, signal_handler, 0);
|
|
+ SETSIG(sa, SIGRESUME,signal_handler, 0);
|
|
SETSIG(sa, SIGSTOP, stop_handler, SA_RESTART);
|
|
SETSIG(sa, SIGTSTP, stop_handler, SA_RESTART);
|
|
SETSIG(sa, SIGCONT, cont_handler, SA_RESTART);
|
|
--- src/init.h
|
|
+++ src/init.h 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -53,6 +53,7 @@
|
|
#define SYSINIT 13
|
|
#define POWERFAILNOW 14
|
|
#define KBREQUEST 15
|
|
+#define RESUME 16
|
|
|
|
/* Information about a process in the in-core inittab */
|
|
typedef struct _child_ {
|
|
--- src/reboot.h
|
|
+++ src/reboot.h 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -32,5 +32,9 @@
|
|
# define BMAGIC_POWEROFF BMAGIC_HALT
|
|
#endif
|
|
|
|
+#ifndef BMAGIC_SWSUSP
|
|
+# define BMAGIC_SWSUSP 0xd000fce2
|
|
+#endif
|
|
+
|
|
#define init_reboot(magic) reboot(magic)
|
|
|
|
--- src/shutdown.c
|
|
+++ src/shutdown.c 2005-10-19 13:52:54.000000000 +0200
|
|
@@ -1,10 +1,11 @@
|
|
/*
|
|
* shutdown.c Shut the system down.
|
|
*
|
|
- * Usage: shutdown [-krhfnc] time [warning message]
|
|
+ * Usage: shutdown [-krhzfnc] time [warning message]
|
|
* -k: don't really shutdown, only warn.
|
|
* -r: reboot after shutdown.
|
|
* -h: halt after shutdown.
|
|
+ * -z: shutdown using software suspend.
|
|
* -f: do a 'fast' reboot (skip fsck).
|
|
* -F: Force fsck on reboot.
|
|
* -n: do not go through init but do it ourselves.
|
|
@@ -113,6 +114,7 @@
|
|
"\t\t -f: do a 'fast' reboot (skip fsck).\n"
|
|
"\t\t -F: Force fsck on reboot.\n"
|
|
"\t\t -n: do not go through \"init\" but go down real fast.\n"
|
|
+ "\t\t -z: shutdown using software suspend.\n"
|
|
"\t\t -c: cancel a running shutdown.\n"
|
|
"\t\t -t secs: delay between warning and kill signal.\n"
|
|
"\t\t ** the \"time\" argument is mandatory! (try \"now\") **\n");
|
|
@@ -271,6 +273,7 @@
|
|
void fastdown()
|
|
{
|
|
int do_halt = (down_level[0] == '0');
|
|
+ int do_swsusp = (down_level[0] == 'z');
|
|
int i;
|
|
#if 0
|
|
char cmd[128];
|
|
@@ -293,6 +296,8 @@
|
|
script = REBOOTSCRIPT2;
|
|
}
|
|
#endif
|
|
+ if(do_swsusp)
|
|
+ init_reboot(BMAGIC_SWSUSP);
|
|
|
|
/* First close all files. */
|
|
for(i = 0; i < 3; i++)
|
|
@@ -364,7 +369,9 @@
|
|
int do_halt = (down_level[0] == '0');
|
|
|
|
/* Warn for the last time */
|
|
- warn(0);
|
|
+ /* I don't want to mess up the later resumed screen */
|
|
+ if(down_level[0] != 'z')
|
|
+ warn(0);
|
|
if (dontshut) {
|
|
hardsleep(1);
|
|
stopit(0);
|
|
@@ -467,7 +474,7 @@
|
|
halttype = NULL;
|
|
|
|
/* Process the options. */
|
|
- while((c = getopt(argc, argv, "HPacqkrhnfFyt:g:i:")) != EOF) {
|
|
+ while((c = getopt(argc, argv, "HPacqkrhnzfFyt:g:i:")) != EOF) {
|
|
switch(c) {
|
|
case 'H':
|
|
halttype = "HALT";
|
|
@@ -499,6 +506,9 @@
|
|
case 'n': /* Don't switch runlevels. */
|
|
doself = 1;
|
|
break;
|
|
+ case 'z': /* Shutdown using software suspend */
|
|
+ down_level[0] = 'z';
|
|
+ break;
|
|
case 't': /* Delay between TERM and KILL */
|
|
sltime = optarg;
|
|
break;
|
|
@@ -592,6 +602,18 @@
|
|
}
|
|
if (message[0]) strcat(message, "\r\n");
|
|
|
|
+ if(down_level[0] == 'z') {
|
|
+ doself = 1;
|
|
+ if(fastboot) {
|
|
+ fprintf(stderr, "shutdown: -f option ignored");
|
|
+ fastboot = 0;
|
|
+ }
|
|
+ if(forcefsck) {
|
|
+ fprintf(stderr, "shutdown: -F option ignored");
|
|
+ forcefsck = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
/* See if we want to run or cancel. */
|
|
if (cancel) {
|
|
if (pid <= 0) {
|
|
@@ -621,7 +643,8 @@
|
|
}
|
|
|
|
/* Extra check. */
|
|
- if (doself && down_level[0] != '0' && down_level[0] != '6') {
|
|
+ if (doself && down_level[0] != '0' && down_level[0] != '6' &&
|
|
+ down_level[0] != 'z') {
|
|
fprintf(stderr,
|
|
"shutdown: can use \"-n\" for halt or reboot only.\r\n");
|
|
exit(1);
|
|
@@ -638,6 +661,9 @@
|
|
case '1':
|
|
strcpy(newstate, "to maintenance mode");
|
|
break;
|
|
+ case 'z':
|
|
+ strcpy(newstate, "for system suspend");
|
|
+ break;
|
|
default:
|
|
sprintf(newstate, "to runlevel %s", down_level);
|
|
break;
|