⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 solaris.c

📁 系统任务管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GKrellM|  Copyright (C) 1999-2006 Bill Wilson||  Author:  Bill Wilson    billw@gkrellm.net|  Latest versions might be found at:  http://gkrellm.net||  Solaris code:  Daisuke Yabuki <dxy@acm.org>||  This program is free software which I release under the GNU General Public|  License. You may redistribute and/or modify this program under the terms|  of that license as published by the Free Software Foundation; either|  version 2 of the License, 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.  Version 2 is in the|  COPYRIGHT file in the top level directory of this distribution.| |  To get a copy of the GNU General Puplic License, write to the Free Software|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include <kstat.h>#include <kvm.h>#include <fcntl.h>kstat_ctl_t *kc;kvm_t *kd = NULL;struct nlist nl[] = {     { "mpid" },    { 0 }};extern void solaris_list_harddisks(void);voidgkrellm_sys_main_init(void)	{	/* 	 * Most of stats (cpu, proc, disk, memory, net and uptime) are 	 * unavailable if kstat_open() failed. So we just exit in that case.	 */	if ((kc = kstat_open()) == NULL) {		perror("kstat_open");		exit(1);	}	/*	 * kvm is utilized solely for getting a value for proc.n_forks 	 * from kernel variable called mpid. Even if kvm_open() fails,	 * we proceed without it.	 */	if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL)) != NULL) { 		kvm_nlist(kd, nl);	}        /*         * a function called by the following requires sys gid privilege.         * the folowing function should be performed here just for that reason.         */         solaris_list_harddisks();        if (setgid(getgid()) != 0) {		perror("Failed to drop setgid privilege");		exit(1);        }	}voidgkrellm_sys_main_cleanup(void)	{	}/* ===================================================================== *//* CPU monitor interface */#include <kstat.h>#include <sys/sysinfo.h>voidgkrellm_sys_cpu_read_data(void){    extern kstat_ctl_t *kc;    kstat_t *ksp;    cpu_stat_t cs;    if (kstat_chain_update(kc) == -1) {        perror("kstat_chain_update");        return;    }    for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {        if (strcmp(ksp->ks_module, "cpu_stat"))             continue;        if (kstat_read(kc, ksp, &cs) == -1) {            perror("kstat_read");            continue;        }		gkrellm_cpu_assign_data(ksp->ks_instance,				cs.cpu_sysinfo.cpu[CPU_USER],				cs.cpu_sysinfo.cpu[CPU_WAIT],				cs.cpu_sysinfo.cpu[CPU_KERNEL],				cs.cpu_sysinfo.cpu[CPU_IDLE]);    }}/* * note: on some SPARC systems, you can monitor temperature of CPUs  * with kstat (unix::temperature:[min/max/state/trend...]) */gbooleangkrellm_sys_cpu_init() {    extern kstat_ctl_t *kc;    kstat_t *ksp;	gint	n_cpus = 0;    if(kstat_chain_update(kc) == -1) {        perror("kstat_chain_update");        return FALSE;    }     for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {        if (strcmp(ksp->ks_module, "cpu_stat"))             continue;        if (kstat_read(kc, ksp, NULL) != -1) {			gkrellm_cpu_add_instance(ksp->ks_instance);			++n_cpus;			}    }	gkrellm_cpu_set_number_of_cpus(n_cpus);	return TRUE;}/* ===================================================================== *//* Proc monitor interface */#include <utmp.h>#include <sys/types.h>#include <dirent.h>#include <sys/loadavg.h>#include <kstat.h>#include <fcntl.h>#include <kvm.h>#include <sys/sysinfo.h>voidgkrellm_sys_proc_read_data(void){    double avenrun[LOADAVG_NSTATS], fload = 0;	guint	n_processes = 0, n_forks = 0;     int last_pid;    extern kstat_ctl_t *kc;    kstat_t *ksp;    kstat_named_t *knp;    extern kvm_t *kd;    extern struct nlist nl[];    if (!GK.second_tick) /* Only one read per second */        return;    if (getloadavg(avenrun, LOADAVG_NSTATS) > 0)        fload = avenrun[LOADAVG_1MIN];    if (kstat_chain_update(kc) == -1) {        perror("kstat_chain_update");        return;    }    ksp = kstat_lookup(kc, "unix", -1, "system_misc");    if (ksp && kstat_read(kc, ksp, NULL) >= 0) {        knp = (kstat_named_t *)kstat_data_lookup(ksp, "nproc");        if (knp) {             n_processes = knp->value.ui32;        }    }    if (kd) {        if (kvm_kread(kd, nl[0].n_value, (char *)&last_pid, sizeof(int)) != -1)            n_forks = last_pid;    } else {        n_forks = 0;    }    /* NOTE: code to get 'n_running' is not implemented (stays untouched).     * but it wouldn't do any harm since nobody seems to refer to it.     */	gkrellm_proc_assign_data(n_processes, 0, n_forks, fload);}voidgkrellm_sys_proc_read_users(void)	{    static struct utmp *utmpp;	gint	n_users;    n_users = 0;    setutent();    while ((utmpp = getutent()) != NULL) {        if (utmpp->ut_type == USER_PROCESS && utmpp->ut_name[0] != '\0')            n_users++;    }    	gkrellm_proc_assign_users(n_users);}gbooleangkrellm_sys_proc_init(void)    {	return TRUE;	}/* ===================================================================== *//* Disk monitor interface */#include <sys/types.h>#include <sys/sysinfo.h>#include <unistd.h>#include <kstat.h>#include <libdevinfo.h>#include <errno.h>#include <sys/dkio.h>#define UNIT_SHIFT 3#define NAME2MAJOR 0#define MAJOR2NAME 1typedef struct {    gint major;    gchar name[32];} name_to_major_t;static gint check_media_type(kstat_t *);static gint isharddisk(kstat_t *);void solaris_list_harddisks(void);                   /* called from main.c */static gint lookup_name_to_major(name_to_major_t *, int);static gint get_major(gchar *);static gint get_devname(gint, gchar *);static gint get_minor(gint);static gint get_instance(gint); typedef struct {    char name[8];} probed_harddisk;GList *hard_disk_list;gchar *gkrellm_sys_disk_name_from_device(gint device_number, gint unit_number,			gint *order)	{	return NULL;	/* Disk data by device not implemented in Solaris */	}gintgkrellm_sys_disk_order_from_name(gchar *name)	{	return -1;  /* Append as added */	}voidgkrellm_sys_disk_read_data(void){    probed_harddisk *drive;    GList *list;    extern kstat_ctl_t *kc;    kstat_t *ksp;    kstat_io_t kios;    if (kstat_chain_update(kc) == -1) {        perror("kstat_chain_update");        return;    }    for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {	for (list = hard_disk_list; list; list = list->next) {            drive = (probed_harddisk *)list->data;            if(strcmp(drive->name, ksp->ks_name))                continue;            memset((void *)&kios, 0, sizeof(kstat_io_t));            kstat_read(kc, ksp, &kios);	    gkrellm_disk_assign_data_by_name(drive->name,						kios.nread, kios.nwritten, FALSE);	}    }}gbooleangkrellm_sys_disk_init(void)	{	return TRUE;	}  /* Is this needed any longer? */static gintlookup_name_to_major(name_to_major_t *name_to_major, gint type) {    FILE *fp;    char line[80];    char *name, *maj;    gint name2major, major2name;    gint majnum;    name2major = major2name = 0;    switch (type) {        case NAME2MAJOR:            name2major = 1;            break;        case MAJOR2NAME:            major2name = 1;            break;        default:            break;    }    if ((fp = fopen("/etc/name_to_major", "r")) == NULL) {        perror("fopen");        return -1;    }    while (fgets(line, sizeof(line), fp) != NULL) {        name = strtok(line, " \t");        if (name == NULL)            continue;        maj = strtok(NULL, "\n");        if (maj == NULL)            continue;        majnum = (gint) atol(maj);         if (name2major) {            if (strcmp(name_to_major->name, name) == 0) {                name_to_major->major = majnum;                fclose(fp);                return 0;            }        } else if (major2name) {            if (name_to_major->major == majnum) {                strcpy(name_to_major->name, name);                fclose(fp);                return 0;             }        }    }    fclose(fp);    return -1;}#if 0  /* Is this needed any longer? */static gintget_major(gchar *devname) {    /* xlation from device name to major (e.g. sd -> 32) */    name_to_major_t name_to_major;    strcpy(name_to_major.name, devname);    if (lookup_name_to_major(&name_to_major, NAME2MAJOR) < 0)        return -1;    return name_to_major.major;}  /* Is this needed any longer? */static gintget_devname(gint major, gchar *devname) {    /* xlation from major to device name (e.g. 118 -> ssd) */    name_to_major_t name_to_major;    name_to_major.major = major;    if (lookup_name_to_major(&name_to_major, MAJOR2NAME) < 0)        return -1;    strcpy(devname, name_to_major.name);    return 0;}  /* Is this needed any longer? */static gintget_minor(gint instance) {    return instance << UNIT_SHIFT;}  /* Is this needed any longer? */static gintget_instance(gint minor) {    return minor >> UNIT_SHIFT;}#endif/*  * An sd instance could be a cdrom or a harddrive. You can't simply tell, * from contents of kstat, which type of device an sd device is  * (well, maybe you could, but at least i can't.) * It, however, doesn't make much sense to count cdrom read/write as  * "Disk" activity. So I'd like to exclude removable media's from  * monitoring target. In order to do this, I try to open a physical  * device of a corresponding sd instance. If it's succeeded, I assume * it's a hard drive. If I get ENXIO or EBUSY, I'll guess it's CDROM. * If you come up with a better (simpler or safer) way to tell it's  * a removable media or a hard drive, please drop me an e-mail at  * Daisuke Yabuki <dxy@acm.org>.  * I don't know any other driver which handle both hard drive and  * removable media, by the way. I hope it wouldn't do any harm on * other type of devices, i.e. ssd, or IDE drivers.  */ static gintcheck_media_type(kstat_t *ksp) {    gint fd;    char *phys_path, devices_path[256]; /* or OBP_MAXPATHLEN? */    di_node_t node;    static di_node_t root_node = NULL;#if 0    /* Not supported on Solaris 7 */    struct dk_minfo dk;#else    int dkRemovable;#endif    if (root_node == NULL) {        if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {                perror("di_init");                return -1;        }    }    node = di_drv_first_node(ksp->ks_module, root_node);    while (node != DI_NODE_NIL) {        if (di_instance(node) != ksp->ks_instance) {            node = di_drv_next_node(node);            continue;        }        if ((phys_path = di_devfs_path(node)) == NULL) {            perror("di_devfs_path");            return -1;        }        if (sprintf(devices_path, "/devices%s:c,raw", phys_path) <= 0) {            di_devfs_path_free(phys_path);            return -1;        }        if ((fd = open(devices_path, O_RDONLY)) == -1) {            if (errno == ENXIO || errno == EBUSY) {                close(fd);                di_devfs_path_free(phys_path);                return 0; /* guess it's removable media */            } else {#ifdef DEBUG                printf("opening %s\n", devices_path);                printf("unexpected errno: %d\n", errno);                printf("disabled auto-detection/exclusion of removable media\n");#endif                close(fd);                di_devfs_path_free(phys_path);                return -1; /* EACCESS (unless setgid sys) or suchlike */            }        }#if 0	/* Not supported on Solaris 7 */        if (ioctl(fd, DKIOCGMEDIAINFO, &dk) < 0)#else	if (ioctl(fd, DKIOCREMOVABLE, &dkRemovable) < 0)#endif	{            close(fd);            di_devfs_path_free(phys_path);            return -1;        }#if 0        if (dk.dki_media_type == DK_FIXED_DISK)#else        if (!dkRemovable)#endif	{	   close(fd);	   di_devfs_path_free(phys_path);	   return 1;        }	return 0;    }    return -1; /* shouldn't be reached */} static gintisharddisk(kstat_t *ksp) {    if (ksp->ks_type != KSTAT_TYPE_IO)         return 0;    if (strncmp(ksp->ks_class, "disk", 4))         return 0; /* excluding nfs etc. */    if (!strcmp(ksp->ks_module, "fd"))        return 0; /* excluding fd */    if (check_media_type(ksp) == 0)        return 0; /* guess it's removable media (e.g. CD-ROM, CD-R/W etc) */    return 1;}/*  * creating a preliminary list of drives, which should be a complete * list of drives available on the system. the list is not supposed to * contain nfs, fd, cdrom, cdrw etc. */voidsolaris_list_harddisks(void) {    extern kstat_ctl_t *kc;    kstat_t *ksp;    probed_harddisk *drive;    if (kstat_chain_update(kc) == -1) {        perror("kstat_chain_update");        return;    }        for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {        if(isharddisk(ksp)) {             drive = g_new0(probed_harddisk, 1);             hard_disk_list = g_list_append(hard_disk_list, drive);             strcpy(drive->name, ksp->ks_name);        }    }}/* ===================================================================== *//* Inet monitor interface */#include "../inet.h"#include <stropts.h>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -