/* * 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)); }
/* * For block devices we have one instance domain for dev_t * based lookup, and another for (real) name lookup. * The reason we need this is that the blkio cgroup stats * are exported using the major:minor numbers, and not the * device names - we must perform that mapping ourselves. * In some places (value refresh) we need to lookup the blk * name from device major/minor, in other places (instances * refresh) we need the usual external instid:name lookup. */ static void refresh_cgroup_devices(void) { pmInDom diskindom = INDOM(DISK_INDOM); pmInDom devtindom = INDOM(DEVT_INDOM); char buf[MAXPATHLEN]; FILE *fp; pmdaCacheOp(devtindom, PMDA_CACHE_INACTIVE); pmdaCacheOp(diskindom, PMDA_CACHE_INACTIVE); if ((fp = proc_statsfile("/proc/diskstats", buf, sizeof(buf))) == NULL) return; while (fgets(buf, sizeof(buf), fp) != NULL) { unsigned int major, minor, unused; device_t *dev = NULL; char namebuf[1024]; int inst; if (sscanf(buf, "%u %u %s %u", &major, &minor, namebuf, &unused) != 4) continue; if (_pm_isloop(namebuf) || _pm_isramdisk(namebuf)) continue; if (pmdaCacheLookupName(diskindom, namebuf, &inst, (void **)&dev) < 0 || dev == NULL) { if (!(dev = (device_t *)malloc(sizeof(device_t)))) { __pmNoMem("device", sizeof(device_t), PM_RECOV_ERR); continue; } dev->major = major; dev->minor = minor; } /* keeping track of all fields (major/minor/inst/name) */ pmdaCacheStore(diskindom, PMDA_CACHE_ADD, namebuf, dev); (void)pmdaCacheLookupName(diskindom, namebuf, &dev->inst, NULL); (void)pmdaCacheLookup(diskindom, dev->inst, &dev->name, NULL); snprintf(buf, sizeof(buf), "%u:%u", major, minor); pmdaCacheStore(devtindom, PMDA_CACHE_ADD, buf, (void *)dev); if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "refresh_devices: \"%s\" \"%d:%d\" inst=%d\n", dev->name, dev->major, dev->minor, dev->inst); } fclose(fp); }
/* * slight improvement to heuristic suggested by * Tim Bradshaw <*****@*****.**> on 29 Dec 2003 */ int _pm_ispartition(char *dname) { int p, m = strlen(dname) - 1; /* * looking at something like foo/x, and we hope x ends p<n>, for * a partition, or not for a disk. */ if (strchr(dname, '/')) { for (p = m; p > 0 && isdigit((int)dname[p]); p--) ; if (p == m) /* name had no trailing digits. Wildly guess a disk. */ return 1; else /* * ends with digits, if preceding character is a 'p' punt * on a partition */ return (dname[p] == 'p'? 1 : 0); } else { /* * default test : partition names end in a digit do not * look like loopback devices. Handle other special-cases * here - mostly seems to be RAM-type disk drivers that're * choosing to end device names with numbers. */ return isdigit((int)dname[m]) && !_pm_isloop(dname) && !_pm_isramdisk(dname) && !_pm_ismmcdisk(dname) && !_pm_isnvmedrive(dname) && !_pm_ismd(dname) && !_pm_isdm(dname); } }