Beispiel #1
0
static long
exacct(int code, idtype_t idtype, id_t id, void *buf, size_t bufsize,
    int flags)
{
	if (secpolicy_acct(CRED()) != 0)
		return (set_errno(EPERM));

	if (exacct_zone_key == ZONE_KEY_UNINITIALIZED)
		return (set_errno(ENOTACTIVE));

	switch (code) {
	case 0:
		return (getacct(idtype, id, buf, bufsize));
	case 1:
		return (putacct(idtype, id, buf, bufsize, flags));
	case 2:
		return (wracct(idtype, id, flags));
	default:
		return (set_errno(EINVAL));
	}
}
Beispiel #2
0
/*
 * Perform process accounting functions.
 */
int
sysacct(char *fname)
{
	struct acct_globals *ag;
	struct vnode *vp;
	int error = 0;

	if (secpolicy_acct(CRED()) != 0)
		return (set_errno(EPERM));

	ag = zone_getspecific(acct_zone_key, curproc->p_zone);
	ASSERT(ag != NULL);

	if (fname == NULL) {
		/*
		 * Close the file and stop accounting.
		 */
		mutex_enter(&ag->aclock);
		vp = ag->acctvp;
		ag->acctvp = NULL;
		mutex_exit(&ag->aclock);
		if (vp) {
			error = VOP_CLOSE(vp, FWRITE, 1, (offset_t)0, CRED(),
			    NULL);
			VN_RELE(vp);
		}
		return (error == 0 ? 0 : set_errno(error));
	}

	/*
	 * Either (a) open a new file and begin accounting -or- (b)
	 * switch accounting from an old to a new file.
	 *
	 * (Open the file without holding aclock in case it
	 * sleeps (holding the lock prevents process exit).)
	 */
	if ((error = vn_open(fname, UIO_USERSPACE, FWRITE,
	    0, &vp, (enum create)0, 0)) != 0) {
		/* SVID  compliance */
		if (error == EISDIR)
			error = EACCES;
		return (set_errno(error));
	}

	if (vp->v_type != VREG) {
		error = EACCES;
	} else {
		mutex_enter(&acct_list_lock);
		if (acct_find(vp, B_FALSE)) {
			error = EBUSY;
		} else {
			mutex_enter(&ag->aclock);
			if (ag->acctvp) {
				vnode_t *oldvp;

				/*
				 * close old acctvp, and point acct()
				 * at new file by swapping vp and acctvp
				 */
				oldvp = ag->acctvp;
				ag->acctvp = vp;
				vp = oldvp;
			} else {
				/*
				 * no existing file, start accounting ..
				 */
				ag->acctvp = vp;
				vp = NULL;
			}
			mutex_exit(&ag->aclock);
		}
		mutex_exit(&acct_list_lock);
	}

	if (vp) {
		(void) VOP_CLOSE(vp, FWRITE, 1, (offset_t)0, CRED(), NULL);
		VN_RELE(vp);
	}
	return (error == 0 ? 0 : set_errno(error));
}