Exemplo n.º 1
0
int
main(int argc, char *argv[])
{
	int ch;

	while ((ch = getopt(argc, argv, "")) != -1)
		switch(ch) {
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	switch(argc) {
	case 0:
		if (acct(NULL))
			err(1, NULL);
		break;
	case 1:
		if (acct(*argv))
			err(1, "%s", *argv);
		break;
	default:
		usage();
	}
	exit(0);
}
Exemplo n.º 2
0
Arquivo: sh.c Projeto: Ju2ender/c-e
/*
 * 父进程等待子进程终止
 * i为子进程pid,-1表示等待所有子进程
 * t为语法树节点
*/
void pwait(int i, int *t) 
{ 
        int p, e; 
        int s; 

        if(i != 0) 
        for(;;) { 
                times(&timeb); 
                time(timeb.proct); 
                p = wait(&s); 
                if(p == -1)     /* 等待失败 */
                        break; 
                e = s&0177;     /* 保留状态环境 */
                if(mesg[e] != 0) {  /* 子进程异常终止 */
                        if(p != i) { 
                                prn(p); 
                                prs(": "); 
                        } 
                        prs(mesg[e]);   /* 打印对应的消息 */
                        if(s&0200)  /* 内核奔溃 */
                                prs(" -- Core dumped"); 
                } 
                if(e != 0) 
                        err("");    /* 等待正常终止 */
                if(i == p) { 
                        acct(t); 
                        break; 
                } else 
                        acct(0); 
        } 
} 
Exemplo n.º 3
0
Arquivo: acct01.c Projeto: disdi/ltp
static void setup(void)
{
	int fd;

	tst_require_root(NULL);

	tst_tmpdir();

	ltpuser = SAFE_GETPWNAM(cleanup, "nobody");

	fd = SAFE_CREAT(cleanup, TEST_FILE5, 0777);
	SAFE_CLOSE(cleanup, fd);

	if (acct(TEST_FILE5) == -1) {
		if (errno == ENOSYS) {
			tst_brkm(TCONF, cleanup,
				 "BSD process accounting is not configured in "
				 "this kernel");
		} else {
			tst_brkm(TBROK | TERRNO, cleanup, "acct failed unexpectedly");
		}
	}

	/* turn off acct, so we are in a known state */
	if (acct(NULL) == -1) {
		if (errno == ENOSYS) {
			tst_brkm(TCONF, cleanup,
				 "BSD process accounting is not configured in "
				 "this kernel");
		} else {
			tst_brkm(TBROK | TERRNO, cleanup, "acct(NULL) failed");
		}
	}

	/* ELOOP SETTING */
	SAFE_SYMLINK(cleanup, TEST_FILE6, "test_file_eloop2");
	SAFE_SYMLINK(cleanup, "test_file_eloop2", TEST_FILE6);

	/* ENAMETOOLONG SETTING */
	memset(nametoolong, 'a', PATH_MAX+1);

	/* EROFS SETTING */
	tst_mkfs(NULL, device, fstype, NULL);
	SAFE_MKDIR(cleanup, "mntpoint", DIR_MODE);
	if (mount(device, "mntpoint", fstype, 0, NULL) < 0) {
		tst_brkm(TBROK | TERRNO, cleanup,
			 "mount device:%s failed", device);
	}
	mount_flag = 1;
	/* Create a file in the file system, then remount it as read-only */
	fd = SAFE_CREAT(cleanup, TEST_FILE8, 0644);
	SAFE_CLOSE(cleanup, fd);
	if (mount(device, "mntpoint", fstype,
		  MS_REMOUNT | MS_RDONLY, NULL) < 0) {
		tst_brkm(TBROK | TERRNO, cleanup,
			 "mount device:%s failed", device);
	}
	mount_flag = 1;
}
Exemplo n.º 4
0
Arquivo: acct01.c Projeto: heluxie/LTP
static void setup(void)
{
	int fd;

	tst_require_root(NULL);

	check_acct_in_kernel();

	tst_tmpdir();

	ltpuser = SAFE_GETPWNAM(cleanup, "nobody");

	fd = SAFE_CREAT(cleanup, TEST_FILE5, 0777);
	SAFE_CLOSE(cleanup, fd);

	if (acct(TEST_FILE5) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "acct failed unexpectedly");

	/* turn off acct, so we are in a known state */
	if (acct(NULL) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "acct(NULL) failed");

	/* ELOOP SETTING */
	SAFE_SYMLINK(cleanup, TEST_FILE6, "test_file_eloop2");
	SAFE_SYMLINK(cleanup, "test_file_eloop2", TEST_FILE6);

	/* ENAMETOOLONG SETTING */
	memset(nametoolong, 'a', PATH_MAX+1);

	/* EROFS SETTING */
	fs_type = tst_dev_fs_type();
	device = tst_acquire_device(cleanup);

	if (!device)
		tst_brkm(TCONF, cleanup, "Failed to obtain block device");

	tst_mkfs(cleanup, device, fs_type, NULL);
	SAFE_MKDIR(cleanup, "mntpoint", DIR_MODE);
	if (mount(device, "mntpoint", fs_type, 0, NULL) < 0) {
		tst_brkm(TBROK | TERRNO, cleanup,
			 "mount device:%s failed", device);
	}
	mount_flag = 1;

	/* Create a file in the file system, then remount it as read-only */
	fd = SAFE_CREAT(cleanup, TEST_FILE8, 0644);
	SAFE_CLOSE(cleanup, fd);
	if (mount(device, "mntpoint", fs_type,
		  MS_REMOUNT | MS_RDONLY, NULL) < 0) {
		tst_brkm(TBROK | TERRNO, cleanup,
			 "mount device:%s failed", device);
	}
}
Exemplo n.º 5
0
static void bootchart_finish() {
    unlink(LOG_STOPFILE);
    fclose(log_stat);
    fclose(log_disks);
    fclose(log_procs);
    acct(NULL);
}
Exemplo n.º 6
0
Arquivo: acct01.c Projeto: disdi/ltp
static void acct_verify(int i)
{

	if (test_cases[i].setupfunc)
		test_cases[i].setupfunc();

	TEST(acct(test_cases[i].filename));

	if (test_cases[i].cleanfunc)
		test_cases[i].cleanfunc();

	if (TEST_RETURN != -1) {
		tst_resm(TFAIL, "acct(%s) succeeded unexpectedly",
			 test_cases[i].filename);
		return;
	}

	if (TEST_ERRNO == test_cases[i].exp_errno) {
		tst_resm(TPASS | TTERRNO, "acct failed as expected");
	} else {
		tst_resm(TFAIL | TTERRNO,
			 "acct failed unexpectedly; expected: %d - %s",
			 test_cases[i].exp_errno,
			 strerror(test_cases[i].exp_errno));
	}
}
Exemplo n.º 7
0
void  bootchart_finish( void )
{
 //   unlink( LOG_STOPFILE );
    file_buff_done(log_stat);
    file_buff_done(log_disks);
    file_buff_done(log_procs);
    acct(NULL);
}
Exemplo n.º 8
0
static void cleanup(void)
{

	if (acct(NULL) == -1)
		tst_resm(TBROK | TERRNO, "acct(NULL) failed");

	tst_rmdir();
}
Exemplo n.º 9
0
int
main(int argc, char *argv[])
{
	if (acct(RECORD_FILE) < 0)
	{
		perror(RECORD_FILE);
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
Exemplo n.º 10
0
/* called to setup bootcharting */
int   bootchart_init( void )
{
    int  ret;
    char buff[4];
    int  timeout = 0, count = 0;

    buff[0] = 0;
    proc_read( LOG_STARTFILE, buff, sizeof(buff) );
    if (buff[0] != 0) {
        timeout = atoi(buff);
    }
    else {
        /* when running with emulator, androidboot.bootchart=<timeout>
         * might be passed by as kernel parameters to specify the bootchart
         * timeout. this is useful when using -wipe-data since the /data
         * partition is fresh
         */
        char  cmdline[1024];
        char* s;
#define  KERNEL_OPTION  "androidboot.bootchart="
        proc_read( "/proc/cmdline", cmdline, sizeof(cmdline) );
        s = strstr(cmdline, KERNEL_OPTION);
        if (s) {
            s      += sizeof(KERNEL_OPTION)-1;
            timeout = atoi(s);
        }
    }
    if (timeout == 0)
        return 0;

    if (timeout > BOOTCHART_MAX_TIME_SEC)
        timeout = BOOTCHART_MAX_TIME_SEC;

    count = (timeout*1000 + BOOTCHART_POLLING_MS-1)/BOOTCHART_POLLING_MS;

    do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR);
    selinux_android_restorecon(LOG_ROOT, 0);

    file_buff_open(log_stat,  LOG_STAT);
    file_buff_open(log_procs, LOG_PROCS);
    file_buff_open(log_disks, LOG_DISK);

    /* create kernel process accounting file */
    {
        int  fd = open( LOG_ACCT, O_WRONLY|O_CREAT|O_TRUNC,0644);
        if (fd >= 0) {
            close(fd);
            acct( LOG_ACCT );
        }
    }

    log_header();
    return count;
}
Exemplo n.º 11
0
Arquivo: acct01.c Projeto: heluxie/LTP
static void check_acct_in_kernel(void)
{
	/* check if acct is implemented in kernel */
	if (acct(NULL) == -1) {
		if (errno == ENOSYS) {
			tst_brkm(TCONF,
				 NULL, "BSD process accounting is not configured in "
				 "this kernel");
		}
	}
}
int main() {
    InsecureAccount acct(12345, 321.98, "Luke Skywalker");
    acct.deposit(6.23);             /*  Error! No matching function -
           hidden by deposit(double, int). */
    acct.m_Balance += 6.23;         /* Error! Member is protected,
         inaccessible. */
    acct.Account::deposit(6.23);    /* Hidden does not mean
        inaccessible. You can still access hidden public members
        via scope resolution. */
    // ... more client code
    return 0;
}
Exemplo n.º 13
0
Arquivo: acct01.c Projeto: disdi/ltp
static void cleanup(void)
{
	TEST_CLEANUP;

	if (acct(NULL) == -1)
		tst_resm(TBROK | TERRNO, "acct(NULL) failed");
	if (mount_flag && umount("mntpoint") < 0) {
		tst_brkm(TBROK | TERRNO, NULL,
			 "umount device:%s failed", device);
	}

	tst_rmdir();
}
Exemplo n.º 14
0
int
main(int argc, char *argv[])
{
    if (argc > 2 || (argc > 1 && strcmp(argv[1], "--help") == 0))
        usageErr("%s [file]\n", argv[0]);

    if (acct(argv[1]) == -1)
        errExit("acct");

    printf("Process accounting %s\n",
            (argv[1] == NULL) ? "disabled" : "enabled");
    exit(EXIT_SUCCESS);
}
Exemplo n.º 15
0
static int bootchart_init() {
    int timeout = 0;

    std::string start;
    android::base::ReadFileToString(LOG_STARTFILE, &start);
    if (!start.empty()) {
        timeout = atoi(start.c_str());
    } else {
        // When running with emulator, androidboot.bootchart=<timeout>
        // might be passed by as kernel parameters to specify the bootchart
        // timeout. this is useful when using -wipe-data since the /data
        // partition is fresh.
        std::string cmdline;
        const char* s;
        android::base::ReadFileToString("/proc/cmdline", &cmdline);
#define KERNEL_OPTION  "androidboot.bootchart="
        if ((s = strstr(cmdline.c_str(), KERNEL_OPTION)) != NULL) {
            timeout = atoi(s + sizeof(KERNEL_OPTION) - 1);
        }
    }
    if (timeout == 0)
        return 0;

    if (timeout > BOOTCHART_MAX_TIME_SEC)
        timeout = BOOTCHART_MAX_TIME_SEC;

    int count = (timeout*1000 + BOOTCHART_POLLING_MS-1)/BOOTCHART_POLLING_MS;

    log_stat = fopen(LOG_STAT, "we");
    if (log_stat == NULL) {
        return -1;
    }
    log_procs = fopen(LOG_PROCS, "we");
    if (log_procs == NULL) {
        fclose(log_stat);
        return -1;
    }
    log_disks = fopen(LOG_DISK, "we");
    if (log_disks == NULL) {
        fclose(log_stat);
        fclose(log_procs);
        return -1;
    }

    // Create kernel process accounting file.
    close(open(LOG_ACCT, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644));
    acct(LOG_ACCT);

    log_header();
    return count;
}
Exemplo n.º 16
0
void
priv_acct_cleanup(int asroot, int injail, struct test *test)
{

    (void)acct(NULL);
    if (fpath1_initialized) {
        (void)unlink(fpath1);
        fpath1_initialized = 0;
    }
    if (fpath2_initialized) {
        (void)unlink(fpath2);
        fpath2_initialized = 0;
    }
}
Exemplo n.º 17
0
int main(int argc, char *argv[])
{
	struct passwd *pwent;

	setup();

	/* EISDIR */
	if (acct("/") == -1 && errno == EISDIR)
		tst_resm(TPASS, "Failed with EISDIR as expected");
	else
		tst_brkm(TFAIL | TERRNO, cleanup,
			 "didn't fail as expected; expected EISDIR");

	/* EACCES */
	if (acct("/dev/null") == -1 && errno == EACCES)
		tst_resm(TPASS, "Failed with EACCES as expected");
	else
		tst_brkm(TFAIL | TERRNO, cleanup,
			 "didn't fail as expected; expected EACCES");

	/* ENOENT */
	if (acct("/tmp/does/not/exist") == -1 && errno == ENOENT)
		tst_resm(TPASS, "Failed with ENOENT as expected");
	else
		tst_brkm(TBROK | TERRNO, cleanup,
			 "didn't fail as expected; expected ENOENT");

	/* ENOTDIR */
	if (acct("/etc/fstab/") == -1 && errno == ENOTDIR)
		tst_resm(TPASS, "Failed with ENOTDIR as expected");
	else
		tst_brkm(TFAIL | TERRNO, cleanup,
			 "didn't fail as expected; expected ENOTDIR");

	/* EPERM */
	sprintf(tmpbuf, "./%s.%d", TCID, getpid());
	fd = SAFE_CREAT(cleanup, tmpbuf, 0777);
	SAFE_CLOSE(cleanup, fd);

	if (acct(tmpbuf) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "acct failed unexpectedly");

	pwent = SAFE_GETPWNAM(cleanup, "nobody");
	SAFE_SETEUID(cleanup, pwent->pw_uid);

	if (acct(tmpbuf) == -1 && errno == EPERM)
		tst_resm(TPASS, "Failed with EPERM as expected");
	else
		tst_brkm(TBROK | TERRNO, cleanup,
			 "didn't fail as expected; expected EPERM");

	SAFE_SETEUID(cleanup, 0);
	SAFE_UNLINK(cleanup, tmpbuf);

	cleanup();
	tst_exit();
}
Exemplo n.º 18
0
void
priv_acct_noopdisable(int asroot, int injail, struct test *test)
{
    int error;

    error = acct(NULL);
    if (asroot && injail)
        expect("priv_acct_noopdisable(root, jail)", error, -1, EPERM);
    if (asroot && !injail)
        expect("priv_acct_noopdisable(root, !jail)", error, 0, 0);
    if (!asroot && injail)
        expect("priv_acct_noopdisable(!root, jail)", error, -1, EPERM);
    if (!asroot && !injail)
        expect("priv_acct_noopdisable(!root, !jail)", error, -1, EPERM);
}
Exemplo n.º 19
0
void
priv_acct_rotate(int asroot, int injail, struct test *test)
{
    int error;

    error = acct(fpath2);
    if (asroot && injail)
        expect("priv_acct_rotate(root, jail)", error, -1, EPERM);
    if (asroot && !injail)
        expect("priv_acct_rotate(root, !jail)", error, 0, 0);
    if (!asroot && injail)
        expect("priv_acct_rotate(!root, jail)", error, -1, EPERM);
    if (!asroot && !injail)
        expect("priv_acct_rotate(!root, !jail)", error, -1, EPERM);
}
Exemplo n.º 20
0
int
priv_acct_setup(int asroot, int injail, struct test *test)
{
    size_t len;
    int i;

    len = sizeof(i);
    if (sysctlbyname(SYSCTL_NAME, &i, &len, NULL, 0) < 0) {
        warn("priv_acct_setup: sysctlbyname(%s)", SYSCTL_NAME);
        return (-1);
    }
    if (i != 0) {
        warnx("sysctlbyname(%s) indicates accounting configured",
              SYSCTL_NAME);
        return (-1);
    }
    setup_file("priv_acct_setup: fpath1", fpath1, 0, 0, 0666);
    fpath1_initialized = 1;
    setup_file("priv_acct_setup: fpath2", fpath2, 0, 0, 0666);
    fpath2_initialized = 1;

    if (test->t_test_func == priv_acct_enable ||
            test->t_test_func == priv_acct_noopdisable) {
        if (acct(NULL) != 0) {
            warn("priv_acct_setup: acct(NULL)");
            return (-1);
        }
    } else if (test->t_test_func == priv_acct_disable ||
               test->t_test_func == priv_acct_rotate) {
        if (acct(fpath1) != 0) {
            warn("priv_acct_setup: acct(\"%s\")", fpath1);
            return (-1);
        }
    }
    return (0);
}
Exemplo n.º 21
0
Arquivo: acct01.c Projeto: heluxie/LTP
static void cleanup(void)
{
	TEST_CLEANUP;

	if (acct(NULL) == -1)
		tst_resm(TWARN | TERRNO, "acct(NULL) failed");

	if (mount_flag && umount("mntpoint") < 0) {
		tst_resm(TWARN | TERRNO,
			 "umount device:%s failed", device);
	}

	if (device)
		tst_release_device(NULL, device);

	tst_rmdir();
}
Exemplo n.º 22
0
void SailfishPlatform::telepathyResponse(const QString &account, const QString &contact, const QString &text) const
{
    QDBusObjectPath acct(account);
    QVariantMap arg1,arg2;
    arg1.insert("message-type",0);
    arg2.insert("content-type",QString("text/plain"));
    arg2.insert("content",text);
    QDBusReply<QString> res = QDBusConnection::sessionBus().call(
                QDBusMessage::createMethodCall("org.freedesktop.Telepathy.ChannelDispatcher",
                                               "/org/freedesktop/Telepathy/ChannelDispatcher",
                                               "org.freedesktop.Telepathy.ChannelDispatcher.Interface.Messages.DRAFT", "SendMessage")
                << qVariantFromValue(acct) << contact << qVariantFromValue(QList<QVariantMap>({arg1,arg2})) << (quint32)0);
    if (res.isValid()) {
        if (res.value().isEmpty()) {
            qWarning() << "Unable to send response from" << account << "to" << contact << "with" << text;
        } else
            qDebug() << "Sent message under uuid" << res.value();
    } else {
        qWarning() << res.error().message();
    }
}
MetadataItemPropertiesPanel::MetadataItemPropertiesPanel(
    MetadataItemPropertiesFrame* parent, MetadataItem* object)
    : wxPanel(parent, wxID_ANY), pageTypeM(ptSummary), objectM(object),
      htmlReloadRequestedM(false)
{
    wxASSERT(object);
    mipPanels.push_back(this);

    html_window = new PrintableHtmlWindow(this, wxID_ANY);
    parent->SetTitle(object->getName_());

    wxBoxSizer* bSizer2 = new wxBoxSizer( wxVERTICAL );
    bSizer2->Add(html_window, 1, wxEXPAND, 0 );
    SetSizer( bSizer2 );
    Layout();

    wxAcceleratorEntry entries[4];
    entries[0].Set(wxACCEL_CMD, (int) 'W', wxID_CLOSE_FRAME);
    entries[1].Set(wxACCEL_CMD, (int) 'R', wxID_REFRESH);
    // MSW only
    entries[2].Set(wxACCEL_CTRL, WXK_F4, wxID_CLOSE_FRAME);
    entries[3].Set(wxACCEL_NORMAL, WXK_F5, wxID_REFRESH);

    bool isMSW =
        (wxPlatformInfo::Get().GetOperatingSystemId() & wxOS_WINDOWS) != 0;
    wxAcceleratorTable acct(isMSW ? 4 : 2, entries);
    SetAcceleratorTable(acct);

    Connect(wxID_CLOSE_FRAME, wxEVT_COMMAND_MENU_SELECTED,
            wxCommandEventHandler(MetadataItemPropertiesPanel::OnCloseFrame));
    Connect(wxID_ANY, wxEVT_COMMAND_HTML_CELL_HOVER,
            wxHtmlCellEventHandler(MetadataItemPropertiesPanel::OnHtmlCellHover));
    Connect(wxID_REFRESH, wxEVT_COMMAND_MENU_SELECTED,
            wxCommandEventHandler(MetadataItemPropertiesPanel::OnRefresh));

    // request initial rendering
    requestLoadPage(true);
    objectM->attachObserver(this, true);
}
Exemplo n.º 24
0
/* called to setup bootcharting */
void  bootchart_init( void )
{
    int  ret;
    char buff[4];

    do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR);

    file_buff_open(log_stat,  LOG_STAT);
    file_buff_open(log_procs, LOG_PROCS);
    file_buff_open(log_disks, LOG_DISK);

    /* create kernel process accounting file */
    {
        int  fd = open( LOG_ACCT, O_WRONLY|O_CREAT|O_TRUNC,0644);
        if (fd >= 0) {
            close(fd);
            acct( LOG_ACCT );
        }
    }

    log_header();
    gettimeofday(&start_time, 0);
}
Exemplo n.º 25
0
static void setup(void)
{

	/*
	 * XXX: FreeBSD says you must always be superuser, but Linux says you
	 * need to have CAP_SYS_PACCT capability.
	 *
	 * Either way, it's better to do this to test out the EPERM
	 * requirement.
	 */
	tst_require_root(NULL);

	tst_tmpdir();

	/* turn off acct, so we are in a known state */
	if (acct(NULL) == -1) {
		if (errno == ENOSYS)
			tst_brkm(TCONF, cleanup,
				 "BSD process accounting is not configured in this "
				 "kernel");
		else
			tst_brkm(TBROK | TERRNO, cleanup, "acct(NULL) failed");
	}
}
Exemplo n.º 26
0
/*
 * Return value:
 *   1 - exitlwps() failed, call (or continue) lwp_exit()
 *   0 - restarting init.  Return through system call path
 */
int
proc_exit(int why, int what)
{
	kthread_t *t = curthread;
	klwp_t *lwp = ttolwp(t);
	proc_t *p = ttoproc(t);
	zone_t *z = p->p_zone;
	timeout_id_t tmp_id;
	int rv;
	proc_t *q;
	task_t *tk;
	vnode_t *exec_vp, *execdir_vp, *cdir, *rdir;
	sigqueue_t *sqp;
	lwpdir_t *lwpdir;
	uint_t lwpdir_sz;
	tidhash_t *tidhash;
	uint_t tidhash_sz;
	ret_tidhash_t *ret_tidhash;
	refstr_t *cwd;
	hrtime_t hrutime, hrstime;
	int evaporate;

	/*
	 * Stop and discard the process's lwps except for the current one,
	 * unless some other lwp beat us to it.  If exitlwps() fails then
	 * return and the calling lwp will call (or continue in) lwp_exit().
	 */
	proc_is_exiting(p);
	if (exitlwps(0) != 0)
		return (1);

	mutex_enter(&p->p_lock);
	if (p->p_ttime > 0) {
		/*
		 * Account any remaining ticks charged to this process
		 * on its way out.
		 */
		(void) task_cpu_time_incr(p->p_task, p->p_ttime);
		p->p_ttime = 0;
	}
	mutex_exit(&p->p_lock);

	DTRACE_PROC(lwp__exit);
	DTRACE_PROC1(exit, int, why);

	/*
	 * Will perform any brand specific proc exit processing, since this
	 * is always the last lwp, will also perform lwp_exit and free brand
	 * data
	 */
	if (PROC_IS_BRANDED(p)) {
		lwp_detach_brand_hdlrs(lwp);
		brand_clearbrand(p, B_FALSE);
	}

	/*
	 * Don't let init exit unless zone_start_init() failed its exec, or
	 * we are shutting down the zone or the machine.
	 *
	 * Since we are single threaded, we don't need to lock the
	 * following accesses to zone_proc_initpid.
	 */
	if (p->p_pid == z->zone_proc_initpid) {
		if (z->zone_boot_err == 0 &&
		    zone_status_get(z) < ZONE_IS_SHUTTING_DOWN &&
		    zone_status_get(global_zone) < ZONE_IS_SHUTTING_DOWN &&
		    z->zone_restart_init == B_TRUE &&
		    restart_init(what, why) == 0)
			return (0);
		/*
		 * Since we didn't or couldn't restart init, we clear
		 * the zone's init state and proceed with exit
		 * processing.
		 */
		z->zone_proc_initpid = -1;
	}

	lwp_pcb_exit();

	/*
	 * Allocate a sigqueue now, before we grab locks.
	 * It will be given to sigcld(), below.
	 * Special case:  If we will be making the process disappear
	 * without a trace because it is either:
	 *	* an exiting SSYS process, or
	 *	* a posix_spawn() vfork child who requests it,
	 * we don't bother to allocate a useless sigqueue.
	 */
	evaporate = (p->p_flag & SSYS) || ((p->p_flag & SVFORK) &&
	    why == CLD_EXITED && what == _EVAPORATE);
	if (!evaporate)
		sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);

	/*
	 * revoke any doors created by the process.
	 */
	if (p->p_door_list)
		door_exit();

	/*
	 * Release schedctl data structures.
	 */
	if (p->p_pagep)
		schedctl_proc_cleanup();

	/*
	 * make sure all pending kaio has completed.
	 */
	if (p->p_aio)
		aio_cleanup_exit();

	/*
	 * discard the lwpchan cache.
	 */
	if (p->p_lcp != NULL)
		lwpchan_destroy_cache(0);

	/*
	 * Clean up any DTrace helper actions or probes for the process.
	 */
	if (p->p_dtrace_helpers != NULL) {
		ASSERT(dtrace_helpers_cleanup != NULL);
		(*dtrace_helpers_cleanup)();
	}

	/* untimeout the realtime timers */
	if (p->p_itimer != NULL)
		timer_exit();

	if ((tmp_id = p->p_alarmid) != 0) {
		p->p_alarmid = 0;
		(void) untimeout(tmp_id);
	}

	/*
	 * Remove any fpollinfo_t's for this (last) thread from our file
	 * descriptors so closeall() can ASSERT() that they're all gone.
	 */
	pollcleanup();

	if (p->p_rprof_cyclic != CYCLIC_NONE) {
		mutex_enter(&cpu_lock);
		cyclic_remove(p->p_rprof_cyclic);
		mutex_exit(&cpu_lock);
	}

	mutex_enter(&p->p_lock);

	/*
	 * Clean up any DTrace probes associated with this process.
	 */
	if (p->p_dtrace_probes) {
		ASSERT(dtrace_fasttrap_exit_ptr != NULL);
		dtrace_fasttrap_exit_ptr(p);
	}

	while ((tmp_id = p->p_itimerid) != 0) {
		p->p_itimerid = 0;
		mutex_exit(&p->p_lock);
		(void) untimeout(tmp_id);
		mutex_enter(&p->p_lock);
	}

	lwp_cleanup();

	/*
	 * We are about to exit; prevent our resource associations from
	 * being changed.
	 */
	pool_barrier_enter();

	/*
	 * Block the process against /proc now that we have really
	 * acquired p->p_lock (to manipulate p_tlist at least).
	 */
	prbarrier(p);

	sigfillset(&p->p_ignore);
	sigemptyset(&p->p_siginfo);
	sigemptyset(&p->p_sig);
	sigemptyset(&p->p_extsig);
	sigemptyset(&t->t_sig);
	sigemptyset(&t->t_extsig);
	sigemptyset(&p->p_sigmask);
	sigdelq(p, t, 0);
	lwp->lwp_cursig = 0;
	lwp->lwp_extsig = 0;
	p->p_flag &= ~(SKILLED | SEXTKILLED);
	if (lwp->lwp_curinfo) {
		siginfofree(lwp->lwp_curinfo);
		lwp->lwp_curinfo = NULL;
	}

	t->t_proc_flag |= TP_LWPEXIT;
	ASSERT(p->p_lwpcnt == 1 && p->p_zombcnt == 0);
	prlwpexit(t);		/* notify /proc */
	lwp_hash_out(p, t->t_tid);
	prexit(p);

	p->p_lwpcnt = 0;
	p->p_tlist = NULL;
	sigqfree(p);
	term_mstate(t);
	p->p_mterm = gethrtime();

	exec_vp = p->p_exec;
	execdir_vp = p->p_execdir;
	p->p_exec = NULLVP;
	p->p_execdir = NULLVP;
	mutex_exit(&p->p_lock);

	pr_free_watched_pages(p);

	closeall(P_FINFO(p));

	/* Free the controlling tty.  (freectty() always assumes curproc.) */
	ASSERT(p == curproc);
	(void) freectty(B_TRUE);

#if defined(__sparc)
	if (p->p_utraps != NULL)
		utrap_free(p);
#endif
	if (p->p_semacct)			/* IPC semaphore exit */
		semexit(p);
	rv = wstat(why, what);

	acct(rv & 0xff);
	exacct_commit_proc(p, rv);

	/*
	 * Release any resources associated with C2 auditing
	 */
	if (AU_AUDITING()) {
		/*
		 * audit exit system call
		 */
		audit_exit(why, what);
	}

	/*
	 * Free address space.
	 */
	relvm();

	if (exec_vp) {
		/*
		 * Close this executable which has been opened when the process
		 * was created by getproc().
		 */
		(void) VOP_CLOSE(exec_vp, FREAD, 1, (offset_t)0, CRED(), NULL);
		VN_RELE(exec_vp);
	}
	if (execdir_vp)
		VN_RELE(execdir_vp);

	/*
	 * Release held contracts.
	 */
	contract_exit(p);

	/*
	 * Depart our encapsulating process contract.
	 */
	if ((p->p_flag & SSYS) == 0) {
		ASSERT(p->p_ct_process);
		contract_process_exit(p->p_ct_process, p, rv);
	}

	/*
	 * Remove pool association, and block if requested by pool_do_bind.
	 */
	mutex_enter(&p->p_lock);
	ASSERT(p->p_pool->pool_ref > 0);
	atomic_add_32(&p->p_pool->pool_ref, -1);
	p->p_pool = pool_default;
	/*
	 * Now that our address space has been freed and all other threads
	 * in this process have exited, set the PEXITED pool flag.  This
	 * tells the pools subsystems to ignore this process if it was
	 * requested to rebind this process to a new pool.
	 */
	p->p_poolflag |= PEXITED;
	pool_barrier_exit();
	mutex_exit(&p->p_lock);

	mutex_enter(&pidlock);

	/*
	 * Delete this process from the newstate list of its parent. We
	 * will put it in the right place in the sigcld in the end.
	 */
	delete_ns(p->p_parent, p);

	/*
	 * Reassign the orphans to the next of kin.
	 * Don't rearrange init's orphanage.
	 */
	if ((q = p->p_orphan) != NULL && p != proc_init) {

		proc_t *nokp = p->p_nextofkin;

		for (;;) {
			q->p_nextofkin = nokp;
			if (q->p_nextorph == NULL)
				break;
			q = q->p_nextorph;
		}
		q->p_nextorph = nokp->p_orphan;
		nokp->p_orphan = p->p_orphan;
		p->p_orphan = NULL;
	}

	/*
	 * Reassign the children to init.
	 * Don't try to assign init's children to init.
	 */
	if ((q = p->p_child) != NULL && p != proc_init) {
		struct proc	*np;
		struct proc	*initp = proc_init;
		boolean_t	setzonetop = B_FALSE;

		if (!INGLOBALZONE(curproc))
			setzonetop = B_TRUE;

		pgdetach(p);

		do {
			np = q->p_sibling;
			/*
			 * Delete it from its current parent new state
			 * list and add it to init new state list
			 */
			delete_ns(q->p_parent, q);

			q->p_ppid = 1;
			q->p_pidflag &= ~(CLDNOSIGCHLD | CLDWAITPID);
			if (setzonetop) {
				mutex_enter(&q->p_lock);
				q->p_flag |= SZONETOP;
				mutex_exit(&q->p_lock);
			}
			q->p_parent = initp;

			/*
			 * Since q will be the first child,
			 * it will not have a previous sibling.
			 */
			q->p_psibling = NULL;
			if (initp->p_child) {
				initp->p_child->p_psibling = q;
			}
			q->p_sibling = initp->p_child;
			initp->p_child = q;
			if (q->p_proc_flag & P_PR_PTRACE) {
				mutex_enter(&q->p_lock);
				sigtoproc(q, NULL, SIGKILL);
				mutex_exit(&q->p_lock);
			}
			/*
			 * sigcld() will add the child to parents
			 * newstate list.
			 */
			if (q->p_stat == SZOMB)
				sigcld(q, NULL);
		} while ((q = np) != NULL);

		p->p_child = NULL;
		ASSERT(p->p_child_ns == NULL);
	}

	TRACE_1(TR_FAC_PROC, TR_PROC_EXIT, "proc_exit: %p", p);

	mutex_enter(&p->p_lock);
	CL_EXIT(curthread); /* tell the scheduler that curthread is exiting */

	/*
	 * Have our task accummulate our resource usage data before they
	 * become contaminated by p_cacct etc., and before we renounce
	 * membership of the task.
	 *
	 * We do this regardless of whether or not task accounting is active.
	 * This is to avoid having nonsense data reported for this task if
	 * task accounting is subsequently enabled. The overhead is minimal;
	 * by this point, this process has accounted for the usage of all its
	 * LWPs. We nonetheless do the work here, and under the protection of
	 * pidlock, so that the movement of the process's usage to the task
	 * happens at the same time as the removal of the process from the
	 * task, from the point of view of exacct_snapshot_task_usage().
	 */
	exacct_update_task_mstate(p);

	hrutime = mstate_aggr_state(p, LMS_USER);
	hrstime = mstate_aggr_state(p, LMS_SYSTEM);
	p->p_utime = (clock_t)NSEC_TO_TICK(hrutime) + p->p_cutime;
	p->p_stime = (clock_t)NSEC_TO_TICK(hrstime) + p->p_cstime;

	p->p_acct[LMS_USER]	+= p->p_cacct[LMS_USER];
	p->p_acct[LMS_SYSTEM]	+= p->p_cacct[LMS_SYSTEM];
	p->p_acct[LMS_TRAP]	+= p->p_cacct[LMS_TRAP];
	p->p_acct[LMS_TFAULT]	+= p->p_cacct[LMS_TFAULT];
	p->p_acct[LMS_DFAULT]	+= p->p_cacct[LMS_DFAULT];
	p->p_acct[LMS_KFAULT]	+= p->p_cacct[LMS_KFAULT];
	p->p_acct[LMS_USER_LOCK] += p->p_cacct[LMS_USER_LOCK];
	p->p_acct[LMS_SLEEP]	+= p->p_cacct[LMS_SLEEP];
	p->p_acct[LMS_WAIT_CPU]	+= p->p_cacct[LMS_WAIT_CPU];
	p->p_acct[LMS_STOPPED]	+= p->p_cacct[LMS_STOPPED];

	p->p_ru.minflt	+= p->p_cru.minflt;
	p->p_ru.majflt	+= p->p_cru.majflt;
	p->p_ru.nswap	+= p->p_cru.nswap;
	p->p_ru.inblock	+= p->p_cru.inblock;
	p->p_ru.oublock	+= p->p_cru.oublock;
	p->p_ru.msgsnd	+= p->p_cru.msgsnd;
	p->p_ru.msgrcv	+= p->p_cru.msgrcv;
	p->p_ru.nsignals += p->p_cru.nsignals;
	p->p_ru.nvcsw	+= p->p_cru.nvcsw;
	p->p_ru.nivcsw	+= p->p_cru.nivcsw;
	p->p_ru.sysc	+= p->p_cru.sysc;
	p->p_ru.ioch	+= p->p_cru.ioch;

	p->p_stat = SZOMB;
	p->p_proc_flag &= ~P_PR_PTRACE;
	p->p_wdata = what;
	p->p_wcode = (char)why;

	cdir = PTOU(p)->u_cdir;
	rdir = PTOU(p)->u_rdir;
	cwd = PTOU(p)->u_cwd;

	ASSERT(cdir != NULL || p->p_parent == &p0);

	/*
	 * Release resource controls, as they are no longer enforceable.
	 */
	rctl_set_free(p->p_rctls);

	/*
	 * Decrement tk_nlwps counter for our task.max-lwps resource control.
	 * An extended accounting record, if that facility is active, is
	 * scheduled to be written.  We cannot give up task and project
	 * membership at this point because that would allow zombies to escape
	 * from the max-processes resource controls.  Zombies stay in their
	 * current task and project until the process table slot is released
	 * in freeproc().
	 */
	tk = p->p_task;

	mutex_enter(&p->p_zone->zone_nlwps_lock);
	tk->tk_nlwps--;
	tk->tk_proj->kpj_nlwps--;
	p->p_zone->zone_nlwps--;
	mutex_exit(&p->p_zone->zone_nlwps_lock);

	/*
	 * Clear the lwp directory and the lwpid hash table
	 * now that /proc can't bother us any more.
	 * We free the memory below, after dropping p->p_lock.
	 */
	lwpdir = p->p_lwpdir;
	lwpdir_sz = p->p_lwpdir_sz;
	tidhash = p->p_tidhash;
	tidhash_sz = p->p_tidhash_sz;
	ret_tidhash = p->p_ret_tidhash;
	p->p_lwpdir = NULL;
	p->p_lwpfree = NULL;
	p->p_lwpdir_sz = 0;
	p->p_tidhash = NULL;
	p->p_tidhash_sz = 0;
	p->p_ret_tidhash = NULL;

	/*
	 * If the process has context ops installed, call the exit routine
	 * on behalf of this last remaining thread. Normally exitpctx() is
	 * called during thread_exit() or lwp_exit(), but because this is the
	 * last thread in the process, we must call it here. By the time
	 * thread_exit() is called (below), the association with the relevant
	 * process has been lost.
	 *
	 * We also free the context here.
	 */
	if (p->p_pctx) {
		kpreempt_disable();
		exitpctx(p);
		kpreempt_enable();

		freepctx(p, 0);
	}

	/*
	 * curthread's proc pointer is changed to point to the 'sched'
	 * process for the corresponding zone, except in the case when
	 * the exiting process is in fact a zsched instance, in which
	 * case the proc pointer is set to p0.  We do so, so that the
	 * process still points at the right zone when we call the VN_RELE()
	 * below.
	 *
	 * This is because curthread's original proc pointer can be freed as
	 * soon as the child sends a SIGCLD to its parent.  We use zsched so
	 * that for user processes, even in the final moments of death, the
	 * process is still associated with its zone.
	 */
	if (p != t->t_procp->p_zone->zone_zsched)
		t->t_procp = t->t_procp->p_zone->zone_zsched;
	else
		t->t_procp = &p0;

	mutex_exit(&p->p_lock);
	if (!evaporate) {
		p->p_pidflag &= ~CLDPEND;
		sigcld(p, sqp);
	} else {
		/*
		 * Do what sigcld() would do if the disposition
		 * of the SIGCHLD signal were set to be ignored.
		 */
		cv_broadcast(&p->p_srwchan_cv);
		freeproc(p);
	}
	mutex_exit(&pidlock);

	/*
	 * We don't release u_cdir and u_rdir until SZOMB is set.
	 * This protects us against dofusers().
	 */
	if (cdir)
		VN_RELE(cdir);
	if (rdir)
		VN_RELE(rdir);
	if (cwd)
		refstr_rele(cwd);

	/*
	 * task_rele() may ultimately cause the zone to go away (or
	 * may cause the last user process in a zone to go away, which
	 * signals zsched to go away).  So prior to this call, we must
	 * no longer point at zsched.
	 */
	t->t_procp = &p0;

	kmem_free(lwpdir, lwpdir_sz * sizeof (lwpdir_t));
	kmem_free(tidhash, tidhash_sz * sizeof (tidhash_t));
	while (ret_tidhash != NULL) {
		ret_tidhash_t *next = ret_tidhash->rth_next;
		kmem_free(ret_tidhash->rth_tidhash,
		    ret_tidhash->rth_tidhash_sz * sizeof (tidhash_t));
		kmem_free(ret_tidhash, sizeof (*ret_tidhash));
		ret_tidhash = next;
	}

	thread_exit();
	/* NOTREACHED */
}
Exemplo n.º 27
0
int
main(int argc, char *argv[])
{
	int c, i, fd;
	char *ptr;

	i = getdtablesize ();
	for (fd = 3; fd < i; fd++) close (fd);
	if (getpid () == 1)
	{
	    for (fd = 0; fd < 3; fd++) close (fd);
	    while (1) wait (NULL);  /*  Grim reaper never stops  */
	}
	sigsetmask (0); /*  simpleinit(8) blocks all signals: undo for ALRM  */
	for (i = 1; i < NSIG; i++) signal (i, SIG_DFL);

        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);

#ifndef DEBUGGING
	if(setreuid (0, 0)) {
		fprintf(stderr, _("%s: Only root can shut a system down.\n"),
			argv[0]);
		exit(1);
	}
#endif

	if(*argv[0] == '-') argv[0]++;	/* allow shutdown as login shell */
	prog = argv[0];
	if((ptr = strrchr(argv[0], '/'))) prog = ++ptr;

	/* All names (halt, reboot, fasthalt, fastboot, shutdown)
	   refer to the same program with the same options,
	   only the defaults differ. */
	if(!strcmp("halt", prog)) {
		opt_reboot = 0;
		opt_quiet = 1;
		opt_fast = 0;
		timeout = 0;
	} else if(!strcmp("fasthalt", prog)) {
		opt_reboot = 0;
		opt_quiet = 1;
		opt_fast = 1;
		timeout = 0;
	} else if(!strcmp("reboot", prog)) {
		opt_reboot = 1;
		opt_quiet = 1;
		opt_fast = 0;
		timeout = 0;
	} else if(!strcmp("fastboot", prog)) {
		opt_reboot = 1;
		opt_quiet = 1;
		opt_fast = 1;
		timeout = 0;
	} else {
		/* defaults */
		opt_reboot = 0;
		opt_quiet = 0;
		opt_fast = 0;
		timeout = 2*60;
	}
		
	c = 0;
	while(++c < argc) {
		if(argv[c][0] == '-') {
			for(i = 1; argv[c][i]; i++) {
				switch(argv[c][i]) {
				case 'C':
					opt_use_config_file = 1;
					break;
				case 'h': 
					opt_reboot = 0;
					break;
				case 'r':
					opt_reboot = 1;
					break;
				case 'f':
					opt_fast = 1;
					break;
				case 'q':
					opt_quiet = 1;
					break;
				case 's':
					opt_single = 1;
					break;
				    
				default:
					usage();
				}
			}
		} else if(!strcmp("now", argv[c])) {
			timeout = 0;
		} else if(argv[c][0] == '+') {
			timeout = 60 * atoi(&argv[c][1]);
		} else if (isdigit(argv[c][0])) {
			char *colon;
			int hour = 0;
			int minute = 0;
			time_t tics;
			struct tm *tt;
			int now, then;
				
			if((colon = strchr(argv[c], ':'))) {
				*colon = '\0';
				hour = atoi(argv[c]);
				minute = atoi(++colon);
			} else usage();
				
			(void) time(&tics);
			tt = localtime(&tics);
				
			now = 3600 * tt->tm_hour + 60 * tt->tm_min;
			then = 3600 * hour + 60 * minute;
			timeout = then - now;
			if(timeout < 0) {
				fprintf(stderr, _("That must be tomorrow, "
					          "can't you wait till then?\n"));
				exit(1);
			}
		} else {
			xstrncpy(message, argv[c], sizeof(message));
			opt_msgset = 1;
		}
	}

	halt_action[0] = 0;

	/* No doubt we shall want to extend this some day
	   and register a series of commands to be executed
	   at various points during the shutdown sequence,
	   and to define the number of milliseconds to sleep, etc. */
	if (opt_use_config_file) {
		char line[256], *p;
		FILE *fp;

		/*  Read and parse the config file */
		halt_action[0] = '\0';
		if ((fp = fopen (_PATH_SHUTDOWN_CONF, "r")) != NULL) {
			if (fgets (line, sizeof(line), fp) != NULL &&
			    strncasecmp (line, "HALT_ACTION", 11) == 0 &&
			    iswhitespace(line[11])) {
				p = index(line, '\n');
				if (p)
					*p = 0;		/* strip final '\n' */
				p = line+11;
				while(iswhitespace(*p))
					p++;
				strcpy(halt_action, p);
			}
			fclose (fp);
		}
	}

	if(!opt_quiet && !opt_msgset) {
		/* now ask for message, gets() is insecure */
		int cnt = sizeof(message)-1;
		char *ptr;
		
		printf("Why? "); fflush(stdout);
		
		ptr = message;
		while(--cnt >= 0 && (*ptr = getchar()) && *ptr != '\n') { 
			ptr++;
		}
		*ptr = '\0';
	} else if (!opt_msgset) {
		strcpy(message, _("for maintenance; bounce, bounce"));
	}

#ifdef DEBUGGING
	printf(_("timeout = %d, quiet = %d, reboot = %d\n"),
		timeout, opt_quiet, opt_reboot);
#endif
	
	/* so much for option-processing, now begin termination... */
	if(!(whom = getlogin()) || !*whom) whom = "ghost";
	if(strlen(whom) > 40) whom[40] = 0; /* see write_user() */

	setpriority(PRIO_PROCESS, 0, PRIO_MIN);
	signal(SIGINT,  int_handler);
	signal(SIGHUP,  int_handler);
	signal(SIGQUIT, int_handler);
	signal(SIGTERM, int_handler);

	chdir("/");

	if(timeout > 5*60) {
		sleep(timeout - 5*60);
		timeout = 5*60;
	}

	
	if((fd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT, 0644)) >= 0) {
		/* keep xgettext happy and leave \r\n outside strings */
		WRCRLF;
		WR(_("The system is being shut down within 5 minutes"));
		WRCRLF;
		write(fd, message, strlen(message));
		WRCRLF;
		WR(_("Login is therefore prohibited."));
		WRCRLF;
		close(fd);
	}
	
	signal(SIGPIPE, SIG_IGN);

	if(timeout > 0) {
		wall();
		sleep(timeout);
	}

	timeout = 0;
	wall();
	sleep(3);

	/* now there's no turning back... */
	signal(SIGINT,  SIG_IGN);

	/* do syslog message... */
	openlog(prog, LOG_CONS, LOG_AUTH);
	if (opt_reboot)
		syslog(LOG_NOTICE, _("rebooted by %s: %s"), 
		       whom, message);
	else
		syslog(LOG_NOTICE, _("halted by %s: %s"), 
		       whom, message);
	closelog();

	if(opt_fast)
		if((fd = open("/fastboot", O_WRONLY|O_CREAT, 0644)) >= 0)
			close(fd);

	kill(1, SIGTSTP);	/* tell init not to spawn more getty's */
	write_wtmp();
	if(opt_single)
		if((fd = open(_PATH_SINGLE, O_CREAT|O_WRONLY, 0644)) >= 0)
			close(fd);
		
	sync();

	signal(SIGTERM, SIG_IGN);
	if(fork() > 0) sleep(1000); /* the parent will die soon... */
	setpgrp();		/* so the shell wont kill us in the fall */

#ifndef DEBUGGING
	/* a gentle kill of all other processes except init */
	kill_mortals (SIGTERM);
	for (fd = 0; fd < 3; fd++) close (fd);
	stop_finalprog ();
	sleep (1);                    /*  Time for saves to start           */
	kill (1, SIGTERM);            /*  Tell init to kill spawned gettys  */
	usleep (100000);              /*  Wait for gettys to die            */
	my_puts ("");                 /*  Get past the login prompt         */
	system ("/sbin/initctl -r");  /*  Roll back services                */
	syncwait (1);
	my_puts ("Sending SIGTERM to all remaining processes...");
	kill (-1, SIGTERM);
	sleep (2);                    /*  Default 2, some people need 5     */

	kill (-1, SIGKILL);           /*  Now use brute force...            */

	/* turn off accounting */
	acct(NULL);
#endif
	/* RedHat and SuSE like to remove /etc/nologin.
	   Perhaps the usual sequence is
	      touch nologin; shutdown -h; fiddle with hardware;
	      boot; fiddle with software; rm nologin
	   and removing it here will be counterproductive.
	   Let us see whether people complain. */
	unlink(_PATH_NOLOGIN);

	/*  Tell init(8) to exec so that the old inode may be freed cleanly if
	    required. Need to sleep before remounting root read-only  */
	kill (1, SIGQUIT);

	sleep (1);	/* Time for processes to die and close files */
	syncwait (2);

	/* remove swap files and partitions using swapoff */
	swap_off();

	/* unmount disks... */
	unmount_disks();
	syncwait (1);

	if(opt_reboot) {
		my_reboot(LINUX_REBOOT_CMD_RESTART); /* RB_AUTOBOOT */
		my_puts(_("\nWhy am I still alive after reboot?"));
	} else {
		my_puts(_("\nNow you can turn off the power..."));

		/* allow C-A-D now, [email protected], re-fixed 8-Jul-96 */
		my_reboot(LINUX_REBOOT_CMD_CAD_ON); /* RB_ENABLE_CAD */
		sleep (1);  /*  Wait for devices to finish writing to media  */
		do_halt(halt_action);
	}
	/* NOTREACHED */
	exit(0); /* to quiet gcc */
}
Exemplo n.º 28
0
void *linux_bootchart_thread (void *ignored) {
    struct cfgnode *node;
    char *save_to = "/var/log/bootchart.tgz";
    FILE *f;
    char try_acct = 1;
    signed int extra_wait = 0;

    if ((node = cfg_getnode ("configuration-bootchart-extra-waiting-time", NULL)) && node->value) {
        extra_wait = node->value;
    }

    char *buffer_ds = NULL;
    char *buffer_ps = NULL;
    char *buffer_st = NULL;

    while (!shutting_down && (linux_bootchart_have_thread || (extra_wait > 0))) {
        char *uptime = linux_bootchart_get_uptime();

        if (linux_bootchart_process_accounting && try_acct) {
            if (acct ("/dev/kernel_pacct") == -1)
                try_acct = 1;
        }

        if (uptime) {
            buffer_ds = linux_bootchart_update_ds (buffer_ds, uptime);
            buffer_ps = linux_bootchart_update_ps (buffer_ps, uptime);
            buffer_st = linux_bootchart_update_st (buffer_st, uptime);

            free (uptime);
            uptime = NULL;
        }

        usleep (linux_bootchart_sleep_time);
        if (!linux_bootchart_have_thread)
            extra_wait -= linux_bootchart_sleep_time;
    }

    if ((node = cfg_getnode ("configuration-bootchart-save-to", NULL)) && node->svalue) {
        save_to = node->svalue;
    }

    if (coremode & einit_mode_sandbox) {
        save_to = "bootchart.tgz";
    }

    mkdir ("/tmp/bootchart.einit", 0755);

    if (buffer_ds) {
        if ((f = fopen ("/tmp/bootchart.einit/proc_diskstats.log", "w"))) {
            fputs (buffer_ds, f);

            fclose (f);
        }

        free (buffer_ds);
        buffer_ds = NULL;
    }

    if (buffer_ps) {
        if ((f = fopen ("/tmp/bootchart.einit/proc_ps.log", "w"))) {
            fputs (buffer_ps, f);

            fclose (f);
        }

        free (buffer_ps);
        buffer_ps = NULL;
    }

    if (buffer_st) {
        if ((f = fopen ("/tmp/bootchart.einit/proc_stat.log", "w"))) {
            fputs (buffer_st, f);

            fclose (f);
        }

        free (buffer_st);
        buffer_st = NULL;
    }

    if (linux_bootchart_process_accounting) {
        char *r = readfile ("/dev/kernel_pacct");
        if (r) {
            if ((f = fopen ("/tmp/bootchart.einit/kernel_pacct", "w"))) {
                fputs (r, f);

                fclose (f);
            }

            unlink ("/dev/kernel_pacct");
        }

        acct(NULL);
    }

    if ((f = fopen ("/tmp/bootchart.einit/header", "w"))) {
        char *t, buffer[BUFFERSIZE];
        time_t ti = time(NULL);
        /* we're emulating bootchartd-0.8/0.9's format... */
        eputs ("version = 0.8\n", f);

        if (gethostname (buffer, BUFFERSIZE) == 0) {
            eprintf (f, "title = eINIT Boot Chart for %s, %s", buffer, ctime(&ti));
        } else {
            eprintf (f, "title = eINIT Boot Chart, %s", ctime(&ti));
        }

        fprintf (f, "system.uname = %s %s %s %s\n", osinfo.sysname, osinfo.release, osinfo.version, osinfo.machine);

        if ((t = readfile ("/etc/gentoo-release"))) {
            strtrim (t);
            eprintf (f, "system.release = %s\n", t);
            free (t);
        } else {
            eputs ("system.release = unknown\n", f);
        }

        if ((t = readfile ("/proc/cpuinfo"))) {
            char **r = str2set ('\n', t);
            char *n = NULL;
            int i;

            if (r) {
                for (i = 0; r[i]; i++) {
                    if (strstr (r[i], "model name") == r[i]) {
                        n = r[i];
                        break;
                    }
                }

                if (n)
                    eprintf (f, "system.cpu = %s\n", n);
                else
                    eputs ("system.cpu = unknown\n", f);
            }

            free (t);
        } else {
            eputs ("system.cpu = unknown\n", f);
        }

        if ((t = readfile ("/proc/cmdline"))) {
            eprintf (f, "system.kernel.options = %s\n", t);
            free (t);
        }

        fclose (f);
    }

    char buffer[BUFFERSIZE];
    if (coremode & einit_mode_sandbox) {
        esprintf (buffer, BUFFERSIZE, "export pwx=`pwd`; cd /tmp/bootchart.einit; tar czf \"${pwx}/%s\" *", save_to);
    } else {
        esprintf (buffer, BUFFERSIZE, "cd /tmp/bootchart.einit; tar czf %s *", save_to);
    }
    system (buffer);

    unlink_recursive ("/tmp/bootchart.einit/", 1);

    char *di = cfg_getstring ("configuration-bootchart-chart-directory", NULL);
    char *fo = cfg_getstring ("configuration-bootchart-chart-format", NULL);
    esprintf (buffer, BUFFERSIZE, "bootchart -o %s -f %s %s", di, fo, save_to);

    return NULL;
}