summaryrefslogtreecommitdiff
path: root/kernel/sysctl
diff options
context:
space:
mode:
authorMartin Baulig <martin@src.gnome.org>1999-03-21 17:57:51 +0000
committerMartin Baulig <martin@src.gnome.org>1999-03-21 17:57:51 +0000
commitc1beefce3a0d1912ceedda4515dff17a2979317c (patch)
treec253706d1f658bc9e6aa374094e70028df76c4fb /kernel/sysctl
parent1667cc8a8d74a915e89f8a3bc0f17ba4117bfbf1 (diff)
downloadlibgtop-c1beefce3a0d1912ceedda4515dff17a2979317c.tar.gz
Initial revision
Diffstat (limited to 'kernel/sysctl')
-rw-r--r--kernel/sysctl/Makefile22
-rw-r--r--kernel/sysctl/libgtop.c318
-rw-r--r--kernel/sysctl/libgtop.h82
-rw-r--r--kernel/sysctl/libgtop_syms.c24
-rw-r--r--kernel/sysctl/main.c4
5 files changed, 450 insertions, 0 deletions
diff --git a/kernel/sysctl/Makefile b/kernel/sysctl/Makefile
new file mode 100644
index 00000000..77dd277a
--- /dev/null
+++ b/kernel/sysctl/Makefile
@@ -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
diff --git a/kernel/sysctl/libgtop.c b/kernel/sysctl/libgtop.c
new file mode 100644
index 00000000..e77c6af2
--- /dev/null
+++ b/kernel/sysctl/libgtop.c
@@ -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;
+}
diff --git a/kernel/sysctl/libgtop.h b/kernel/sysctl/libgtop.h
new file mode 100644
index 00000000..f860e546
--- /dev/null
+++ b/kernel/sysctl/libgtop.h
@@ -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
diff --git a/kernel/sysctl/libgtop_syms.c b/kernel/sysctl/libgtop_syms.c
new file mode 100644
index 00000000..874dadcd
--- /dev/null
+++ b/kernel/sysctl/libgtop_syms.c
@@ -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);
+
diff --git a/kernel/sysctl/main.c b/kernel/sysctl/main.c
new file mode 100644
index 00000000..6d391eb4
--- /dev/null
+++ b/kernel/sysctl/main.c
@@ -0,0 +1,4 @@
+/*
+ * linux/libgtop/main.c
+ * Copyright (C) 1999 Martin Baulig
+ */