Blame sysdeps/solaris/open.c

Packit Service 407539
/* Copyright (C) 1998-99 Martin Baulig
Packit Service 407539
   This file is part of LibGTop 1.0.
Packit Service 407539
Packit Service 407539
   Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998.
Packit Service 407539
Packit Service 407539
   LibGTop is free software; you can redistribute it and/or modify it
Packit Service 407539
   under the terms of the GNU General Public License as published by
Packit Service 407539
   the Free Software Foundation; either version 2 of the License,
Packit Service 407539
   or (at your option) any later version.
Packit Service 407539
Packit Service 407539
   LibGTop is distributed in the hope that it will be useful, but WITHOUT
Packit Service 407539
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit Service 407539
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit Service 407539
   for more details.
Packit Service 407539
Packit Service 407539
   You should have received a copy of the GNU General Public License
Packit Service 407539
   along with LibGTop; see the file COPYING. If not, write to the
Packit Service 407539
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit Service 407539
   Boston, MA 02110-1301, USA.
Packit Service 407539
*/
Packit Service 407539
Packit Service 407539
#include <config.h>
Packit Service 407539
#include <glibtop/open.h>
Packit Service 407539
#include <glibtop/cpu.h>
Packit Service 407539
#include <glibtop/error.h>
Packit Service 407539
Packit Service 407539
#include <unistd.h>
Packit Service 407539
#include <dlfcn.h>
Packit Service 407539
#include <sys/types.h>
Packit Service 407539
#include <sys/processor.h>
Packit Service 407539
Packit Service 407539
#include <glibtop_private.h>
Packit Service 407539
Packit Service 407539
/* We need to call this when kstat_chain_update() returns new KID.
Packit Service 407539
 * In that case all kstat pointers and data are invalid, so we
Packit Service 407539
 * need to reread everything. The condition shouldn't happen very
Packit Service 407539
 * often.
Packit Service 407539
 */
Packit Service 407539
Packit Service 407539
void
Packit Service 407539
glibtop_get_kstats(glibtop *server)
Packit Service 407539
{
Packit Service 407539
    kstat_ctl_t *kc = server->machine->kc;
Packit Service 407539
    kstat_t *ksp;
Packit Service 407539
    int nproc_same, new_ncpu;
Packit Service 407539
Packit Service 407539
    server->ncpu = new_ncpu = sysconf(_SC_NPROCESSORS_CONF);
Packit Service 407539
Packit Service 407539
Packit Service 407539
    if(!kc)
Packit Service 407539
    {
Packit Service 407539
	server->ncpu = new_ncpu;
Packit Service 407539
	server->machine->vminfo_kstat = NULL;
Packit Service 407539
	server->machine->system = NULL;
Packit Service 407539
	server->machine->syspages = NULL;
Packit Service 407539
	server->machine->bunyip = NULL;
Packit Service 407539
	return;
Packit Service 407539
    }
Packit Service 407539
Packit Service 407539
    do {
Packit Service 407539
Packit Service 407539
	ksp = kstat_lookup(kc, "unix", -1, "vminfo");
Packit Service 407539
	server->machine->vminfo_kstat = ksp;
Packit Service 407539
	if(ksp)
Packit Service 407539
	{
Packit Service 407539
	    kstat_read(kc, ksp, &server->machine->vminfo);
Packit Service 407539
	    /* Don't change snaptime if we only need to reinitialize kstats */
Packit Service 407539
	    if(!(server->machine->vminfo_snaptime))
Packit Service 407539
		server->machine->vminfo_snaptime = ksp->ks_snaptime;
Packit Service 407539
	}
Packit Service 407539
Packit Service 407539
	/* We don't know why was kstat chain invalidated. It could have
Packit Service 407539
	   been because the number of processors changed. The sysconf()
Packit Service 407539
	   man page says that values returned won't change during the
Packit Service 407539
	   life time of a process, but let's hope that's just an error in
Packit Service 407539
	   the documentation. */
Packit Service 407539
Packit Service 407539
	if((nproc_same = new_ncpu) == server->ncpu)
Packit Service 407539
	{
Packit Service 407539
	    int checked, i;
Packit Service 407539
	    char cpu[20];
Packit Service 407539
Packit Service 407539
	    for(i = 0, checked = 0; i < GLIBTOP_NCPU || checked == new_ncpu; ++i)
Packit Service 407539
                if(!server->machine->cpu_stat_kstat[i])
Packit Service 407539
Packit Service 407539
		{
Packit Service 407539
		    sprintf(cpu, "cpu_stat%d", i);
Packit Service 407539
		    if(!(server->machine->cpu_stat_kstat[i] =
Packit Service 407539
			     kstat_lookup(kc, "cpu_stat", -1, cpu)))
Packit Service 407539
		    {
Packit Service 407539
			nproc_same = 0;
Packit Service 407539
			break;
Packit Service 407539
		    }
Packit Service 407539
		    ++checked;
Packit Service 407539
		}
Packit Service 407539
	}
Packit Service 407539
Packit Service 407539
	if(!nproc_same)
Packit Service 407539
	{
Packit Service 407539
	    processorid_t p;
Packit Service 407539
	    int found;
Packit Service 407539
	    char cpu[20];
Packit Service 407539
Packit Service 407539
	    server->ncpu = new_ncpu = MIN(new_ncpu, GLIBTOP_NCPU);
Packit Service 407539
Packit Service 407539
	    for(p = 0, found = 0; p < GLIBTOP_NCPU && found != new_ncpu; ++p)
Packit Service 407539
	    {
Packit Service 407539
		if(p_online(p, P_STATUS) < 0)
Packit Service 407539
		{
Packit Service 407539
		    server->machine->cpu_stat_kstat[p] = NULL;
Packit Service 407539
		    continue;
Packit Service 407539
		}
Packit Service 407539
		sprintf(cpu, "cpu_stat%d", (int)p);
Packit Service 407539
		server->machine->cpu_stat_kstat[p] =
Packit Service 407539
			kstat_lookup(kc, "cpu_stat", -1, cpu);
Packit Service 407539
		++found;
Packit Service 407539
	    }
Packit Service 407539
	}
Packit Service 407539
Packit Service 407539
	server->machine->system   = kstat_lookup(kc, "unix", -1, "system_misc");
Packit Service 407539
	server->machine->syspages = kstat_lookup(kc, "unix", -1, "system_pages");
Packit Service 407539
	server->machine->bunyip   = kstat_lookup(kc, "bunyip", -1, "mempages");
Packit Service 407539
Packit Service 407539
    } while(kstat_chain_update(kc) > 0 &&
Packit Service 407539
	    (new_ncpu = sysconf(_SC_NPROCESSORS_CONF)));
Packit Service 407539
Packit Service 407539
    /* We'll ignore -1 from kstat_chain_update here, since it really
Packit Service 407539
       shouldn't happen */
Packit Service 407539
}
Packit Service 407539
Packit Service 407539
void
Packit Service 407539
glibtop_open_s (glibtop *server, const char *program_name,
Packit Service 407539
		const unsigned long features, const unsigned flags)
Packit Service 407539
{
Packit Service 407539
    kstat_ctl_t *kc;
Packit Service 407539
    kstat_t *ksp;
Packit Service 407539
    kstat_named_t *kn;
Packit Service 407539
    int i, page;
Packit Service 407539
    void *dl;
Packit Service 407539
Packit Service 407539
    server->name = program_name;
Packit Service 407539
Packit Service 407539
    page = sysconf(_SC_PAGESIZE) >> 10;
Packit Service 407539
    for(i = 0; page; ++i, page >>= 1);
Packit Service 407539
    server->machine->pagesize = i - 1;
Packit Service 407539
    server->machine->ticks = sysconf(_SC_CLK_TCK);
Packit Service 407539
    if(server->machine->kc)
Packit Service 407539
    	kstat_close(server->machine->kc);
Packit Service 407539
    server->machine->kc = kc = kstat_open ();
Packit Service 407539
Packit Service 407539
#if 0
Packit Service 407539
    for (ksp = server->machine->kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
Packit Service 407539
	if (!strcmp (ksp->ks_class, "vm") && !strcmp (ksp->ks_name, "vminfo")) {
Packit Service 407539
	    server->machine->vminfo_kstat = ksp;
Packit Service 407539
	    kstat_read (server->machine->kc, ksp, &server->machine->vminfo);
Packit Service 407539
	    server->machine->vminfo_snaptime = ksp->ks_snaptime;
Packit Service 407539
	    continue;
Packit Service 407539
	}
Packit Service 407539
Packit Service 407539
	if (!strcmp (ksp->ks_class, "misc") && !strncmp (ksp->ks_name, "cpu_stat", 8)) {
Packit Service 407539
	    int cpu;
Packit Service 407539
Packit Service 407539
	    if ((sscanf (ksp->ks_name+8, "%d", &cpu) != 1) || (cpu > 63))
Packit Service 407539
		continue;
Packit Service 407539
Packit Service 407539
	    if (cpu >= server->ncpu)
Packit Service 407539
		server->ncpu = cpu+1;
Packit Service 407539
Packit Service 407539
	    server->machine->cpu_stat_kstat [cpu] = ksp;
Packit Service 407539
	    continue;
Packit Service 407539
	}
Packit Service 407539
    }
Packit Service 407539
Packit Service 407539
#endif
Packit Service 407539
Packit Service 407539
    if (!kc)
Packit Service 407539
	glibtop_warn_io_r (server, "kstat_open ()");
Packit Service 407539
Packit Service 407539
    server->ncpu = -1;  /* Force processor detection */
Packit Service 407539
    server->machine->vminfo_snaptime = 0;  /* Force snaptime read */
Packit Service 407539
    glibtop_get_kstats(server);
Packit Service 407539
Packit Service 407539
    server->machine->boot = 0;
Packit Service 407539
    if((ksp = server->machine->system) && kstat_read(kc, ksp, NULL) >= 0)
Packit Service 407539
    {
Packit Service 407539
	kn = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time");
Packit Service 407539
	if(kn)
Packit Service 407539
	    switch(kn->data_type)
Packit Service 407539
	    {
Packit Service 407539
#ifdef KSTAT_DATA_INT32
Packit Service 407539
		case KSTAT_DATA_INT32:  server->machine->boot = kn->value.i32;
Packit Service 407539
					break;
Packit Service 407539
		case KSTAT_DATA_UINT32: server->machine->boot = kn->value.ui32;
Packit Service 407539
					break;
Packit Service 407539
		case KSTAT_DATA_INT64:  server->machine->boot = kn->value.i64;
Packit Service 407539
					break;
Packit Service 407539
		case KSTAT_DATA_UINT64: server->machine->boot = kn->value.ui64;
Packit Service 407539
					break;
Packit Service 407539
#else
Packit Service 407539
		case KSTAT_DATA_LONG:      server->machine->boot = kn->value.l;
Packit Service 407539
					   break;
Packit Service 407539
		case KSTAT_DATA_ULONG:     server->machine->boot = kn->value.ul;
Packit Service 407539
					   break;
Packit Service 407539
		case KSTAT_DATA_LONGLONG:  server->machine->boot = kn->value.ll;
Packit Service 407539
					   break;
Packit Service 407539
		case KSTAT_DATA_ULONGLONG: server->machine->boot = kn->value.ull;
Packit Service 407539
					   break;
Packit Service 407539
#endif
Packit Service 407539
	    }
Packit Service 407539
    }
Packit Service 407539
Packit Service 407539
    /* Now let's have a bit of magic dust... */
Packit Service 407539
Packit Service 407539
#if GLIBTOP_SOLARIS_RELEASE >= 50600
Packit Service 407539
Packit Service 407539
    dl = dlopen("/usr/lib/libproc.so", RTLD_LAZY);
Packit Service 407539
    if(server->machine->libproc)
Packit Service 407539
    	dlclose(server->machine->libproc);
Packit Service 407539
    server->machine->libproc = dl;
Packit Service 407539
    if(dl)
Packit Service 407539
    {
Packit Service 407539
       void *func;
Packit Service 407539
Packit Service 407539
       func = dlsym(dl, "Pobjname");		/* Solaris 8 */
Packit Service 407539
       if(!func)
Packit Service 407539
	  func = dlsym(dl, "proc_objname");	/* Solaris 7 */
Packit Service 407539
       server->machine->objname = (void (*)
Packit Service 407539
				 (void *, uintptr_t, const char *, size_t))func;
Packit Service 407539
       server->machine->pgrab = (struct ps_prochandle *(*)(pid_t, int, int *))
Packit Service 407539
	  		       dlsym(dl, "Pgrab");
Packit Service 407539
       server->machine->pfree = (void (*)(void *))dlsym(dl, "Pfree");
Packit Service 407539
       
Packit Service 407539
    }
Packit Service 407539
    else
Packit Service 407539
    {
Packit Service 407539
       server->machine->objname = NULL;
Packit Service 407539
       server->machine->pgrab = NULL;
Packit Service 407539
       server->machine->pfree = NULL;
Packit Service 407539
    }
Packit Service 407539
#endif
Packit Service 407539
    server->machine->me = getpid();
Packit Service 407539
}