int blktrace_lookup_device(const char *redirect, char *path, unsigned int maj, unsigned int min) { 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 (lstat(full_path, &st) == -1) { perror("lstat"); break; } if (S_ISDIR(st.st_mode)) { found = blktrace_lookup_device(redirect, full_path, maj, min); if (found) { strcpy(path, full_path); break; } } if (!S_ISBLK(st.st_mode)) continue; /* * If replay_redirect is set then always return this device * upon lookup which overrides the device lookup based on * major minor in the actual blktrace */ if (redirect) { strcpy(path, redirect); found = 1; break; } if (maj == major(st.st_rdev) && min == minor(st.st_rdev)) { strcpy(path, full_path); found = 1; break; } } closedir(D); return found; }
static int trace_add_file(struct thread_data *td, __u32 device) { static unsigned int last_maj, last_min, last_fileno; unsigned int maj = FMAJOR(device); unsigned int min = FMINOR(device); struct fio_file *f; char dev[256]; unsigned int i; if (last_maj == maj && last_min == min) return last_fileno; last_maj = maj; last_min = min; /* * check for this file in our list */ for_each_file(td, f, i) if (f->major == maj && f->minor == min) { last_fileno = f->fileno; return last_fileno; } strcpy(dev, "/dev"); if (blktrace_lookup_device(td->o.replay_redirect, dev, maj, min)) { int fileno; if (td->o.replay_redirect) dprint(FD_BLKTRACE, "device lookup: %d/%d\n overridden" " with: %s\n", maj, min, td->o.replay_redirect); else dprint(FD_BLKTRACE, "device lookup: %d/%d\n", maj, min); dprint(FD_BLKTRACE, "add devices %s\n", dev); fileno = add_file_exclusive(td, dev); td->o.open_files++; td->files[fileno]->major = maj; td->files[fileno]->minor = min; trace_add_open_close_event(td, fileno, FIO_LOG_OPEN_FILE); last_fileno = fileno; } return last_fileno; }