Ejemplo n.º 1
0
int
refresh_proc_sys_fs(proc_sys_fs_t *proc_sys_fs)
{
    static int err_reported;
    char buf[MAXPATHLEN];
    FILE *filesp = NULL;
    FILE *inodep = NULL;
    FILE *dentryp = NULL;

    memset(proc_sys_fs, 0, sizeof(proc_sys_fs_t));

    if ((filesp  = linux_statsfile("/proc/sys/fs/file-nr", buf, sizeof(buf))) == NULL ||
	(inodep  = linux_statsfile("/proc/sys/fs/inode-state", buf, sizeof(buf))) == NULL ||
	(dentryp = linux_statsfile("/proc/sys/fs/dentry-state", buf, sizeof(buf))) == NULL) {
	proc_sys_fs->errcode = -oserror();
	if (err_reported == 0)
	    fprintf(stderr, "Warning: vfs metrics are not available : %s\n",
		    osstrerror());
    }
    else {
	proc_sys_fs->errcode = 0;
	if (fscanf(filesp,  "%d %d %d",
			&proc_sys_fs->fs_files_count,
			&proc_sys_fs->fs_files_free,
			&proc_sys_fs->fs_files_max) != 3)
	    proc_sys_fs->errcode = PM_ERR_VALUE;
	if (fscanf(inodep,  "%d %d",
			&proc_sys_fs->fs_inodes_count,
			&proc_sys_fs->fs_inodes_free) != 2)
	    proc_sys_fs->errcode = PM_ERR_VALUE;
	if (fscanf(dentryp, "%d %d",
			&proc_sys_fs->fs_dentry_count,
			&proc_sys_fs->fs_dentry_free) != 2)
	    proc_sys_fs->errcode = PM_ERR_VALUE;
#if PCP_DEBUG
	if (pmDebug & DBG_TRACE_LIBPMDA) {
	    if (proc_sys_fs->errcode == 0)
		fprintf(stderr, "refresh_proc_sys_fs: found vfs metrics\n");
	    else
		fprintf(stderr, "refresh_proc_sys_fs: botch! missing vfs metrics\n");
	}
#endif
    }
    if (filesp)
	fclose(filesp);
    if (inodep)
	fclose(inodep);
    if (dentryp)
	fclose(dentryp);

    if (!err_reported)
	err_reported = 1;

    if (proc_sys_fs->errcode == 0)
	return 0;
    return -1;
}
Ejemplo n.º 2
0
static int
refresh_net_dev_ipv6_addr(pmInDom indom)
{
    FILE *fp;
    char addr6p[8][5];
    char addr6[40], devname[20+1];
    char addr[INET6_ADDRSTRLEN];
    char buf[MAXPATHLEN];
    struct sockaddr_in6 sin6;
    int sts, plen, scope, dad_status, if_idx;
    net_addr_t *netip;
    static uint32_t cache_err;

    if ((fp = linux_statsfile("/proc/net/if_inet6", buf, sizeof(buf))) == NULL)
	return 0;

    while (fscanf(fp, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
		  addr6p[0], addr6p[1], addr6p[2], addr6p[3],
		  addr6p[4], addr6p[5], addr6p[6], addr6p[7],
		  &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
	sts = pmdaCacheLookupName(indom, devname, NULL, (void **)&netip);
	if (sts == PM_ERR_INST || (sts >= 0 && netip == NULL)) {
	    /* first time since re-loaded, else new one */
	    netip = (net_addr_t *)calloc(1, sizeof(net_addr_t));
	}
	else if (sts < 0) {
	    if (cache_err++ < 10) {
		fprintf(stderr, "refresh_net_dev_ipv6_addr: "
				"pmdaCacheLookupName(%s, %s, ...) failed: %s\n",
		    pmInDomStr(indom), devname, pmErrStr(sts));
	    }
	    continue;
	}
	if ((sts = pmdaCacheStore(indom, PMDA_CACHE_ADD, devname, (void *)netip)) < 0) {
	    if (cache_err++ < 10) {
		fprintf(stderr, "refresh_net_dev_ipv6_addr: "
			"pmdaCacheStore(%s, PMDA_CACHE_ADD, %s, "
			PRINTF_P_PFX "%p) failed: %s\n",
		    pmInDomStr(indom), devname, netip, pmErrStr(sts));
	    }
	    continue;
	}

	sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
		addr6p[0], addr6p[1], addr6p[2], addr6p[3],
		addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
	if (inet_pton(AF_INET6, addr6, sin6.sin6_addr.s6_addr) != 1)
	    continue;

	sin6.sin6_family = AF_INET6;
	sin6.sin6_port = 0;
	if (!inet_ntop(AF_INET6, &sin6.sin6_addr, addr, INET6_ADDRSTRLEN))
	    continue;
	snprintf(netip->ipv6, sizeof(netip->ipv6), "%s/%d", addr, plen);
	netip->ipv6scope = (uint16_t)scope;
	netip->has_ipv6 = 1;
    }
    fclose(fp);
    return 0;
}
Ejemplo n.º 3
0
int
refresh_proc_net_snmp(proc_net_snmp_t *snmp)
{
    char	buf[MAXPATHLEN];
    char	header[1024];
    FILE	*fp;

    init_refresh_proc_net_snmp(snmp);
    if ((fp = linux_statsfile("/proc/net/snmp", buf, sizeof(buf))) == NULL)
	return -oserror();
    while (fgets(header, sizeof(header), fp) != NULL) {
	if (fgets(buf, sizeof(buf), fp) != NULL) {
	    if (strncmp(buf, "Ip:", 3) == 0)
		get_fields(ip_fields, header, buf);
	    else if (strncmp(buf, "Icmp:", 5) == 0)
		get_fields(icmp_fields, header, buf);
	    else if (strncmp(buf, "IcmpMsg:", 8) == 0)
		get_ordinal_fields(icmpmsg_fields, header, buf,
                                   NR_ICMPMSG_COUNTERS);
	    else if (strncmp(buf, "Tcp:", 4) == 0)
		get_fields(tcp_fields, header, buf);
	    else if (strncmp(buf, "Udp:", 4) == 0)
		get_fields(udp_fields, header, buf);
	    else if (strncmp(buf, "UdpLite:", 8) == 0)
		get_fields(udplite_fields, header, buf);
	    else
	    	fprintf(stderr, "Error: unrecognised snmp row: %s", buf);
	}
    }
    fclose(fp);
    return 0;
}
Ejemplo n.º 4
0
int
refresh_interrupt_values(void)
{
    FILE *fp;
    char buf[4096];
    int i, ncolumns;

    if (cpu_count == 0) {
	long ncpus = sysconf(_SC_NPROCESSORS_CONF);
	online_cpumap = malloc(ncpus * sizeof(int));
	if (!online_cpumap)
	    return -oserror();
	cpu_count = ncpus;
    }
    memset(online_cpumap, 0, cpu_count * sizeof(int));

    if ((fp = linux_statsfile("/proc/interrupts", buf, sizeof(buf))) == NULL)
	return -oserror();

    /* first parse header, which maps online CPU number to column number */
    if (fgets(buf, sizeof(buf), fp)) {
	ncolumns = map_online_cpus(buf);
    } else {
	fclose(fp);
	return -EINVAL;		/* unrecognised file format */
    }

    /* next we parse each interrupt line row (starting with a digit) */
    i = 0;
    while (fgets(buf, sizeof(buf), fp))
	if (!extract_interrupt_lines(buf, ncolumns, i++))
	    break;

    /* parse other per-CPU interrupt counter rows (starts non-digit) */
    i = 0;
    while (fgets(buf, sizeof(buf), fp) != NULL) {
	if (extract_interrupt_errors(buf))
	    continue;
	if (extract_interrupt_misses(buf))
	    continue;
	if (!extract_interrupt_other(buf, ncolumns, i++))
	    break;
    }

    fclose(fp);
    return 0;
}
Ejemplo n.º 5
0
int
refresh_proc_net_softnet(proc_net_softnet_t *proc_net_softnet)
{
    char buf[1024];
    int count, flags;
    FILE *fp;
    uint64_t filler;
    proc_net_softnet_t sn;

    if ((fp = linux_statsfile("/proc/net/softnet_stat", buf, sizeof(buf))) == NULL)
	return -oserror();
    memset(proc_net_softnet, 0, sizeof(proc_net_softnet_t));
    while (fgets(buf, sizeof(buf), fp) != NULL) {
	memset(&sn, 0, sizeof(sn));
	count = sscanf(buf, "%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx",
		    &sn.processed, &sn.dropped, &sn.time_squeeze,
		    &filler, &filler, &filler, &filler, &filler,
		    &sn.cpu_collision, &sn.received_rps, &sn.flow_limit_count);
	flags = 0;
	if (count >= 9)
	    flags |= SN_PROCESSED | SN_DROPPED | SN_TIME_SQUEEZE | SN_CPU_COLLISION;
	if (count >= 10)
	    flags |= SN_RECEIVED_RPS;
	if (count >= 11)
	    flags |= SN_FLOW_LIMIT_COUNT;
	proc_net_softnet->flags = flags;
	/* summed, one line per-cpu */
	proc_net_softnet->processed += sn.processed;
	proc_net_softnet->dropped += sn.dropped;
	proc_net_softnet->time_squeeze += sn.time_squeeze;
	proc_net_softnet->cpu_collision += sn.cpu_collision;
	proc_net_softnet->received_rps += sn.received_rps;
	proc_net_softnet->flow_limit_count += sn.flow_limit_count;
    }

    fclose(fp);
    return 0;
}
Ejemplo n.º 6
0
int
refresh_proc_net_netstat(proc_net_netstat_t *netstat)
{
    /* Need a sufficiently large value to hold a full line */
    char	buf[MAXPATHLEN];
    char	header[2048];
    FILE	*fp;

    init_refresh_proc_net_netstat(netstat);
    if ((fp = linux_statsfile("/proc/net/netstat", buf, sizeof(buf))) == NULL)
	return -oserror();
    while (fgets(header, sizeof(header), fp) != NULL) {
	if (fgets(buf, sizeof(buf), fp) != NULL) {
	    if (strncmp(buf, "IpExt:", 6) == 0)
		get_fields(netstat_ip_fields, header, buf);
	    else if (strncmp(buf, "TcpExt:", 7) == 0)
		get_fields(netstat_tcp_fields, header, buf);
	    else
		__pmNotifyErr(LOG_ERR, "Unrecognised netstat row: %s\n", buf);
	}
    }
    fclose(fp);
    return 0;
}
Ejemplo n.º 7
0
int
refresh_proc_partitions(pmInDom disk_indom, pmInDom partitions_indom, pmInDom dm_indom)
{
    FILE *fp;
    int devmin;
    int devmaj;
    int n;
    int indom;
    int have_proc_diskstats;
    int inst;
    unsigned long long blocks;
    partitions_entry_t *p;
    int indom_changes = 0;
    char *dmname;
    char buf[MAXPATHLEN];
    char namebuf[MAXPATHLEN];
    static int first = 1;

    if (first) {
	/* initialize the instance domain caches */
	pmdaCacheOp(disk_indom, PMDA_CACHE_LOAD);
	pmdaCacheOp(partitions_indom, PMDA_CACHE_LOAD);
	pmdaCacheOp(dm_indom, PMDA_CACHE_LOAD);

	first = 0;
	indom_changes = 1;
    }

    pmdaCacheOp(disk_indom, PMDA_CACHE_INACTIVE);
    pmdaCacheOp(partitions_indom, PMDA_CACHE_INACTIVE);
    pmdaCacheOp(dm_indom, PMDA_CACHE_INACTIVE);

    if ((fp = linux_statsfile("/proc/diskstats", buf, sizeof(buf))) != NULL)
    	/* 2.6 style disk stats */
	have_proc_diskstats = 1;
    else {
	if ((fp = linux_statsfile("/proc/partitions", buf, sizeof(buf))) != NULL)
	    have_proc_diskstats = 0;
	else
	    return -oserror();
    }

    while (fgets(buf, sizeof(buf), fp) != NULL) {
	dmname = NULL;
	if (buf[0] != ' ' || buf[0] == '\n') {
	    /* skip heading */
	    continue;
	}

	if (have_proc_diskstats) {
	    if ((n = sscanf(buf, "%d %d %s", &devmaj, &devmin, namebuf)) != 3)
		continue;
	}
	else {
	    /* /proc/partitions */
	    if ((n = sscanf(buf, "%d %d %llu %s", &devmaj, &devmin, &blocks, namebuf)) != 4)
		continue;
	}

	if (_pm_isdm(namebuf)) {
	    indom = dm_indom;
	    dmname = strdup(namebuf);
	}
	else if (_pm_ispartition(namebuf))
	    indom = partitions_indom;
	else if (_pm_isdisk(namebuf))
	    indom = disk_indom;
	else
	    continue;

	if (indom == dm_indom) {
	    /* replace dm-[0-9]* with the persistent name from /dev/mapper */
	    if (!map_persistent_dm_name(namebuf, sizeof(namebuf), devmaj, devmin)) {
		/* skip dm devices that have no persistent name mapping */
		free(dmname);
		continue;
	    }
	}

	p = NULL;
	if (pmdaCacheLookupName(indom, namebuf, &inst, (void **)&p) < 0 || !p) {
	    /* not found: allocate and add a new entry */
	    p = (partitions_entry_t *)malloc(sizeof(partitions_entry_t));
	    memset(p, 0, sizeof(partitions_entry_t));
	    indom_changes++;
	}

	if (p->dmname)
	    free(p->dmname);
	p->dmname = dmname; /* NULL if not a dm device */

        if (!p->namebuf)
            p->namebuf = strdup(namebuf);
        else
        if (strcmp(namebuf, p->namebuf) != 0) {
            free(p->namebuf);
            p->namebuf = strdup(namebuf);
        }

	/* activate this entry */
	if (p->udevnamebuf)
	    /* long xscsi name */
	    inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, p->udevnamebuf, p);
	else
	    /* short /proc/diskstats or /proc/partitions name */
	    inst = pmdaCacheStore(indom, PMDA_CACHE_ADD, namebuf, p);

	if (have_proc_diskstats) {
	    /* 2.6 style /proc/diskstats */
	    p->nr_blocks = 0;
	    namebuf[0] = '\0';
	    /* Linux source: block/genhd.c::diskstats_show(1) */
	    n = sscanf(buf, "%u %u %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u",
		&p->major, &p->minor, namebuf,
		&p->rd_ios, &p->rd_merges, &p->rd_sectors, &p->rd_ticks,
		&p->wr_ios, &p->wr_merges, &p->wr_sectors, &p->wr_ticks,
		&p->ios_in_flight, &p->io_ticks, &p->aveq);
	    if (n != 14) {
		p->rd_merges = p->wr_merges = p->wr_ticks =
			p->ios_in_flight = p->io_ticks = p->aveq = 0;
		/* Linux source: block/genhd.c::diskstats_show(2) */
		n = sscanf(buf, "%u %u %s %u %u %u %u\n",
		    &p->major, &p->minor, namebuf,
		    (unsigned int *)&p->rd_ios, (unsigned int *)&p->rd_sectors,
		    (unsigned int *)&p->wr_ios, (unsigned int *)&p->wr_sectors);
	    }
	}
	else {
	    /* 2.4 style /proc/partitions */
	    namebuf[0] = '\0';
	    n = sscanf(buf, "%u %u %lu %s %lu %lu %llu %u %lu %lu %llu %u %u %u %u",
		&p->major, &p->minor, &p->nr_blocks, namebuf,
		&p->rd_ios, &p->rd_merges, &p->rd_sectors,
		&p->rd_ticks, &p->wr_ios, &p->wr_merges,
		&p->wr_sectors, &p->wr_ticks, &p->ios_in_flight,
		&p->io_ticks, &p->aveq);
	}

    }

    /*
     * If any new disks or partitions have appeared then we
     * we need to remap the long device names (if /dev/xscsi
     * exists) and then flush the pmda cache.
     *
     * We just let inactive instances rot in the inactive state
     * (this doesn't happen very often, so is only a minor leak).
     */
    if (indom_changes) {
	refresh_udev(disk_indom, partitions_indom);
	pmdaCacheOp(disk_indom, PMDA_CACHE_SAVE);
	pmdaCacheOp(partitions_indom, PMDA_CACHE_SAVE);
	pmdaCacheOp(dm_indom, PMDA_CACHE_SAVE);
    }

    /*
     * success
     */
    if (fp)
	fclose(fp);
    return 0;
}
Ejemplo n.º 8
0
int
refresh_proc_net_dev(pmInDom indom, linux_container_t *container)
{
    static uint32_t	gen;	/* refresh generation number */
    static uint32_t	cache_err;	/* throttle messages */
    char		buf[1024];
    FILE		*fp;
    char		*p, *v;
    int			j, sts;
    net_interface_t	*netip;

    if ((fp = linux_statsfile("/proc/net/dev", buf, sizeof(buf))) == NULL)
    	return -oserror();

    if (gen == 0) {
	/*
	 * first time, reload cache from external file, and force any
	 * subsequent changes to be saved
	 */
	pmdaCacheOp(indom, PMDA_CACHE_LOAD);
	gen++;
    }

    /*
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo: 4060748   39057    0    0    0     0          0         0  4060748   39057    0    0    0     0       0          0
  eth0:       0  337614    0    0    0     0          0         0        0  267537    0    0    0 27346      62          0
     */

    pmdaCacheOp(indom, PMDA_CACHE_INACTIVE);

    while (fgets(buf, sizeof(buf), fp) != NULL) {
	if ((p = v = strchr(buf, ':')) == NULL)
	    continue;
	*p = '\0';
	for (p=buf; *p && isspace((int)*p); p++) {;}

	sts = pmdaCacheLookupName(indom, p, NULL, (void **)&netip);
	if (sts == PM_ERR_INST || (sts >= 0 && netip == NULL)) {
	    /* first time since re-loaded, else new one */
	    netip = (net_interface_t *)calloc(1, sizeof(net_interface_t));
#if PCP_DEBUG
	    if (pmDebug & DBG_TRACE_LIBPMDA) {
		fprintf(stderr, "refresh_proc_net_dev: initialize \"%s\"\n", p);
	    }
#endif
	}
	else if (sts < 0) {
	    if (cache_err++ < 10) {
		fprintf(stderr, "refresh_proc_net_dev: pmdaCacheLookupName(%s, %s, ...) failed: %s\n",
		    pmInDomStr(indom), p, pmErrStr(sts));
	    }
	    continue;
	}
	if ((sts = pmdaCacheStore(indom, PMDA_CACHE_ADD, p, (void *)netip)) < 0) {
	    if (cache_err++ < 10) {
		fprintf(stderr, "refresh_proc_net_dev: pmdaCacheStore(%s, PMDA_CACHE_ADD, %s, " PRINTF_P_PFX "%p) failed: %s\n",
		    pmInDomStr(indom), p, netip, pmErrStr(sts));
	    }
	    continue;
	}

	memset(&netip->ioc, 0, sizeof(netip->ioc));
	for (p=v, j=0; j < PROC_DEV_COUNTERS_PER_LINE; j++) {
	    for (; !isdigit((int)*p); p++) {;}
	    sscanf(p, "%llu", (long long unsigned int *)&netip->counters[j]);
	    for (; !isspace((int)*p); p++) {;}
	}
    }

    /* success */
    fclose(fp);

    if (!container)
	pmdaCacheOp(indom, PMDA_CACHE_SAVE);
    return 0;
}
Ejemplo n.º 9
0
int
refresh_proc_slabinfo(pmInDom slab_indom, proc_slabinfo_t *slabinfo)
{
    slab_cache_t sbuf, *s;
    char buf[BUFSIZ];
    char name[128];
    char *w, *p;
    FILE *fp;
    int i, sts = 0, indom_change = 0;
    static int major_version = -1;
    static int minor_version = 0;

    for (pmdaCacheOp(slab_indom, PMDA_CACHE_WALK_REWIND);;) {
	if ((i = pmdaCacheOp(slab_indom, PMDA_CACHE_WALK_NEXT)) < 0)
	    break;
	if (!pmdaCacheLookup(slab_indom, i, NULL, (void **)&s) || !s)
	    continue;
	s->seen = 0;
    }
    pmdaCacheOp(slab_indom, PMDA_CACHE_INACTIVE);

    if ((fp = linux_statsfile("/proc/slabinfo", buf, sizeof(buf))) == NULL)
	return -oserror();

    /* skip header */
    if (fgets(buf, sizeof(buf), fp) == NULL) {
    	/* oops, no header! */
	fclose(fp);
	return -oserror();
    }

    if (major_version < 0) {
	major_version = minor_version = 0;
	if (strstr(buf, "slabinfo - version:")) {
	    for (p = buf; *p; p++) {
		if (isdigit((int)*p)) {
		    sscanf(p, "%d.%d", &major_version, &minor_version);
		    break;
		}
	    }
	}
    }

    while (fgets(buf, sizeof(buf), fp) != NULL) {
	/* try to convert whitespace in cache names to underscores, */
	/* by looking for alphabetic chars which follow whitespace. */
	if (buf[0] == '#')
	    continue;
	for (w = NULL, p = buf; *p != '\0'; p++) {
	    if (isspace((int)*p))
		w = p;
	    else if (isdigit((int)*p))
		break;
	    else if (isalpha((int)*p) && w) {
		for (; w && w != p; w++)
		    *w = '_';
		w = NULL;
	    }
	}

	memset(&sbuf, 0, sizeof(slab_cache_t));

	if (major_version == 1 && minor_version == 0) {
	    /*
	     * <name> <active_objs> <num_objs>
	     * (generally 2.2 kernels)
	     */
	    i = sscanf(buf, "%s %lu %lu", name,
			    (unsigned long *)&sbuf.num_active_objs,
			    (unsigned long *)&sbuf.total_objs);
	    if (i != 3) {
		sts = PM_ERR_APPVERSION;
		break;
	    }
	}
	else if (major_version == 1 && minor_version == 1) {
	    /*
	     * <name> <active_objs> <num_objs> <objsize> <active_slabs> <num_slabs> <pagesperslab>
	     * (generally 2.4 kernels)
	     */
	    i = sscanf(buf, "%s %lu %lu %u %u %u %u", name,
			    (unsigned long *)&sbuf.num_active_objs,
			    (unsigned long *)&sbuf.total_objs,
			    &sbuf.object_size, 
			    &sbuf.num_active_slabs,
			    &sbuf.total_slabs, 
			    &sbuf.pages_per_slab);
	    if (i != 7) {
		sts = PM_ERR_APPVERSION;
		break;
	    }

	    sbuf.total_size = sbuf.pages_per_slab * sbuf.num_active_slabs;
	    sbuf.total_size <<= _pm_pageshift;
	}
	else if (major_version == 2 && minor_version >= 0 && minor_version <= 1) {
	    /* 
	     * <name> <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>  .. and more
	     * (generally for kernels up to at least 2.6.11)
	     */
	    i = sscanf(buf, "%s %lu %lu %u %u %u", name,
			    (unsigned long *)&sbuf.num_active_objs,
			    (unsigned long *)&sbuf.total_objs,
			    &sbuf.object_size,
			    &sbuf.objects_per_slab, 
			    &sbuf.pages_per_slab);
	    if (i != 6) {
		sts = PM_ERR_APPVERSION;
		break;
	    }

	    sbuf.total_size = sbuf.pages_per_slab * sbuf.num_active_objs;
	    sbuf.total_size <<= _pm_pageshift;
	    sbuf.total_size /= sbuf.objects_per_slab;
	}
	else {
	    /* no support */
	    sts = PM_ERR_APPVERSION;
	    break;
	}

	sts = pmdaCacheLookupName(slab_indom, name, &i, (void **)&s);
	if (sts < 0 || !s) {
	    /* new cache has appeared */
	    if ((s = calloc(1, sizeof(*s))) == NULL)
		continue;
#if PCP_DEBUG
	    if (pmDebug & DBG_TRACE_LIBPMDA)
		fprintf(stderr, "refresh_slabinfo: added \"%s\"\n", name);
#endif
	    indom_change++;
	}

	s->num_active_objs	= sbuf.num_active_objs;
	s->total_objs		= sbuf.total_objs;
	s->object_size		= sbuf.object_size;
	s->num_active_slabs	= sbuf.num_active_slabs;
	s->total_slabs		= sbuf.total_slabs;
	s->pages_per_slab	= sbuf.pages_per_slab;
	s->objects_per_slab	= sbuf.objects_per_slab;
	s->total_size		= sbuf.total_size;

	s->seen = major_version * 10 + minor_version;

	pmdaCacheStore(slab_indom, PMDA_CACHE_ADD, name, s);
    }
    fclose(fp);

    if (indom_change)
	pmdaCacheOp(slab_indom, PMDA_CACHE_SAVE);

    return sts;
}
Ejemplo n.º 10
0
int
refresh_proc_meminfo(proc_meminfo_t *proc_meminfo)
{
    char	buf[1024];
    char	*bufp;
    int64_t	*p;
    int		i;
    FILE	*fp;

    for (i = 0; meminfo_fields[i].field != NULL; i++) {
	p = MOFFSET(i, proc_meminfo);
	*p = -1; /* marked as "no value available" */
    }

    if ((fp = linux_statsfile("/proc/meminfo", buf, sizeof(buf))) == NULL)
	return -oserror();

    while (fgets(buf, sizeof(buf), fp) != NULL) {
	if ((bufp = strchr(buf, ':')) == NULL)
	    continue;
	*bufp = '\0';
	for (i=0; meminfo_fields[i].field != NULL; i++) {
	    if (strcmp(buf, meminfo_fields[i].field) != 0)
		continue;
	    p = MOFFSET(i, proc_meminfo);
	    for (bufp++; *bufp; bufp++) {
	    	if (isdigit((int)*bufp)) {
		    sscanf(bufp, "%llu", (unsigned long long *)p);
		    *p *= 1024; /* kbytes -> bytes */
		    break;
		}
	    }
	}
    }

    fclose(fp);

    /*
     * MemAvailable is only in 3.x or later kernels but we can calculate it
     * using other values, similar to upstream kernel commit 34e431b0ae.
     */
    if (!MEMINFO_VALID_VALUE(proc_meminfo->MemAvailable) ||
	(linux_test_mode & LINUX_TEST_MEMINFO)) {
	if (MEMINFO_VALID_VALUE(proc_meminfo->MemTotal) &&
	    MEMINFO_VALID_VALUE(proc_meminfo->MemFree) &&
	    MEMINFO_VALID_VALUE(proc_meminfo->Active_file) &&
	    MEMINFO_VALID_VALUE(proc_meminfo->Inactive_file) &&
	    MEMINFO_VALID_VALUE(proc_meminfo->SlabReclaimable)) {

	    int64_t pagecache;
	    int64_t wmark_low = 0;

	    /*
	     * sum for each zone->watermark[WMARK_LOW];
	     */
	    if ((fp = linux_statsfile("/proc/zoneinfo", buf, sizeof(buf))) != NULL) {
		while (fgets(buf, sizeof(buf), fp) != NULL) {
		    if ((bufp = strstr(buf, "low ")) != NULL) {
			int64_t low;
		    	if (sscanf(bufp+4, "%lld", (long long int *)&low) == 1)
			    wmark_low += low;
		    }
		}
		fclose(fp);
		wmark_low <<= _pm_pageshift;
	    }

	    /*  
	     * Free memory cannot be taken below the low watermark, before the
	     * system starts swapping.
	     */
	    proc_meminfo->MemAvailable = proc_meminfo->MemFree - wmark_low;

	    /*
	     * Not all the page cache can be freed, otherwise the system will
	     * start swapping. Assume at least half of the page cache, or the
	     * low watermark worth of cache, needs to stay.
	     */
	    pagecache = proc_meminfo->Active_file + proc_meminfo->Inactive_file;
	    pagecache -= MIN(pagecache / 2, wmark_low);
	    proc_meminfo->MemAvailable += pagecache;

	    /*
	     * Part of the reclaimable slab consists of items that are in use,
	     * and cannot be freed. Cap this estimate at the low watermark.
	     */
	    proc_meminfo->MemAvailable += proc_meminfo->SlabReclaimable;
	    proc_meminfo->MemAvailable -= MIN(proc_meminfo->SlabReclaimable / 2, wmark_low);

	    if (proc_meminfo->MemAvailable < 0)
	    	proc_meminfo->MemAvailable = 0;
	}
    }

    /* success */
    return 0;
}
Ejemplo n.º 11
0
int
refresh_proc_net_softnet(proc_net_softnet_t *proc_net_softnet)
{
    char buf[1024];
    int count;
    unsigned flags = 0;
    int cpu;
    FILE *fp;
    uint64_t filler;
    proc_net_softnet_t *sn = proc_net_softnet;

    /* size > (11*7)+1 bytes, where 7 == strlen("%08llx "), and +1 for '\0' */
    static char fmt[128] = { '\0' };

    if (fmt[0] == '\0') {
	int i;
	/*
	 * one trip initialization to decide the correct sscanf format
	 * for a uint64_t data type .. needs to be
	 * "%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx"
	 * or
	 * "%08llx %08llx %08llx %08llx %08llx %08llx %08llx %08llx %08llx %08llx %08llx"
	 */
	fmt[0] = '\0';
	if (strcmp(FMT_INT64, "lld") == 0) {
	    for (i = 0; i < 11; i++)
		strcat(fmt, "%08llx ");
	}
	else {
	    for (i = 0; i < 11; i++)
		strcat(fmt, "%08lx ");
	}
	/* chop off last ' ' */
	fmt[strlen(fmt)] = '\0';

	/* one-trip - allocate per-cpu counter arrays */
	memset(sn, 0, sizeof(proc_net_softnet_t));
	sn->processed = (uint64_t *)malloc(_pm_ncpus * sizeof(uint64_t));
	sn->dropped = (uint64_t *)malloc(_pm_ncpus * sizeof(uint64_t));
	sn->time_squeeze = (uint64_t *)malloc(_pm_ncpus * sizeof(uint64_t));
	sn->cpu_collision = (uint64_t *)malloc(_pm_ncpus * sizeof(uint64_t));
	sn->received_rps = (uint64_t *)malloc(_pm_ncpus * sizeof(uint64_t));
	sn->flow_limit_count = (uint64_t *)malloc(_pm_ncpus * sizeof(uint64_t));

	if (!sn->processed || !sn->dropped || !sn->time_squeeze ||
	    !sn->cpu_collision || !sn->received_rps || !sn->flow_limit_count) {
	    return -ENOMEM;
	}
    }

    if ((fp = linux_statsfile("/proc/net/softnet_stat", buf, sizeof(buf))) == NULL)
	return -oserror();
    for (cpu=0; cpu < _pm_ncpus; cpu++) {
	if (fgets(buf, sizeof(buf), fp) == NULL)
	    break;
	count = sscanf(buf, fmt,
		&sn->processed[cpu], &sn->dropped[cpu], &sn->time_squeeze[cpu],
		&filler, &filler, &filler, &filler, &filler,
		&sn->cpu_collision[cpu], &sn->received_rps[cpu], &sn->flow_limit_count[cpu]);
	sn->flags = 0;
	if (count >= 9)
	    sn->flags |= SN_PROCESSED | SN_DROPPED | SN_TIME_SQUEEZE | SN_CPU_COLLISION;
	if (count >= 10)
	    sn->flags |= SN_RECEIVED_RPS;
	if (count >= 11)
	    sn->flags |= SN_FLOW_LIMIT_COUNT;

	if (cpu > 0 && sn->flags != flags)
	    fprintf(stderr, "refresh_proc_net_softnet: warning: inconsistent flags, cpu %d\n", cpu);
	flags = sn->flags;
    }

    fclose(fp);
    return 0;
}
Ejemplo n.º 12
0
int
refresh_proc_net_softnet(proc_net_softnet_t *proc_net_softnet)
{
    char buf[1024];
    int count, flags;
    FILE *fp;
    uint64_t filler;
    proc_net_softnet_t sn;

    /* size > (11*7)+1 bytes, where 7 == strlen("%08llx "), and +1 for '\0' */
    static char fmt[128] = { '\0' };

    if (fmt[0] == '\0') {
	int i;
	/*
	 * one trip initialization to decide the correct sscanf format
	 * for a uint64_t data type .. needs to be
	 * "%08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx"
	 * or
	 * "%08llx %08llx %08llx %08llx %08llx %08llx %08llx %08llx %08llx %08llx %08llx"
	 */
	fmt[0] = '\0';
	if (strcmp(FMT_INT64, "lld") == 0) {
	    for (i = 0; i < 11; i++)
		strcat(fmt, "%08llx ");
	}
	else {
	    for (i = 0; i < 11; i++)
		strcat(fmt, "%08lx ");
	}
	/* chop off last ' ' */
	fmt[strlen(fmt)] = '\0';
    }

    if ((fp = linux_statsfile("/proc/net/softnet_stat", buf, sizeof(buf))) == NULL)
	return -oserror();
    memset(proc_net_softnet, 0, sizeof(proc_net_softnet_t));
    while (fgets(buf, sizeof(buf), fp) != NULL) {
	memset(&sn, 0, sizeof(sn));
	count = sscanf(buf, fmt,
		&sn.processed, &sn.dropped, &sn.time_squeeze,
		&filler, &filler, &filler, &filler, &filler,
		&sn.cpu_collision, &sn.received_rps, &sn.flow_limit_count);
	flags = 0;
	if (count >= 9)
	    flags |= SN_PROCESSED | SN_DROPPED | SN_TIME_SQUEEZE | SN_CPU_COLLISION;
	if (count >= 10)
	    flags |= SN_RECEIVED_RPS;
	if (count >= 11)
	    flags |= SN_FLOW_LIMIT_COUNT;
	proc_net_softnet->flags = flags;
	/* summed, one line per-cpu */
	proc_net_softnet->processed += sn.processed;
	proc_net_softnet->dropped += sn.dropped;
	proc_net_softnet->time_squeeze += sn.time_squeeze;
	proc_net_softnet->cpu_collision += sn.cpu_collision;
	proc_net_softnet->received_rps += sn.received_rps;
	proc_net_softnet->flow_limit_count += sn.flow_limit_count;
    }

    fclose(fp);
    return 0;
}
Ejemplo n.º 13
0
int
refresh_proc_buddyinfo(proc_buddyinfo_t *proc_buddyinfo)
{
    int i, j;
    char buf[2048];
    char read_buf[SPLIT_MAX][128];
    FILE *fp;
    static int next_id = -1;

    if (next_id < 0) {
        next_id = 0;
        proc_buddyinfo->nbuddys = 0;
        if ((fp = linux_statsfile("/proc/buddyinfo", buf, sizeof(buf))) == NULL)
            return -oserror();
        if (fgets(buf,sizeof(buf),fp) == NULL) { /* read first line */
            fclose(fp);
            return -oserror();
        }
        fclose(fp);
        MAX_ORDER = read_buddyinfo(buf,read_buf,0) - 5; /* get maximum page order */
    }

    if ((fp = linux_statsfile("/proc/buddyinfo", buf, sizeof(buf))) == NULL)
        return -oserror();

    while (fgets(buf,sizeof(buf),fp) != NULL) {
        char node_name[64];
        char *zone_name;
        int values[SPLIT_MAX];
        i = read_node_name(buf, node_name);
        i+=6; /* erase ", zone" */
        read_buddyinfo(buf+i, read_buf, MAX_ORDER+1); /* read zone name and page order */
        zone_name=read_buf[0];
        for (i=0; i < MAX_ORDER; i++)
            values[i] = atoi(read_buf[i+1]);
        for (i=0; i < proc_buddyinfo->nbuddys; i++) {
            if (strcmp(proc_buddyinfo->buddys[i].node_name, node_name)==0 && strcmp(proc_buddyinfo->buddys[i].zone_name, zone_name)==0 )
                break;
        }
        if (i==proc_buddyinfo->nbuddys) {
            proc_buddyinfo->nbuddys += MAX_ORDER;
            proc_buddyinfo->buddys = (buddyinfo_t *)realloc(proc_buddyinfo->buddys, proc_buddyinfo->nbuddys * sizeof(buddyinfo_t));
            for (j=0; j < MAX_ORDER; j++) {
                proc_buddyinfo->buddys[i+j].id = next_id++;
                strncpy(proc_buddyinfo->buddys[i+j].node_name, node_name,
			sizeof(proc_buddyinfo->buddys[i+j].node_name) - 1);
                strncpy(proc_buddyinfo->buddys[i+j].zone_name, zone_name,
			sizeof(proc_buddyinfo->buddys[i+j].zone_name) - 1);
                snprintf(proc_buddyinfo->buddys[i+j].id_name,
			 sizeof(proc_buddyinfo->buddys[i+j].id_name),
			 "%s::order%u::%s", zone_name, j, node_name);
            }
        }
        /* update data */
        for (j=0; j < MAX_ORDER; j++) {
            proc_buddyinfo->buddys[i+j].value = values[j];
        }
    }
    fclose(fp);

    /* refresh buddyinfo indom */
    if (proc_buddyinfo->indom->it_numinst != proc_buddyinfo->nbuddys) {
        proc_buddyinfo->indom->it_numinst = proc_buddyinfo->nbuddys;
        proc_buddyinfo->indom->it_set = (pmdaInstid *)realloc(proc_buddyinfo->indom->it_set,
                proc_buddyinfo->nbuddys * sizeof(pmdaInstid));
        memset(proc_buddyinfo->indom->it_set, 0, proc_buddyinfo->nbuddys * sizeof(pmdaInstid));
    }
    for (i=0; i < proc_buddyinfo->nbuddys; i++) {
        proc_buddyinfo->indom->it_set[i].i_inst = proc_buddyinfo->buddys[i].id;
        proc_buddyinfo->indom->it_set[i].i_name = proc_buddyinfo->buddys[i].id_name;
    }

    return 0;
}