示例#1
0
/*
 * return true is arg is a disk name
 */
static int
_pm_isdisk(char *dname)
{
    return (!_pm_isloop(dname) && !_pm_isramdisk(dname) &&
	    !_pm_ispartition(dname) && !_pm_isxvmvol(dname) &&
	    !_pm_isdm(dname) && !_pm_ismd(dname));
}
示例#2
0
static void
refresh_udev(pmInDom disk_indom, pmInDom partitions_indom)
{
    char buf[MAXNAMELEN];
    char realname[MAXNAMELEN];
    char *shortname;
    char *p;
    char *udevname;
    FILE *pfp;
    partitions_entry_t *entry;
    int indom;
    int inst;

    if (access("/dev/xscsi", R_OK) != 0)
    	return;
    if (!(pfp = popen("find /dev/xscsi -name disc -o -name part[0-9]*", "r")))
    	return;
    while (fgets(buf, sizeof(buf), pfp)) {
	if ((p = strrchr(buf, '\n')) != NULL)
	    *p = '\0';
	if (realpath(buf, realname)) {
	    udevname = buf + 5; /* /dev/xscsi/.... */
	    if ((shortname = strrchr(realname, '/')) != NULL) {
		shortname++;
		indom = _pm_ispartition(shortname) ?
		    partitions_indom : disk_indom;
		if (pmdaCacheLookupName(indom, shortname, &inst, (void **)&entry) != PMDA_CACHE_ACTIVE)
		    continue;
		entry->udevnamebuf = strdup(udevname);
		pmdaCacheStore(indom, PMDA_CACHE_HIDE, shortname, entry); /* inactive */
		pmdaCacheStore(indom, PMDA_CACHE_ADD, udevname, entry); /* active */
	    }
	}
    }
    pclose(pfp);
}
示例#3
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;
}