Sometimes in the development process, we need to simulate slow disk conditions to verify if our code can still function on low-performance machines. Typically, we would use cgroup
or Docker for this purpose, but it can be cumbersome on a MacBook. However, there’s a built-in tool on macOS that can help us achieve this: dmc
.
This piece was originally published in the Medium MPP plan. If you’re a Medium user, feel free to follow me on Medium. Thanks!
Using dmc
macOS comes with dmc
, which we can explore using dmc -h
.
1
2
3
4
5
6
7
8
9
10
11
|
➜ /tmp dmc -h
usage: dmc <commands...>
# commands:
start <mount> (profile_name|profile_index [-boot])
stop <mount>
status <mount> [-json]
show profile_name|profile_index
list
select <mount> (profile_name|profile_index)
configure <mount> <type> <access_time> <read_throughput> <write_throughput> [<ioqueue_depth> <maxreadcnt> <maxwritecnt> <segreadcnt> <segwritecnt>]
help | -h
|
It offers various disk profiles to choose from:
1
2
3
4
5
6
7
8
9
|
➜ /tmp dmc list
0: Faulty 5400 HDD
1: 5400 HDD
2: 7200 HDD
3: Slow SSD
4: SATA II SSD
5: SATA III SSD
6: PCIe 2 SSD
7: PCIe 3 SSD
|
Each profile corresponds to different speed modes, such as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
➜ /tmp dmc show 0
Profile: Faulty 5400 HDD
Type: HDD
Access time: 52222 us
Read throughput: 50 MB/s
Write throughput: 50 MB/s
I/O Queue Depth: 16
Max Read Bytes: 16777216
Max Write Bytes: 16777216
Max Read Segments: 128
Max Write Segments: 128
➜ /tmp dmc show 7
Profile: PCIe 3 SSD
Type: SSD
Access time: 3 us
Read throughput: 3072 MB/s
Write throughput: 2560 MB/s
I/O Queue Depth: 256
Max Read Bytes: 67108864
Max Write Bytes: 67108864
Max Read Segments: 256
Max Write Segments: 256
|
Using it is straightforward. Suppose our disk is mounted on /tmp/data
, and we want to set it to level 0. We simply execute:
1
|
sudo dmc start /tmp/data 0
|
Then, to verify the status:
1
2
3
4
5
6
7
8
9
10
11
12
|
➜ /tmp dmc status /tmp/data
Disk Mount Conditioner: ON
Profile: Custom
Type: HDD
Access time: 52222 us
Read throughput: 50 MB/s
Write throughput: 50 MB/s
I/O Queue Depth: 16
Max Read Bytes: 1048576
Max Write Bytes: 1048576
Max Read Segments: 128
Max Write Segments: 128
|
Verification
We can validate using the fio
tool:
1
|
➜ /tmp fio --filename=./data/test1 -direct=1 --rw=write --ioengine=posixaio --bs=1m --iodepth=32 --size=1G --numjobs=1 --runtime=60 --time_base=1 --group_reporting --name=test-seq-read --log_avg_msec=1000
|
Writing a 1GB file sequentially yields a speed of only 95.4MB/s, with IOPS at 91:
1
2
|
Run status group 0 (all jobs):
WRITE: bw=91.0MiB/s (95.4MB/s), 91.0MiB/s-91.0MiB/s (95.4MB/s-95.4MB/s), io=5468MiB (5734MB), run=60073-60073msec
|
Now, with dmc
turned off and the same command:
1
2
|
/tmp sudo dmc stop /tmp/data
/tmp fio --filename=./data/test1 -direct=1 --rw=write --ioengine=posixaio --bs=1m --iodepth=32 --size=1G --numjobs=1 --runtime=60 --time_base=1 --group_reporting --name=test-seq-read --log_avg_msec=1000
|
The test results in 3211MB/s and IOPS of 3061, which represents the true speed of the disk:
1
|
WRITE: bw=3062MiB/s (3211MB/s), 3062MiB/s-3062MiB/s (3211MB/s-3211MB/s), io=179GiB (193GB), run=60006-60006msec
|
In conclusion, dmc
is quite handy in testing scenarios. I hadn’t known about this software before; if you find it useful, give it a try.