Messages in this thread | | | Date | Wed, 12 May 1999 08:09:20 -0400 (EDT) | From | "Richard B. Johnson" <> | Subject | Re: 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/
| |