Exemplo n.º 1
0
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;
};
Exemplo n.º 2
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);
};