Initial revision
This commit is contained in:
22
kernel/sysctl/Makefile
Normal file
22
kernel/sysctl/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# Makefile for the LibGTop linux sysctl interface.
|
||||
#
|
||||
# Note! Dependencies are done automagically by 'make dep', which also
|
||||
# removes any old dependencies. DON'T put your own dependencies here
|
||||
# unless it's something special (ie not a .c file).
|
||||
#
|
||||
# Note 2! The CFLAGS definition is now in the main makefile...
|
||||
|
||||
O_TARGET := kernel.o
|
||||
ifeq ($(CONFIG_LIBGTOP),y)
|
||||
O_OJBS := main.o libgtop.o
|
||||
else
|
||||
O_OBJS := main.o
|
||||
endif
|
||||
OX_OBJS := libgtop_syms.o
|
||||
|
||||
ifeq ($(CONFIG_LIBGTOP),m)
|
||||
M_OBJS := libgtop.o
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/Rules.make
|
318
kernel/sysctl/libgtop.c
Normal file
318
kernel/sysctl/libgtop.c
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* linux/libgtop/module.c
|
||||
* Copyright (C) 1999 Martin Baulig
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/a.out.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/config.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/signal.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/libgtop.h>
|
||||
|
||||
EXPORT_NO_SYMBOLS;
|
||||
|
||||
static int system_ctl_handler (ctl_table *table, int *name, int nlen,
|
||||
void *oldval, size_t *oldlenp, void *newval,
|
||||
size_t newlen, void **context);
|
||||
|
||||
static int proc_ctl_handler (ctl_table *table, int *name, int nlen,
|
||||
void *oldval, size_t *oldlenp, void *newval,
|
||||
size_t newlen, void **context);
|
||||
|
||||
static int libgtop_sysctl_version = 1;
|
||||
static int libgtop_update_expensive = 5000;
|
||||
|
||||
static struct ctl_table_header *libgtop_sysctl_header = NULL;
|
||||
|
||||
static libgtop_stat_t libgtop_stat;
|
||||
static unsigned int libgtop_mem_timestamp = 0;
|
||||
static libgtop_mem_t libgtop_mem;
|
||||
static unsigned int libgtop_swap_timestamp = 0;
|
||||
static libgtop_swap_t libgtop_swap;
|
||||
static libgtop_proclist_t libgtop_proclist;
|
||||
|
||||
static ctl_table libgtop_table[];
|
||||
static ctl_table proc_table[];
|
||||
|
||||
static ctl_table libgtop_root_table[] = {
|
||||
{CTL_LIBGTOP, "libgtop", NULL, 0, 0555, libgtop_table},
|
||||
{0}
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
static
|
||||
#endif
|
||||
ctl_table libgtop_table[] = {
|
||||
{LIBGTOP_VERSION, "version", &libgtop_sysctl_version,
|
||||
sizeof (int), 0444, NULL, &proc_dointvec},
|
||||
{LIBGTOP_PROC, NULL, NULL, 0, 0555, proc_table},
|
||||
{LIBGTOP_UPDATE_EXPENSIVE, "update_expensive",
|
||||
&libgtop_update_expensive, sizeof (int), 0664, NULL, &proc_dointvec},
|
||||
{LIBGTOP_STAT, NULL, &libgtop_stat, sizeof (libgtop_stat),
|
||||
0444, NULL, NULL, &system_ctl_handler},
|
||||
{LIBGTOP_MEM, NULL, &libgtop_mem, sizeof (libgtop_mem),
|
||||
0444, NULL, NULL, &system_ctl_handler},
|
||||
{LIBGTOP_SWAP, NULL, &libgtop_swap, sizeof (libgtop_swap),
|
||||
0444, NULL, NULL, &system_ctl_handler},
|
||||
{LIBGTOP_PROCLIST, NULL, &libgtop_proclist, sizeof (libgtop_proclist),
|
||||
0444, NULL, NULL, &system_ctl_handler},
|
||||
{0}
|
||||
};
|
||||
|
||||
static ctl_table proc_table[] = {
|
||||
{CTL_ANY, NULL, NULL, 0, 04444, NULL, NULL, &proc_ctl_handler},
|
||||
{0}
|
||||
};
|
||||
|
||||
#ifdef MODULE
|
||||
static void
|
||||
libgtop_sysctl_register(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
|
||||
if (initialized == 1)
|
||||
return;
|
||||
|
||||
libgtop_sysctl_header = register_sysctl_table(libgtop_root_table, 1);
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
libgtop_sysctl_unregister(void)
|
||||
{
|
||||
unregister_sysctl_table(libgtop_sysctl_header);
|
||||
}
|
||||
|
||||
int init_module(void)
|
||||
{
|
||||
libgtop_sysctl_register();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cleanup_module(void)
|
||||
{
|
||||
libgtop_sysctl_unregister();
|
||||
}
|
||||
|
||||
#endif /* MODULE */
|
||||
|
||||
static int
|
||||
libgtop_sysctl (ctl_table *table, int nlen, int *name)
|
||||
{
|
||||
extern unsigned long total_forks;
|
||||
int index, tindex, tty, which, arg;
|
||||
libgtop_stat_t *lstat;
|
||||
libgtop_mem_t *mem;
|
||||
libgtop_swap_t *swap;
|
||||
libgtop_proclist_t *proclist;
|
||||
struct task_struct *tsk = NULL;
|
||||
struct sysinfo i;
|
||||
|
||||
switch (table->ctl_name) {
|
||||
case LIBGTOP_STAT:
|
||||
lstat = table->data;
|
||||
lstat->cpu.total = jiffies;
|
||||
lstat->cpu.user = kstat.cpu_user;
|
||||
lstat->cpu.nice = kstat.cpu_nice;
|
||||
lstat->cpu.sys = kstat.cpu_system;
|
||||
lstat->cpu.idle = jiffies*smp_num_cpus -
|
||||
(lstat->cpu.user + lstat->cpu.nice + lstat->cpu.sys);
|
||||
#ifdef __SMP__
|
||||
for (i = 0; i < smp_num_cpus; i++) {
|
||||
lstat->xcpu[i].user = kstat.per_cpu_user[cpu_logical_map(i)];
|
||||
lstat->xcpu[i].nice = kstat.per_cpu_nice[cpu_logical_map(i)];
|
||||
lstat->xcpu[i].sys = kstat.per_cpu_system[cpu_logical_map(i)];
|
||||
lstat->xcpu[i].idle = jiffies -
|
||||
(lstat->xcpu[i].user + lstat->xcpu[i].nice +
|
||||
lstat->xcpu[i].sys);
|
||||
}
|
||||
|
||||
lstat->ncpu = smp_num_cpus;
|
||||
#else
|
||||
lstat->ncpu = 0;
|
||||
#endif
|
||||
|
||||
lstat->frequency = HZ;
|
||||
|
||||
lstat->loadavg [0] = (double) avenrun [0] / (1 << FSHIFT);
|
||||
lstat->loadavg [1] = (double) avenrun [1] / (1 << FSHIFT);
|
||||
lstat->loadavg [2] = (double) avenrun [2] / (1 << FSHIFT);
|
||||
|
||||
lstat->pgpgin = kstat.pgpgin;
|
||||
lstat->pgpgout = kstat.pgpgout;
|
||||
lstat->pswpin = kstat.pswpin;
|
||||
lstat->pswpout = kstat.pswpout;
|
||||
|
||||
lstat->context_swtch = kstat.context_swtch;
|
||||
lstat->boot_time = xtime.tv_sec - jiffies / HZ;
|
||||
lstat->total_forks = total_forks;
|
||||
break;
|
||||
case LIBGTOP_MEM:
|
||||
if (jiffies - libgtop_mem_timestamp < libgtop_update_expensive)
|
||||
return 0;
|
||||
libgtop_mem_timestamp = jiffies;
|
||||
printk ("Time: %lu\n", jiffies);
|
||||
|
||||
mem = table->data;
|
||||
si_meminfo (&i);
|
||||
|
||||
mem->totalram = i.totalram;
|
||||
mem->freeram = i.freeram;
|
||||
mem->sharedram = i.sharedram;
|
||||
mem->bufferram = i.bufferram;
|
||||
return 0;
|
||||
case LIBGTOP_SWAP:
|
||||
if (jiffies - libgtop_swap_timestamp < libgtop_update_expensive)
|
||||
return 0;
|
||||
libgtop_swap_timestamp = jiffies;
|
||||
printk ("Time: %lu\n", jiffies);
|
||||
|
||||
swap = table->data;
|
||||
si_swapinfo (&i);
|
||||
|
||||
swap->totalswap = i.totalswap;
|
||||
swap->freeswap = i.freeswap;
|
||||
return 0;
|
||||
case LIBGTOP_PROCLIST:
|
||||
proclist = table->data;
|
||||
|
||||
if (nlen == 1) {
|
||||
which = 0;
|
||||
arg = 0;
|
||||
} else if (nlen == 2) {
|
||||
which = name [1];
|
||||
arg = 0;
|
||||
} else if (nlen == 3) {
|
||||
which = name [1];
|
||||
arg = name [2];
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tsk = task [0];
|
||||
read_lock (&tasklist_lock);
|
||||
for (index = tindex = 0; index < nr_tasks;
|
||||
index++, tsk = tsk->next_task) {
|
||||
if (tsk->pid == 0) continue;
|
||||
switch (which & LIBGTOP_PROCLIST_MASK) {
|
||||
case LIBGTOP_PROCLIST_PID:
|
||||
if (tsk->pid != arg) continue;
|
||||
break;
|
||||
case LIBGTOP_PROCLIST_PGRP:
|
||||
if (tsk->pgrp != arg) continue;
|
||||
break;
|
||||
case LIBGTOP_PROCLIST_SESSION:
|
||||
if (tsk->session != arg) continue;
|
||||
break;
|
||||
case LIBGTOP_PROCLIST_TTY:
|
||||
tty = tsk->tty ?
|
||||
kdev_t_to_nr (tsk->tty->device) : 0;
|
||||
if (tty != arg) continue;
|
||||
break;
|
||||
case LIBGTOP_PROCLIST_UID:
|
||||
if (tsk->uid != arg) continue;
|
||||
break;
|
||||
case LIBGTOP_PROCLIST_RUID:
|
||||
if (tsk->euid != arg) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((which & LIBGTOP_EXCLUDE_IDLE) && (tsk->state != 0))
|
||||
continue;
|
||||
|
||||
if ((which & LIBGTOP_EXCLUDE_NOTTY) && (tsk->tty == NULL))
|
||||
continue;
|
||||
|
||||
proclist->pids [tindex++] = tsk->pid;
|
||||
}
|
||||
|
||||
proclist->nr_running = nr_running;
|
||||
proclist->last_pid = last_pid;
|
||||
proclist->nr_tasks = tindex;
|
||||
read_unlock(&tasklist_lock);
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
system_ctl_handler (ctl_table *table, int *name, int nlen,
|
||||
void *oldval, size_t *oldlenp, void *newval,
|
||||
size_t newlen, void **context)
|
||||
{
|
||||
int ret, len, len_name;
|
||||
|
||||
if (!table->data || !table->maxlen)
|
||||
return -ENOTDIR;
|
||||
|
||||
if (!oldval || !oldlenp || get_user(len, oldlenp))
|
||||
return -EFAULT;
|
||||
|
||||
if (!name || !nlen || get_user(len_name, name))
|
||||
return -EFAULT;
|
||||
|
||||
if (len != table->maxlen)
|
||||
return -EFAULT;
|
||||
|
||||
ret = libgtop_sysctl (table, nlen, name);
|
||||
if (ret) return ret;
|
||||
|
||||
if(copy_to_user(oldval, table->data, len))
|
||||
return -EFAULT;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_ctl_handler (ctl_table *table, int *name, int nlen,
|
||||
void *oldval, size_t *oldlenp, void *newval,
|
||||
size_t newlen, void **context)
|
||||
{
|
||||
int ret, len;
|
||||
|
||||
printk ("proc_ctl_handler: %p - %p - %d - (%p,%p) - (%p,%d) - %p\n",
|
||||
table, name, nlen, oldval, oldlenp, newval, newlen, context);
|
||||
|
||||
if (!name || !nlen || get_user(len, name))
|
||||
return -EFAULT;
|
||||
|
||||
printk ("FUNCTION: %d - %d - %p\n", table->ctl_name,
|
||||
*name, table->de);
|
||||
|
||||
if (!table->data || !table->maxlen)
|
||||
return -ENOTDIR;
|
||||
|
||||
if (!oldval || !oldlenp || get_user(len, oldlenp))
|
||||
return -EFAULT;
|
||||
|
||||
if (len != table->maxlen)
|
||||
return -EFAULT;
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
82
kernel/sysctl/libgtop.h
Normal file
82
kernel/sysctl/libgtop.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef _LINUX_LIBGTOP_H
|
||||
#define _LINUX_LIBGTOP_H 1
|
||||
|
||||
#include <linux/tasks.h>
|
||||
|
||||
enum {
|
||||
LIBGTOP_VERSION = 1,
|
||||
LIBGTOP_PROC,
|
||||
LIBGTOP_UPDATE_EXPENSIVE,
|
||||
LIBGTOP_STAT,
|
||||
LIBGTOP_MEM,
|
||||
LIBGTOP_SWAP,
|
||||
LIBGTOP_PROCLIST
|
||||
};
|
||||
|
||||
enum {
|
||||
LIBGTOP_PROCLIST_ALL = 0,
|
||||
LIBGTOP_PROCLIST_PID,
|
||||
LIBGTOP_PROCLIST_PGRP,
|
||||
LIBGTOP_PROCLIST_SESSION,
|
||||
LIBGTOP_PROCLIST_TTY,
|
||||
LIBGTOP_PROCLIST_UID,
|
||||
LIBGTOP_PROCLIST_RUID
|
||||
};
|
||||
|
||||
#define LIBGTOP_PROCLIST_MASK 15
|
||||
|
||||
#define LIBGTOP_EXCLUDE_IDLE 0x1000
|
||||
#define LIBGTOP_EXCLUDE_SYSTEM 0x2000
|
||||
#define LIBGTOP_EXCLUDE_NOTTY 0x4000
|
||||
|
||||
typedef struct libgtop_stat libgtop_stat_t;
|
||||
|
||||
typedef struct libgtop_cpu libgtop_cpu_t;
|
||||
typedef struct libgtop_mem libgtop_mem_t;
|
||||
typedef struct libgtop_swap libgtop_swap_t;
|
||||
typedef struct libgtop_proclist libgtop_proclist_t;
|
||||
|
||||
struct libgtop_cpu
|
||||
{
|
||||
unsigned long total; /* Total CPU Time */
|
||||
unsigned long user; /* CPU Time in User Mode */
|
||||
unsigned long nice; /* CPU Time in User Mode (nice) */
|
||||
unsigned long sys; /* CPU Time in System Mode */
|
||||
unsigned long idle; /* CPU Time in the Idle Task */
|
||||
};
|
||||
|
||||
struct libgtop_mem
|
||||
{
|
||||
unsigned long totalram; /* Total usable main memory size */
|
||||
unsigned long freeram; /* Available memory size */
|
||||
unsigned long sharedram; /* Amount of shared memory */
|
||||
unsigned long bufferram; /* Memory used by buffers */
|
||||
};
|
||||
|
||||
struct libgtop_swap
|
||||
{
|
||||
unsigned long totalswap; /* Total swap space size */
|
||||
unsigned long freeswap; /* swap space still available */
|
||||
};
|
||||
|
||||
struct libgtop_proclist
|
||||
{
|
||||
int nr_running, nr_tasks, last_pid;
|
||||
unsigned pids [NR_TASKS];
|
||||
};
|
||||
|
||||
struct libgtop_stat
|
||||
{
|
||||
int ncpu; /* Number of CPUs */
|
||||
unsigned long frequency; /* Tick frequency (HZ) */
|
||||
libgtop_cpu_t cpu; /* CPU statistics */
|
||||
libgtop_cpu_t xcpu [NR_CPUS]; /* SMP per-CPU statistics */
|
||||
double loadavg [3]; /* Load average */
|
||||
unsigned long total_forks; /* Total # of forks */
|
||||
unsigned int context_swtch; /* Total # of context switches */
|
||||
unsigned long boot_time; /* Boot time (seconds s. epoch) */
|
||||
unsigned int pgpgin, pgpgout; /* # of pages paged in/out */
|
||||
unsigned int pswpin, pswpout; /* # of swap pgs brought in/out */
|
||||
};
|
||||
|
||||
#endif
|
24
kernel/sysctl/libgtop_syms.c
Normal file
24
kernel/sysctl/libgtop_syms.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* linux/libgtop/libgtop_syms.c
|
||||
* Copyright (C) 1999 Martin Baulig
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/swap.h>
|
||||
|
||||
extern unsigned long total_forks;
|
||||
|
||||
EXPORT_SYMBOL(task);
|
||||
EXPORT_SYMBOL(avenrun);
|
||||
EXPORT_SYMBOL(nr_running);
|
||||
EXPORT_SYMBOL(nr_tasks);
|
||||
EXPORT_SYMBOL(last_pid);
|
||||
EXPORT_SYMBOL(total_forks);
|
||||
EXPORT_SYMBOL(si_swapinfo);
|
||||
|
4
kernel/sysctl/main.c
Normal file
4
kernel/sysctl/main.c
Normal file
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
* linux/libgtop/main.c
|
||||
* Copyright (C) 1999 Martin Baulig
|
||||
*/
|
Reference in New Issue
Block a user