int main(int argc, char *argv[]) { if (getpid() == 1) { setenv("PATH", "/bin:/usr/local/bin:/usr/bin:/mnt/bin", 1); setenv("HOME", "/root", 1); struct sigaction sa; sa.sa_sigaction = on_signal; sa.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &sa, NULL) != 0) { perror("sigaction SIGINT"); return 1; }; if (sigaction(SIGCHLD, &sa, NULL) != 0) { perror("sigaction SIGCHLD"); return 1; }; if (sigaction(SIGTERM, &sa, NULL) != 0) { perror("sigaction SIGTERM"); return 1; }; if (sigaction(SIGHUP, &sa, NULL) != 0) // SIGHUP is sent when the power button is pressed { perror("sigaction SIGHUP"); return 1; }; loadmods(); printf("init: initializing partitions...\n"); init_parts(); printf("init: loading configuration file /initrd/startup.conf...\n"); if (load_config("/initrd/startup.conf") == -1) { printf("init: attempting startup with fallback configuration file /initrd/startup-fallback.conf...\n"); if (load_config("/initrd/startup-fallback.conf") == -1) { printf("init: failed to start up\n"); }; }; /* if (_glidix_mount("isofs", "/dev/sdb", "/mnt/", 0) != 0) { perror("init: mount failed"); }; close(open("/dev/sda", O_RDONLY)); if (_glidix_mount("gxfs", "/dev/sda0", "/", 0) != 0) { perror("init: mount gxfs on /"); }; */ /* if (fork() == 0) { setenv("PATH", "/bin:/usr/local/bin:/usr/bin:/mnt/bin", 1); setenv("HOME", "/root", 1); if (execl("/mnt/bin/sh", "sh", NULL) != 0) { perror("exec"); exit(1); }; }; */ while (1) { pause(); if (shouldHalt) { sa.sa_handler = SIG_DFL; if (sigaction(SIGCHLD, &sa, NULL) != 0) { perror("sigaction SIGCHLD"); return 1; }; int fd = open("/etc/down-action", O_RDONLY); char downAction[256]; memset(downAction, 0, 256); read(fd, downAction, 16); close(fd); int action = _GLIDIX_DOWN_HALT; if (strcmp(downAction, "poweroff") == 0) { action = _GLIDIX_DOWN_POWEROFF; } else if (strcmp(downAction, "reboot") == 0) { action = _GLIDIX_DOWN_REBOOT; }; _glidix_down(action); } else if ((shouldRunPoweroff) && (!ranPoweroff)) { ranPoweroff = 1; if (fork() == 0) { if (execl("/usr/bin/halt", "poweroff", NULL) == -1) { perror("exec poweroff"); fprintf(stderr, "forcing shutdown\n"); kill(1, SIGTERM); exit(1); }; }; }; }; } else { fprintf(stderr, "%s: not allowed to execute with pid other than 1!\n", argv[0]); return 1; }; return 0; };
void shutdownSystem(int action) { struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = onShutdownAlarm; sigaction(SIGALRM, &sa, NULL); printf("init: asking remaining processes to terminate...\n"); while (killNextProcess() == 0); printf("init: closing my remaining files...\n"); int fd; for (fd=3; fd<sysconf(_SC_OPEN_MAX); fd++) { close(fd); }; printf("init: unmounting filesystems...\n"); struct fsinfo currentFSList[256]; chdir("/"); chroot("rootfs"); size_t count = _glidix_fsinfo(currentFSList, 256); chroot("."); int i; for (i=count-1; i>=0; i--) { char actual_mntpoint[512]; sprintf(actual_mntpoint, "/rootfs/%s", currentFSList[i].fs_mntpoint); printf("init: unmount %s\n", actual_mntpoint); if (unmount(actual_mntpoint, 0) != 0) { printf("init: failed to unmount %s: %s\n", currentFSList[i].fs_mntpoint, strerror(errno)); printf("init: waiting 5 seconds and skipping this filesystem\n"); sleep(5); }; }; printf("init: removing all kernel modules...\n"); struct modstat ms; for (i=0; i<512; i++) { if (modstat(i, &ms) == 0) { if (rmmod(ms.mod_name, 0) != 0) { printf("init: failed to rmmod %s: %s\n", ms.mod_name, strerror(errno)); printf("Report this problem to the module developer.\n"); printf("I will now hang, you may turn off power manually.\n"); printf("If the problem persists, remove the module for your safety.\n"); while (1) pause(); }; }; }; printf("init: bringing the system down...\n"); _glidix_down(action); };