lkml.org 
[lkml]   [1999]   [May]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: Clear reboot?
On Wed, 12 May 1999, David Guo wrote:

> Hi.
> I have add some "feature" in the kernel to remote control it's reboot.
> When someone from a certain host trigger a certain port (like 24) for some times ,
> the machine will reboot, I use machine_restart(NULL), But after reboot the ext2fs
> will have some bad inode or so. Is there any way to do sync before reboot ?
>
Execute this remotely (perhaps making an account called 'reboot' that
uses this as a shell, or executing this as a daemon from the inet
daemon, as a 'service'

/*
Free software from rjohnson@analogic.com
Written by Richard B. Johnson. No Copyright is claimed. It's free.
This software is not guaranteed to do anything useful but:

This version of reboot doesn't require init to be running.
This will run even if you booted the kernel with a shell instead of
init.

You can reboot locally, over the network, or over a wire line.

For an ordinary user to use this, `chmod 4755` is required and the
program file has to be put in a root-owned directory.

Bugs(sorta):

(1) Only "MOUNTS" file systems will be dismounted. Adjust if you
have more than 0x100 mounted file-systems.

(2) This is deliberately statically-linked.

(3) This requires the glibc headers to compile.

*/


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <malloc.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
/* #include <sys/mount.h> */
#include <sys/reboot.h>
#include <sys/stat.h>
#include <dirent.h>
#define INIT 1
#define MOUNTS 0x100
#define NAME_LEN (0x100 * sizeof(char))

#undef umount
#define MNT_FORCE 0x000000001
extern int umount(const char *, int);
extern int mount(const char *, const char *, const char *, int, int);
const char halted[]="\r System halted\n";

int main(int args, char *argv[])
{
int i, j;
FILE *file;
char *mounts[MOUNTS];
char mountp[NAME_LEN];
DIR *dir;
struct dirent *d;
pid_t pid;
pid_t me;
if(args == 1)
puts("Rebooting.....");
else
puts("Shutting down.....");
(void)fflush(stdout);
(void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGWINCH, SIG_IGN);
(void)signal(SIGTERM, SIG_IGN);
(void)signal(SIGTSTP, SIG_IGN); /* In case we are pid 1 */
if((fork()) != 0) exit(0);
memset(argv[0], 0x00, (strlen(argv[0])));
strcpy(argv[0], "Reboot");
(void)setuid(0);
(void)setgid(0);
(void)chdir("/");
if((file = fopen("/proc/mounts", "r")) == NULL)
{
(void) mkdir("/proc", ACCESSPERMS);
(void) mount("proc", "/proc", "proc", 0, 0);
if((file = fopen("/proc/mounts", "r")) == NULL)
{
fprintf(stderr, "Can't read /proc filesystem.");
return 1;
}
}
j = fileno(file);
for(i = 0; i< MOUNTS; i++)
{
if((mounts[i] = (char *) malloc(NAME_LEN)) == NULL)
break;
*mounts[i] = (char ) 0x00;
if((fgets(mounts[i], NAME_LEN, file)) == NULL)
{
free(mounts[i]);
break;
}
}
/*
* Note: 'i' always points beyond the last buffer when we exit the
* above loop even if 'i' is still 0 (no file-systems mounted).
*/
(void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGWINCH, SIG_IGN);
(void)signal(SIGTERM, SIG_IGN);
(void)signal(SIGTSTP, SIG_IGN); /* In case we are pid 1 */
while (j >= 0)
(void)close(j--);
(void)setsid();
(void)sync();
if(open("/dev/console", O_RDWR) != -1)
{
(void)dup(0);
(void)dup(0);
}
me = getpid();
if(me != INIT)
(void)kill(INIT, SIGTSTP); /* Tell init to pause if it exists */
if((dir = opendir("/proc")) != NULL)
{
while((d = readdir(dir)) != NULL)
{
pid = (pid_t) atoi(d->d_name);
if((pid > 1) && (pid != me))
(void)kill(pid, SIGTERM);
}
rewinddir(dir);
(void)sync(); /* Update for killed processes */
(void) sleep(2); /* Let processes die naturally */
while((d = readdir(dir)) != NULL)
{
pid = (pid_t) atoi(d->d_name);
if((pid > 1) && (pid != me))
(void)kill(pid, SIGKILL);
}
(void)closedir(dir);
}
(void)unlink("/etc/mtab~"); /* One of these could exist */
(void)sync(); /* Try to help umount */
while(i-- > 0) /* This logic is correct ! */
{
if((sscanf(mounts[i], "%*s %s", mountp)) == 1)
{
if(umount(mountp, 0) < 0)
(void)umount(mountp, MNT_FORCE);
(void)sleep(1);
}
free(mounts[i]);
}
(void)sleep(5); /* Let Disks get flushed */
if(args > 1)
{
(void)write(0, halted, sizeof(halted));
pause();
}
return (reboot(RB_AUTOBOOT));
}


Cheers,
Dick Johnson
***** FILE SYSTEM WAS MODIFIED *****
Penguin : Linux version 2.2.6 on an i686 machine (400.59 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:51    [from the cache]
©2003-2011 Jasper Spaans