-static int get_io_ticks(struct disk_util *du, struct disk_util_stat *dus)
-{
- unsigned in_flight;
- char line[256];
- FILE *f;
- char *p;
-
- f = fopen(du->path, "r");
- if (!f)
- return 1;
-
- p = fgets(line, sizeof(line), f);
- if (!p) {
- fclose(f);
- return 1;
- }
-
- if (sscanf(p, "%u %u %llu %u %u %u %llu %u %u %u %u\n", &dus->ios[0], &dus->merges[0], &dus->sectors[0], &dus->ticks[0], &dus->ios[1], &dus->merges[1], &dus->sectors[1], &dus->ticks[1], &in_flight, &dus->io_ticks, &dus->time_in_queue) != 11) {
- fclose(f);
- return 1;
- }
-
- fclose(f);
- return 0;
-}
-
-static void update_io_tick_disk(struct disk_util *du)
-{
- struct disk_util_stat __dus, *dus, *ldus;
- struct timeval t;
-
- if (get_io_ticks(du, &__dus))
- return;
-
- dus = &du->dus;
- ldus = &du->last_dus;
-
- dus->sectors[0] += (__dus.sectors[0] - ldus->sectors[0]);
- dus->sectors[1] += (__dus.sectors[1] - ldus->sectors[1]);
- dus->ios[0] += (__dus.ios[0] - ldus->ios[0]);
- dus->ios[1] += (__dus.ios[1] - ldus->ios[1]);
- dus->merges[0] += (__dus.merges[0] - ldus->merges[0]);
- dus->merges[1] += (__dus.merges[1] - ldus->merges[1]);
- dus->ticks[0] += (__dus.ticks[0] - ldus->ticks[0]);
- dus->ticks[1] += (__dus.ticks[1] - ldus->ticks[1]);
- dus->io_ticks += (__dus.io_ticks - ldus->io_ticks);
- dus->time_in_queue += (__dus.time_in_queue - ldus->time_in_queue);
-
- fio_gettime(&t, NULL);
- du->msec += mtime_since(&du->time, &t);
- memcpy(&du->time, &t, sizeof(t));
- memcpy(ldus, &__dus, sizeof(__dus));
-}
-
-void update_io_ticks(void)
-{
- struct list_head *entry;
- struct disk_util *du;
-
- list_for_each(entry, &disk_list) {
- du = list_entry(entry, struct disk_util, list);
- update_io_tick_disk(du);
- }
-}
-
-static int disk_util_exists(dev_t dev)
-{
- struct list_head *entry;
- struct disk_util *du;
-
- list_for_each(entry, &disk_list) {
- du = list_entry(entry, struct disk_util, list);
-
- if (du->dev == dev)
- return 1;
- }
-
- return 0;
-}
-
-static void disk_util_add(dev_t dev, char *path)
-{
- struct disk_util *du, *__du;
- struct list_head *entry;
-
- du = malloc(sizeof(*du));
- memset(du, 0, sizeof(*du));
- INIT_LIST_HEAD(&du->list);
- sprintf(du->path, "%s/stat", path);
- du->name = strdup(basename(path));
- du->dev = dev;
-
- list_for_each(entry, &disk_list) {
- __du = list_entry(entry, struct disk_util, list);
-
- if (!strcmp(du->name, __du->name)) {
- free(du->name);
- free(du);
- return;
- }
- }
-
- fio_gettime(&du->time, NULL);
- get_io_ticks(du, &du->last_dus);
-
- list_add_tail(&du->list, &disk_list);
-}
-
-static int check_dev_match(dev_t dev, char *path)
-{
- unsigned int major, minor;
- char line[256], *p;
- FILE *f;
-
- f = fopen(path, "r");
- if (!f) {
- perror("open path");
- return 1;
- }
-
- p = fgets(line, sizeof(line), f);
- if (!p) {
- fclose(f);
- return 1;
- }
-
- if (sscanf(p, "%u:%u", &major, &minor) != 2) {
- fclose(f);
- return 1;
- }
-
- if (((major << 8) | minor) == dev) {
- fclose(f);
- return 0;
- }
-
- fclose(f);
- return 1;
-}
-
-static int find_block_dir(dev_t dev, char *path)
-{
- struct dirent *dir;
- struct stat st;
- int found = 0;
- DIR *D;
-
- D = opendir(path);
- if (!D)
- return 0;
-
- while ((dir = readdir(D)) != NULL) {
- char full_path[256];
-
- if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))
- continue;
-
- sprintf(full_path, "%s/%s", path, dir->d_name);
-
- if (!strcmp(dir->d_name, "dev")) {
- if (!check_dev_match(dev, full_path)) {
- found = 1;
- break;
- }
- }
-
- if (lstat(full_path, &st) == -1) {
- perror("stat");
- break;
- }
-
- if (!S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))
- continue;
-
- found = find_block_dir(dev, full_path);
- if (found) {
- strcpy(path, full_path);
- break;
- }
- }
-
- closedir(D);
- return found;
-}
-
-void init_disk_util(struct thread_data *td)