19f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include <stdio.h> 29f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include <string.h> 39f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include <sys/time.h> 49f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include <sys/types.h> 59f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include <sys/stat.h> 69f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include <dirent.h> 79f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include <libgen.h> 89f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include <math.h> 99edf7b3ed581a61433ad620d457b4d0349115e52Jens Axboe#include <assert.h> 109f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 119f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe#include "fio.h" 12c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe#include "smalloc.h" 137c9b1bce094d58c374b086bbb780c08265623ea4Jens Axboe#include "diskutil.h" 149f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 159f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboestatic int last_majdev, last_mindev; 16c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboestatic struct disk_util *last_du; 179f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 189ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboestatic struct fio_mutex *disk_util_mutex; 199ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 20d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens AxboeFLIST_HEAD(disk_list); 219f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 222db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboestatic struct disk_util *__init_per_file_disk_util(struct thread_data *td, 232db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboe int majdev, int mindev, char *path); 242db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboe 25c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboestatic void disk_util_free(struct disk_util *du) 26c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe{ 27c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe if (du == last_du) 28c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe last_du = NULL; 29c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe 30b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe while (!flist_empty(&du->slaves)) { 31b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe struct disk_util *slave; 32b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe 33b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe slave = flist_entry(du->slaves.next, struct disk_util, slavelist); 34b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe flist_del(&slave->slavelist); 35b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe slave->users--; 36b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe } 3793bcfd20e37cef8cec350fe06d3a086724c9f257Bruce Cran 38c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe fio_mutex_remove(du->lock); 39c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe sfree(du); 40c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe} 41c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe 429f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboestatic int get_io_ticks(struct disk_util *du, struct disk_util_stat *dus) 439f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 449f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe unsigned in_flight; 45d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe unsigned long long sectors[2]; 469f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe char line[256]; 479f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe FILE *f; 489f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe char *p; 495ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe int ret; 509f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 51cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe dprint(FD_DISKUTIL, "open stat file: %s\n", du->path); 52cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe 539f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe f = fopen(du->path, "r"); 549f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (!f) 559f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe return 1; 569f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 579f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe p = fgets(line, sizeof(line), f); 589f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (!p) { 599f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe fclose(f); 609f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe return 1; 619f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 629f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 63cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe dprint(FD_DISKUTIL, "%s: %s", du->path, p); 64cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe 65a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe ret = sscanf(p, "%u %u %llu %u %u %u %llu %u %u %u %u\n", 66a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe &dus->s.ios[0], 67a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe &dus->s.merges[0], §ors[0], 68a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe &dus->s.ticks[0], &dus->s.ios[1], 69a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe &dus->s.merges[1], §ors[1], 70a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe &dus->s.ticks[1], &in_flight, 71a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe &dus->s.io_ticks, 72a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe &dus->s.time_in_queue); 739f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe fclose(f); 74cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe dprint(FD_DISKUTIL, "%s: stat read ok? %d\n", du->path, ret == 1); 75a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.sectors[0] = sectors[0]; 76a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.sectors[1] = sectors[1]; 77cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe return ret != 11; 789f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 799f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 809f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboestatic void update_io_tick_disk(struct disk_util *du) 819f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 829f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct disk_util_stat __dus, *dus, *ldus; 839f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct timeval t; 849f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 85c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe if (!du->users) 86c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return; 8790b97ac3bc4368b79300207c796bcfbb828d07b9Jens Axboe if (get_io_ticks(du, &__dus)) 8890b97ac3bc4368b79300207c796bcfbb828d07b9Jens Axboe return; 899f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 909f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe dus = &du->dus; 919f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe ldus = &du->last_dus; 929f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 93a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.sectors[0] += (__dus.s.sectors[0] - ldus->s.sectors[0]); 94a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.sectors[1] += (__dus.s.sectors[1] - ldus->s.sectors[1]); 95a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.ios[0] += (__dus.s.ios[0] - ldus->s.ios[0]); 96a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.ios[1] += (__dus.s.ios[1] - ldus->s.ios[1]); 97a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.merges[0] += (__dus.s.merges[0] - ldus->s.merges[0]); 98a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.merges[1] += (__dus.s.merges[1] - ldus->s.merges[1]); 99a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.ticks[0] += (__dus.s.ticks[0] - ldus->s.ticks[0]); 100a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.ticks[1] += (__dus.s.ticks[1] - ldus->s.ticks[1]); 101a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.io_ticks += (__dus.s.io_ticks - ldus->s.io_ticks); 102a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.time_in_queue += (__dus.s.time_in_queue - ldus->s.time_in_queue); 1039f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 1049f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe fio_gettime(&t, NULL); 105a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.msec += mtime_since(&du->time, &t); 1069f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe memcpy(&du->time, &t, sizeof(t)); 107a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe memcpy(&ldus->s, &__dus.s, sizeof(__dus.s)); 1089f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 1099f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 1109ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboeint update_io_ticks(void) 1119f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 11201743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe struct flist_head *entry; 1139f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct disk_util *du; 1149ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe int ret = 0; 1159f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 116cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe dprint(FD_DISKUTIL, "update io ticks\n"); 117cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe 1189ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_down(disk_util_mutex); 1199ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 1209ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe if (!disk_util_exit) { 1219ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe flist_for_each(entry, &disk_list) { 1229ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe du = flist_entry(entry, struct disk_util, list); 1239ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe update_io_tick_disk(du); 1249ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe } 1259ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe } else 1269ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe ret = 1; 1279ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 1289ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_up(disk_util_mutex); 1299ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe return ret; 1309f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 1319f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 132e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboestatic struct disk_util *disk_util_exists(int major, int minor) 1339f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 13401743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe struct flist_head *entry; 1359f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct disk_util *du; 1369f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 1379ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_down(disk_util_mutex); 1389ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 13901743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe flist_for_each(entry, &disk_list) { 14001743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe du = flist_entry(entry, struct disk_util, list); 1419f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 1429ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe if (major == du->major && minor == du->minor) { 1439ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_up(disk_util_mutex); 144e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe return du; 1459ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe } 1469f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 1479f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 1489ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_up(disk_util_mutex); 149e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe return NULL; 1509f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 1519f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 1526742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoostatic int get_device_numbers(char *file_name, int *maj, int *min) 1536742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo{ 1546742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo struct stat st; 1556742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo int majdev, mindev; 1566742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo char tempname[PATH_MAX], *p; 1576742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 1586742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (!lstat(file_name, &st)) { 1596742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (S_ISBLK(st.st_mode)) { 1606742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo majdev = major(st.st_rdev); 1616742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo mindev = minor(st.st_rdev); 1626742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } else if (S_ISCHR(st.st_mode)) { 1636742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo majdev = major(st.st_rdev); 1646742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo mindev = minor(st.st_rdev); 1656742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (fio_lookup_raw(st.st_rdev, &majdev, &mindev)) 1666742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return -1; 1676742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } else if (S_ISFIFO(st.st_mode)) 1686742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return -1; 1696742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo else { 1706742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo majdev = major(st.st_dev); 1716742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo mindev = minor(st.st_dev); 1726742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } 1736742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } else { 1746742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo /* 1756742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo * must be a file, open "." in that path 1766742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo */ 1776742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo strncpy(tempname, file_name, PATH_MAX - 1); 1786742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo p = dirname(tempname); 1796742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (stat(p, &st)) { 1806742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo perror("disk util stat"); 1816742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return -1; 1826742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } 1836742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 1846742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo majdev = major(st.st_dev); 1856742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo mindev = minor(st.st_dev); 1866742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } 1876742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 1886742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo *min = mindev; 1896742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo *maj = majdev; 1906742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 1916742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return 0; 1926742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo} 1936742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 1946742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoostatic int read_block_dev_entry(char *path, int *maj, int *min) 1956742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo{ 1966742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo char line[256], *p; 1976742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo FILE *f; 1986742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 1996742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo f = fopen(path, "r"); 2006742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (!f) { 2016742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo perror("open path"); 2026742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return 1; 2036742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } 2046742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2056742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo p = fgets(line, sizeof(line), f); 2066742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo fclose(f); 2076742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2086742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (!p) 2096742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return 1; 2106742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2116742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (sscanf(p, "%u:%u", maj, min) != 2) 2126742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return 1; 2136742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2146742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return 0; 2156742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo} 2166742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2176742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoostatic void find_add_disk_slaves(struct thread_data *td, char *path, 2182db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboe struct disk_util *masterdu) 2196742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo{ 2206742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo DIR *dirhandle = NULL; 2216742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo struct dirent *dirent = NULL; 2226742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo char slavesdir[PATH_MAX], temppath[PATH_MAX], slavepath[PATH_MAX]; 2236742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo struct disk_util *slavedu = NULL; 2246742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo int majdev, mindev; 2256742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo ssize_t linklen; 2266742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2272db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboe sprintf(slavesdir, "%s/%s", path, "slaves"); 2286742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo dirhandle = opendir(slavesdir); 2296742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (!dirhandle) 2306742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return; 2316742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2326742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo while ((dirent = readdir(dirhandle)) != NULL) { 2332db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboe if (!strcmp(dirent->d_name, ".") || 2342db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboe !strcmp(dirent->d_name, "..")) 2356742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo continue; 2366742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 237b9fd788f0e8adacc33316107594e9eb0463743d7Bruce Cran sprintf(temppath, "%s%s%s", slavesdir, FIO_OS_PATH_SEPARATOR, dirent->d_name); 2386742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo /* Can we always assume that the slaves device entries 2396742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo * are links to the real directories for the slave 2406742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo * devices? 2416742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo */ 242976406b8a0d823f053400178b7b86f32a973762dJens Axboe linklen = readlink(temppath, slavepath, PATH_MAX - 1); 2432db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboe if (linklen < 0) { 2446742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo perror("readlink() for slave device."); 245f0cc675fd0a5902f3637a91024082d2d24a665a7Jens Axboe closedir(dirhandle); 2466742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return; 2476742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } 2482db4ecca2d502c6d26386b5eb918a7957d98afb7Jens Axboe slavepath[linklen] = '\0'; 2496742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2506742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo sprintf(temppath, "%s/%s/dev", slavesdir, slavepath); 2516742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (read_block_dev_entry(temppath, &majdev, &mindev)) { 2526742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo perror("Error getting slave device numbers."); 253f0cc675fd0a5902f3637a91024082d2d24a665a7Jens Axboe closedir(dirhandle); 2546742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return; 2556742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } 2566742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 257b06de82e3b075874733dd233571499c1c1ca453cAlan D. Brunelle /* 258b06de82e3b075874733dd233571499c1c1ca453cAlan D. Brunelle * See if this maj,min already exists 259b06de82e3b075874733dd233571499c1c1ca453cAlan D. Brunelle */ 260b06de82e3b075874733dd233571499c1c1ca453cAlan D. Brunelle slavedu = disk_util_exists(majdev, mindev); 261b06de82e3b075874733dd233571499c1c1ca453cAlan D. Brunelle if (slavedu) 262b06de82e3b075874733dd233571499c1c1ca453cAlan D. Brunelle continue; 263b06de82e3b075874733dd233571499c1c1ca453cAlan D. Brunelle 264b9fd788f0e8adacc33316107594e9eb0463743d7Bruce Cran sprintf(temppath, "%s%s%s", slavesdir, FIO_OS_PATH_SEPARATOR, slavepath); 2656742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo __init_per_file_disk_util(td, majdev, mindev, temppath); 2666742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo slavedu = disk_util_exists(majdev, mindev); 2676742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2686742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo /* Should probably use an assert here. slavedu should 2696742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo * always be present at this point. */ 270b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe if (slavedu) { 271b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe slavedu->users++; 2726742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo flist_add_tail(&slavedu->slavelist, &masterdu->slaves); 273b8d541d5705ef74307277d541ca9153ab8844096Jens Axboe } 2746742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo } 2756742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 2766742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo closedir(dirhandle); 2776742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo} 2786742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 279b8fefc2b27591449b75e946da781342f616fae14Jens Axboestatic struct disk_util *disk_util_add(struct thread_data *td, int majdev, 280c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe int mindev, char *path) 2819f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 2829f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct disk_util *du, *__du; 28301743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe struct flist_head *entry; 2844b919f7740f4875d73c0619a08d269d5c679e19fKen Raeburn int l; 2859f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 286cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe dprint(FD_DISKUTIL, "add maj/min %d/%d: %s\n", majdev, mindev, path); 287cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe 288c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe du = smalloc(sizeof(*du)); 289fba5c5ff89163062922c3e560e871c087f2177c3Jens Axboe if (!du) { 290fba5c5ff89163062922c3e560e871c087f2177c3Jens Axboe log_err("fio: smalloc() pool exhausted\n"); 291fba5c5ff89163062922c3e560e871c087f2177c3Jens Axboe return NULL; 292fba5c5ff89163062922c3e560e871c087f2177c3Jens Axboe } 293fba5c5ff89163062922c3e560e871c087f2177c3Jens Axboe 2949f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe memset(du, 0, sizeof(*du)); 29501743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe INIT_FLIST_HEAD(&du->list); 2964b919f7740f4875d73c0619a08d269d5c679e19fKen Raeburn l = snprintf(du->path, sizeof(du->path), "%s/stat", path); 2974b919f7740f4875d73c0619a08d269d5c679e19fKen Raeburn if (l < 0 || l >= sizeof(du->path)) { 2984b919f7740f4875d73c0619a08d269d5c679e19fKen Raeburn log_err("constructed path \"%.100s[...]/stat\" larger than buffer (%zu bytes)\n", 2994b919f7740f4875d73c0619a08d269d5c679e19fKen Raeburn path, sizeof(du->path) - 1); 3004b919f7740f4875d73c0619a08d269d5c679e19fKen Raeburn sfree(du); 3014b919f7740f4875d73c0619a08d269d5c679e19fKen Raeburn return NULL; 3024b919f7740f4875d73c0619a08d269d5c679e19fKen Raeburn } 303a2ba41edb1d278237a5990c4860291b35463f231Jens Axboe strncpy((char *) du->dus.name, basename(path), FIO_DU_NAME_SZ - 1); 304e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe du->sysfs_root = path; 3059f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe du->major = majdev; 3069f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe du->minor = mindev; 3076742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo INIT_FLIST_HEAD(&du->slavelist); 3086742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo INIT_FLIST_HEAD(&du->slaves); 309521da527743088a9bd2ab882f8b64799d49d5848Jens Axboe du->lock = fio_mutex_init(FIO_MUTEX_UNLOCKED); 310c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe du->users = 0; 3119f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3129ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_down(disk_util_mutex); 3139ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 31401743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe flist_for_each(entry, &disk_list) { 31501743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe __du = flist_entry(entry, struct disk_util, list); 3169f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 317d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dprint(FD_DISKUTIL, "found %s in list\n", __du->dus.name); 318cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe 319d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe if (!strcmp((char *) du->dus.name, (char *) __du->dus.name)) { 320c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe disk_util_free(du); 3219ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_up(disk_util_mutex); 322c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return __du; 3239f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 3249f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 3259f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 326d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe dprint(FD_DISKUTIL, "add %s to list\n", du->dus.name); 327cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe 3289f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe fio_gettime(&du->time, NULL); 3299f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe get_io_ticks(du, &du->last_dus); 3309f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 33101743ee1718e7ec4b16ae3e53c8f64900c6052ccJens Axboe flist_add_tail(&du->list, &disk_list); 3329ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_up(disk_util_mutex); 3339ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 3346742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo find_add_disk_slaves(td, path, du); 335c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return du; 3369f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 3379f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3389f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboestatic int check_dev_match(int majdev, int mindev, char *path) 3399f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 3409f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe int major, minor; 3419f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3426742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (read_block_dev_entry(path, &major, &minor)) 3439f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe return 1; 3449f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 345c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe if (majdev == major && mindev == minor) 3469f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe return 0; 3479f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3489f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe return 1; 3499f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 3509f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 351ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboestatic int find_block_dir(int majdev, int mindev, char *path, int link_ok) 3529f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 3539f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct dirent *dir; 3549f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct stat st; 3559f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe int found = 0; 3569f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe DIR *D; 3579f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3589f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe D = opendir(path); 3599f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (!D) 3609f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe return 0; 3619f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3629f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe while ((dir = readdir(D)) != NULL) { 3639f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe char full_path[256]; 3649f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3659f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, "..")) 3669f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe continue; 3679f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 368b9fd788f0e8adacc33316107594e9eb0463743d7Bruce Cran sprintf(full_path, "%s%s%s", path, FIO_OS_PATH_SEPARATOR, dir->d_name); 3699f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3709f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (!strcmp(dir->d_name, "dev")) { 3719f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (!check_dev_match(majdev, mindev, full_path)) { 3729f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe found = 1; 3739f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe break; 3749f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 3759f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 3769f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 377ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe if (link_ok) { 378ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe if (stat(full_path, &st) == -1) { 379ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe perror("stat"); 380ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe break; 381ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe } 382ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe } else { 383ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe if (lstat(full_path, &st) == -1) { 384ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe perror("stat"); 385ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe break; 386ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe } 3879f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 3889f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3899f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (!S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) 3909f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe continue; 3919f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 392ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe found = find_block_dir(majdev, mindev, full_path, 0); 3939f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (found) { 3949f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe strcpy(path, full_path); 3959f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe break; 3969f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 3979f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 3989f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 3999f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe closedir(D); 4009f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe return found; 4019f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 4029f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 403c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboestatic struct disk_util *__init_per_file_disk_util(struct thread_data *td, 404c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe int majdev, int mindev, 405c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe char *path) 4069f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 4079f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct stat st; 4086742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo char tmp[PATH_MAX]; 4099f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe char *p; 4109f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 4116742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo /* 4126742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo * If there's a ../queue/ directory there, we are inside a partition. 4136742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo * Check if that is the case and jump back. For loop/md/dm etc we 4146742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo * are already in the right spot. 4156742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo */ 4166742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo sprintf(tmp, "%s/../queue", path); 4176742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (!stat(tmp, &st)) { 4186742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo p = dirname(path); 4196742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo sprintf(tmp, "%s/queue", p); 4206742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (stat(tmp, &st)) { 4216742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo log_err("unknown sysfs layout\n"); 422c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return NULL; 4239f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 4246742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo strncpy(tmp, p, PATH_MAX - 1); 4256742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo sprintf(path, "%s", tmp); 4269f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe } 4279f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 4286742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo if (td->o.ioscheduler && !td->sysfs_root) 4296742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo td->sysfs_root = strdup(path); 4306742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 431c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return disk_util_add(td, majdev, mindev, path); 4326742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo} 4336742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 434c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboestatic struct disk_util *init_per_file_disk_util(struct thread_data *td, 435c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe char *filename) 4366742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo{ 4376742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 4386742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo char foo[PATH_MAX]; 4396742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo struct disk_util *du; 4406742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo int mindev, majdev; 4416742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 442c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe if (get_device_numbers(filename, &majdev, &mindev)) 443c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return NULL; 4446742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo 4456742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo dprint(FD_DISKUTIL, "%s belongs to maj/min %d/%d\n", filename, majdev, 4466742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo mindev); 447cd991b9e36b18903f1564a4bfafdc83a9f165219Jens Axboe 448e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe du = disk_util_exists(majdev, mindev); 449e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe if (du) { 450e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe if (td->o.ioscheduler && !td->sysfs_root) 451e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe td->sysfs_root = strdup(du->sysfs_root); 452e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe 453c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return du; 454e11c410cbd60400c10d92d0115880c6e5728aa4eJens Axboe } 4559f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 4569f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe /* 4579f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe * for an fs without a device, we will repeatedly stat through 4589f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe * sysfs which can take oodles of time for thousands of files. so 4599f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe * cache the last lookup and compare with that before going through 4609f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe * everything again. 4619f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe */ 4629f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (mindev == last_mindev && majdev == last_majdev) 463c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return last_du; 4649f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 4659f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe last_mindev = mindev; 4669f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe last_majdev = majdev; 4675ec10eaad3b09875b91e19a20bbdfa06f2117562Jens Axboe 4689f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe sprintf(foo, "/sys/block"); 469ac0be2acff3864979e5e260d332d25ca90e22417Jens Axboe if (!find_block_dir(majdev, mindev, foo, 1)) 470c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return NULL; 4719f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 472c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe return __init_per_file_disk_util(td, majdev, mindev, foo); 4736742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo} 4749f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 475c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboestatic struct disk_util *__init_disk_util(struct thread_data *td, 476c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe struct fio_file *f) 4776742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo{ 4786742301361b7eeded19656ac18a09fde33122b74Shehjar Tikoo return init_per_file_disk_util(td, f->file_name); 4799f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 4809f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 4819f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboevoid init_disk_util(struct thread_data *td) 4829f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 4839f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct fio_file *f; 4849f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe unsigned int i; 4859f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 4869f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe if (!td->o.do_disk_util || 4879f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe (td->io_ops->flags & (FIO_DISKLESSIO | FIO_NODISKUTIL))) 4889f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe return; 4899f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 4909f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe for_each_file(td, f, i) 491c97bd0fa0f68d924f4e6f3c480f380c4ca20b872Jens Axboe f->du = __init_disk_util(td, f); 4929f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 4939f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 494f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboestatic void show_agg_stats(struct disk_util_agg *agg, int terse) 495d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 496d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe if (!agg->slavecount) 497d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe return; 498d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 499f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe if (!terse) { 500f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe log_info(", aggrios=%u/%u, aggrmerge=%u/%u, aggrticks=%u/%u," 501f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe " aggrin_queue=%u, aggrutil=%3.2f%%", 502f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->ios[0] / agg->slavecount, 503f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->ios[1] / agg->slavecount, 504f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->merges[0] / agg->slavecount, 505f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->merges[1] / agg->slavecount, 506f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->ticks[0] / agg->slavecount, 507f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->ticks[1] / agg->slavecount, 508f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->time_in_queue / agg->slavecount, 509f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->max_util.u.f); 510f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe } else { 51197b007ec1428ae434790d64cf528a9b101d1265dJens Axboe log_info(";slaves;%u;%u;%u;%u;%u;%u;%u;%3.2f%%", 512f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->ios[0] / agg->slavecount, 513f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->ios[1] / agg->slavecount, 514f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->merges[0] / agg->slavecount, 515f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->merges[1] / agg->slavecount, 516f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->ticks[0] / agg->slavecount, 517f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->ticks[1] / agg->slavecount, 518f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->time_in_queue / agg->slavecount, 519f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe agg->max_util.u.f); 520f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe } 521d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 522d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 523043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoostatic void aggregate_slaves_stats(struct disk_util *masterdu) 524043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo{ 525d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe struct disk_util_agg *agg = &masterdu->agg; 526043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo struct disk_util_stat *dus; 527043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo struct flist_head *entry; 528043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo struct disk_util *slavedu; 529d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe double util; 530043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo 531043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo flist_for_each(entry, &masterdu->slaves) { 532043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo slavedu = flist_entry(entry, struct disk_util, slavelist); 533043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo dus = &slavedu->dus; 534a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->ios[0] += dus->s.ios[0]; 535a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->ios[1] += dus->s.ios[1]; 536a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->merges[0] += dus->s.merges[0]; 537a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->merges[1] += dus->s.merges[1]; 538a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->sectors[0] += dus->s.sectors[0]; 539a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->sectors[1] += dus->s.sectors[1]; 540a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->ticks[0] += dus->s.ticks[0]; 541a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->ticks[1] += dus->s.ticks[1]; 542a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe agg->time_in_queue += dus->s.time_in_queue; 543d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe agg->slavecount++; 544d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 545a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe util = (double) (100 * dus->s.io_ticks / (double) slavedu->dus.s.msec); 546043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo /* System utilization is the utilization of the 547043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo * component with the highest utilization. 548043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo */ 549d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe if (util > agg->max_util.u.f) 550d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe agg->max_util.u.f = util; 551043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo 552043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo } 553043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo 554d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe if (agg->max_util.u.f > 100.0) 555d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe agg->max_util.u.f = 100.0; 556d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 557d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 55827357187b0899380bae5c6748f2b2d034502e162Jens Axboevoid disk_util_prune_entries(void) 559d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 5609ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_down(disk_util_mutex); 5619ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 562d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe while (!flist_empty(&disk_list)) { 56327357187b0899380bae5c6748f2b2d034502e162Jens Axboe struct disk_util *du; 56427357187b0899380bae5c6748f2b2d034502e162Jens Axboe 565d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe du = flist_entry(disk_list.next, struct disk_util, list); 566d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe flist_del(&du->list); 567d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe disk_util_free(du); 568d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe } 569043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo 570d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe last_majdev = last_mindev = -1; 5719ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_up(disk_util_mutex); 5729ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_remove(disk_util_mutex); 573d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe} 574d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 575f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboevoid print_disk_util(struct disk_util_stat *dus, struct disk_util_agg *agg, 576f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe int terse) 577d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe{ 5786914f59e5e3560325dc8892c9f77689df7b9aa8bJens Axboe double util = 0; 579d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 580a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe if (dus->s.msec) 581a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe util = (double) 100 * dus->s.io_ticks / (double) dus->s.msec; 582d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe if (util > 100.0) 583d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe util = 100.0; 584d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 585f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe if (!terse) { 586f1d64553c9dc0e99c038cf3a5f0cb2a50026e7d3Jens Axboe if (agg->slavecount) 587f1d64553c9dc0e99c038cf3a5f0cb2a50026e7d3Jens Axboe log_info(" "); 588f1d64553c9dc0e99c038cf3a5f0cb2a50026e7d3Jens Axboe 589f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe log_info(" %s: ios=%u/%u, merge=%u/%u, ticks=%u/%u, " 590f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe "in_queue=%u, util=%3.2f%%", dus->name, 591a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.ios[0], dus->s.ios[1], 592a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.merges[0], dus->s.merges[1], 593a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.ticks[0], dus->s.ticks[1], 594a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.time_in_queue, util); 595f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe } else { 5963d7cd9b4c2570548bebfae4871c3ca068c5a29feJens Axboe log_info(";%s;%u;%u;%u;%u;%u;%u;%u;%3.2f%%", 597a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->name, dus->s.ios[0], 598a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.ios[1], dus->s.merges[0], 599a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.merges[1], dus->s.ticks[0], 600a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.ticks[1], 601a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe dus->s.time_in_queue, util); 602f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe } 603d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 604d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe /* 605d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe * If the device has slaves, aggregate the stats for 606d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe * those slave devices also. 607d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe */ 608f1d64553c9dc0e99c038cf3a5f0cb2a50026e7d3Jens Axboe show_agg_stats(agg, terse); 609d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe 610f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe if (!terse) 611f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe log_info("\n"); 612043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo} 613043b74b9ddba4cc7ecb876ca41b7daa7d1ec5da3Shehjar Tikoo 614952b05e00103bf45576e1860cde0626bd42ed52aCastor Fuvoid json_array_add_disk_util(struct disk_util_stat *dus, 615952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu struct disk_util_agg *agg, struct json_array *array) 616cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li{ 617cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li struct json_object *obj; 618952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu double util = 0; 619cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li 620a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe if (dus->s.msec) 621a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe util = (double) 100 * dus->s.io_ticks / (double) dus->s.msec; 622cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li if (util > 100.0) 623cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li util = 100.0; 624cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li 625952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu obj = json_create_object(); 626952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu json_array_add_value_object(array, obj); 627cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li 628cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_string(obj, "name", dus->name); 629a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe json_object_add_value_int(obj, "read_ios", dus->s.ios[0]); 630a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe json_object_add_value_int(obj, "write_ios", dus->s.ios[1]); 631a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe json_object_add_value_int(obj, "read_merges", dus->s.merges[0]); 632a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe json_object_add_value_int(obj, "write_merges", dus->s.merges[1]); 633a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe json_object_add_value_int(obj, "read_ticks", dus->s.ticks[0]); 634a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe json_object_add_value_int(obj, "write_ticks", dus->s.ticks[1]); 635a3b4cf7dcae447729f0f4a4ea122f605b909ed70Jens Axboe json_object_add_value_int(obj, "in_queue", dus->s.time_in_queue); 636cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_float(obj, "util", util); 637cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li 638cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li /* 639cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li * If the device has slaves, aggregate the stats for 640cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li * those slave devices also. 641cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li */ 642cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li if (!agg->slavecount) 643cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li return; 644cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_int(obj, "aggr_read_ios", 645cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li agg->ios[0] / agg->slavecount); 646cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_int(obj, "aggr_write_ios", 647cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li agg->ios[1] / agg->slavecount); 648cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_int(obj, "aggr_read_merges", 649cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li agg->merges[0] / agg->slavecount); 650cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_int(obj, "aggr_write_merge", 651cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li agg->merges[1] / agg->slavecount); 652cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_int(obj, "aggr_read_ticks", 653cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li agg->ticks[0] / agg->slavecount); 654cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_int(obj, "aggr_write_ticks", 655cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li agg->ticks[1] / agg->slavecount); 656cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_int(obj, "aggr_in_queue", 657cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li agg->time_in_queue / agg->slavecount); 658cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li json_object_add_value_float(obj, "aggr_util", agg->max_util.u.f); 659cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li} 660cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li 66110aa136bddbaa7c845ab4eacb4a9a4a88d6657a3Jens Axboestatic void json_object_add_disk_utils(struct json_object *obj, 66210aa136bddbaa7c845ab4eacb4a9a4a88d6657a3Jens Axboe struct flist_head *head) 663952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu{ 664952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu struct json_array *array = json_create_array(); 665952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu struct flist_head *entry; 666952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu struct disk_util *du; 667952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu 668952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu json_object_add_value_array(obj, "disk_util", array); 669952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu 670952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu flist_for_each(entry, head) { 671952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu du = flist_entry(entry, struct disk_util, list); 672952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu 673952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu aggregate_slaves_stats(du); 674952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu json_array_add_disk_util(&du->dus, &du->agg, array); 675952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu } 676952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu} 677952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu 678cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Livoid show_disk_util(int terse, struct json_object *parent) 6799f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe{ 680d09a64a01a6c807596e9286c93f6c6f30fd2ea26Jens Axboe struct flist_head *entry; 6819f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe struct disk_util *du; 6829f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 6839ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_down(disk_util_mutex); 6849ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 6859ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe if (flist_empty(&disk_list)) { 6869ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_up(disk_util_mutex); 6870a839f308177e95c4c45c41ee1d4fa2b8f231f24Jens Axboe return; 6889ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe } 6890a839f308177e95c4c45c41ee1d4fa2b8f231f24Jens Axboe 6909edf7b3ed581a61433ad620d457b4d0349115e52Jens Axboe if (output_format == FIO_OUTPUT_JSON) 6919edf7b3ed581a61433ad620d457b4d0349115e52Jens Axboe assert(parent); 6929edf7b3ed581a61433ad620d457b4d0349115e52Jens Axboe 6939edf7b3ed581a61433ad620d457b4d0349115e52Jens Axboe if (!terse && output_format != FIO_OUTPUT_JSON) 694f2f788dd732d97c2c3a5f5dd93223a7bfafcc410Jens Axboe log_info("\nDisk stats (read/write):\n"); 6959f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 6969edf7b3ed581a61433ad620d457b4d0349115e52Jens Axboe if (output_format == FIO_OUTPUT_JSON) 697952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu json_object_add_disk_utils(parent, &disk_list); 6989edf7b3ed581a61433ad620d457b4d0349115e52Jens Axboe else 699952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu flist_for_each(entry, &disk_list) { 700952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu du = flist_entry(entry, struct disk_util, list); 7019f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe 702952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu aggregate_slaves_stats(du); 703cc372b17f2827e89da79241f1bbaca1e7c650611Shaohua Li print_disk_util(&du->dus, &du->agg, terse); 704952b05e00103bf45576e1860cde0626bd42ed52aCastor Fu } 7059ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 7069ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe fio_mutex_up(disk_util_mutex); 7079ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe} 7089ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe 7099ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboevoid setup_disk_util(void) 7109ec7779f89d4dde9fe1e23d68abaefda54b35de7Jens Axboe{ 711521da527743088a9bd2ab882f8b64799d49d5848Jens Axboe disk_util_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED); 7129f8f2064bcb196c10c9d3a2b64b951d796af22b5Jens Axboe} 713