Changeset 43831 in vbox for trunk/src/VBox/Main/src-server
- Timestamp:
- Nov 7, 2012 1:11:51 PM (12 years ago)
- Location:
- trunk/src/VBox/Main/src-server
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/HostImpl.cpp
r43629 r43831 2930 2930 /* For now we are concerned with the root file system only. */ 2931 2931 pm::DiskList disks; 2932 int rc = pm::getDiskListByFs("/", disks);2932 int rc = hal->getDiskListByFs("/", disks); 2933 2933 if (RT_FAILURE(rc) || disks.empty()) 2934 2934 return; -
trunk/src/VBox/Main/src-server/Performance.cpp
r43629 r43831 85 85 86 86 int CollectorHAL::getProcessMemoryUsage(RTPROCESS /* process */, ULONG * /* used */) 87 { 88 return E_NOTIMPL; 89 } 90 91 int CollectorHAL::getDiskListByFs(const char * /* name */, DiskList& /* list */) 87 92 { 88 93 return E_NOTIMPL; -
trunk/src/VBox/Main/src-server/linux/PerformanceLinux.cpp
r43715 r43831 55 55 virtual int getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms); 56 56 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total); 57 58 virtual int getDiskListByFs(const char *name, DiskList& list); 57 59 private: 58 60 virtual int _getRawHostCpuLoad(); … … 394 396 } 395 397 396 int getDiskListByFs(const char *pszPath, DiskList& listDisks)398 int CollectorLinux::getDiskListByFs(const char *pszPath, DiskList& listDisks) 397 399 { 398 400 FILE *mtab = setmntent("/etc/mtab", "r"); -
trunk/src/VBox/Main/src-server/solaris/PerformanceSolaris.cpp
r43629 r43831 27 27 #include <sys/sysinfo.h> 28 28 #include <sys/time.h> 29 #include <sys/types.h> 30 #include <sys/statvfs.h> 29 31 30 32 #include <iprt/ctype.h> … … 33 35 #include <iprt/alloc.h> 34 36 #include <iprt/param.h> 37 #include <iprt/path.h> 35 38 #include <VBox/log.h> 36 39 #include "Performance.h" 37 40 41 #include <dlfcn.h> 42 43 #include <libzfs.h> 44 #include <libnvpair.h> 45 46 #include <map> 47 38 48 namespace pm { 49 50 typedef libzfs_handle_t *(*PFNZFSINIT)(void); 51 typedef zfs_handle_t *(*PFNZFSOPEN)(libzfs_handle_t *, const char *, int); 52 typedef void (*PFNZFSCLOSE)(zfs_handle_t *); 53 typedef uint64_t (*PFNZFSPROPGETINT)(zfs_handle_t *, zfs_prop_t); 54 typedef zpool_handle_t *(*PFNZPOOLOPEN)(libzfs_handle_t *, const char *); 55 typedef void (*PFNZPOOLCLOSE)(zpool_handle_t *); 56 typedef nvlist_t *(*PFNZPOOLGETCONFIG)(zpool_handle_t *, nvlist_t **); 57 typedef char *(*PFNZPOOLVDEVNAME)(libzfs_handle_t *, zpool_handle_t *, nvlist_t *, boolean_t); 58 59 typedef std::map<RTCString,RTCString> FsMap; 39 60 40 61 class CollectorSolaris : public CollectorHAL … … 44 65 virtual ~CollectorSolaris(); 45 66 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available); 67 virtual int getHostFilesystemUsage(const char *name, ULONG *total, ULONG *used, ULONG *available); 46 68 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used); 47 69 48 70 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle); 49 71 virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx); 72 virtual int getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms); 50 73 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total); 74 75 virtual int getDiskListByFs(const char *name, DiskList& list); 51 76 private: 52 77 static uint32_t getInstance(const char *pszIfaceName, char *pszDevName); 78 uint64_t getZfsTotal(uint64_t cbTotal, const char *szFsType, const char *szFsName); 79 void updateFilesystemMap(void); 80 RTCString physToInstName(const char *pcszPhysName); 81 53 82 kstat_ctl_t *mKC; 54 83 kstat_t *mSysPages; 55 84 kstat_t *mZFSCache; 85 86 void *mZfsSo; 87 libzfs_handle_t *mZfsLib; 88 PFNZFSINIT mZfsInit; 89 PFNZFSOPEN mZfsOpen; 90 PFNZFSCLOSE mZfsClose; 91 PFNZFSPROPGETINT mZfsPropGetInt; 92 PFNZPOOLOPEN mZpoolOpen; 93 PFNZPOOLCLOSE mZpoolClose; 94 PFNZPOOLGETCONFIG mZpoolGetConfig; 95 PFNZPOOLVDEVNAME mZpoolVdevName; 96 97 FsMap mFsMap; 56 98 }; 57 99 … … 67 109 : mKC(0), 68 110 mSysPages(0), 69 mZFSCache(0) 111 mZFSCache(0), 112 mZfsLib(0) 70 113 { 71 114 if ((mKC = kstat_open()) == 0) … … 85 128 Log(("kstat_lookup(system_pages) -> %d\n", errno)); 86 129 } 130 131 /* Try to load libzfs dynamically, it may be missing. */ 132 mZfsSo = dlopen("libzfs.so", RTLD_LAZY); 133 if (mZfsSo) 134 { 135 mZfsInit = (PFNZFSINIT)dlsym(mZfsSo, "libzfs_init"); 136 mZfsOpen = (PFNZFSOPEN)dlsym(mZfsSo, "zfs_open"); 137 mZfsClose = (PFNZFSCLOSE)dlsym(mZfsSo, "zfs_close"); 138 mZfsPropGetInt = (PFNZFSPROPGETINT)dlsym(mZfsSo, "zfs_prop_get_int"); 139 mZpoolOpen = (PFNZPOOLOPEN)dlsym(mZfsSo, "zpool_open"); 140 mZpoolClose = (PFNZPOOLCLOSE)dlsym(mZfsSo, "zpool_close"); 141 mZpoolGetConfig = (PFNZPOOLGETCONFIG)dlsym(mZfsSo, "zpool_get_config"); 142 mZpoolVdevName = (PFNZPOOLVDEVNAME)dlsym(mZfsSo, "zpool_vdev_name"); 143 144 if (mZfsInit && mZfsOpen && mZfsClose && mZfsPropGetInt 145 && mZpoolOpen && mZpoolClose && mZpoolGetConfig && mZpoolVdevName) 146 mZfsLib = mZfsInit(); 147 else 148 LogRel(("Incompatible libzfs? libzfs_init=%p zfs_open=%p zfs_close=%p zfs_prop_get_int=%p\n", 149 mZfsInit, mZfsOpen, mZfsClose, mZfsPropGetInt)); 150 } 151 152 updateFilesystemMap(); 87 153 } 88 154 … … 91 157 if (mKC) 92 158 kstat_close(mKC); 159 if (mZfsSo) 160 dlclose(mZfsSo); 93 161 } 94 162 … … 300 368 { 301 369 LogFlowThisFunc(("m=%s i=%u n=%s\n", szModule, uInstance, name)); 302 ksAdapter = kstat_lookup(mKC, szModule, uInstance, name);370 ksAdapter = kstat_lookup(mKC, szModule, uInstance, (char *)name); 303 371 if (ksAdapter == 0) 304 372 { … … 329 397 } 330 398 331 int getDiskListByFs(const char *name, DiskList& list) 332 { 333 return VERR_NOT_IMPLEMENTED; 334 } 335 336 } 399 int CollectorSolaris::getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms) 400 { 401 int rc = VINF_SUCCESS; 402 AssertReturn(strlen(name) < KSTAT_STRLEN, VERR_INVALID_PARAMETER); 403 LogFlowThisFunc(("n=%s\n", name)); 404 kstat_t *ksDisk = kstat_lookup(mKC, NULL, -1, (char *)name); 405 if (ksDisk != 0) 406 { 407 if (kstat_read(mKC, ksDisk, 0) == -1) 408 { 409 LogRel(("kstat_read(%s) -> %d\n", name, errno)); 410 rc = VERR_INTERNAL_ERROR; 411 } 412 else 413 { 414 kstat_io_t *ksIo = KSTAT_IO_PTR(ksDisk); 415 /* 416 * We do not care for wrap possibility here, although we may 417 * reconsider in about 300 years (9223372036854775807 ns). 418 */ 419 *disk_ms = ksIo->rtime / 1000000; 420 *total_ms = ksDisk->ks_snaptime / 1000000; 421 } 422 } 423 else 424 { 425 LogRel(("kstat_lookup(%s) -> %d\n", name, errno)); 426 rc = VERR_INTERNAL_ERROR; 427 } 428 429 return rc; 430 } 431 432 uint64_t CollectorSolaris::getZfsTotal(uint64_t cbTotal, const char *szFsType, const char *szFsName) 433 { 434 if (strcmp(szFsType, "zfs")) 435 return cbTotal; 436 FsMap::iterator it = mFsMap.find(szFsName); 437 if (it == mFsMap.end()) 438 return cbTotal; 439 440 char *pszDataset = strdup(it->second.c_str()); 441 char *pszEnd = pszDataset + strlen(pszDataset); 442 uint64_t uAvail = 0; 443 while (pszEnd) 444 { 445 zfs_handle_t *hDataset; 446 447 *pszEnd = 0; 448 hDataset = mZfsOpen(mZfsLib, pszDataset, ZFS_TYPE_DATASET); 449 if (!hDataset) 450 break; 451 452 if (uAvail == 0) 453 { 454 uAvail = mZfsPropGetInt(hDataset, ZFS_PROP_REFQUOTA); 455 if (uAvail == 0) 456 uAvail = UINT64_MAX; 457 } 458 459 uint64_t uQuota = mZfsPropGetInt(hDataset, ZFS_PROP_QUOTA); 460 if (uQuota && uAvail > uQuota) 461 uAvail = uQuota; 462 463 pszEnd = strrchr(pszDataset, '/'); 464 if (!pszEnd) 465 { 466 uint64_t uPoolSize = mZfsPropGetInt(hDataset, ZFS_PROP_USED) + 467 mZfsPropGetInt(hDataset, ZFS_PROP_AVAILABLE); 468 if (uAvail > uPoolSize) 469 uAvail = uPoolSize; 470 } 471 mZfsClose(hDataset); 472 } 473 free(pszDataset); 474 475 return uAvail ? uAvail : cbTotal; 476 } 477 478 int CollectorSolaris::getHostFilesystemUsage(const char *path, ULONG *total, ULONG *used, ULONG *available) 479 { 480 struct statvfs64 stats; 481 const unsigned _MB = 1024 * 1024; 482 483 if (statvfs64(path, &stats) == -1) 484 { 485 LogRel(("Failed to collect %s filesystem usage: errno=%d.\n", path, errno)); 486 return VERR_ACCESS_DENIED; 487 } 488 uint64_t cbBlock = stats.f_frsize ? stats.f_frsize : stats.f_bsize; 489 *total = (ULONG)(getZfsTotal(cbBlock * stats.f_blocks, stats.f_basetype, path) / _MB); 490 LogRel(("f_blocks=%llu.\n", stats.f_blocks)); 491 *used = (ULONG)(cbBlock * (stats.f_blocks - stats.f_bfree) / _MB); 492 *available = (ULONG)(cbBlock * stats.f_bavail / _MB); 493 494 return VINF_SUCCESS; 495 } 496 497 RTCString CollectorSolaris::physToInstName(const char *pcszPhysName) 498 { 499 FILE *fp = fopen("/etc/path_to_inst", "r"); 500 if (!fp) 501 return RTCString(); 502 503 RTCString strInstName; 504 size_t cbName = strlen(pcszPhysName); 505 char szBuf[RTPATH_MAX]; 506 while (fgets(szBuf, sizeof(szBuf), fp)) 507 { 508 if (szBuf[0] == '"' && strncmp(szBuf + 1, pcszPhysName, cbName) == 0) 509 { 510 char *pszDriver, *pszInstance; 511 pszDriver = strrchr(szBuf, '"'); 512 if (pszDriver) 513 { 514 *pszDriver = '\0'; 515 pszDriver = strrchr(szBuf, '"'); 516 if (pszDriver) 517 { 518 *pszDriver++ = '\0'; 519 pszInstance = strrchr(szBuf, ' '); 520 if (pszInstance) 521 { 522 *pszInstance = '\0'; 523 pszInstance = strrchr(szBuf, ' '); 524 if (pszInstance) 525 { 526 *pszInstance++ = '\0'; 527 strInstName = pszDriver; 528 strInstName += pszInstance; 529 break; 530 } 531 } 532 } 533 } 534 } 535 } 536 fclose(fp); 537 538 return strInstName; 539 } 540 541 int CollectorSolaris::getDiskListByFs(const char *name, DiskList& list) 542 { 543 FsMap::iterator it = mFsMap.find(name); 544 if (it == mFsMap.end()) 545 return VERR_INVALID_PARAMETER; 546 547 RTCString strName = it->second.substr(0, it->second.find("/")); 548 if (mZpoolOpen && mZpoolClose && mZpoolGetConfig) 549 { 550 zpool_handle_t *zh = mZpoolOpen(mZfsLib, strName.c_str()); 551 if (zh) 552 { 553 unsigned int cChildren; 554 nvlist_t **nvChildren, *nvRoot, *nvConfig = mZpoolGetConfig(zh, NULL); 555 Assert(!nvlist_lookup_nvlist(nvConfig, ZPOOL_CONFIG_VDEV_TREE, &nvRoot)); 556 if (!nvlist_lookup_nvlist_array(nvRoot, ZPOOL_CONFIG_CHILDREN, &nvChildren, &cChildren)) 557 { 558 for (unsigned int i = 0; i < cChildren; ++i) 559 { 560 uint64_t fHole = 0; 561 uint64_t fLog = 0; 562 563 nvlist_lookup_uint64(nvChildren[i], ZPOOL_CONFIG_IS_HOLE, &fHole); 564 nvlist_lookup_uint64(nvChildren[i], ZPOOL_CONFIG_IS_LOG, &fLog); 565 566 if (!fHole && !fLog) 567 { 568 char *pszChildName = mZpoolVdevName(mZfsLib, zh, nvChildren[i], _B_FALSE); 569 Assert(pszChildName); 570 RTCString strDevPath("/dev/dsk/"); 571 strDevPath += pszChildName; 572 char szLink[RTPATH_MAX]; 573 if (readlink(strDevPath.c_str(), szLink, sizeof(szLink)) != -1) 574 { 575 char *pszStart, *pszEnd; 576 pszStart = strstr(szLink, "/devices/"); 577 pszEnd = strrchr(szLink, ':'); 578 if (pszStart && pszEnd) 579 { 580 pszStart += 8; // Skip "/devices" 581 *pszEnd = '\0'; // Trim partition 582 list.push_back(physToInstName(pszStart)); 583 } 584 } 585 free(pszChildName); 586 } 587 } 588 } 589 mZpoolClose(zh); 590 } 591 } 592 else 593 list.push_back(RTCString(name)); 594 return VINF_SUCCESS; 595 } 596 597 void CollectorSolaris::updateFilesystemMap(void) 598 { 599 FILE *fp = fopen("/etc/mnttab", "r"); 600 if (fp) 601 { 602 struct mnttab Entry; 603 int rc = 0; 604 resetmnttab(fp); 605 while ((rc = getmntent(fp, &Entry)) == 0) 606 mFsMap[Entry.mnt_mountp] = Entry.mnt_special; 607 fclose(fp); 608 if (rc != -1) 609 LogRel(("Error while reading mnttab: %d\n", rc)); 610 } 611 } 612 613 }
Note:
See TracChangeset
for help on using the changeset viewer.