Exemple #1
0
int
route_loop(route_t *r, route_handler callback, void *arg)
{
	struct radix_node_head *rnh, head;
	struct nlist nl[2];
	int fd, ret = 0;

	memset(nl, 0, sizeof(nl));
	nl[0].n_name = "radix_node_head";
	
	if (knlist(nl) < 0 || nl[0].n_type == 0 ||
	    (fd = open("/dev/kmem", O_RDONLY, 0)) < 0)
		return (-1);
	
	for (_kread(fd, (void *)nl[0].n_value, &rnh, sizeof(rnh));
	    rnh != NULL; rnh = head.rnh_next) {
		_kread(fd, rnh, &head, sizeof(head));
		/* XXX - only IPv4 for now... */
		if (head.rnh_af == AF_INET) {
			if ((ret = _radix_walk(fd, head.rnh_treetop,
				 callback, arg)) != 0)
				break;
		}
	}
	close(fd);
	return (ret);
}
Exemple #2
0
int
arp_loop(arp_t *r, arp_handler callback, void *arg)
{
	struct ifnet *ifp, ifnet;
	struct ifnet_arp_cache_head ifarp;
	struct radix_node_head *head;
	
	struct nlist nl[2];
	int fd, ret = 0;

	memset(nl, 0, sizeof(nl));
	nl[0].n_name = "ifnet";
	
	if (knlist(nl) < 0 || nl[0].n_type == 0 ||
	    (fd = open("/dev/kmem", O_RDONLY, 0)) < 0)
		return (-1);

	for (ifp = (struct ifnet *)nl[0].n_value;
	    ifp != NULL; ifp = ifnet.if_next) {
		_kread(fd, ifp, &ifnet, sizeof(ifnet));
		if (ifnet.if_arp_cache_head != NULL) {
			_kread(fd, ifnet.if_arp_cache_head,
			    &ifarp, sizeof(ifarp));
			/* XXX - only ever one rnh, only ever AF_INET. */
			if ((ret = _radix_walk(fd, ifarp.arp_cache_head.rnh_treetop,
				 callback, arg)) != 0)
				break;
		}
	}
	close(fd);
	return (ret);
}
Exemple #3
0
static int kvm_nlist (kvm_t *kd, struct nlist *nl) {
  int count;
  
#ifdef HAVE_KNLIST
  if (kd->execfile == NULL) {
#ifdef HAVE_KNLIST_ARGS3 
    for(count = 0; nl[count].n_name != NULL; count++);
    count = knlist(nl, count, sizeof(struct nlist));
#else
    count = knlist(nl);
#endif
    if (count < 0)
      _kvm_error(kd->errbuf, "error looking up symbol in live kernel");
    return count;
  }
#endif  
  if ((count = nlist(kd->execfile ? kd->execfile : _PATH_UNIX, nl)) < 0)
    _kvm_error(kd->errbuf, "error looking up symbol in kernel file");
  return count;
}
/*
 * Initialize globals, get kernel offsets and stuff...
 */
machine_init(struct statics *statics)

{
    time_t uptime, now;
    struct tms tbuf;

    if ((kmem = open(KMEM, O_RDONLY)) == -1) {
	perror(KMEM);
	return -1;
    }

    /* get kernel symbol offsets */
    if (knlist(nlst, 5, sizeof(struct nlist)) != 0) {
	perror("knlist");
	return -1;
    }
    avenrun_offset = nlst[X_AVENRUN].n_value;
    sysinfo_offset = nlst[X_SYSINFO].n_value;
    vmker_offset   = nlst[X_VMKER].n_value;
    proc_offset    = nlst[X_PROC].n_value;
    v_offset       = nlst[X_V].n_value;

    getkval(v_offset, (caddr_t)&v_info, sizeof v_info, "v");

    ncpus = v_info.v_ncpus;	/* number of cpus */
    nprocs = PROCMASK(PIDMAX);
    if (nprocs > 1024) nprocs = 1024;

    ptsize = nprocs * sizeof (struct proc);
    p_proc = (struct proc *)malloc(ptsize);
    p_info = (struct procsinfo *)malloc(nprocs * sizeof (struct procsinfo));
    pref = (struct procsinfo **)malloc(nprocs * sizeof (struct procsinfo *));

    if (!p_proc || !p_info || !pref) {
	fprintf(stderr, "top: not enough memory\n");
	return -1;
    }

    /* set boot time */
    now = time(NULL);
    uptime = times(&tbuf) / HZ;
    statics->boottime = now - uptime;

    statics->procstate_names = procstatenames;
    statics->cpustate_names = cpustatenames;
    statics->memory_names = memorynames;
    statics->order_names = ordernames;
    statics->swap_names = swapnames;

    return(0);
}
Exemple #5
0
int getla()
{
    static int kmem = -1;
#if LA_TYPE == LA_INT
    long avenrun[3];
#else
#if LA_TYPE == LA_SHORT
    short avenrun[3];
#else
    double avenrun[3];
#endif
#endif
    extern int errno;
    extern off_t lseek();

    if (kmem < 0) {
#ifdef _AUX_SOURCE
	strcpy(Nl[X_AVENRUN].n_name, LA_AVENRUN);
	Nl[1].n_name[0] = '\0';
#endif

#if defined(_AIX3) || defined(_AIX4)
	if (knlist(Nl, 1, sizeof Nl[0]) < 0)
#else
	if (nlist(_PATH_UNIX, Nl) < 0)
#endif
	    return (-1);
	if (Nl[X_AVENRUN].n_value == 0)
	    return (-1);
#ifdef NAMELISTMASK
	Nl[X_AVENRUN].n_value &= NAMELISTMASK;
#endif

	kmem = open(_PATH_KMEM, 0, 0);
	if (kmem < 0)
	    return (-1);
	(void) fcntl(kmem, F_SETFD, 1);
    }
    if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, SEEK_SET) == -1 ||
	read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
	/* thank you Ian */
	return (-1);
#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_SHORT)
    return ((int) (avenrun[0] + FSCALE / 2) >> FSHIFT);
#else /* LA_TYPE == LA_FLOAT */
    return ((int) (avenrun[0] + 0.5));
#endif
}
Exemple #6
0
void
domem()
{
    register struct kmembuckets *kp;
    register struct kmemstats *ks;
    register int i;
    int size;
    long totuse = 0, totfree = 0, totreq = 0;
    struct kmemstats kmemstats[M_LAST];
    struct kmembuckets buckets[MINBUCKET + 16];

    knlist(nl);
    kread(nl[X_BUCKET].n_value, &buckets, sizeof buckets, "kmembucket");
    (void)printf("Memory statistics by bucket size\n");
    (void)printf(
        "    Size   In Use   Free   Requests  HighWater  Couldfree\n");
    for (i = MINBUCKET, kp = &buckets[i]; i < MINBUCKET + 16; i++, kp++) {
        if (kp->kb_calls == 0)
            continue;
        size = 1 << i;
        (void)printf("%8d %8ld %6ld %10ld %7ld %10ld\n", size,
                     kp->kb_total - kp->kb_totalfree,
                     kp->kb_totalfree, kp->kb_calls,
                     kp->kb_highwat, kp->kb_couldfree);
        totfree += size * kp->kb_totalfree;
    }

    kread(nl[X_KMEMSTATS].n_value, &kmemstats, sizeof kmemstats,
          "kmemstats");
    (void)printf("\nMemory statistics by type\n");
    (void)printf(
        "       Type  In Use  MemUse   HighUse  Limit Requests  TypeLimit KernLimit\n");
    for (i = 0, ks = &kmemstats[0]; i < M_LAST; i++, ks++) {
        if (ks->ks_calls == 0)
            continue;
        (void)printf("%11s %6ld %7ldK %8ldK %5ldK %8ld %6u %9u\n",
                     kmemnames[i] ? kmemnames[i] : "undefined",
                     ks->ks_inuse, (ks->ks_memuse + 1023) / 1024,
                     (ks->ks_maxused + 1023) / 1024,
                     (ks->ks_limit + 1023) / 1024, ks->ks_calls,
                     ks->ks_limblocks, ks->ks_mapblocks);
        totuse += ks->ks_memuse;
        totreq += ks->ks_calls;
    }
    (void)printf("\nMemory Totals:  In Use    Free    Requests\n");
    (void)printf("              %7ldK %6ldK    %8ld\n",
                 (totuse + 1023) / 1024, (totfree + 1023) / 1024, totreq);
}
Exemple #7
0
int
getloadavg (double loadavg[], int nelem)
{
  int elem = 0;                 /* Return value.  */

# ifdef NO_GET_LOAD_AVG
#  define LDAV_DONE
  /* Set errno to zero to indicate that there was no particular error;
     this function just can't work at all on this system.  */
  errno = 0;
  elem = -1;
# endif

# if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT)
/* Use libkstat because we don't have to be root.  */
#  define LDAV_DONE
  kstat_ctl_t *kc;
  kstat_t *ksp;
  kstat_named_t *kn;

  kc = kstat_open ();
  if (kc == 0)
    return -1;
  ksp = kstat_lookup (kc, "unix", 0, "system_misc");
  if (ksp == 0)
    return -1;
  if (kstat_read (kc, ksp, 0) == -1)
    return -1;


  kn = kstat_data_lookup (ksp, "avenrun_1min");
  if (kn == 0)
    {
      /* Return -1 if no load average information is available.  */
      nelem = 0;
      elem = -1;
    }

  if (nelem >= 1)
    loadavg[elem++] = (double) kn->value.ul / FSCALE;

  if (nelem >= 2)
    {
      kn = kstat_data_lookup (ksp, "avenrun_5min");
      if (kn != 0)
        {
          loadavg[elem++] = (double) kn->value.ul / FSCALE;

          if (nelem >= 3)
            {
              kn = kstat_data_lookup (ksp, "avenrun_15min");
              if (kn != 0)
                loadavg[elem++] = (double) kn->value.ul / FSCALE;
            }
        }
    }

  kstat_close (kc);
# endif /* HAVE_LIBKSTAT */

# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC)
/* Use pstat_getdynamic() because we don't have to be root.  */
#  define LDAV_DONE
#  undef LOAD_AVE_TYPE

  struct pst_dynamic dyn_info;
  if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0)
    return -1;
  if (nelem > 0)
    loadavg[elem++] = dyn_info.psd_avg_1_min;
  if (nelem > 1)
    loadavg[elem++] = dyn_info.psd_avg_5_min;
  if (nelem > 2)
    loadavg[elem++] = dyn_info.psd_avg_15_min;

# endif /* hpux && HAVE_PSTAT_GETDYNAMIC */

# if ! defined LDAV_DONE && defined HAVE_LIBPERFSTAT
#  define LDAV_DONE
#  undef LOAD_AVE_TYPE
/* Use perfstat_cpu_total because we don't have to be root. */
  {
    perfstat_cpu_total_t cpu_stats;
    int result = perfstat_cpu_total (NULL, &cpu_stats, sizeof cpu_stats, 1);
    if (result == -1)
      return result;
    loadavg[0] = cpu_stats.loadavg[0] / (double)(1 << SBITS);
    loadavg[1] = cpu_stats.loadavg[1] / (double)(1 << SBITS);
    loadavg[2] = cpu_stats.loadavg[2] / (double)(1 << SBITS);
    elem = 3;
  }
# endif

# if !defined (LDAV_DONE) && (defined (__linux__) || defined (__CYGWIN__))
#  define LDAV_DONE
#  undef LOAD_AVE_TYPE

#  ifndef LINUX_LDAV_FILE
#   define LINUX_LDAV_FILE "/proc/loadavg"
#  endif

  char ldavgbuf[3 * (INT_STRLEN_BOUND (int) + sizeof ".00 ")];
  char const *ptr = ldavgbuf;
  int fd, count;

  fd = open (LINUX_LDAV_FILE, O_RDONLY);
  if (fd == -1)
    return -1;
  count = read (fd, ldavgbuf, sizeof ldavgbuf - 1);
  (void) close (fd);
  if (count <= 0)
    return -1;
  ldavgbuf[count] = '\0';

  for (elem = 0; elem < nelem; elem++)
    {
      char *endptr;
      double d;

      errno = 0;
      d = c_strtod (ptr, &endptr);
      if (ptr == endptr || (d == 0 && errno != 0))
        {
          if (elem == 0)
            return -1;
          break;
        }
      loadavg[elem] = d;
      ptr = endptr;
    }

  return elem;

# endif /* __linux__ || __CYGWIN__ */

# if !defined (LDAV_DONE) && defined (__NetBSD__)
#  define LDAV_DONE
#  undef LOAD_AVE_TYPE

#  ifndef NETBSD_LDAV_FILE
#   define NETBSD_LDAV_FILE "/kern/loadavg"
#  endif

  unsigned long int load_ave[3], scale;
  int count;
  FILE *fp;

  fp = fopen (NETBSD_LDAV_FILE, "r");
  if (fp == NULL)
    return -1;
  count = fscanf (fp, "%lu %lu %lu %lu\n",
                  &load_ave[0], &load_ave[1], &load_ave[2],
                  &scale);
  (void) fclose (fp);
  if (count != 4)
    return -1;

  for (elem = 0; elem < nelem; elem++)
    loadavg[elem] = (double) load_ave[elem] / (double) scale;

  return elem;

# endif /* __NetBSD__ */

# if !defined (LDAV_DONE) && defined (NeXT)
#  define LDAV_DONE
  /* The NeXT code was adapted from iscreen 3.2.  */

  host_t host;
  struct processor_set_basic_info info;
  unsigned int info_count;

  /* We only know how to get the 1-minute average for this system,
     so even if the caller asks for more than 1, we only return 1.  */

  if (!getloadavg_initialized)
    {
      if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
        getloadavg_initialized = true;
    }

  if (getloadavg_initialized)
    {
      info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
      if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
                              (processor_set_info_t) &info, &info_count)
          != KERN_SUCCESS)
        getloadavg_initialized = false;
      else
        {
          if (nelem > 0)
            loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
        }
    }

  if (!getloadavg_initialized)
    return -1;
# endif /* NeXT */

# if !defined (LDAV_DONE) && defined (UMAX)
#  define LDAV_DONE
/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
   have a /dev/kmem.  Information about the workings of the running kernel
   can be gathered with inq_stats system calls.
   We only know how to get the 1-minute average for this system.  */

  struct proc_summary proc_sum_data;
  struct stat_descr proc_info;
  double load;
  register unsigned int i, j;

  if (cpus == 0)
    {
      register unsigned int c, i;
      struct cpu_config conf;
      struct stat_descr desc;

      desc.sd_next = 0;
      desc.sd_subsys = SUBSYS_CPU;
      desc.sd_type = CPUTYPE_CONFIG;
      desc.sd_addr = (char *) &conf;
      desc.sd_size = sizeof conf;

      if (inq_stats (1, &desc))
        return -1;

      c = 0;
      for (i = 0; i < conf.config_maxclass; ++i)
        {
          struct class_stats stats;
          bzero ((char *) &stats, sizeof stats);

          desc.sd_type = CPUTYPE_CLASS;
          desc.sd_objid = i;
          desc.sd_addr = (char *) &stats;
          desc.sd_size = sizeof stats;

          if (inq_stats (1, &desc))
            return -1;

          c += stats.class_numcpus;
        }
      cpus = c;
      samples = cpus < 2 ? 3 : (2 * cpus / 3);
    }

  proc_info.sd_next = 0;
  proc_info.sd_subsys = SUBSYS_PROC;
  proc_info.sd_type = PROCTYPE_SUMMARY;
  proc_info.sd_addr = (char *) &proc_sum_data;
  proc_info.sd_size = sizeof (struct proc_summary);
  proc_info.sd_sizeused = 0;

  if (inq_stats (1, &proc_info) != 0)
    return -1;

  load = proc_sum_data.ps_nrunnable;
  j = 0;
  for (i = samples - 1; i > 0; --i)
    {
      load += proc_sum_data.ps_nrun[j];
      if (j++ == PS_NRUNSIZE)
        j = 0;
    }

  if (nelem > 0)
    loadavg[elem++] = load / samples / cpus;
# endif /* UMAX */

# if !defined (LDAV_DONE) && defined (DGUX)
#  define LDAV_DONE
  /* This call can return -1 for an error, but with good args
     it's not supposed to fail.  The first argument is for no
     apparent reason of type `long int *'.  */
  dg_sys_info ((long int *) &load_info,
               DG_SYS_INFO_LOAD_INFO_TYPE,
               DG_SYS_INFO_LOAD_VERSION_0);

  if (nelem > 0)
    loadavg[elem++] = load_info.one_minute;
  if (nelem > 1)
    loadavg[elem++] = load_info.five_minute;
  if (nelem > 2)
    loadavg[elem++] = load_info.fifteen_minute;
# endif /* DGUX */

# if !defined (LDAV_DONE) && defined (apollo)
#  define LDAV_DONE
/* Apollo code from [email protected] (Ray Lischner).

   This system call is not documented.  The load average is obtained as
   three long integers, for the load average over the past minute,
   five minutes, and fifteen minutes.  Each value is a scaled integer,
   with 16 bits of integer part and 16 bits of fraction part.

   I'm not sure which operating system first supported this system call,
   but I know that SR10.2 supports it.  */

  extern void proc1_$get_loadav ();
  unsigned long load_ave[3];

  proc1_$get_loadav (load_ave);

  if (nelem > 0)
    loadavg[elem++] = load_ave[0] / 65536.0;
  if (nelem > 1)
    loadavg[elem++] = load_ave[1] / 65536.0;
  if (nelem > 2)
    loadavg[elem++] = load_ave[2] / 65536.0;
# endif /* apollo */

# if !defined (LDAV_DONE) && defined (OSF_MIPS)
#  define LDAV_DONE

  struct tbl_loadavg load_ave;
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
  loadavg[elem++]
    = (load_ave.tl_lscale == 0
       ? load_ave.tl_avenrun.d[0]
       : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
# endif /* OSF_MIPS */

# if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32))
#  define LDAV_DONE

  /* A faithful emulation is going to have to be saved for a rainy day.  */
  for ( ; elem < nelem; elem++)
    {
      loadavg[elem] = 0.0;
    }
# endif  /* __MSDOS__ || WINDOWS32 */

# if !defined (LDAV_DONE) && defined (OSF_ALPHA)
#  define LDAV_DONE

  struct tbl_loadavg load_ave;
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
  for (elem = 0; elem < nelem; elem++)
    loadavg[elem]
      = (load_ave.tl_lscale == 0
         ? load_ave.tl_avenrun.d[elem]
         : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
# endif /* OSF_ALPHA */

# if ! defined LDAV_DONE && defined __VMS
  /* VMS specific code -- read from the Load Ave driver.  */

  LOAD_AVE_TYPE load_ave[3];
  static bool getloadavg_initialized;
#  ifdef eunice
  struct
  {
    int dsc$w_length;
    char *dsc$a_pointer;
  } descriptor;
#  endif

  /* Ensure that there is a channel open to the load ave device.  */
  if (!getloadavg_initialized)
    {
      /* Attempt to open the channel.  */
#  ifdef eunice
      descriptor.dsc$w_length = 18;
      descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE";
#  else
      $DESCRIPTOR (descriptor, "LAV0:");
#  endif
      if (sys$assign (&descriptor, &channel, 0, 0) & 1)
        getloadavg_initialized = true;
    }

  /* Read the load average vector.  */
  if (getloadavg_initialized
      && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
                     load_ave, 12, 0, 0, 0, 0) & 1))
    {
      sys$dassgn (channel);
      getloadavg_initialized = false;
    }

  if (!getloadavg_initialized)
    return -1;
# endif /* ! defined LDAV_DONE && defined __VMS */

# if ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS

  /* UNIX-specific code -- read the average from /dev/kmem.  */

#  define LDAV_PRIVILEGED               /* This code requires special installation.  */

  LOAD_AVE_TYPE load_ave[3];

  /* Get the address of LDAV_SYMBOL.  */
  if (offset == 0)
    {
#  ifndef sgi
#   if ! defined NLIST_STRUCT || ! defined N_NAME_POINTER
      strcpy (nl[0].n_name, LDAV_SYMBOL);
      strcpy (nl[1].n_name, "");
#   else /* NLIST_STRUCT */
#    ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME
      nl[0].n_un.n_name = LDAV_SYMBOL;
      nl[1].n_un.n_name = 0;
#    else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
      nl[0].n_name = LDAV_SYMBOL;
      nl[1].n_name = 0;
#    endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */
#   endif /* NLIST_STRUCT */

#   ifndef SUNOS_5
      if (
#    if !(defined (_AIX) && !defined (ps2))
          nlist (KERNEL_FILE, nl)
#    else  /* _AIX */
          knlist (nl, 1, sizeof (nl[0]))
#    endif
          >= 0)
          /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
          {
#    ifdef FIXUP_KERNEL_SYMBOL_ADDR
            FIXUP_KERNEL_SYMBOL_ADDR (nl);
#    endif
            offset = nl[0].n_value;
          }
#   endif /* !SUNOS_5 */
#  else  /* sgi */
      int ldav_off;

      ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
      if (ldav_off != -1)
        offset = (long int) ldav_off & 0x7fffffff;
#  endif /* sgi */
    }

  /* Make sure we have /dev/kmem open.  */
  if (!getloadavg_initialized)
    {
#  ifndef SUNOS_5
      channel = open ("/dev/kmem", O_RDONLY);
      if (channel >= 0)
        {
          /* Set the channel to close on exec, so it does not
             litter any child's descriptor table.  */
          set_cloexec_flag (channel, true);
          getloadavg_initialized = true;
        }
#  else /* SUNOS_5 */
      /* We pass 0 for the kernel, corefile, and swapfile names
         to use the currently running kernel.  */
      kd = kvm_open (0, 0, 0, O_RDONLY, 0);
      if (kd != 0)
        {
          /* nlist the currently running kernel.  */
          kvm_nlist (kd, nl);
          offset = nl[0].n_value;
          getloadavg_initialized = true;
        }
#  endif /* SUNOS_5 */
    }

  /* If we can, get the load average values.  */
  if (offset && getloadavg_initialized)
    {
      /* Try to read the load.  */
#  ifndef SUNOS_5
      if (lseek (channel, offset, 0) == -1L
          || read (channel, (char *) load_ave, sizeof (load_ave))
          != sizeof (load_ave))
        {
          close (channel);
          getloadavg_initialized = false;
        }
#  else  /* SUNOS_5 */
      if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
          != sizeof (load_ave))
        {
          kvm_close (kd);
          getloadavg_initialized = false;
        }
#  endif /* SUNOS_5 */
    }

  if (offset == 0 || !getloadavg_initialized)
    return -1;
# endif /* ! defined LDAV_DONE && defined LOAD_AVE_TYPE && ! defined __VMS */

# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS.  */
  if (nelem > 0)
    loadavg[elem++] = LDAV_CVT (load_ave[0]);
  if (nelem > 1)
    loadavg[elem++] = LDAV_CVT (load_ave[1]);
  if (nelem > 2)
    loadavg[elem++] = LDAV_CVT (load_ave[2]);

#  define LDAV_DONE
# endif /* !LDAV_DONE && LOAD_AVE_TYPE */

# if !defined LDAV_DONE
  /* Set errno to zero to indicate that there was no particular error;
     this function just can't work at all on this system.  */
  errno = 0;
  elem = -1;
# endif
  return elem;
}
Exemple #8
0
void
dosum()
{
	long nchtotal;
	struct nchstats nchstats;
	struct vmmeter cnt;
#ifdef tahoe
	struct keystats keystats;
#endif

	knlist(nl);
	kread(nl[X_CNT].n_value, &cnt, sizeof cnt, "cnt");
	(void)printf("%9u cpu context switches\n", cnt.v_swtch);
	(void)printf("%9u device interrupts\n", cnt.v_intr);
	(void)printf("%9u software interrupts\n", cnt.v_soft);
#ifdef vax
	(void)printf("%9u pseudo-dma dz interrupts\n", cnt.v_pdma);
#endif
	(void)printf("%9u traps\n", cnt.v_trap);
	(void)printf("%9u system calls\n", cnt.v_syscall);
	(void)printf("%9u total faults taken\n", cnt.v_faults);
	(void)printf("%9u swap ins\n", cnt.v_swpin);
	(void)printf("%9u swap outs\n", cnt.v_swpout);
	(void)printf("%9u pages swapped in\n", cnt.v_pswpin / CLSIZE);
	(void)printf("%9u pages swapped out\n", cnt.v_pswpout / CLSIZE);
	(void)printf("%9u page ins\n", cnt.v_pageins);
	(void)printf("%9u page outs\n", cnt.v_pageouts);
	(void)printf("%9u pages paged in\n", cnt.v_pgpgin);
	(void)printf("%9u pages paged out\n", cnt.v_pgpgout);
	(void)printf("%9u pages reactivated\n", cnt.v_reactivated);
	(void)printf("%9u intransit blocking page faults\n", cnt.v_intrans);
	(void)printf("%9u zero fill pages created\n", cnt.v_nzfod / CLSIZE);
	(void)printf("%9u zero fill page faults\n", cnt.v_zfod / CLSIZE);
	(void)printf("%9u pages examined by the clock daemon\n", cnt.v_scan);
	(void)printf("%9u revolutions of the clock hand\n", cnt.v_rev);
	(void)printf("%9u VM object cache lookups\n", cnt.v_lookups);
	(void)printf("%9u VM object hits\n", cnt.v_hits);
	(void)printf("%9u total VM faults taken\n", cnt.v_vm_faults);
	(void)printf("%9u copy-on-write faults\n", cnt.v_cow_faults);
	(void)printf("%9u pages freed by daemon\n", cnt.v_dfree);
	(void)printf("%9u pages freed by exiting processes\n", cnt.v_pfree);
	(void)printf("%9u pages free\n", cnt.v_free_count);
	(void)printf("%9u pages wired down\n", cnt.v_wire_count);
	(void)printf("%9u pages active\n", cnt.v_active_count);
	(void)printf("%9u pages inactive\n", cnt.v_inactive_count);
	(void)printf("%9u bytes per page\n", cnt.v_page_size);
	kread(nl[X_NCHSTATS].n_value, &nchstats, sizeof nchstats, "nchstats");
	nchtotal = nchstats.ncs_goodhits + nchstats.ncs_neghits +
	    nchstats.ncs_badhits + nchstats.ncs_falsehits +
	    nchstats.ncs_miss + nchstats.ncs_long;
	(void)printf("%9ld total name lookups\n", nchtotal);
	(void)printf(
	    "%9s cache hits (%d%% pos + %d%% neg) system %d%% per-process\n",
	    "", PCT(nchstats.ncs_goodhits, nchtotal),
	    PCT(nchstats.ncs_neghits, nchtotal),
	    PCT(nchstats.ncs_pass2, nchtotal));
	(void)printf("%9s deletions %d%%, falsehits %d%%, toolong %d%%\n", "",
	    PCT(nchstats.ncs_badhits, nchtotal),
	    PCT(nchstats.ncs_falsehits, nchtotal),
	    PCT(nchstats.ncs_long, nchtotal));
#if defined(tahoe)
	kread(nl[X_CKEYSTATS].n_value, &keystats, sizeof keystats, "ckeystats");
	(void)printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
	    keystats.ks_allocs, "code cache keys allocated",
	    PCT(keystats.ks_allocfree, keystats.ks_allocs),
	    PCT(keystats.ks_norefs, keystats.ks_allocs),
	    PCT(keystats.ks_taken, keystats.ks_allocs),
	    PCT(keystats.ks_shared, keystats.ks_allocs));
	kread(nl[X_DKEYSTATS].n_value, &keystats, sizeof keystats, "ckeystats");
	(void)printf("%9d %s (free %d%% norefs %d%% taken %d%% shared %d%%)\n",
	    keystats.ks_allocs, "data cache keys allocated",
	    PCT(keystats.ks_allocfree, keystats.ks_allocs),
	    PCT(keystats.ks_norefs, keystats.ks_allocs),
	    PCT(keystats.ks_taken, keystats.ks_allocs),
	    PCT(keystats.ks_shared, keystats.ks_allocs));
#endif
}
Exemple #9
0
int
getloadavg (double loadavg[], int nelem)
{
  int elem = 0;			/* Return value.  */

#ifdef NO_GET_LOAD_AVG
#define LDAV_DONE
  /* Set errno to zero to indicate that there was no particular error;
     this function just can't work at all on this system.  */
  errno = 0;
  elem = -2;
#endif /* NO_GET_LOAD_AVG */

#if ! defined (LDAV_DONE) && defined (HAVE_KSTAT_H) && defined (HAVE_LIBKSTAT)
#define LDAV_DONE
/* getloadavg is best implemented using kstat (kernel stats), on
   systems (like SunOS5) that support it, since you don't need special
   privileges to use it.

   Initial implementation courtesy Zlatko Calusic <*****@*****.**>.
   Integrated to XEmacs by Hrvoje Niksic <*****@*****.**>.
   Additional cleanup by Hrvoje Niksic, based on code published by
   Casper Dik <*****@*****.**>.  */
  kstat_ctl_t *kc;
  kstat_t *ksp;
  static char *avestrings[] = { "avenrun_1min",
				"avenrun_5min",
				"avenrun_15min" };

  if (nelem > countof (avestrings))
    nelem = countof (avestrings);

  kc = kstat_open ();
  if (!kc)
    return -1;
  ksp = kstat_lookup (kc, "unix", 0, "system_misc");
  if (!ksp)
    {
      kstat_close (kc);
      return -1;
    }
  if (kstat_read (kc, ksp, 0) < 0)
    {
      kstat_close (kc);
      return -1;
    }
  for (elem = 0; elem < nelem; elem++)
    {
      kstat_named_t *kn =
	(kstat_named_t *) kstat_data_lookup (ksp, avestrings[elem]);
      if (!kn)
	{
	  kstat_close (kc);
	  return -1;
	}
      loadavg[elem] = (double)kn->value.ul / FSCALE;
    }
  kstat_close (kc);
#endif /* HAVE_KSTAT_H && HAVE_LIBKSTAT */

#if !defined (LDAV_DONE) && defined (HAVE_SYS_PSTAT_H)
#define LDAV_DONE
  /* This is totally undocumented, and is not guaranteed to work, but
     mayhap it might ....  If it does work, it will work only on HP-UX
     8.0 or later.  -- Darryl Okahata <*****@*****.**> */
#undef LOAD_AVE_TYPE		/* Make sure these don't exist. */
#undef LOAD_AVE_CVT
#undef LDAV_SYMBOL
  struct pst_dynamic	procinfo;
  union pstun		statbuf;

  statbuf.pst_dynamic = &procinfo;
  if (pstat (PSTAT_DYNAMIC, statbuf, sizeof (struct pst_dynamic), 0, 0) == -1)
    return (-1);
  loadavg[elem++] = procinfo.psd_avg_1_min;
  loadavg[elem++] = procinfo.psd_avg_5_min;
  loadavg[elem++] = procinfo.psd_avg_15_min;
#endif	/* HPUX */

#if !defined (LDAV_DONE) && defined (__linux__)
#define LDAV_DONE
#undef LOAD_AVE_TYPE

#ifndef LINUX_LDAV_FILE
#define LINUX_LDAV_FILE "/proc/loadavg"
#endif

  char ldavgbuf[40];
  double load_ave[3];
  int fd, count;

  fd = open (LINUX_LDAV_FILE, O_RDONLY);
  if (fd == -1)
    return -1;
  count = read (fd, ldavgbuf, 40);
  (void) close (fd);
  if (count <= 0)
    return -1;

  count = sscanf (ldavgbuf, "%lf %lf %lf",
		  &load_ave[0], &load_ave[1], &load_ave[2]);
  if (count < 1)
    return -1;

  for (elem = 0; elem < nelem && elem < count; elem++)
    loadavg[elem] = load_ave[elem];
#endif /* __linux__ */

#if !defined (LDAV_DONE) && defined (__NetBSD__) || defined (__OpenBSD__)
#define LDAV_DONE
#undef LOAD_AVE_TYPE

#ifndef NETBSD_LDAV_FILE
#define NETBSD_LDAV_FILE "/kern/loadavg"
#endif

  unsigned long int load_ave[3], scale;
  int count;
  FILE *fp;

  fp = fopen (NETBSD_LDAV_FILE, "r");
  if (fp == NULL)
    return -1;
  count = fscanf (fp, "%lu %lu %lu %lu\n",
		  &load_ave[0], &load_ave[1], &load_ave[2],
		  &scale);
  (void) fclose (fp);
  if (count != 4)
    return -1;

  for (elem = 0; elem < nelem; elem++)
    loadavg[elem] = (double) load_ave[elem] / (double) scale;
#endif /* __NetBSD__ or __OpenBSD__ */

#if !defined (LDAV_DONE) && defined (NeXT)
#define LDAV_DONE
  /* The NeXT code was adapted from iscreen 3.2.  */

  host_t host;
  struct processor_set_basic_info info;
  unsigned info_count;

  /* We only know how to get the 1-minute average for this system,
     so even if the caller asks for more than 1, we only return 1.  */

  if (!getloadavg_initialized)
    {
      if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS)
	getloadavg_initialized = 1;
    }

  if (getloadavg_initialized)
    {
      info_count = PROCESSOR_SET_BASIC_INFO_COUNT;
      if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host,
			     (processor_set_info_t) &info, &info_count)
	  != KERN_SUCCESS)
	getloadavg_initialized = 0;
      else
	{
	  if (nelem > 0)
	    loadavg[elem++] = (double) info.load_average / LOAD_SCALE;
	}
    }

  if (!getloadavg_initialized)
    return -1;
#endif /* NeXT */

#if !defined (LDAV_DONE) && defined (UMAX)
#define LDAV_DONE
/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not
   have a /dev/kmem.  Information about the workings of the running kernel
   can be gathered with inq_stats system calls.
   We only know how to get the 1-minute average for this system.  */

  struct proc_summary proc_sum_data;
  struct stat_descr proc_info;
  double load;
  REGISTER unsigned int i, j;

  if (cpus == 0)
    {
      REGISTER unsigned int c, i;
      struct cpu_config conf;
      struct stat_descr desc;

      desc.sd_next = 0;
      desc.sd_subsys = SUBSYS_CPU;
      desc.sd_type = CPUTYPE_CONFIG;
      desc.sd_addr = (char *) &conf;
      desc.sd_size = sizeof conf;

      if (inq_stats (1, &desc))
	return -1;

      c = 0;
      for (i = 0; i < conf.config_maxclass; ++i)
	{
	  struct class_stats stats;
	  memset ((char *) &stats, 0, sizeof stats);

	  desc.sd_type = CPUTYPE_CLASS;
	  desc.sd_objid = i;
	  desc.sd_addr = (char *) &stats;
	  desc.sd_size = sizeof stats;

	  if (inq_stats (1, &desc))
	    return -1;

	  c += stats.class_numcpus;
	}
      cpus = c;
      samples = cpus < 2 ? 3 : (2 * cpus / 3);
    }

  proc_info.sd_next = 0;
  proc_info.sd_subsys = SUBSYS_PROC;
  proc_info.sd_type = PROCTYPE_SUMMARY;
  proc_info.sd_addr = (char *) &proc_sum_data;
  proc_info.sd_size = sizeof (struct proc_summary);
  proc_info.sd_sizeused = 0;

  if (inq_stats (1, &proc_info) != 0)
    return -1;

  load = proc_sum_data.ps_nrunnable;
  j = 0;
  for (i = samples - 1; i > 0; --i)
    {
      load += proc_sum_data.ps_nrun[j];
      if (j++ == PS_NRUNSIZE)
	j = 0;
    }

  if (nelem > 0)
    loadavg[elem++] = load / samples / cpus;
#endif /* UMAX */

#if !defined (LDAV_DONE) && defined (DGUX)
#define LDAV_DONE
  /* This call can return -1 for an error, but with good args
     it's not supposed to fail.  The first argument is for no
     apparent reason of type `long int *'.  */
  dg_sys_info ((long int *) &load_info,
	       DG_SYS_INFO_LOAD_INFO_TYPE,
	       DG_SYS_INFO_LOAD_VERSION_0);

  if (nelem > 0)
    loadavg[elem++] = load_info.one_minute;
  if (nelem > 1)
    loadavg[elem++] = load_info.five_minute;
  if (nelem > 2)
    loadavg[elem++] = load_info.fifteen_minute;
#endif /* DGUX */

#if !defined (LDAV_DONE) && defined (OSF_MIPS)
#define LDAV_DONE

  struct tbl_loadavg load_ave;
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
  loadavg[elem++]
    = (load_ave.tl_lscale == 0
       ? load_ave.tl_avenrun.d[0]
       : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale));
#endif	/* OSF_MIPS */

#if !defined (LDAV_DONE) && (defined (WIN32_NATIVE) || defined (CYGWIN))
#define LDAV_DONE

  /* A faithful emulation is going to have to be saved for a rainy day.  */
  for ( ; elem < nelem; elem++)
    {
      loadavg[elem] = 0.0;
    }
#endif  /* WIN32_NATIVE or CYGWIN */

#if !defined (LDAV_DONE) && defined (OSF_ALPHA)
#define LDAV_DONE

  struct tbl_loadavg load_ave;
  table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave));
  for (elem = 0; elem < nelem; elem++)
    loadavg[elem]
      = (load_ave.tl_lscale == 0
       ? load_ave.tl_avenrun.d[elem]
       : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale));
#endif /* OSF_ALPHA */

#if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE)

  /* UNIX-specific code -- read the average from /dev/kmem.  */

#define LDAV_PRIVILEGED		/* This code requires special installation.  */

  LOAD_AVE_TYPE load_ave[3];

  /* Get the address of LDAV_SYMBOL.  */
  if (offset == 0)
    {
#ifndef sgi
#ifndef NLIST_STRUCT
      strcpy (nl[0].n_name, LDAV_SYMBOL);
      strcpy (nl[1].n_name, "");
#else /* NLIST_STRUCT */
#ifdef NLIST_NAME_UNION
      nl[0].n_un.n_name = LDAV_SYMBOL;
      nl[1].n_un.n_name = 0;
#else /* not NLIST_NAME_UNION */
      nl[0].n_name = (char *) LDAV_SYMBOL;
      nl[1].n_name = 0;
#endif /* not NLIST_NAME_UNION */
#endif /* NLIST_STRUCT */

#ifndef SUNOS_5
      if (
#if !(defined (_AIX) && !defined (ps2))
	  nlist (KERNEL_FILE, nl)
#else  /* _AIX */
	  knlist (nl, 1, sizeof (nl[0]))
#endif
	  >= 0)
	  /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i.  */
	  {
#ifdef FIXUP_KERNEL_SYMBOL_ADDR
	    FIXUP_KERNEL_SYMBOL_ADDR (nl);
#endif
	    offset = nl[0].n_value;
	  }
#endif /* !SUNOS_5 */
#else  /* sgi */
	  int ldav_off;

	  ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN);
	  if (ldav_off != -1)
	  offset = (long) ldav_off & 0x7fffffff;
#endif /* sgi */
	}

  /* Make sure we have /dev/kmem open.  */
  if (!getloadavg_initialized)
    {
#ifndef SUNOS_5
      channel = open ("/dev/kmem", 0);
      if (channel >= 0)
	{
	  /* Set the channel to close on exec, so it does not
	     litter any child's descriptor table.  */
#ifdef FD_SETFD
#ifndef FD_CLOEXEC
#define FD_CLOEXEC 1
#endif
	  (void) fcntl (channel, F_SETFD, FD_CLOEXEC);
#endif
	  getloadavg_initialized = 1;
	}
#else /* SUNOS_5 */
      /* We pass 0 for the kernel, corefile, and swapfile names
	 to use the currently running kernel.  */
      kd = kvm_open (0, 0, 0, O_RDONLY, 0);
      if (kd != 0)
	{
	  /* nlist the currently running kernel.  */
	  kvm_nlist (kd, nl);
	  offset = nl[0].n_value;
	  getloadavg_initialized = 1;
	}
#endif /* SUNOS_5 */
    }

  /* If we can, get the load average values.  */
  if (offset && getloadavg_initialized)
    {
      /* Try to read the load.  */
#ifndef SUNOS_5
      if (lseek (channel, offset, 0) == -1L
	  || read (channel, (char *) load_ave, sizeof (load_ave))
	  != sizeof (load_ave))
	{
	  close (channel);
	  getloadavg_initialized = 0;
	}
#else  /* SUNOS_5 */
      if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave))
	  != sizeof (load_ave))
        {
          kvm_close (kd);
          getloadavg_initialized = 0;
	}
#endif /* SUNOS_5 */
    }

  if (offset == 0 || !getloadavg_initialized)
    return -1;

  if (nelem > 0)
    loadavg[elem++] = LDAV_CVT (load_ave[0]);
  if (nelem > 1)
    loadavg[elem++] = LDAV_CVT (load_ave[1]);
  if (nelem > 2)
    loadavg[elem++] = LDAV_CVT (load_ave[2]);

#define LDAV_DONE
#endif /* !LDAV_DONE && LOAD_AVE_TYPE */

  return elem;
}
Exemple #10
0
/**
 * Returns the system uptime in centiseconds.
 *
 * @note The value returned by this function is not identical to sysUpTime
 *   defined in RFC 1213. get_uptime() returns the system uptime while
 *   sysUpTime represents the time that has elapsed since the most recent
 *   restart of the network manager (snmpd).
 *
 * @see See also netsnmp_get_agent_uptime().
 */
long
get_uptime(void)
{
#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
    static char lbolt_name[] = "lbolt";
    struct nlist nl;
    int kmem;
    time_t lbolt;
    nl.n_name = lbolt_name;
    if(knlist(&nl, 1, sizeof(struct nlist)) != 0) return(0);
    if(nl.n_type == 0 || nl.n_value == 0) return(0);
    if((kmem = open("/dev/mem", 0)) < 0) return 0;
    lseek(kmem, (long) nl.n_value, L_SET);
    read(kmem, &lbolt, sizeof(lbolt));
    close(kmem);
    return(lbolt);
#elif defined(solaris2)
    kstat_ctl_t    *ksc = kstat_open();
    kstat_t        *ks;
    kid_t           kid;
    kstat_named_t  *named;
    u_long          lbolt = 0;

    if (ksc) {
        ks = kstat_lookup(ksc, "unix", -1, "system_misc");
        if (ks) {
            kid = kstat_read(ksc, ks, NULL);
            if (kid != -1) {
                named = kstat_data_lookup(ks, "lbolt");
                if (named) {
#ifdef KSTAT_DATA_UINT32
                    lbolt = named->value.ui32;
#else
                    lbolt = named->value.ul;
#endif
                }
            }
        }
        kstat_close(ksc);
    }
    return lbolt;
#elif defined(linux) || defined(cygwin)
    FILE           *in = fopen("/proc/uptime", "r");
    long            uptim = 0, a, b;
    if (in) {
        if (2 == fscanf(in, "%ld.%ld", &a, &b))
            uptim = a * 100 + b;
        fclose(in);
    }
    return uptim;
#else
    struct timeval  now;
    long            boottime_csecs, nowtime_csecs;

    boottime_csecs = get_boottime();
    if (boottime_csecs == 0)
        return 0;
    gettimeofday(&now, (struct timezone *) 0);
    nowtime_csecs = (now.tv_sec * 100) + (now.tv_usec / 10000);

    return (nowtime_csecs - boottime_csecs);
#endif
}