Blame sysdeps/solaris/open.c

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