MIB: initial tree population
Change-Id: I28ef0a81a59faaf341bfc15178df89474779a136
This commit is contained in:
parent
1b75f6357e
commit
25d39513e7
@ -4,7 +4,7 @@
|
||||
#include <minix/timers.h>
|
||||
|
||||
/* First minor numbers for the various classes of TTY devices. */
|
||||
#define CONS_MINOR 0
|
||||
/* CONS_MINOR is defined in minix/dmap.h */
|
||||
#define LOG_MINOR 15
|
||||
#define RS232_MINOR 16
|
||||
#define VIDEO_MINOR 125
|
||||
|
@ -3,7 +3,8 @@
|
||||
|
||||
/* Minix release and version numbers. */
|
||||
#define OS_NAME "Minix"
|
||||
#define OS_RELEASE "3.3.0"
|
||||
#define OS_RELEASE "3.3.0" /* 3.m.p */
|
||||
#define OS_REV 303000000 /* see NetBSD sys/param.h: 3mm00pp00 */
|
||||
#define OS_CONFIG "GENERIC"
|
||||
#define OS_VERSION OS_NAME " " OS_RELEASE " (" OS_CONFIG ")"
|
||||
|
||||
|
@ -91,6 +91,9 @@
|
||||
# define IMGRD_DEV 6 /* minor device for /dev/imgrd */
|
||||
# define RAM_DEV_FIRST 7 /* first minor device for /dev/ram* */
|
||||
|
||||
/* Minor device numbers for the TTY driver. */
|
||||
# define CONS_MINOR 0 /* console device */
|
||||
|
||||
#define CTRLR(n) ((n)==0 ? 3 : (8 + 2*((n)-1))) /* magic formula */
|
||||
|
||||
/* Minor device numbers for log driver. */
|
||||
|
@ -288,7 +288,7 @@ CLEANFILES+= ${f:C/\.o/.bc/}
|
||||
init.o kernel_utils.o link.o loadname.o lseek.o _mcontext.o mknod.o \
|
||||
mmap.o nanosleep.o open.o pread.o pwrite.o read.o sbrk.o \
|
||||
select.o setuid.o sigprocmask.o stack_utils.o stat.o stime.o \
|
||||
syscall.o _ucontext.o umask.o unlink.o wait4.o write.o \
|
||||
svrctl.o syscall.o _ucontext.o umask.o unlink.o wait4.o write.o \
|
||||
kill.o
|
||||
${f} ${f:C/\.o/.bc/}: ${LIBMINIXCDIR}/sys/${f:C/\.o/.c/}
|
||||
OBJS+= ${f}
|
||||
|
@ -13,9 +13,12 @@ getuptime(clock_t * uptime, clock_t * realtime, time_t * boottime)
|
||||
minix_kerninfo = get_minix_kerninfo();
|
||||
|
||||
/* We assume atomic 32-bit field retrieval. TODO: 64-bit support. */
|
||||
*uptime = minix_kerninfo->kclockinfo->uptime;
|
||||
*realtime = minix_kerninfo->kclockinfo->realtime;
|
||||
*boottime = minix_kerninfo->kclockinfo->boottime;
|
||||
if (uptime != NULL)
|
||||
*uptime = minix_kerninfo->kclockinfo->uptime;
|
||||
if (realtime != NULL)
|
||||
*realtime = minix_kerninfo->kclockinfo->realtime;
|
||||
if (boottime != NULL)
|
||||
*boottime = minix_kerninfo->kclockinfo->boottime;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
# Makefile for the Management Information Base (MIB) server
|
||||
|
||||
PROG= mib
|
||||
SRCS= main.c tree.c kern.c minix.c
|
||||
SRCS= main.c tree.c kern.c vm.c hw.c proc.c minix.c
|
||||
|
||||
CPPFLAGS+= -I${NETBSDSRCDIR}/minix
|
||||
|
||||
DPADD+= ${LIBSYS}
|
||||
LDADD+= -lsys
|
||||
|
140
minix/servers/mib/hw.c
Normal file
140
minix/servers/mib/hw.c
Normal file
@ -0,0 +1,140 @@
|
||||
/* MIB service - hw.c - implementation of the CTL_HW subtree */
|
||||
|
||||
#include "mib.h"
|
||||
|
||||
#if defined(__i386__)
|
||||
static const char mach[] = "i386"; /* machine (cpu) type */
|
||||
static const char arch[] = "i386"; /* architecture */
|
||||
#elif defined(__arm__)
|
||||
static const char mach[] = "evbarm"; /* machine (cpu) type */
|
||||
static const char arch[] = "evbarm"; /* architecture */
|
||||
#else
|
||||
#error "unknown machine architecture"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Implementation of CTL_HW HW_PHYSMEM/HW_PHYSMEM64.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_hw_physmem(struct mib_call * call __unused, struct mib_node * node,
|
||||
struct mib_oldp * oldp, struct mib_newp * newp __unused)
|
||||
{
|
||||
struct vm_stats_info vsi;
|
||||
u_quad_t physmem64;
|
||||
unsigned int physmem;
|
||||
|
||||
if (vm_info_stats(&vsi) != OK)
|
||||
return EINVAL;
|
||||
|
||||
physmem64 = (u_quad_t)vsi.vsi_total * vsi.vsi_pagesize;
|
||||
|
||||
if (node->node_size == sizeof(int)) {
|
||||
if (physmem64 > UINT_MAX)
|
||||
physmem = UINT_MAX;
|
||||
else
|
||||
physmem = (unsigned int)physmem64;
|
||||
|
||||
return mib_copyout(oldp, 0, &physmem, sizeof(physmem));
|
||||
} else
|
||||
return mib_copyout(oldp, 0, &physmem64, sizeof(physmem64));
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_HW HW_USERMEM/HW_USERMEM64.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_hw_usermem(struct mib_call * call __unused, struct mib_node * node,
|
||||
struct mib_oldp * oldp, struct mib_newp * newp __unused)
|
||||
{
|
||||
struct vm_stats_info vsi;
|
||||
struct vm_usage_info vui;
|
||||
u_quad_t usermem64;
|
||||
unsigned int usermem;
|
||||
|
||||
if (vm_info_stats(&vsi) != OK)
|
||||
return EINVAL;
|
||||
|
||||
usermem64 = (u_quad_t)vsi.vsi_total * vsi.vsi_pagesize;
|
||||
|
||||
if (vm_info_usage(KERNEL, &vui) != OK)
|
||||
return EINVAL;
|
||||
|
||||
if (usermem64 >= vui.vui_total)
|
||||
usermem64 -= vui.vui_total;
|
||||
else
|
||||
usermem64 = 0;
|
||||
|
||||
if (node->node_size == sizeof(int)) {
|
||||
if (usermem64 > UINT_MAX)
|
||||
usermem = UINT_MAX;
|
||||
else
|
||||
usermem = (unsigned int)usermem64;
|
||||
|
||||
return mib_copyout(oldp, 0, &usermem, sizeof(usermem));
|
||||
} else
|
||||
return mib_copyout(oldp, 0, &usermem64, sizeof(usermem64));
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_HW HW_NCPUONLINE.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_hw_ncpuonline(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
struct machine machine;
|
||||
int ncpuonline;
|
||||
|
||||
if (sys_getmachine(&machine) != OK)
|
||||
return EINVAL;
|
||||
|
||||
ncpuonline = machine.processors_count;
|
||||
|
||||
return mib_copyout(oldp, 0, &ncpuonline, sizeof(ncpuonline));
|
||||
}
|
||||
|
||||
/* The CTL_HW nodes. */
|
||||
static struct mib_node mib_hw_table[] = {
|
||||
/* 1*/ [HW_MACHINE] = MIB_STRING(_P | _RO, mach, "machine",
|
||||
"Machine class"),
|
||||
/* 2*/ /* HW_MODEL: not yet supported */
|
||||
/* 3*/ [HW_NCPU] = MIB_INT(_P | _RO, CONFIG_MAX_CPUS,
|
||||
"ncpu", "Number of CPUs configured"),
|
||||
/* 4*/ [HW_BYTEORDER] = MIB_INT(_P | _RO, BYTE_ORDER, "byteorder",
|
||||
"System byte order"),
|
||||
/* 5*/ [HW_PHYSMEM] = MIB_FUNC(_P | _RO | CTLFLAG_UNSIGNED |
|
||||
CTLTYPE_INT, sizeof(int), mib_hw_physmem,
|
||||
"physmem", "Bytes of physical memory"),
|
||||
/* 6*/ [HW_USERMEM] = MIB_FUNC(_P | _RO | CTLFLAG_UNSIGNED |
|
||||
CTLTYPE_INT, sizeof(int), mib_hw_usermem,
|
||||
"usermem", "Bytes of non-kernel memory"),
|
||||
/* 7*/ [HW_PAGESIZE] = MIB_INT(_P | _RO, PAGE_SIZE, "pagesize",
|
||||
"Software page size"),
|
||||
/* 8*/ /* HW_DISKNAMES: not yet supported */
|
||||
/* 9*/ /* HW_IOSTATS: not yet supported */
|
||||
/*10*/ [HW_MACHINE_ARCH] = MIB_STRING(_P | _RO, arch, "machine_arch",
|
||||
"Machine CPU class"),
|
||||
/*11*/ /* HW_ALIGNBYTES: not yet supported */
|
||||
/*12*/ /* HW_CNMAGIC: not yet supported */
|
||||
/*13*/ [HW_PHYSMEM64] = MIB_FUNC(_P | _RO | CTLTYPE_QUAD,
|
||||
sizeof(u_quad_t), mib_hw_physmem,
|
||||
"physmem64", "Bytes of physical memory"),
|
||||
/*14*/ [HW_USERMEM64] = MIB_FUNC(_P | _RO | CTLTYPE_QUAD,
|
||||
sizeof(u_quad_t), mib_hw_usermem,
|
||||
"usermem64", "Bytes of non-kernel memory"),
|
||||
/*15*/ /* HW_IOSTATNAMES: not yet supported */
|
||||
/*16*/ [HW_NCPUONLINE] = MIB_FUNC(_P | _RO | CTLTYPE_INT, sizeof(int),
|
||||
mib_hw_ncpuonline, "ncpuonline",
|
||||
"Number of CPUs online"),
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the CTL_HW subtree.
|
||||
*/
|
||||
void
|
||||
mib_hw_init(struct mib_node * node)
|
||||
{
|
||||
|
||||
MIB_INIT_ENODE(node, mib_hw_table);
|
||||
}
|
@ -2,10 +2,486 @@
|
||||
|
||||
#include "mib.h"
|
||||
|
||||
#include <sys/svrctl.h>
|
||||
#include <minix/sysinfo.h>
|
||||
#include <machine/partition.h>
|
||||
|
||||
#include "servers/vfs/const.h"
|
||||
#include "servers/vfs/dmap.h"
|
||||
|
||||
static char hostname[MAXHOSTNAMELEN], domainname[MAXHOSTNAMELEN];
|
||||
|
||||
/*
|
||||
* Verification for CTL_KERN KERN_SECURELVL.
|
||||
*/
|
||||
static int
|
||||
mib_kern_securelvl(struct mib_call * call __unused, struct mib_node * node,
|
||||
void * ptr, size_t size __unused)
|
||||
{
|
||||
int v;
|
||||
|
||||
memcpy(&v, ptr, sizeof(v));
|
||||
|
||||
/*
|
||||
* Only ever allow the security level to be increased. This is a mock
|
||||
* implementation. TODO: implement actual support for security levels.
|
||||
*/
|
||||
return (v >= node->node_int);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_CLOCKRATE.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_clockrate(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
struct clockinfo clockinfo;
|
||||
|
||||
memset(&clockinfo, 0, sizeof(clockinfo));
|
||||
|
||||
clockinfo.hz = sys_hz();
|
||||
clockinfo.tick = 1000000 / clockinfo.hz;
|
||||
clockinfo.profhz = clockinfo.hz;
|
||||
clockinfo.stathz = clockinfo.hz;
|
||||
|
||||
/*
|
||||
* Number of microseconds that can be corrected per clock tick through
|
||||
* adjtime(2). The kernel allows correction of one clock tick per
|
||||
* clock tick, which means it should be the same as .tick.. I think.
|
||||
* TODO: get this from the kernel itself.
|
||||
*/
|
||||
clockinfo.tickadj = clockinfo.tick;
|
||||
|
||||
return mib_copyout(oldp, 0, &clockinfo, sizeof(clockinfo));
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_PROFILING.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_profiling(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp __unused,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
|
||||
/* As per sysctl(7). We have a different profiling API. */
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_HARDCLOCK_TICKS.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_hardclock_ticks(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
int uptime;
|
||||
|
||||
/*
|
||||
* The number of hardclock (hardware clock driver) ticks is what we
|
||||
* call the number of monotonic clock ticks AKA the uptime clock ticks.
|
||||
*/
|
||||
uptime = (int)getticks();
|
||||
|
||||
return mib_copyout(oldp, 0, &uptime, sizeof(uptime));
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_ROOT_DEVICE.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_root_device(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
char name[PATH_MAX];
|
||||
struct sysgetenv sysgetenv;
|
||||
|
||||
sysgetenv.key = __UNCONST("rootdevname");
|
||||
sysgetenv.keylen = strlen(sysgetenv.key) + 1;
|
||||
sysgetenv.val = name;
|
||||
sysgetenv.vallen = sizeof(name);
|
||||
|
||||
if (svrctl(PMGETPARAM, &sysgetenv) != 0)
|
||||
return EINVAL;
|
||||
|
||||
name[MIN(sysgetenv.vallen, sizeof(name) - 1)] = '\0';
|
||||
|
||||
return mib_copyout(oldp, 0, name, strlen(name) + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_CCPU.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_ccpu(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
int ccpu;
|
||||
|
||||
ccpu = (int)cpuavg_getccpu();
|
||||
|
||||
return mib_copyout(oldp, 0, &ccpu, sizeof(ccpu));
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_CP_TIME.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_cp_time(struct mib_call * call, struct mib_node * node __unused,
|
||||
struct mib_oldp * oldp, struct mib_newp * newp __unused)
|
||||
{
|
||||
uint64_t ticks[MINIX_CPUSTATES], sum[MINIX_CPUSTATES];
|
||||
unsigned int cpu;
|
||||
int i, r, do_sum;
|
||||
|
||||
/*
|
||||
* If a subnode is provided, it identifies the CPU number for which to
|
||||
* return information. If no subnode is provided, but a size is given
|
||||
* that allows returning information for all CPUs, return information
|
||||
* for all of them in an array. If no such size is given either,
|
||||
* return a summation of all CPU statistics. Both we and the kernel
|
||||
* are considering the number of configured CPUs (hw.ncpu).
|
||||
*/
|
||||
if (call->call_namelen > 1)
|
||||
return EINVAL;
|
||||
|
||||
if (call->call_namelen == 1) {
|
||||
/* Do not bother saving on this call if oldp is NULL. */
|
||||
if ((r = sys_getcputicks(ticks, call->call_name[0])) != OK)
|
||||
return r;
|
||||
|
||||
return mib_copyout(oldp, 0, ticks, sizeof(ticks));
|
||||
}
|
||||
|
||||
if (oldp == NULL)
|
||||
return sizeof(ticks); /* implying a summation request */
|
||||
|
||||
do_sum = (mib_getoldlen(oldp) == sizeof(ticks));
|
||||
|
||||
if (do_sum)
|
||||
memset(&sum, 0, sizeof(sum));
|
||||
|
||||
for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) {
|
||||
if ((r = sys_getcputicks(ticks, cpu)) != OK)
|
||||
return r;
|
||||
|
||||
if (do_sum) {
|
||||
for (i = 0; i < MINIX_CPUSTATES; i++)
|
||||
sum[i] += ticks[i];
|
||||
} else {
|
||||
if ((r = mib_copyout(oldp, cpu * sizeof(ticks), ticks,
|
||||
sizeof(ticks))) < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_sum)
|
||||
return mib_copyout(oldp, 0, sum, sizeof(sum));
|
||||
else
|
||||
return cpu * sizeof(ticks);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_CONSDEV.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_consdev(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
dev_t dev;
|
||||
|
||||
dev = makedev(TTY_MAJOR, CONS_MINOR);
|
||||
|
||||
/* No support for legacy 32-bit requests. */
|
||||
return mib_copyout(oldp, 0, &dev, sizeof(dev));
|
||||
}
|
||||
|
||||
/*
|
||||
* Verification for CTL_KERN KERN_FORKFSLEEP.
|
||||
*/
|
||||
static int
|
||||
mib_kern_forkfsleep(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, void * ptr, size_t size __unused)
|
||||
{
|
||||
int v;
|
||||
|
||||
memcpy(&v, ptr, sizeof(v));
|
||||
|
||||
return (v >= 0 && v <= MAXSLP * 1000); /* rules from NetBSD */
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_DRIVERS.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_drivers(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
struct dmap dmap_tab[NR_DEVICES];
|
||||
struct kinfo_drivers drivers[NR_DEVICES + 1];
|
||||
unsigned int count;
|
||||
devmajor_t maj;
|
||||
|
||||
/*
|
||||
* On MINIX3, we list only drivers that are actually running.
|
||||
*/
|
||||
|
||||
if (getsysinfo(VFS_PROC_NR, SI_DMAP_TAB, dmap_tab,
|
||||
sizeof(dmap_tab)) != OK)
|
||||
return EINVAL;
|
||||
|
||||
count = 0;
|
||||
|
||||
/*
|
||||
* Compatibility hack. NetBSD userland expects that the name of the
|
||||
* PTY driver is "pts". Add an extra entry for this purpose if needed.
|
||||
*/
|
||||
if (dmap_tab[PTY_MAJOR].dmap_driver != NONE &&
|
||||
strcmp(dmap_tab[PTY_MAJOR].dmap_label, "pts")) {
|
||||
if (mib_inrange(oldp, 0)) {
|
||||
memset(&drivers[0], 0, sizeof(drivers[0]));
|
||||
strlcpy(drivers[count].d_name, "pts",
|
||||
sizeof(drivers[0].d_name));
|
||||
drivers[count].d_bmajor = -1;
|
||||
drivers[count].d_cmajor = PTY_MAJOR;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
for (maj = 0; maj < NR_DEVICES; maj++) {
|
||||
if (dmap_tab[maj].dmap_driver == NONE)
|
||||
continue;
|
||||
|
||||
if (mib_inrange(oldp, sizeof(drivers[0]) * count)) {
|
||||
memset(&drivers[count], 0, sizeof(drivers[0]));
|
||||
|
||||
strlcpy(drivers[count].d_name,
|
||||
dmap_tab[maj].dmap_label,
|
||||
sizeof(drivers[0].d_name));
|
||||
|
||||
/*
|
||||
* We do not know whether the device is a block device,
|
||||
* character device, or both. In any case, a driver
|
||||
* has only one major number.
|
||||
*/
|
||||
drivers[count].d_bmajor = maj;
|
||||
drivers[count].d_cmajor = maj;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return mib_copyout(oldp, 0, drivers, count * sizeof(drivers[0]));
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_KERN KERN_BOOTTIME.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_kern_boottime(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
|
||||
if (getuptime(NULL, NULL, &tv.tv_sec) != OK)
|
||||
return EINVAL;
|
||||
|
||||
return mib_copyout(oldp, 0, &tv, sizeof(tv));
|
||||
}
|
||||
|
||||
/* The CTL_KERN KERN_SYSVIPC nodes. */
|
||||
static struct mib_node mib_kern_ipc_table[] = {
|
||||
/* 1*/ /* KERN_SYSVIPC_INFO: not yet supported */
|
||||
/* 2*/ [KERN_SYSVIPC_MSG] = MIB_INT(_P | _RO, 0, "sysvmsg", "System V "
|
||||
"style message support available"),
|
||||
/* 3*/ [KERN_SYSVIPC_SEM] = MIB_INT(_P | _RO, 1, "sysvsem", "System V "
|
||||
"style semaphore support available"),
|
||||
/* 4*/ [KERN_SYSVIPC_SHM] = MIB_INT(_P | _RO, 1, "sysvshm", "System V "
|
||||
"style shared memory support available"),
|
||||
/* 5*/ /* KERN_SYSVIPC_SHMMAX: not yet supported */
|
||||
/* 6*/ /* KERN_SYSVIPC_SHMMNI: not yet supported */
|
||||
/* 7*/ /* KERN_SYSVIPC_SHMSEG: not yet supported */
|
||||
/* 8*/ /* KERN_SYSVIPC_SHMMAXPGS: not yet supported */
|
||||
/* 9*/ /* KERN_SYSVIPC_SHMUSEPHYS: not yet supported */
|
||||
/* In addition, NetBSD has a number of dynamic nodes here. */
|
||||
};
|
||||
|
||||
/* The CTL_KERN nodes. */
|
||||
static struct mib_node mib_kern_table[] = {
|
||||
/* 1*/ [KERN_OSTYPE] = MIB_STRING(_P | _RO, OS_NAME, "ostype",
|
||||
"Operating system type"),
|
||||
/* 2*/ [KERN_OSRELEASE] = MIB_STRING(_P | _RO, OS_RELEASE, "osrelease",
|
||||
"Operating system release"),
|
||||
/* 3*/ [KERN_OSREV] = MIB_INT(_P | _RO , OS_REV, "osrevision",
|
||||
"Operating system revision"),
|
||||
/* 4*/ [KERN_VERSION] = MIB_STRING(_P | _RO, OS_VERSION, "version",
|
||||
"Kernel version"),
|
||||
/* 5*/ [KERN_MAXVNODES] = MIB_INT(_P | _RO, NR_VNODES, "maxvnodes",
|
||||
"Maximum number of vnodes"),
|
||||
/* 6*/ [KERN_MAXPROC] = MIB_INT(_P | _RO, NR_PROCS, "maxproc",
|
||||
"Maximum number of simultaneous "
|
||||
"processes"),
|
||||
/* 7*/ [KERN_MAXFILES] = MIB_INT(_P | _RO, NR_VNODES, "maxfiles",
|
||||
"Maximum number of open files"),
|
||||
/* 8*/ [KERN_ARGMAX] = MIB_INT(_P | _RO, ARG_MAX, "argmax",
|
||||
"Maximum number of bytes of arguments to "
|
||||
"execve(2)"),
|
||||
/* 9*/ [KERN_SECURELVL] = MIB_INTV(_P | _RW, -1, mib_kern_securelvl,
|
||||
"securelevel", "System security level"),
|
||||
/*10*/ [KERN_HOSTNAME] = MIB_STRING(_P | _RW, hostname, "hostname",
|
||||
"System hostname"),
|
||||
/*11*/ [KERN_HOSTID] = MIB_INT(_P | _RW | CTLFLAG_HEX, 0, "hostid",
|
||||
"System host ID number"),
|
||||
/*12*/ [KERN_CLOCKRATE] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
|
||||
sizeof(struct clockinfo),
|
||||
mib_kern_clockrate, "clockrate",
|
||||
"Kernel clock rates"),
|
||||
/*13*/ /* KERN_VNODE: not yet implemented */
|
||||
/*14*/ /* KERN_PROC: not yet implemented */
|
||||
/*15*/ /* KERN_FILE: not yet implemented */
|
||||
/*16*/ [KERN_PROF] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
|
||||
mib_kern_profiling, "profiling",
|
||||
"Profiling information (not available)"),
|
||||
/*17*/ [KERN_POSIX1] = MIB_INT(_P | _RO, _POSIX_VERSION,
|
||||
"posix1version", "Version of ISO/IEC 9945 "
|
||||
"(POSIX 1003.1) with which the operating "
|
||||
"system attempts to comply"),
|
||||
/*18*/ [KERN_NGROUPS] = MIB_INT(_P | _RO, NGROUPS_MAX, "ngroups",
|
||||
"Maximum number of supplemental groups"),
|
||||
/*19*/ [KERN_JOB_CONTROL] = MIB_INT(_P | _RO, 0, "job_control",
|
||||
"Whether job control is available"),
|
||||
/*20*/ [KERN_SAVED_IDS] = MIB_INT(_P | _RO, 0, "saved_ids",
|
||||
"Whether POSIX saved set-group/user ID is "
|
||||
"available"),
|
||||
/*21*/ /* KERN_OBOOTTIME: obsolete */
|
||||
/*22*/ [KERN_DOMAINNAME] = MIB_STRING(_P | _RW, domainname,
|
||||
"domainname", "YP domain name"),
|
||||
/*23*/ [KERN_MAXPARTITIONS] = MIB_INT(_P | _RO, NR_PARTITIONS,
|
||||
"maxpartitions", "Maximum number of "
|
||||
"partitions allowed per disk"),
|
||||
/*24*/ /* KERN_RAWPARTITION: incompatible with our device node scheme */
|
||||
/*25*/ /* KERN_NTPTIME: not yet supported */
|
||||
/*26*/ /* KERN_TIMEX: not yet supported */
|
||||
/*27*/ /* KERN_AUTONICETIME: not yet supported */
|
||||
/*28*/ /* KERN_AUTONICEVAL: not yet supported */
|
||||
/*29*/ [KERN_RTC_OFFSET] = MIB_INT(_P | _RW, 0, "rtc_offset", "Offset "
|
||||
"of real time clock from UTC in minutes"),
|
||||
/*30*/ [KERN_ROOT_DEVICE] = MIB_FUNC(_P | _RO | CTLTYPE_STRING, 0,
|
||||
mib_kern_root_device, "root_device",
|
||||
"Name of the root device"),
|
||||
/*31*/ [KERN_MSGBUFSIZE] = MIB_INT(_P | _RO, DIAG_BUFSIZE, "msgbufsize",
|
||||
"Size of the kernel message buffer"),
|
||||
/*32*/ [KERN_FSYNC] = MIB_INT(_P | _RO, 1, "fsync", "Whether the "
|
||||
"POSIX 1003.1b File Synchronization Option"
|
||||
" is available on this system"),
|
||||
/*33*/ /* KERN_OLDSYSVMSG: obsolete */
|
||||
/*34*/ /* KERN_OLDSYSVSEM: obsolete */
|
||||
/*35*/ /* KERN_OLDSYSVSHM: obsolete */
|
||||
/*36*/ /* KERN_OLDSHORTCORENAME: obsolete */
|
||||
/*37*/ [KERN_SYNCHRONIZED_IO] = MIB_INT(_P | _RO, 0, "synchronized_io",
|
||||
"Whether the POSIX 1003.1b Synchronized "
|
||||
"I/O Option is available on this system"),
|
||||
/*38*/ [KERN_IOV_MAX] = MIB_INT(_P | _RO, IOV_MAX, "iov_max",
|
||||
"Maximum number of iovec structures per "
|
||||
"process"),
|
||||
/*39*/ /* KERN_MBUF: not yet supported */
|
||||
/*40*/ [KERN_MAPPED_FILES] = MIB_INT(_P | _RO, 1, "mapped_files",
|
||||
"Whether the POSIX 1003.1b Memory Mapped "
|
||||
"Files Option is available on this "
|
||||
"system"),
|
||||
/*41*/ [KERN_MEMLOCK] = MIB_INT(_P | _RO, 0, "memlock", "Whether "
|
||||
"the POSIX 1003.1b Process Memory Locking "
|
||||
"Option is available on this system"),
|
||||
/*42*/ [KERN_MEMLOCK_RANGE] = MIB_INT(_P | _RO, 0, "memlock_range",
|
||||
"Whether the POSIX 1003.1b Range Memory "
|
||||
"Locking Option is available on this "
|
||||
"system"),
|
||||
/*43*/ [KERN_MEMORY_PROTECTION]= MIB_INT(_P | _RO, 0, "memory_protection",
|
||||
"Whether the POSIX 1003.1b Memory "
|
||||
"Protection Option is available on this "
|
||||
"system"),
|
||||
/*44*/ /* KERN_LOGIN_NAME_MAX: not yet supported */
|
||||
/*45*/ /* KERN_DEFCORENAME: obsolete */
|
||||
/*46*/ /* KERN_LOGSIGEXIT: not yet supported */
|
||||
/*47*/ [KERN_PROC2] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
|
||||
mib_kern_proc2, "proc2",
|
||||
"Machine-independent process information"),
|
||||
/*48*/ [KERN_PROC_ARGS] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
|
||||
mib_kern_proc_args, "proc_args",
|
||||
"Process argument information"),
|
||||
/*49*/ [KERN_FSCALE] = MIB_INT(_P | _RO, FSCALE, "fscale",
|
||||
"Kernel fixed-point scale factor"),
|
||||
/*50*/ [KERN_CCPU] = MIB_FUNC(_P | _RO | CTLTYPE_INT, sizeof(int),
|
||||
mib_kern_ccpu, "ccpu",
|
||||
"Scheduler exponential decay value"),
|
||||
/*51*/ [KERN_CP_TIME] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
|
||||
mib_kern_cp_time, "cp_time", "Clock ticks "
|
||||
"spent in different CPU states"),
|
||||
/*52*/ /* KERN_OLDSYSVIPC_INFO: obsolete */
|
||||
/*53*/ /* KERN_MSGBUF: not yet supported */
|
||||
/*54*/ [KERN_CONSDEV] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
|
||||
sizeof(dev_t), mib_kern_consdev, "consdev",
|
||||
"Console device"),
|
||||
/*55*/ [KERN_MAXPTYS] = MIB_INT(_P | _RO, NR_PTYS, "maxptys",
|
||||
"Maximum number of pseudo-ttys"),
|
||||
/*56*/ /* KERN_PIPE: not yet supported */
|
||||
/*57*/ [KERN_MAXPHYS] = MIB_INT(_P | _RO, 4*1024*1024, "maxphys",
|
||||
"Maximum raw I/O transfer size"),
|
||||
/* 4MB is the upper limit for AHCI */
|
||||
/*58*/ /* KERN_SBMAX: not yet supported */
|
||||
/*59*/ /* KERN_TKSTAT: not yet supported */
|
||||
/*60*/ [KERN_MONOTONIC_CLOCK] = MIB_INT(_P | _RO, _POSIX_MONOTONIC_CLOCK,
|
||||
"monotonic_clock",
|
||||
"Implementation version of the POSIX "
|
||||
"1003.1b Monotonic Clock Option"),
|
||||
/*61*/ /* KERN_URND: not yet supported */
|
||||
/*62*/ /* KERN_LABELSECTOR: not yet supported */
|
||||
/*63*/ /* KERN_LABELOFFSET: not yet supported */
|
||||
/*64*/ [KERN_LWP] = MIB_FUNC(_P | _RO | CTLTYPE_NODE, 0,
|
||||
mib_kern_lwp, "lwp",
|
||||
"System-wide LWP information"),
|
||||
/*65*/ [KERN_FORKFSLEEP] = MIB_INTV(_P | _RW, 0, mib_kern_forkfsleep,
|
||||
"forkfsleep", "Milliseconds to sleep on "
|
||||
"fork failure due to process limits"),
|
||||
/*66*/ /* KERN_POSIX_THREADS: not yet supported */
|
||||
/*67*/ /* KERN_POSIX_SEMAPHORES: not yet supported */
|
||||
/*68*/ /* KERN_POSIX_BARRIERS: not yet supported */
|
||||
/*69*/ /* KERN_POSIX_TIMERS: not yet supported */
|
||||
/*70*/ /* KERN_POSIX_SPIN_LOCKS: not yet supported */
|
||||
/*71*/ /* KERN_POSIX_READER_WRITER_LOCKS: not yet supported */
|
||||
/*72*/ [KERN_DUMP_ON_PANIC] = MIB_INT(_P | _RO, 0, "dump_on_panic",
|
||||
"Perform a crash dump on system panic"),
|
||||
/*73*/ /* KERN_SOMAXKVA: not yet supported */
|
||||
/*74*/ /* KERN_ROOT_PARTITION: incompatible with our device node scheme */
|
||||
/*75*/ [KERN_DRIVERS] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT, 0,
|
||||
mib_kern_drivers, "drivers",
|
||||
"List of all drivers with block and "
|
||||
"character device numbers"),
|
||||
/*76*/ /* KERN_BUF: not yet supported */
|
||||
/*77*/ /* KERN_FILE2: not yet supported */
|
||||
/*78*/ /* KERN_VERIEXEC: not yet supported */
|
||||
/*79*/ /* KERN_CP_ID: not yet supported */
|
||||
/*80*/ [KERN_HARDCLOCK_TICKS] = MIB_FUNC(_P | _RO | CTLFLAG_UNSIGNED |
|
||||
CTLTYPE_INT, sizeof(int),
|
||||
mib_kern_hardclock_ticks,
|
||||
"hardclock_ticks",
|
||||
"Number of hardclock ticks"),
|
||||
/*81*/ /* KERN_ARND: not yet supported */
|
||||
/*82*/ [KERN_SYSVIPC] = MIB_NODE(_P | _RO, mib_kern_ipc_table, "ipc",
|
||||
"SysV IPC options"),
|
||||
/*83*/ [KERN_BOOTTIME] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
|
||||
sizeof(struct timeval), mib_kern_boottime,
|
||||
"boottime", "System boot time"),
|
||||
/*84*/ /* KERN_EVCNT: not yet supported */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -32,6 +32,8 @@
|
||||
*/
|
||||
static struct mib_node mib_table[] = {
|
||||
/* 1*/ [CTL_KERN] = MIB_ENODE(_P | _RO, "kern", "High kernel"),
|
||||
/* 2*/ [CTL_VM] = MIB_ENODE(_P | _RO, "vm", "Virtual memory"),
|
||||
/* 6*/ [CTL_HW] = MIB_ENODE(_P | _RO, "hw", "Generic CPU, I/O"),
|
||||
/* 8*/ [CTL_USER] = MIB_ENODE(_P | _RO, "user", "User-level"),
|
||||
/*11*/ [CTL_VENDOR] = MIB_ENODE(_P | _RW, "vendor", "Vendor specific"),
|
||||
/*32*/ [CTL_MINIX] = MIB_ENODE(_P | _RO, "minix", "MINIX3 specific"),
|
||||
@ -322,6 +324,8 @@ mib_init(int type __unused, sef_init_info_t * info __unused)
|
||||
* large enough to store the entry.
|
||||
*/
|
||||
mib_kern_init(&mib_table[CTL_KERN]);
|
||||
mib_vm_init(&mib_table[CTL_VM]);
|
||||
mib_hw_init(&mib_table[CTL_HW]);
|
||||
mib_minix_init(&mib_table[CTL_MINIX]);
|
||||
|
||||
/*
|
||||
|
@ -6,6 +6,14 @@
|
||||
#include <machine/vmparam.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(__i386__)
|
||||
#include "kernel/arch/i386/include/archconst.h"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_MAX_CPUS
|
||||
#define CONFIG_MAX_CPUS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following setting toggles the existence of the minix.test subtree. For
|
||||
* production environments, it should probably be disabled, although it should
|
||||
@ -261,8 +269,18 @@ void mib_tree_init(struct mib_node *);
|
||||
extern unsigned int nodes;
|
||||
extern unsigned int objects;
|
||||
|
||||
/* proc.c */
|
||||
ssize_t mib_kern_lwp(struct mib_call *, struct mib_node *, struct mib_oldp *,
|
||||
struct mib_newp *);
|
||||
ssize_t mib_kern_proc2(struct mib_call *, struct mib_node *, struct mib_oldp *,
|
||||
struct mib_newp *);
|
||||
ssize_t mib_kern_proc_args(struct mib_call *, struct mib_node *,
|
||||
struct mib_oldp *, struct mib_newp *);
|
||||
|
||||
/* subtree modules */
|
||||
void mib_kern_init(struct mib_node *);
|
||||
void mib_vm_init(struct mib_node *);
|
||||
void mib_hw_init(struct mib_node *);
|
||||
void mib_minix_init(struct mib_node *);
|
||||
|
||||
#endif /* !_MINIX_MIB_MIB_H */
|
||||
|
1169
minix/servers/mib/proc.c
Normal file
1169
minix/servers/mib/proc.c
Normal file
File diff suppressed because it is too large
Load Diff
154
minix/servers/mib/vm.c
Normal file
154
minix/servers/mib/vm.c
Normal file
@ -0,0 +1,154 @@
|
||||
/* MIB service - vm.c - implementation of the CTL_VM subtree */
|
||||
|
||||
#include "mib.h"
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
/*
|
||||
* Implementation of CTL_VM VM_LOADAVG.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_vm_loadavg(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
struct loadavg loadavg;
|
||||
struct loadinfo loadinfo;
|
||||
unsigned long proc_load;
|
||||
u32_t ticks_per_slot, ticks;
|
||||
unsigned int p;
|
||||
int unfilled_ticks;
|
||||
int h, slots, latest, slot;
|
||||
int minutes[3] = { 1, 5, 15 };
|
||||
|
||||
assert(__arraycount(loadavg.ldavg) == __arraycount(minutes));
|
||||
|
||||
if (sys_getloadinfo(&loadinfo) != OK)
|
||||
return EINVAL;
|
||||
|
||||
memset(&loadavg, 0, sizeof(loadavg));
|
||||
|
||||
/*
|
||||
* The following code is inherited from the old MINIX libc.
|
||||
*/
|
||||
|
||||
/* How many ticks are missing from the newest-filled slot? */
|
||||
ticks_per_slot = _LOAD_UNIT_SECS * sys_hz();
|
||||
unfilled_ticks =
|
||||
ticks_per_slot - (loadinfo.last_clock % ticks_per_slot);
|
||||
|
||||
for (p = 0; p < __arraycount(loadavg.ldavg); p++) {
|
||||
latest = loadinfo.proc_last_slot;
|
||||
slots = minutes[p] * 60 / _LOAD_UNIT_SECS;
|
||||
proc_load = 0;
|
||||
|
||||
/*
|
||||
* Add up the total number of process ticks for this number
|
||||
* of minutes (minutes[p]). Start with the newest slot, which
|
||||
* is latest, and count back for the number of slots that
|
||||
* correspond to the right number of minutes. Take wraparound
|
||||
* into account by calculating the index modulo _LOAD_HISTORY,
|
||||
* which is the number of slots of history kept.
|
||||
*/
|
||||
for (h = 0; h < slots; h++) {
|
||||
slot = (latest - h + _LOAD_HISTORY) % _LOAD_HISTORY;
|
||||
proc_load += loadinfo.proc_load_history[slot];
|
||||
}
|
||||
|
||||
/*
|
||||
* The load average over this number of minutes is the number
|
||||
* of process-ticks divided by the number of ticks, not
|
||||
* counting the number of ticks the last slot hasn't been
|
||||
* around yet.
|
||||
*/
|
||||
ticks = slots * ticks_per_slot - unfilled_ticks;
|
||||
|
||||
loadavg.ldavg[p] = 100UL * proc_load / ticks;
|
||||
}
|
||||
|
||||
loadavg.fscale = 100L;
|
||||
|
||||
return mib_copyout(oldp, 0, &loadavg, sizeof(loadavg));
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of CTL_VM VM_UVMEXP2.
|
||||
*/
|
||||
static ssize_t
|
||||
mib_vm_uvmexp2(struct mib_call * call __unused,
|
||||
struct mib_node * node __unused, struct mib_oldp * oldp,
|
||||
struct mib_newp * newp __unused)
|
||||
{
|
||||
struct vm_stats_info vsi;
|
||||
struct uvmexp_sysctl ues;
|
||||
unsigned int shift;
|
||||
|
||||
if (vm_info_stats(&vsi) != OK)
|
||||
return EINVAL;
|
||||
|
||||
memset(&ues, 0, sizeof(ues));
|
||||
|
||||
/*
|
||||
* TODO: by far most of the structure is not filled correctly yet,
|
||||
* since the MINIX3 system does not provide much of the information
|
||||
* exposed by NetBSD. This will gradually have to be filled in.
|
||||
* For now, we provide just some basic information used by top(1).
|
||||
*/
|
||||
ues.pagesize = vsi.vsi_pagesize;
|
||||
ues.pagemask = vsi.vsi_pagesize - 1;
|
||||
for (shift = 0; shift < CHAR_BIT * sizeof(void *); shift++)
|
||||
if ((1U << shift) == vsi.vsi_pagesize)
|
||||
break;
|
||||
if (shift < CHAR_BIT * sizeof(void *))
|
||||
ues.pageshift = shift;
|
||||
ues.npages = vsi.vsi_total;
|
||||
ues.free = vsi.vsi_free;
|
||||
ues.filepages = vsi.vsi_cached;
|
||||
/*
|
||||
* We use one of the structure's unused fields to expose information
|
||||
* not exposed by NetBSD, namely the largest area of physically
|
||||
* contiguous memory. If NetBSD repurposes this field, we have to find
|
||||
* another home for it (or expose it through a separate node or so).
|
||||
*/
|
||||
ues.unused1 = vsi.vsi_largest;
|
||||
|
||||
return mib_copyout(oldp, 0, &ues, sizeof(ues));
|
||||
}
|
||||
|
||||
/* The CTL_VM nodes. */
|
||||
static struct mib_node mib_vm_table[] = {
|
||||
/* 1*/ /* VM_METER: not yet supported */
|
||||
/* 2*/ [VM_LOADAVG] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
|
||||
sizeof(struct loadavg), mib_vm_loadavg,
|
||||
"loadavg", "System load average history"),
|
||||
/* 3*/ /* VM_UVMEXP: not yet supported */
|
||||
/* 4*/ /* VM_NKMEMPAGES: not yet supported */
|
||||
/* 5*/ [VM_UVMEXP2] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
|
||||
sizeof(struct uvmexp_sysctl),
|
||||
mib_vm_uvmexp2, "uvmexp2",
|
||||
"Detailed system-wide virtual memory "
|
||||
"statistics (MI)"),
|
||||
/* 6*/ /* VM_ANONMIN: not yet supported */
|
||||
/* 7*/ /* VM_EXECMIN: not yet supported */
|
||||
/* 8*/ /* VM_FILEMIN: not yet supported */
|
||||
/* 9*/ [VM_MAXSLP] = MIB_INT(_P | _RO, MAXSLP, "maxslp",
|
||||
"Maximum process sleep time before being "
|
||||
"swapped"),
|
||||
/*10*/ [VM_USPACE] = MIB_INT(_P | _RO, 0, "uspace", "Number of "
|
||||
"bytes allocated for a kernel stack"),
|
||||
/* MINIX3 processes don't have k-stacks */
|
||||
/*11*/ /* VM_ANONMAX: not yet supported */
|
||||
/*12*/ /* VM_EXECMAX: not yet supported */
|
||||
/*13*/ /* VM_FILEMAX: not yet supported */
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the CTL_VM subtree.
|
||||
*/
|
||||
void
|
||||
mib_vm_init(struct mib_node * node)
|
||||
{
|
||||
|
||||
MIB_INIT_ENODE(node, mib_vm_table);
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
|
||||
#include "inc.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sched.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
struct sysctl_tab {
|
||||
int id;
|
||||
@ -13,13 +16,272 @@ struct sysctl_tab {
|
||||
#define NODE(i,t) { .id = i, .size = __arraycount(t), .tab = t }
|
||||
#define PROC(i,s,p) { .id = i, .size = s, .proc = p }
|
||||
|
||||
/*
|
||||
* Print CTL_KERN KERN_CLOCKRATE.
|
||||
*/
|
||||
static int
|
||||
put_kern_clockrate(struct trace_proc * proc, const char * name,
|
||||
int type __unused, const void * ptr, vir_bytes addr __unused,
|
||||
size_t size __unused)
|
||||
{
|
||||
struct clockinfo *ci;
|
||||
|
||||
ci = (struct clockinfo *)ptr;
|
||||
|
||||
put_value(proc, "hz", "%d", ci->hz);
|
||||
put_value(proc, "tick", "%d", ci->tick);
|
||||
if (verbose > 0) {
|
||||
put_value(proc, "tickadj", "%d", ci->tickadj);
|
||||
put_value(proc, "stathz", "%d", ci->stathz);
|
||||
put_value(proc, "profhz", "%d", ci->profhz);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print CTL_KERN KERN_PROC2.
|
||||
*/
|
||||
static int
|
||||
put_kern_proc2(struct trace_proc * proc, const char * name, int type,
|
||||
const void * ptr, vir_bytes addr, size_t size)
|
||||
{
|
||||
const int *mib;
|
||||
const char *text;
|
||||
int i;
|
||||
|
||||
if (type == ST_NAME) {
|
||||
mib = (const int *)ptr;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
text = NULL;
|
||||
|
||||
if (i == 0) {
|
||||
switch (mib[i]) {
|
||||
case KERN_PROC_ALL: text = "<all>"; break;
|
||||
case KERN_PROC_PID: text = "<pid>"; break;
|
||||
case KERN_PROC_PGRP: text = "<pgrp>"; break;
|
||||
case KERN_PROC_SESSION:
|
||||
text = "<session>"; break;
|
||||
case KERN_PROC_TTY: text = "<tty>"; break;
|
||||
case KERN_PROC_UID: text = "<uid>"; break;
|
||||
case KERN_PROC_RUID: text = "<ruid>"; break;
|
||||
case KERN_PROC_GID: text = "<gid>"; break;
|
||||
case KERN_PROC_RGID: text = "<rgid>"; break;
|
||||
}
|
||||
} else if (i == 1 && mib[0] == KERN_PROC_TTY) {
|
||||
switch ((dev_t)mib[i]) {
|
||||
case KERN_PROC_TTY_NODEV:
|
||||
text = "<nodev>"; break;
|
||||
case KERN_PROC_TTY_REVOKE:
|
||||
text = "<revoke>"; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valuesonly && text != NULL)
|
||||
put_field(proc, NULL, text);
|
||||
else
|
||||
put_value(proc, NULL, "%d", mib[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the requested structure length, so that we can later
|
||||
* determine how many elements were returned (see below).
|
||||
*/
|
||||
proc->sctl_arg = (size == 4) ? mib[2] : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (proc->sctl_arg > 0) {
|
||||
/* TODO: optionally dump struct kinfo_drivers array */
|
||||
put_open(proc, name, 0, "[", ", ");
|
||||
if (size > 0)
|
||||
put_tail(proc, size / proc->sctl_arg, 0);
|
||||
put_close(proc, "]");
|
||||
} else
|
||||
put_ptr(proc, name, addr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print CTL_KERN KERN_PROC_ARGS.
|
||||
*/
|
||||
static int
|
||||
put_kern_proc_args(struct trace_proc * proc, const char * name, int type,
|
||||
const void * ptr, vir_bytes addr, size_t size)
|
||||
{
|
||||
const int *mib;
|
||||
const char *text;
|
||||
int i, v;
|
||||
|
||||
if (type == ST_NAME) {
|
||||
mib = (const int *)ptr;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
text = NULL;
|
||||
|
||||
if (i == 1) {
|
||||
switch (mib[i]) {
|
||||
case KERN_PROC_ARGV: text = "<argv>"; break;
|
||||
case KERN_PROC_ENV: text = "<env>"; break;
|
||||
case KERN_PROC_NARGV: text = "<nargv>"; break;
|
||||
case KERN_PROC_NENV: text = "<nenv>"; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valuesonly && text != NULL)
|
||||
put_field(proc, NULL, text);
|
||||
else
|
||||
put_value(proc, NULL, "%d", mib[i]);
|
||||
}
|
||||
|
||||
/* Save the subrequest, so that we can later print data. */
|
||||
proc->sctl_arg = (size == 2) ? mib[1] : -999;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((proc->sctl_arg == KERN_PROC_NARGV ||
|
||||
proc->sctl_arg == KERN_PROC_NENV) && size == sizeof(v) &&
|
||||
mem_get_data(proc->pid, addr, &v, sizeof(v)) >= 0) {
|
||||
put_open(proc, name, PF_NONAME, "{", ", ");
|
||||
|
||||
put_value(proc, NULL, "%d", v);
|
||||
|
||||
put_close(proc, "}");
|
||||
} else
|
||||
put_ptr(proc, name, addr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print CTL_KERN KERN_CP_TIME.
|
||||
*/
|
||||
static int
|
||||
put_kern_cp_time(struct trace_proc * proc, const char * name __unused,
|
||||
int type, const void * ptr, vir_bytes addr __unused, size_t size)
|
||||
{
|
||||
uint64_t *p;
|
||||
unsigned int i;
|
||||
const int *mib;
|
||||
|
||||
if (type == ST_NAME) {
|
||||
mib = (const int *)ptr;
|
||||
for (i = 0; i < size; i++)
|
||||
put_value(proc, NULL, "%d", mib[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = (uint64_t *)ptr;
|
||||
|
||||
/* TODO: support for multi-CPU results */
|
||||
for (i = 0; i < CPUSTATES; i++)
|
||||
put_value(proc, NULL, "%"PRIu64, p[i]);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print CTL_KERN KERN_CONSDEV.
|
||||
*/
|
||||
static int
|
||||
put_kern_consdev(struct trace_proc * proc, const char * name,
|
||||
int type __unused, const void * ptr, vir_bytes addr __unused,
|
||||
size_t size __unused)
|
||||
{
|
||||
|
||||
put_dev(proc, NULL, *(dev_t *)ptr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print CTL_KERN KERN_DRIVERS.
|
||||
*/
|
||||
static int
|
||||
put_kern_drivers(struct trace_proc * proc, const char * name,
|
||||
int type __unused, const void * ptr __unused, vir_bytes addr __unused,
|
||||
size_t size)
|
||||
{
|
||||
|
||||
/* TODO: optionally dump struct kinfo_drivers array */
|
||||
put_open(proc, name, 0, "[", ", ");
|
||||
if (size > 0)
|
||||
put_tail(proc, size / sizeof(struct kinfo_drivers), 0);
|
||||
put_close(proc, "]");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print CTL_KERN KERN_BOOTTIME.
|
||||
*/
|
||||
static int
|
||||
put_kern_boottime(struct trace_proc * proc, const char * name,
|
||||
int type __unused, const void * ptr __unused, vir_bytes addr,
|
||||
size_t size)
|
||||
{
|
||||
|
||||
if (size == sizeof(struct timeval))
|
||||
put_struct_timeval(proc, name, 0, addr);
|
||||
else
|
||||
put_ptr(proc, name, addr);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* The CTL_KERN table. */
|
||||
static const struct sysctl_tab kern_tab[] = {
|
||||
PROC(KERN_CLOCKRATE, sizeof(struct clockinfo), put_kern_clockrate),
|
||||
PROC(KERN_PROC2, 0, put_kern_proc2),
|
||||
PROC(KERN_PROC_ARGS, 0, put_kern_proc_args),
|
||||
PROC(KERN_CP_TIME, sizeof(uint64_t) * CPUSTATES, put_kern_cp_time),
|
||||
PROC(KERN_CONSDEV, sizeof(dev_t), put_kern_consdev),
|
||||
PROC(KERN_DRIVERS, 0, put_kern_drivers),
|
||||
PROC(KERN_BOOTTIME, 0, put_kern_boottime),
|
||||
};
|
||||
|
||||
/*
|
||||
* Print CTL_VM VM_LOADAVG.
|
||||
*/
|
||||
static int
|
||||
put_vm_loadavg(struct trace_proc * proc, const char * name __unused,
|
||||
int type __unused, const void * ptr, vir_bytes addr __unused,
|
||||
size_t size __unused)
|
||||
{
|
||||
struct loadavg *loadavg;
|
||||
unsigned int i;
|
||||
|
||||
loadavg = (struct loadavg *)ptr;
|
||||
|
||||
put_open(proc, "ldavg", 0, "{", ", ");
|
||||
|
||||
for (i = 0; i < __arraycount(loadavg->ldavg); i++)
|
||||
put_value(proc, NULL, "%"PRIu32, loadavg->ldavg[i]);
|
||||
|
||||
put_close(proc, "}");
|
||||
|
||||
if (verbose > 0) {
|
||||
put_value(proc, "fscale", "%ld", loadavg->fscale);
|
||||
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The CTL_VM table. */
|
||||
static const struct sysctl_tab vm_tab[] = {
|
||||
PROC(VM_LOADAVG, sizeof(struct loadavg), put_vm_loadavg),
|
||||
};
|
||||
|
||||
/* The top-level table, which is indexed by identifier. */
|
||||
static const struct sysctl_tab root_tab[] = {
|
||||
[CTL_KERN] = NODE(0, kern_tab),
|
||||
[CTL_VM] = NODE(0, vm_tab),
|
||||
};
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user