Fio 1.20-rc2
[fio.git] / diskutil.c
index 399aced467e0c855884b3c1ea4d7c09752d1f97d..b5ba709e1638846994db9a990671a8296de25240 100644 (file)
@@ -20,6 +20,7 @@ static int get_io_ticks(struct disk_util *du, struct disk_util_stat *dus)
        char line[256];
        FILE *f;
        char *p;
+       int ret;
 
        f = fopen(du->path, "r");
        if (!f)
@@ -31,7 +32,13 @@ static int get_io_ticks(struct disk_util *du, struct disk_util_stat *dus)
                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) {
+       ret = scanf(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);
+       if (ret != 11) {
                fclose(f);
                return 1;
        }
@@ -79,7 +86,7 @@ void update_io_ticks(void)
        }
 }
 
-static int disk_util_exists(int major, int minor)
+static struct disk_util *disk_util_exists(int major, int minor)
 {
        struct list_head *entry;
        struct disk_util *du;
@@ -88,10 +95,10 @@ static int disk_util_exists(int major, int minor)
                du = list_entry(entry, struct disk_util, list);
 
                if (major == du->major && minor == du->minor)
-                       return 1;
+                       return du;
        }
 
-       return 0;
+       return NULL;
 }
 
 static void disk_util_add(int majdev, int mindev, char *path)
@@ -104,6 +111,7 @@ static void disk_util_add(int majdev, int mindev, char *path)
        INIT_LIST_HEAD(&du->list);
        sprintf(du->path, "%s/stat", path);
        du->name = strdup(basename(path));
+       du->sysfs_root = path;
        du->major = majdev;
        du->minor = mindev;
 
@@ -204,18 +212,22 @@ static void __init_disk_util(struct thread_data *td, struct fio_file *f)
 {
        struct stat st;
        char foo[PATH_MAX], tmp[PATH_MAX];
+       struct disk_util *du;
        int mindev, majdev;
        char *p;
 
-       if (!stat(f->file_name, &st)) {
+       if (!lstat(f->file_name, &st)) {
                if (S_ISBLK(st.st_mode)) {
                        majdev = major(st.st_rdev);
                        mindev = minor(st.st_rdev);
                } else if (S_ISCHR(st.st_mode)) {
                        majdev = major(st.st_rdev);
                        mindev = minor(st.st_rdev);
-                       fio_lookup_raw(st.st_rdev, &majdev, &mindev);
-               } else {
+                       if (fio_lookup_raw(st.st_rdev, &majdev, &mindev))
+                               return;
+               } else if (S_ISFIFO(st.st_mode))
+                       return;
+               else {
                        majdev = major(st.st_dev);
                        mindev = minor(st.st_dev);
                }
@@ -234,8 +246,13 @@ static void __init_disk_util(struct thread_data *td, struct fio_file *f)
                mindev = minor(st.st_dev);
        }
 
-       if (disk_util_exists(majdev, mindev))
+       du = disk_util_exists(majdev, mindev);
+       if (du) {
+               if (td->o.ioscheduler && !td->sysfs_root)
+                       td->sysfs_root = strdup(du->sysfs_root);
+
                return;
+       }
 
        /*
         * for an fs without a device, we will repeatedly stat through
@@ -248,7 +265,7 @@ static void __init_disk_util(struct thread_data *td, struct fio_file *f)
 
        last_mindev = mindev;
        last_majdev = majdev;
-               
+
        sprintf(foo, "/sys/block");
        if (!find_block_dir(majdev, mindev, foo))
                return;
@@ -303,6 +320,9 @@ void show_disk_util(void)
        struct disk_util *du;
        double util;
 
+       if (list_empty(&disk_list))
+               return;
+
        log_info("\nDisk stats (read/write):\n");
 
        list_for_each(entry, &disk_list) {
@@ -313,7 +333,12 @@ void show_disk_util(void)
                if (util > 100.0)
                        util = 100.0;
 
-               log_info("  %s: ios=%u/%u, merge=%u/%u, ticks=%u/%u, in_queue=%u, util=%3.2f%%\n", du->name, dus->ios[0], dus->ios[1], dus->merges[0], dus->merges[1], dus->ticks[0], dus->ticks[1], dus->time_in_queue, util);
+               log_info("  %s: ios=%u/%u, merge=%u/%u, ticks=%u/%u, "
+                        "in_queue=%u, util=%3.2f%%\n", du->name,
+                                               dus->ios[0], dus->ios[1],
+                                               dus->merges[0], dus->merges[1],
+                                               dus->ticks[0], dus->ticks[1],
+                                               dus->time_in_queue, util);
        }
 
        /*