How to simulate slow DVD drive?
dmg, dvd, iso, macos, performance-testing
Solution
With hdiutil, you could mount a disk image over a specially crafted HTTP server, but you do not control the OS cache and I/O slowness would not be fine-grained. I would suggest two non-network solutions.
Inserting slowness in I/O system calls
You could do slow-down I/O system calls, for example through `DYLD_INSERT_LIBRARIES`. This approach is quite easy and this is what I would try first.
You simply create a library with `read(2)` and `pread(2)` implementations like:
/* slow.c */
#define SLEEP_TIMESPEC {0, 25000000} // 25ms
ssize_t
read(int fildes, void *buf, size_t nbyte) {
struct timespec s = SLEEP_TIMESPEC;
(void) nanosleep(&s, NULL);
return (ssize_t) syscall(SYS_read, fildes, buf, nbyte);
}
ssize_t
pread(int d, void *buf, size_t nbyte, off_t offset) {
struct timespec s = SLEEP_TIMESPEC;
(void) nanosleep(&s, NULL);
return (ssize_t) syscall(SYS_pread, d, buf, nbyte, offset);
}
You might also need to implement `readv(2)`. You simply need to compile this C code as a shared library and set `DYLD_INSERT_LIBRARIES` to load this library before running your program. You will probably also need to define `DYLD_FORCE_FLAT_NAMESPACE`. See `dyld(1)`.
clang -arch i386 -arch x86_64 -shared -Wall slow.c -o slow.dylib
(The library is compiled universally, as the AIR app I had on disk was actually i386, not x86_64).
To test the library, simply do:
env DYLD_INSERT_LIBRARIES=slow.dylib DYLD_FORCE_FLAT_NAMESPACE=1 cat slow.c
You might want to try with values higher than 25ms for `cat`, e.g. 1 second which can be inlined as `{1, 0}`. Likewise, you should start your application from the command line:
env DYLD_INSERT_LIBRARIES=slow.dylib DYLD_FORCE_FLAT_NAMESPACE=1 path/to/YourApp.app/Contents/MacOS/YourApp
This will slow down every read calls (even through higher-level APIs). Some read operations will not be affected (e.g. `mmap(2)`), however, and you might want to slow down I/Os on some files but not on others. This later case can be handled by trapping `open(2)` but requires more work.
25ms per read accesses is enough to make any AIR app noticeably slower. Of course, you should adjust this value to your needs.
Working with a slower file system
Alternatively, you could implement a Fuse plug-in. This is especially easy if you start from LoopbackFS (C or ObjC).
Indeed, you can very easily call `nanosleep(2)` in the `readFileAtPath:userData:buffer:size:offset:error:` method or `loopback_read` function.
Problem
Does anyone know any feasible ways to simulate a slow DVD drive, e.g. over a mounted DMG/ISO image? The goal is to program against a slow drive, thus a simulation requirement. Any ideas would be greatly appreciated! Update: again, the goal would be to simulate a slow I/O process. Tools like Network Conditioner or Charles do not provide a solution unfortunately. trickle is out of date and no more actively developed :(