/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/sysmacros.h>
#include <sys/pathname.h>
/*
* acctctl(2)
*
* acctctl() provides the administrative interface to the extended accounting
* subsystem. The process and task accounting facilities are configurable:
* resources can be individually specified for recording in the appropriate
* accounting file.
*
* The current implementation of acctctl() requires that the process and task
* and flow files be distinct across all zones.
*
* Locking
* Each accounting species has an ac_info_t which contains a mutex,
* used to protect the ac_info_t's contents, and to serialize access to the
* appropriate file.
*/
static int
{
int state;
return (EINVAL);
return (EFAULT);
return (EINVAL);
return (0);
}
static int
{
return (EINVAL);
return (EFAULT);
}
return (0);
}
static boolean_t
{
return (B_FALSE);
/*
* Start off by grabbing all locks.
*/
}
/*
* We need to verify that we aren't already using this file for
* accounting in any zone.
*/
}
/*
* Drop all locks.
*/
}
return (in_use);
}
static int
{
int error = 0;
void *kbuf;
void *namebuf;
int namelen;
void *hdr;
/*
* Closing accounting file
*/
if (error) {
return (error);
}
}
}
return (error);
}
return (EINVAL);
/*
* We have to copy in the whole buffer since we can't tell the length
* of the string in user's address space.
*/
return (error);
}
if (*((char *)kbuf) != '/') {
return (EINVAL);
}
/*
* Now, allocate the space where we are going to save the
* name of the accounting file and kmem_free kbuf. We have to do this
* now because it is not good to sleep in kmem_alloc() while
* holding ac_info's lock.
*/
/*
* Check if this file already exists.
*/
/*
* Check if the file is already in use.
*/
if (!error) {
if (ac_file_in_use(vp)) {
/*
* If we're already using it then return EBUSY
*/
return (EBUSY);
}
}
/*
* Create an exacct header here because exacct_create_header() may
* sleep so we should not be holding ac_lock. At this point we cannot
* reliably know if we need the header or not, so we may end up not
* using the header.
*/
/*
* Now, grab info's ac_lock and try to set up everything.
*/
return (error);
}
return (EACCES);
}
/*
* Switch from an old file to a new file by swapping
* their vnode pointers.
*/
} else {
/*
* Start writing accounting records to a new file.
*/
}
if (vp) {
/*
* We still need to close the old file.
*/
return (error);
}
}
}
/*
* Write the exacct header only if the file is empty.
*/
return (error);
}
static int
{
int error = 0;
char *file;
return (ENOTACTIVE);
}
else
return (error);
}
static int
{
int id;
/*
* Validate that a non-zero buffer, sized within limits and to an
* integral number of ac_res_t's has been specified.
*/
if (bufsz == 0 ||
return (EINVAL);
return (EFAULT);
}
return (EINVAL);
}
} else {
return (EINVAL);
}
tmp++;
counter++;
}
return (0);
}
static int
{
int error = 0;
int id;
return (EINVAL);
tmp++;
}
return (error);
}
/*
* acctctl()
*
* Overview
* acctctl() is the entry point for the acctctl(2) system call.
*
* Return values
* On successful completion, return 0; otherwise -1 is returned and errno is
* set appropriately.
*
* Caller's context
* Called from the system call path.
*/
int
{
int error = 0;
int maxres;
/*
* exacct_zone_key and associated per-zone state were initialized when
* the module was loaded.
*/
switch (mode) { /* sanity check */
case AC_TASK:
break;
case AC_PROC:
break;
/*
* zones, but we have this field on a per-zone basis for future
* expansion as well as the ability to return default "unset"
* values for the various AC_*_GET queries. AC_*_SET commands
* fail with EPERM for AC_FLOW and AC_NET in non-global zones.
*/
case AC_FLOW:
break;
case AC_NET:
break;
default:
}
switch (option) {
case AC_STATE_SET:
break;
getzoneid() != GLOBAL_ZONEID) {
break;
}
break;
case AC_STATE_GET:
break;
case AC_FILE_SET:
break;
getzoneid() != GLOBAL_ZONEID) {
break;
}
break;
case AC_FILE_GET:
break;
case AC_RES_SET:
break;
getzoneid() != GLOBAL_ZONEID) {
break;
}
break;
case AC_RES_GET:
break;
default:
}
if (error)
return (0);
}
3,
};
"acctctl system call",
};
#ifdef _SYSCALL32_IMPL
"32-bit acctctl system call",
};
#endif
&modlsys,
#ifdef _SYSCALL32_IMPL
#endif
};
/* ARGSUSED */
static void *
{
return (acg);
}
static void
{
}
}
/* ARGSUSED */
static void
{
/*
* The accounting files need to be closed during shutdown rather than
* destroy, since otherwise the filesystem they reside on may fail to
*/
}
/* ARGSUSED */
static void
{
}
int
_init()
{
int error;
(void) zone_key_delete(exacct_zone_key);
}
return (error);
}
int
{
}
int
_fini()
{
return (EBUSY);
}