openbsd: merge patches from ports tree
Bring OpenBSD closer to FreeBSD to help checking what is missing/different. Also we make sure to use and build mountlist and fsusage from the sysdeps/openbsd directory instead of the common one. https://bugzilla.gnome.org/show_bug.cgi?id=723521
This commit is contained in:
@@ -2,18 +2,23 @@ INCLUDES = @INCLUDES@
|
||||
|
||||
noinst_LTLIBRARIES = libgtop_sysdeps-2.0.la libgtop_sysdeps_suid-2.0.la
|
||||
|
||||
libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c
|
||||
libgtop_sysdeps_2_0_la_SOURCES = nosuid.c siglist.c sysinfo.c \
|
||||
cpu.c loadavg.c \
|
||||
uptime.c netlist.c fsusage.c mem.c \
|
||||
mountlist.c procopenfiles.c procwd.c \
|
||||
procaffinity.c glibtop_private.c open.c
|
||||
|
||||
libgtop_sysdeps_2_0_la_LDFLAGS = $(LT_VERSION_INFO)
|
||||
|
||||
libgtop_sysdeps_suid_2_0_la_LIBADD = $(KVM_LIBS)
|
||||
libgtop_sysdeps_suid_2_0_la_SOURCES = open.c close.c cpu.c mem.c swap.c \
|
||||
uptime.c loadavg.c shm_limits.c msg_limits.c \
|
||||
sem_limits.c proclist.c procstate.c procuid.c \
|
||||
proctime.c procmem.c procsignal.c prockernel.c \
|
||||
procsegment.c procargs.c procmap.c netlist.c \
|
||||
netload.c ppp.c procopenfiles.c fsusage.c \
|
||||
procwd.c procaffinity.c glibtop_private.c
|
||||
libgtop_sysdeps_suid_2_0_la_LIBADD = $(KVM_LIBS) $(EXTRA_SYSDEPS_LIBS)
|
||||
libgtop_sysdeps_suid_2_0_la_SOURCES = suid_open.c close.c swap.c \
|
||||
proclist.c procstate.c procuid.c \
|
||||
proctime.c procmem.c procsignal.c \
|
||||
prockernel.c procsegment.c procargs.c \
|
||||
procmap.c netload.c ppp.c
|
||||
|
||||
# TODO should be made nosuid like FreeBSD
|
||||
libgtop_sysdeps_suid_2_0_la_SOURCES += shm_limits.c msg_limits.c sem_limits.c
|
||||
|
||||
libgtop_sysdeps_suid_2_0_la_LDFLAGS = $(LT_VERSION_INFO)
|
||||
|
||||
|
@@ -42,7 +42,7 @@ static int mib2 [] = { CTL_KERN, KERN_CPTIME };
|
||||
/* Init function. */
|
||||
|
||||
void
|
||||
_glibtop_init_cpu_p (glibtop *server)
|
||||
_glibtop_init_cpu_s (glibtop *server)
|
||||
{
|
||||
server->sysdeps.cpu = _glibtop_sysdeps_cpu;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ _glibtop_init_cpu_p (glibtop *server)
|
||||
/* Provides information about cpu usage. */
|
||||
|
||||
void
|
||||
glibtop_get_cpu_p (glibtop *server, glibtop_cpu *buf)
|
||||
glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf)
|
||||
{
|
||||
gulong cpts [CPUSTATES];
|
||||
|
||||
|
@@ -1,13 +1,4 @@
|
||||
#include <config.h>
|
||||
|
||||
/*
|
||||
* statvfs is lacking various members which are present in statfs,
|
||||
* like f_(a)syncreads and f_(a)syncwrites. So eventhough we have
|
||||
* statvfs, undef it here untill those members are added.
|
||||
*/
|
||||
#undef HAVE_SYS_STATVFS_H
|
||||
#undef STAT_STATVFS
|
||||
|
||||
#include <glibtop.h>
|
||||
#include <glibtop/error.h>
|
||||
#include <glibtop/fsusage.h>
|
||||
@@ -18,44 +9,57 @@
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
#if defined (HAVE_SYS_STATVFS_H)
|
||||
#include <sys/statvfs.h>
|
||||
#else
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void
|
||||
_glibtop_openbsd_get_fsusage_read_write(glibtop *server,
|
||||
glibtop_fsusage *buf,
|
||||
const char *path);
|
||||
static const unsigned long _glibtop_sysdeps_fsusage =
|
||||
(1L << GLIBTOP_FSUSAGE_BLOCKS) + (1L << GLIBTOP_FSUSAGE_BFREE)
|
||||
+ (1L << GLIBTOP_FSUSAGE_BAVAIL) + (1L << GLIBTOP_FSUSAGE_FILES)
|
||||
+ (1L << GLIBTOP_FSUSAGE_FFREE) + (1L << GLIBTOP_FSUSAGE_BLOCK_SIZE);
|
||||
|
||||
void
|
||||
_glibtop_openbsd_get_fsusage_read_write(glibtop *server,
|
||||
glibtop_fsusage *buf,
|
||||
const char *path)
|
||||
static void
|
||||
_glibtop_get_fsusage_read_write (glibtop *server, glibtop_fsusage *buf, const char *path)
|
||||
{
|
||||
int result;
|
||||
#if defined (STAT_STATVFS)
|
||||
struct statvfs sfs;
|
||||
#else
|
||||
struct statfs sfs;
|
||||
#endif
|
||||
int result;
|
||||
struct statfs sfs;
|
||||
|
||||
#if defined (STAT_STATVFS)
|
||||
result = statvfs (path, &sfs);
|
||||
#else
|
||||
result = statfs (path, &sfs);
|
||||
#endif
|
||||
result = statfs (path, &sfs);
|
||||
|
||||
if (result == -1) {
|
||||
return;
|
||||
}
|
||||
if (result == -1) {
|
||||
glibtop_warn_io_r (server, "statfs");
|
||||
return;
|
||||
}
|
||||
|
||||
buf->read = sfs.f_syncreads + sfs.f_asyncreads;
|
||||
buf->write = sfs.f_syncwrites + sfs.f_asyncwrites;
|
||||
buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
|
||||
buf->read = sfs.f_syncreads + sfs.f_asyncreads;
|
||||
buf->write = sfs.f_syncwrites + sfs.f_asyncwrites;
|
||||
buf->flags |= (1 << GLIBTOP_FSUSAGE_READ) | (1 << GLIBTOP_FSUSAGE_WRITE);
|
||||
}
|
||||
|
||||
void
|
||||
glibtop_get_fsusage_s(glibtop *server, glibtop_fsusage *buf, const char *path)
|
||||
{
|
||||
struct statvfs fsd;
|
||||
|
||||
glibtop_init_r (&server, 0, 0);
|
||||
|
||||
memset (buf, 0, sizeof (glibtop_fsusage));
|
||||
|
||||
if (statvfs (path, &fsd) < 0)
|
||||
return;
|
||||
|
||||
buf->block_size = fsd.f_frsize;
|
||||
buf->blocks = fsd.f_blocks;
|
||||
buf->bfree = fsd.f_bfree;
|
||||
buf->bavail = (fsd.f_bavail > fsd.f_bfree) ? 0 : fsd.f_bavail;
|
||||
buf->files = fsd.f_files;
|
||||
buf->ffree = fsd.f_ffree;
|
||||
|
||||
buf->flags = _glibtop_sysdeps_fsusage;
|
||||
|
||||
_glibtop_get_fsusage_read_write(server, buf, path);
|
||||
}
|
||||
|
||||
|
@@ -24,11 +24,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GLIBTOP_SUID_CPU (1 << GLIBTOP_SYSDEPS_CPU)
|
||||
#define GLIBTOP_SUID_MEM (1 << GLIBTOP_SYSDEPS_MEM)
|
||||
#define GLIBTOP_SUID_SWAP (1 << GLIBTOP_SYSDEPS_SWAP)
|
||||
#define GLIBTOP_SUID_UPTIME (1 << GLIBTOP_SYSDEPS_UPTIME)
|
||||
#define GLIBTOP_SUID_LOADAVG (1 << GLIBTOP_SYSDEPS_LOADAVG)
|
||||
#define GLIBTOP_SUID_SHM_LIMITS (1 << GLIBTOP_SYSDEPS_SHM_LIMITS)
|
||||
#define GLIBTOP_SUID_MSG_LIMITS (1 << GLIBTOP_SYSDEPS_MSG_LIMITS)
|
||||
#define GLIBTOP_SUID_SEM_LIMITS (1 << GLIBTOP_SYSDEPS_SEM_LIMITS)
|
||||
@@ -43,8 +39,12 @@ G_BEGIN_DECLS
|
||||
#define GLIBTOP_SUID_PROC_ARGS (1 << GLIBTOP_SYSDEPS_PROC_ARGS)
|
||||
#define GLIBTOP_SUID_PROC_MAP (1 << GLIBTOP_SYSDEPS_PROC_MAP)
|
||||
#define GLIBTOP_SUID_NETLOAD (1 << GLIBTOP_SYSDEPS_NETLOAD)
|
||||
#define GLIBTOP_SUID_NETLIST 0
|
||||
#define GLIBTOP_SUID_PPP (1 << GLIBTOP_SYSDEPS_PPP)
|
||||
#define GLIBTOP_SUID_CPU 0
|
||||
#define GLIBTOP_SUID_MEM 0
|
||||
#define GLIBTOP_SUID_UPTIME 0
|
||||
#define GLIBTOP_SUID_LOADAVG 0
|
||||
#define GLIBTOP_SUID_NETLIST 0
|
||||
#define GLIBTOP_SUID_PROC_WD 0
|
||||
#define GLIBTOP_SUID_PROC_AFFINITY 0
|
||||
|
||||
|
@@ -32,7 +32,7 @@ static const unsigned long _glibtop_sysdeps_loadavg =
|
||||
/* Init function. */
|
||||
|
||||
void
|
||||
_glibtop_init_loadavg_p (glibtop *server)
|
||||
_glibtop_init_loadavg_s (glibtop *server)
|
||||
{
|
||||
server->sysdeps.loadavg = _glibtop_sysdeps_loadavg;
|
||||
}
|
||||
@@ -40,7 +40,7 @@ _glibtop_init_loadavg_p (glibtop *server)
|
||||
/* Provides load averange. */
|
||||
|
||||
void
|
||||
glibtop_get_loadavg_p (glibtop *server, glibtop_loadavg *buf)
|
||||
glibtop_get_loadavg_s (glibtop *server, glibtop_loadavg *buf)
|
||||
{
|
||||
double ldavg[3];
|
||||
int i;
|
||||
|
@@ -48,12 +48,6 @@ static int pageshift; /* log base 2 of the pagesize */
|
||||
/* define pagetok in terms of pageshift */
|
||||
#define pagetok(size) ((size) << pageshift)
|
||||
|
||||
/* nlist structure for kernel access */
|
||||
static struct nlist nlst [] = {
|
||||
{ "_bufpages" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* MIB array for sysctl */
|
||||
static int vmmeter_mib [] = { CTL_VM, VM_METER };
|
||||
static int uvmexp_mib [] = { CTL_VM, VM_UVMEXP };
|
||||
@@ -62,15 +56,10 @@ static int bcstats_mib [] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT };
|
||||
/* Init function. */
|
||||
|
||||
void
|
||||
_glibtop_init_mem_p (glibtop *server)
|
||||
_glibtop_init_mem_s (glibtop *server)
|
||||
{
|
||||
register int pagesize;
|
||||
|
||||
if (kvm_nlist (server->machine.kd, nlst) < 0) {
|
||||
glibtop_warn_io_r (server, "kvm_nlist (mem)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the page size and calculate pageshift from it */
|
||||
pagesize = sysconf(_SC_PAGESIZE);
|
||||
pageshift = 0;
|
||||
@@ -86,7 +75,7 @@ _glibtop_init_mem_p (glibtop *server)
|
||||
}
|
||||
|
||||
void
|
||||
glibtop_get_mem_p (glibtop *server, glibtop_mem *buf)
|
||||
glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
|
||||
{
|
||||
struct vmtotal vmt;
|
||||
struct uvmexp uvmexp;
|
||||
|
168
sysdeps/openbsd/mountlist.c
Normal file
168
sysdeps/openbsd/mountlist.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/* mountlist.c -- return a list of mounted filesystems
|
||||
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glibtop.h>
|
||||
#include <glibtop/mountlist.h>
|
||||
|
||||
/* A mount table entry. */
|
||||
struct mount_entry
|
||||
{
|
||||
char *me_devname; /* Device node pathname, including "/dev/". */
|
||||
char *me_mountdir; /* Mount point directory pathname. */
|
||||
char *me_type; /* "nfs", "4.2", etc. */
|
||||
dev_t me_dev; /* Device number of me_mountdir. */
|
||||
struct mount_entry *me_next;
|
||||
};
|
||||
|
||||
static struct mount_entry *read_filesystem_list (void);
|
||||
|
||||
/* Return a list of the currently mounted filesystems, or NULL on error.
|
||||
Add each entry to the tail of the list so that they stay in order.
|
||||
*/
|
||||
|
||||
static struct mount_entry *
|
||||
read_filesystem_list (void)
|
||||
{
|
||||
struct mount_entry *mount_list;
|
||||
struct mount_entry *me;
|
||||
struct mount_entry *mtail;
|
||||
|
||||
/* Start the list off with a dummy entry. */
|
||||
me = g_new (struct mount_entry, 1);
|
||||
me->me_next = NULL;
|
||||
mount_list = mtail = me;
|
||||
{
|
||||
struct statfs *fsp;
|
||||
int entries;
|
||||
|
||||
entries = getmntinfo (&fsp, MNT_NOWAIT);
|
||||
if (entries < 0)
|
||||
return NULL;
|
||||
while (entries-- > 0)
|
||||
{
|
||||
me = (struct mount_entry *) g_malloc (sizeof (struct mount_entry));
|
||||
me->me_devname = g_strdup (fsp->f_mntfromname);
|
||||
me->me_mountdir = g_strdup (fsp->f_mntonname);
|
||||
me->me_type = g_strdup (fsp->f_fstypename);
|
||||
me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
|
||||
me->me_next = NULL;
|
||||
|
||||
/* Add to the linked list. */
|
||||
mtail->me_next = me;
|
||||
mtail = me;
|
||||
fsp++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the dummy head. */
|
||||
me = mount_list;
|
||||
mount_list = mount_list->me_next;
|
||||
g_free (me);
|
||||
return mount_list;
|
||||
}
|
||||
|
||||
static gboolean ignore_mount_entry(const struct mount_entry *me)
|
||||
{
|
||||
/* keep sorted */
|
||||
static const char ignored[][17] = {
|
||||
"autofs",
|
||||
"devfs",
|
||||
"fusectl",
|
||||
"linprocfs",
|
||||
"linsysfs",
|
||||
"mfs",
|
||||
"none",
|
||||
"nfs",
|
||||
"nullfs",
|
||||
"nwfs",
|
||||
"portalfs",
|
||||
"proc",
|
||||
"procfs",
|
||||
"smbfs",
|
||||
"tmpfs",
|
||||
"unionfs",
|
||||
"unknown"
|
||||
};
|
||||
|
||||
typedef int (*Comparator)(const void*, const void*);
|
||||
|
||||
return bsearch(me->me_type,
|
||||
ignored, G_N_ELEMENTS(ignored), sizeof ignored[0],
|
||||
(Comparator) strcmp) != NULL;
|
||||
}
|
||||
|
||||
|
||||
glibtop_mountentry *
|
||||
glibtop_get_mountlist_s (glibtop *server, glibtop_mountlist *buf, int all_fs)
|
||||
{
|
||||
struct mount_entry *entries, *cur, *next;
|
||||
|
||||
GArray *mount_array = g_array_new(FALSE, FALSE,
|
||||
sizeof(glibtop_mountentry));
|
||||
|
||||
glibtop_init_r (&server, 0, 0);
|
||||
|
||||
memset (buf, 0, sizeof (glibtop_mountlist));
|
||||
|
||||
/* Read filesystem list. */
|
||||
|
||||
if((entries = read_filesystem_list ()) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (cur = &entries[0]; cur != NULL; cur = next) {
|
||||
|
||||
if(all_fs || !ignore_mount_entry(cur)) {
|
||||
/* add a new glibtop_mountentry */
|
||||
glibtop_mountentry e;
|
||||
|
||||
g_strlcpy(e.devname, cur->me_devname, sizeof e.devname);
|
||||
g_strlcpy(e.mountdir, cur->me_mountdir, sizeof e.mountdir);
|
||||
g_strlcpy(e.type, cur->me_type, sizeof e.type);
|
||||
e.dev = cur->me_dev;
|
||||
|
||||
g_array_append_val(mount_array, e);
|
||||
}
|
||||
|
||||
/* free current mount_entry and move to the next */
|
||||
next = cur->me_next;
|
||||
g_free(cur->me_devname);
|
||||
g_free(cur->me_mountdir);
|
||||
g_free(cur->me_type);
|
||||
g_free(cur);
|
||||
}
|
||||
|
||||
buf->size = sizeof (glibtop_mountentry);
|
||||
buf->number = mount_array->len;
|
||||
buf->total = buf->number * buf->size;
|
||||
|
||||
buf->flags = (1 << GLIBTOP_MOUNTLIST_SIZE)
|
||||
| (1 << GLIBTOP_MOUNTLIST_NUMBER)
|
||||
| (1 << GLIBTOP_MOUNTLIST_TOTAL);
|
||||
|
||||
return (glibtop_mountentry*) g_array_free(mount_array, FALSE);
|
||||
}
|
@@ -21,16 +21,8 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <glibtop.h>
|
||||
#include <glibtop/open.h>
|
||||
#include <glibtop/close.h>
|
||||
|
||||
void
|
||||
glibtop_open_s (glibtop *server,
|
||||
const char *program_name,
|
||||
const unsigned long features,
|
||||
const unsigned flags)
|
||||
{ }
|
||||
|
||||
void
|
||||
glibtop_close_s (glibtop *server)
|
||||
{ }
|
||||
|
@@ -20,75 +20,17 @@
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <sys/types.h>
|
||||
#include <glibtop.h>
|
||||
#include <glibtop/error.h>
|
||||
#include <glibtop/open.h>
|
||||
#include <glibtop/init_hooks.h>
|
||||
|
||||
/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */
|
||||
#include <glibtop_private.h>
|
||||
|
||||
|
||||
void
|
||||
glibtop_init_p (glibtop *server, const unsigned long features,
|
||||
const unsigned flags)
|
||||
{
|
||||
const _glibtop_init_func_t *init_fkt;
|
||||
|
||||
if (server == NULL)
|
||||
glibtop_error_r (NULL, "glibtop_init_p (server == NULL)");
|
||||
|
||||
/* Do the initialization, but only if not already initialized. */
|
||||
|
||||
if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) {
|
||||
glibtop_open_p (server, "glibtop", features, flags);
|
||||
|
||||
for (init_fkt = _glibtop_init_hook_p; *init_fkt; init_fkt++)
|
||||
(*init_fkt) (server);
|
||||
|
||||
server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
glibtop_open_p (glibtop *server, const char *program_name,
|
||||
glibtop_open_s (glibtop *server, const char *program_name,
|
||||
const unsigned long features,
|
||||
const unsigned flags)
|
||||
{
|
||||
char errbuf[_POSIX2_LINE_MAX];
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ());
|
||||
#endif
|
||||
|
||||
/* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */
|
||||
|
||||
server->machine.uid = getuid ();
|
||||
server->machine.euid = geteuid ();
|
||||
server->machine.gid = getgid ();
|
||||
server->machine.egid = getegid ();
|
||||
|
||||
server->os_version_code = OpenBSD;
|
||||
|
||||
/* Setup machine-specific data */
|
||||
server->machine.kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf);
|
||||
|
||||
if (server->machine.kd == NULL)
|
||||
glibtop_error_io_r (server, "kvm_open");
|
||||
|
||||
/* Drop priviledges. */
|
||||
|
||||
if (setreuid (server->machine.euid, server->machine.uid))
|
||||
_exit (1);
|
||||
|
||||
if (setregid (server->machine.egid, server->machine.gid))
|
||||
_exit (1);
|
||||
|
||||
/* !!! END OF SUID ROOT PART !!! */
|
||||
|
||||
/* Our effective uid is now those of the user invoking the server,
|
||||
* so we do no longer have any priviledges. */
|
||||
|
||||
/* NOTE: On FreeBSD, we do not need to be suid root, we just need to
|
||||
* be sgid kmem.
|
||||
*
|
||||
* The server will only use setegid() to get back it's priviledges,
|
||||
* so it will fail if it is suid root and not sgid kmem. */
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* procaffinity stub.
|
||||
* TODO (procaffinity stub)
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@@ -34,12 +34,13 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
static const unsigned long _glibtop_sysdeps_proc_kernel_pstats =
|
||||
(1L << GLIBTOP_PROC_KERNEL_K_FLAGS) +
|
||||
(1L << GLIBTOP_PROC_KERNEL_MIN_FLT) +
|
||||
(1L << GLIBTOP_PROC_KERNEL_MAJ_FLT);
|
||||
|
||||
static const unsigned long _glibtop_sysdeps_proc_kernel_wchan =
|
||||
(1L << GLIBTOP_PROC_KERNEL_NWCHAN) +
|
||||
(1L << GLIBTOP_PROC_KERNEL_WCHAN);
|
||||
(1L << GLIBTOP_PROC_KERNEL_WCHAN) +
|
||||
(1L << GLIBTOP_PROC_KERNEL_NWCHAN);
|
||||
|
||||
/* Init function. */
|
||||
|
||||
@@ -68,22 +69,39 @@ glibtop_get_proc_kernel_p (glibtop *server,
|
||||
/* It does not work for the swapper task. */
|
||||
if (pid == 0) return;
|
||||
|
||||
glibtop_suid_enter (server);
|
||||
|
||||
/* Get the process information */
|
||||
pinfo = kvm_getprocs (server->machine.kd, KERN_PROC_PID, pid,
|
||||
sizeof(*pinfo), &count);
|
||||
if ((pinfo == NULL) || (count != 1)) {
|
||||
glibtop_warn_io_r (server, "kvm_getprocs (%d)", pid);
|
||||
glibtop_suid_leave (server);
|
||||
return;
|
||||
}
|
||||
|
||||
buf->min_flt = pinfo[0].p_uru_minflt;
|
||||
buf->maj_flt = pinfo[0].p_uru_majflt;
|
||||
glibtop_suid_leave (server);
|
||||
|
||||
buf->nwchan = pinfo[0].p_wchan;
|
||||
if (pinfo[0].p_wchan && pinfo[0].p_wmesg)
|
||||
g_strlcpy(buf->wchan, pinfo[0].p_wmesg,
|
||||
sizeof buf->wchan);
|
||||
#define PROC_WCHAN p_wchan
|
||||
#define PROC_WMESG p_wmesg
|
||||
|
||||
buf->flags |= (_glibtop_sysdeps_proc_kernel_wchan
|
||||
| _glibtop_sysdeps_proc_kernel_pstats);
|
||||
buf->nwchan = (unsigned long) pinfo [0].PROC_WCHAN;
|
||||
|
||||
buf->flags |= (1L << GLIBTOP_PROC_KERNEL_NWCHAN);
|
||||
|
||||
if (pinfo [0].PROC_WCHAN && pinfo [0].PROC_WMESG[0] != 0) {
|
||||
g_strlcpy (buf->wchan, pinfo [0].PROC_WMESG,
|
||||
sizeof buf->wchan);
|
||||
buf->flags |= (1L << GLIBTOP_PROC_KERNEL_WCHAN);
|
||||
} else {
|
||||
buf->wchan [0] = 0;
|
||||
}
|
||||
|
||||
buf->k_flags = (unsigned long) pinfo [0].p_flag;
|
||||
buf->min_flt = (unsigned long) pinfo [0].p_uru_minflt;
|
||||
buf->maj_flt = (unsigned long) pinfo [0].p_uru_majflt;
|
||||
|
||||
buf->flags |= _glibtop_sysdeps_proc_kernel_pstats;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@@ -191,8 +191,11 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
|
||||
|
||||
if (kvm_read (server->machine.kd,
|
||||
(unsigned long) pinfo [0].p_vmspace,
|
||||
(char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace))
|
||||
glibtop_error_io_r (server, "kvm_read (vmspace)");
|
||||
(char *) &vmspace, sizeof (vmspace)) != sizeof (vmspace)) {
|
||||
glibtop_warn_io_r (server, "kvm_read (vmspace)");
|
||||
glibtop_suid_leave (server);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RB_INIT(&root);
|
||||
nentries = load_vmmap_entries(server,
|
||||
@@ -236,6 +239,7 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
|
||||
&vnode, sizeof (vnode)) != sizeof (vnode)) {
|
||||
glibtop_warn_io_r (server, "kvm_read (vnode)");
|
||||
unload_vmmap_entries(RB_ROOT(&root));
|
||||
glibtop_suid_leave (server);
|
||||
return (glibtop_map_entry*) g_array_free(maps, TRUE);
|
||||
}
|
||||
|
||||
@@ -248,8 +252,12 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
|
||||
|
||||
if (kvm_read (server->machine.kd,
|
||||
(unsigned long) vnode.v_data,
|
||||
&inode, sizeof (inode)) != sizeof (inode))
|
||||
glibtop_error_io_r (server, "kvm_read (inode)");
|
||||
&inode, sizeof (inode)) != sizeof (inode)) {
|
||||
glibtop_warn_io_r (server, "kvm_read (inode)");
|
||||
unload_vmmap_entries(RB_ROOT(&root));
|
||||
glibtop_suid_leave (server);
|
||||
return (glibtop_map_entry*) g_array_free(maps, TRUE);
|
||||
}
|
||||
|
||||
inum = inode.i_number;
|
||||
dev = inode.i_dev;
|
||||
@@ -276,6 +284,8 @@ glibtop_get_proc_map_p (glibtop *server, glibtop_proc_map *buf,
|
||||
mentry->perm |= GLIBTOP_MAP_PERM_EXECUTE;
|
||||
}
|
||||
|
||||
glibtop_suid_leave (server);
|
||||
|
||||
buf->flags = _glibtop_sysdeps_proc_map;
|
||||
|
||||
buf->number = maps->len;
|
||||
|
@@ -56,59 +56,6 @@ _glibtop_init_proc_time_p (glibtop *server)
|
||||
_glibtop_sysdeps_proc_time_user;
|
||||
}
|
||||
|
||||
/* Taken from /usr/src/sys/kern/kern_resource.c */
|
||||
|
||||
/*
|
||||
* Transform the running time and tick information in proc p into user,
|
||||
* system, and interrupt time usage.
|
||||
*/
|
||||
|
||||
static void
|
||||
calcru(struct proc *p, struct timeval *up, struct timeval *sp,
|
||||
struct timeval *ip)
|
||||
{
|
||||
quad_t totusec;
|
||||
u_quad_t u, st, ut, it, tot;
|
||||
long sec, nsec;
|
||||
struct timeval tv;
|
||||
|
||||
st = p->p_sticks;
|
||||
ut = p->p_uticks;
|
||||
it = p->p_iticks;
|
||||
|
||||
tot = st + ut + it;
|
||||
if (tot == 0) {
|
||||
st = 1;
|
||||
tot = 1;
|
||||
}
|
||||
|
||||
sec = p->p_rtime.tv_sec;
|
||||
nsec = p->p_rtime.tv_nsec;
|
||||
|
||||
totusec = (quad_t)sec * 1000000 + nsec/1000;
|
||||
|
||||
if (totusec < 0) {
|
||||
/* XXX no %qd in kernel. Truncate. */
|
||||
fprintf (stderr, "calcru: negative time: %ld usec\n",
|
||||
(long)totusec);
|
||||
totusec = 0;
|
||||
}
|
||||
|
||||
|
||||
u = totusec;
|
||||
st = (u * st) / tot;
|
||||
sp->tv_sec = st / 1000000;
|
||||
sp->tv_usec = st % 1000000;
|
||||
ut = (u * ut) / tot;
|
||||
up->tv_sec = ut / 1000000;
|
||||
up->tv_usec = ut % 1000000;
|
||||
if (ip != NULL) {
|
||||
it = (u * it) / tot;
|
||||
ip->tv_sec = it / 1000000;
|
||||
ip->tv_usec = it % 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
/* Provides detailed information about a process. */
|
||||
|
||||
void
|
||||
|
@@ -39,58 +39,6 @@ _glibtop_init_proc_wd_s(glibtop *server)
|
||||
server->sysdeps.proc_wd = _glibtop_sysdeps_proc_wd;
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
parse_output(const char *output, glibtop_proc_wd *buf)
|
||||
{
|
||||
GPtrArray *dirs;
|
||||
char **lines;
|
||||
gboolean nextwd = FALSE;
|
||||
gboolean nextrtd = FALSE;
|
||||
gboolean havertd = FALSE;
|
||||
guint i;
|
||||
guint len;
|
||||
|
||||
dirs = g_ptr_array_sized_new(1);
|
||||
|
||||
lines = g_strsplit(output, "\n", 0);
|
||||
len = g_strv_length(lines);
|
||||
|
||||
for (i = 0; i < len && lines[i]; i++) {
|
||||
if (strlen(lines[i]) < 2)
|
||||
continue;
|
||||
|
||||
if (!strcmp(lines[i], "fcwd")) {
|
||||
nextwd = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(lines[i], "frtd")) {
|
||||
nextrtd = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!g_str_has_prefix(lines[i], "n"))
|
||||
continue;
|
||||
|
||||
if (nextwd) {
|
||||
g_ptr_array_add(dirs, g_strdup(lines[i] + 1));
|
||||
nextwd = FALSE;
|
||||
}
|
||||
|
||||
if (nextrtd && !havertd) {
|
||||
g_strlcpy(buf->root, lines[i] + 1,
|
||||
sizeof(buf->root));
|
||||
buf->flags |= (1 << GLIBTOP_PROC_WD_ROOT);
|
||||
nextrtd = FALSE;
|
||||
havertd = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev(lines);
|
||||
|
||||
return dirs;
|
||||
}
|
||||
|
||||
char**
|
||||
glibtop_get_proc_wd_s(glibtop *server, glibtop_proc_wd *buf, pid_t pid)
|
||||
{
|
||||
|
92
sysdeps/openbsd/suid_open.c
Normal file
92
sysdeps/openbsd/suid_open.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/* Copyright (C) 1998 Joshua Sled
|
||||
This file is part of LibGTop 1.0.
|
||||
|
||||
Contributed by Joshua Sled <jsled@xcf.berkeley.edu>, July 1998.
|
||||
|
||||
LibGTop is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
LibGTop is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with LibGTop; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <glibtop.h>
|
||||
#include <glibtop/error.h>
|
||||
#include <glibtop/cpu.h>
|
||||
#include <glibtop/open.h>
|
||||
#include <glibtop/init_hooks.h>
|
||||
|
||||
|
||||
/* !!! THIS FUNCTION RUNS SUID ROOT - CHANGE WITH CAUTION !!! */
|
||||
|
||||
void
|
||||
glibtop_init_p (glibtop *server, const unsigned long features,
|
||||
const unsigned flags)
|
||||
{
|
||||
const _glibtop_init_func_t *init_fkt;
|
||||
|
||||
if (server == NULL)
|
||||
glibtop_error_r (NULL, "glibtop_init_p (server == NULL)");
|
||||
|
||||
/* Do the initialization, but only if not already initialized. */
|
||||
|
||||
if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) {
|
||||
glibtop_open_p (server, "glibtop", features, flags);
|
||||
|
||||
for (init_fkt = _glibtop_init_hook_p; *init_fkt; init_fkt++)
|
||||
(*init_fkt) (server);
|
||||
|
||||
server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
glibtop_open_p (glibtop *server, const char *program_name,
|
||||
const unsigned long features,
|
||||
const unsigned flags)
|
||||
{
|
||||
char errbuf[_POSIX2_LINE_MAX];
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr, "DEBUG (%d): glibtop_open_p ()\n", getpid ());
|
||||
#endif
|
||||
|
||||
/* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */
|
||||
server->machine.uid = getuid ();
|
||||
server->machine.euid = geteuid ();
|
||||
server->machine.gid = getgid ();
|
||||
server->machine.egid = getegid ();
|
||||
/* Setup machine-specific data */
|
||||
server->machine.kd = kvm_openfiles (NULL, NULL, NULL, O_RDONLY, errbuf);
|
||||
|
||||
if (server->machine.kd == NULL)
|
||||
glibtop_error_io_r (server, "kvm_open");
|
||||
|
||||
/* Drop priviledges. */
|
||||
|
||||
if (setreuid (server->machine.euid, server->machine.uid))
|
||||
_exit (1);
|
||||
|
||||
if (setregid (server->machine.egid, server->machine.gid))
|
||||
_exit (1);
|
||||
|
||||
/* !!! END OF SUID ROOT PART !!! */
|
||||
|
||||
/* Our effective uid is now those of the user invoking the server,
|
||||
* so we do no longer have any priviledges. */
|
||||
|
||||
/* NOTE: On OpenBSD, we do not need to be suid root, we just need to
|
||||
* be sgid kmem.
|
||||
*
|
||||
* The server will only use setegid() to get back it's priviledges,
|
||||
* so it will fail if it is suid root and not sgid kmem. */
|
||||
}
|
@@ -37,7 +37,7 @@ static const unsigned long _required_cpu_flags =
|
||||
/* Init function. */
|
||||
|
||||
void
|
||||
_glibtop_init_uptime_p (glibtop *server)
|
||||
_glibtop_init_uptime_s (glibtop *server)
|
||||
{
|
||||
server->sysdeps.uptime = _glibtop_sysdeps_uptime;
|
||||
}
|
||||
@@ -45,7 +45,7 @@ _glibtop_init_uptime_p (glibtop *server)
|
||||
/* Provides uptime and idle time. */
|
||||
|
||||
void
|
||||
glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf)
|
||||
glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf)
|
||||
{
|
||||
time_t now;
|
||||
int mib[2];
|
||||
@@ -63,7 +63,7 @@ glibtop_get_uptime_p (glibtop *server, glibtop_uptime *buf)
|
||||
buf->boot_time = boottime.tv_sec;
|
||||
}
|
||||
|
||||
glibtop_get_cpu_p (server, &cpu);
|
||||
glibtop_get_cpu_s (server, &cpu);
|
||||
|
||||
/* Put something clever in buf->idletime: CP_IDLE. */
|
||||
buf->idletime = (double) cpu.idle / (double) cpu.frequency;
|
||||
|
Reference in New Issue
Block a user