exacct_core.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/exacct_catalog.h>
#include <sys/exacct_impl.h>
#ifndef _KERNEL
#include <limits.h>
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <strings.h>
#else
#endif
/*
* extended accounting file core routines
*
* Routines shared by libexacct and the kernel for the definition,
* construction and packing of extended accounting (exacct) records.
*
* Locking
* All routines in this file use ea_alloc(), which is a malloc() wrapper
* in userland and a kmem_alloc(..., KM_SLEEP) wrapper in the kernel.
* Accordingly, all routines require a context suitable for KM_SLEEP
* allocations.
*/
#define DEFAULT_ENTRIES 4
/*
* ea_alloc() and ea_free() provide a wrapper for the common
* exacct code offering access to either the kmem allocator, or to libc's
* malloc.
*/
void *
{
#ifndef _KERNEL
void *p;
if (p == NULL) {
} else {
}
return (p);
#else
#endif
}
#ifndef _KERNEL
/*ARGSUSED*/
#endif
void
{
#ifndef _KERNEL
#else
#endif
}
/*
* ea_strdup() returns a pointer that, if non-NULL, must be freed using
* ea_strfree() once its useful life ends.
*/
char *
{
/* Sets exacct_errno. */
if (p != NULL) {
}
return (p);
}
/*
* ea_strfree() frees a string allocated with ea_strdup().
*/
void
ea_strfree(char *ptr)
{
#ifndef _KERNEL
#else
#endif
}
/*
* ea_cond_memcpy_at_offset() provides a simple conditional memcpy() that allows
* us to write a pack routine that returns a valid buffer size, copying only in
* the case that a non-NULL buffer is provided.
*/
static void
{
return;
}
/*
* exacct_order{16,32,64}() are byte-swapping routines that place the native
* data indicated by the input pointer in big-endian order. Each exacct_order
* function is its own inverse.
*/
#ifndef _LITTLE_ENDIAN
/*ARGSUSED*/
#endif /* _LITTLE_ENDIAN */
void
{
#ifdef _LITTLE_ENDIAN
uint8_t s;
union {
} t;
s = t.arr[0];
t.arr[1] = s;
#endif /* _LITTLE_ENDIAN */
}
#ifndef _LITTLE_ENDIAN
/*ARGSUSED*/
#endif /* _LITTLE_ENDIAN */
void
{
#ifdef _LITTLE_ENDIAN
uint16_t s;
union {
} t;
exacct_order16(&t.arr[0]);
s = t.arr[0];
t.arr[1] = s;
#endif /* _LITTLE_ENDIAN */
}
#ifndef _LITTLE_ENDIAN
/*ARGSUSED*/
#endif /* _LITTLE_ENDIAN */
void
{
#ifdef _LITTLE_ENDIAN
uint32_t s;
union {
} t;
exacct_order32(&t.arr[0]);
s = t.arr[0];
t.arr[1] = s;
#endif /* _LITTLE_ENDIAN */
}
int
{
#define EM_MATCH(v, m, M) ((m & M) == 0 || (v & M) == (m & M))
}
int
{
return (-1);
}
case EXT_UINT8:
break;
case EXT_UINT16:
break;
case EXT_UINT32:
break;
case EXT_UINT64:
break;
case EXT_DOUBLE:
break;
case EXT_STRING:
/* exacct_errno set above. */
return (-1);
}
break;
case EXT_EXACCT_OBJECT:
/* exacct_errno set above. */
return (-1);
}
break;
case EXT_RAW:
/* exacct_errno set above. */
return (-1);
}
break;
default:
return (-1);
}
return (0);
}
int
{
return (-1);
}
return (0);
}
void
{
case EXT_STRING:
break;
case EXT_RAW:
case EXT_EXACCT_OBJECT:
break;
default:
/* No action required for other types. */
break;
}
}
/* No action required for EO_NONE. */
#ifdef _KERNEL
#else
#endif /* _KERNEL */
}
}
int
{
return (-1);
}
case EXT_STRING:
break;
case EXT_RAW:
case EXT_EXACCT_OBJECT:
break;
default:
/* No action required for other types. */
break;
}
obj->eo_catalog = 0;
return (0);
}
static void
{
}
int
{
return (0);
} else {
return (-1);
}
}
/*
* ea_attach_to_group() takes a group object and an additional exacct object and
* attaches the latter to the object list of the former. The attached exacct
* object can be the head of a chain of objects. If group isn't actually an
* object of type EO_GROUP, do nothing, such that we don't destroy its contents.
*/
int
{
uint_t n = 0;
ea_object_t **nextp;
return (-1);
}
n++;
continue;
return (0);
}
/*
* ea_pack_object takes the given exacct object series beginning with obj and
* places it in buf. Since ea_pack_object needs to be runnable in kernel
* context, we construct it to use its own stack of state. Specifically, we
* store the locations of the sizes of open records (records whose construction
* is in progress). curr_frame is used to indicate the current frame. Just
* prior to decrementing curr_frame, we must ensure that the correct size for
* that frame is placed in the given offset.
*/
struct es_frame {
};
static void
{
int i;
for (i = 0; i <= n; i++) {
}
}
{
int curr_frame = 0;
ea_size_t placeholder = 0;
int end_of_group = 0;
/* exacct_errno set above. */
return ((size_t)-1);
}
/*
* 1. Start with the current object.
*/
for (;;) {
void *src;
/*
* 1a. If at the bottom of the stack, we are done.
* If at the end of a group, place the correct size at the head
* of the chain, the correct backskip amount in the next
* position in the buffer, and retreat to the previous frame.
*/
if (end_of_group) {
if (--curr_frame < 0) {
break;
}
/*
* Note that the large backskip is only 32 bits, whereas
* an object can be up to 2^64 bytes long. If an object
* is greater than 2^32 bytes long set the large
* backskip to 0. This will prevent the file being
* read backwards by causing EOF to be returned when the
* big object is encountered, but reading forwards will
* still be OK as it ignores the large backskip field.
*/
&lge_backskip, sizeof (lge_backskip));
sizeof (uint32_t));
end_of_group = 0;
} else {
continue;
}
}
/*
* 2. Write the catalog tag.
*/
curr_pos += sizeof (ea_catalog_t);
/*
* 2a. If this type is of variable size, reserve space for the
* size field.
*/
case EXT_GROUP:
case EXT_STRING:
case EXT_EXACCT_OBJECT:
case EXT_RAW:
&placeholder, sizeof (ea_size_t));
sizeof (ea_size_t));
break;
default:
break;
}
/*
* 3A. If it's a group put its next pointer, size, and
* size position on the stack, add 1 to the stack,
* set the current object to eg_objs, and goto 1.
*/
/*
* 3Aa. Insert the number of objects in the group.
*/
sizeof (uint32_t));
sizeof (uint32_t));
/*
* 3Ab. Insert a backskip of the appropriate size.
*/
&gp_backskip, sizeof (uint32_t));
sizeof (uint32_t));
curr_frame++;
if (curr_frame >= neframes) {
/*
* Expand the eframe stack to handle the
* requested depth.
*/
struct es_frame *new_estack =
sizeof (struct es_frame));
if (new_estack == NULL) {
sizeof (struct es_frame));
/* exacct_errno set above. */
return ((size_t)-1);
}
sizeof (struct es_frame));
sizeof (struct es_frame));
sizeof (struct es_frame));
estack = new_estack;
} else {
sizeof (struct es_frame));
}
end_of_group = 1;
}
continue;
}
/*
* 3B. Otherwise we're considering an item: add its ei_size to
* all sizes on the stack, and copy its size into position.
*/
case EXT_UINT8:
break;
case EXT_UINT16:
break;
case EXT_UINT32:
break;
case EXT_UINT64:
break;
case EXT_DOUBLE:
size = sizeof (double);
break;
case EXT_STRING:
break;
case EXT_EXACCT_OBJECT:
break;
case EXT_RAW:
break;
case EXT_NONE:
default:
size = 0;
break;
}
/*
* 4. Write the large backskip amount into the buffer.
* See above for note about why this may be set to 0.
*/
&lge_backskip, sizeof (lge_backskip));
case EXT_RAW:
case EXT_STRING:
case EXT_EXACCT_OBJECT:
break;
case EXT_UINT16:
break;
case EXT_UINT32:
break;
case EXT_UINT64:
break;
case EXT_DOUBLE:
break;
default:
break;
}
/*
* 5. If ei_next is NULL, we are at the end of a group.a If
* not, move on to the next item on the list.
*/
end_of_group = 1;
} else {
}
}
return (curr_pos);
}