1#!/usr/bin/env zsh -e -u 2 3 4# This is a script that creates a disk image with slow IO (a fake, artificial disk that lives on ram resources), 5# and then runs the vm stress test with one single configuration on objects that are backed by files in that disk. 6# In the end it's going to eject the newly created volume. 7 8eject_volumes() { 9 diskutil list | awk '/disk image/{print $1}' | tail -r | xargs -L1 diskutil eject 10} 11 12trap eject_volumes EXIT 13 14# Default values for the flags 15SIZE_MB=2048 16HELP=false 17RAMDISK_MP="/Volumes/apfs-dmg" 18SLOW_DMG="slow-dmg.dmg" 19TYPE="ssd" 20IOQUEUE_DEPTH=1 21ACCESS_TIME=$((1 << 18)) # in microseconds 22READ_THROUGHPUT=1000 # in MB/s 23WRITE_THROUGHPUT=1000 # in MB/s 24MAX_READ_CNT=$((1 << 10)) # max bytes per read (1Kb) 25MAX_WRITE_CNT=$((1 << 10)) # max bytes per write (1Kb) 26SEG_READ_CNT=$((1 << 10)) 27SEG_WRITE_CNT=$((1 << 10)) 28 29 30show_help() { 31 echo "Usage: sudo $0 [options]" 32 echo 33 echo "Running this script will create a ramdisk with a disk image configured to run slower than usual, " 34 echo "and then run the vm_stress test on a file that comes from this disk image." 35 echo 36 echo "Options:" 37 echo " -h, --help Show this help message" 38 echo " -s, --speed Set paging speed (slower, slowerer, slowest)" 39 echo 40} 41 42while [[ $# -gt 0 ]]; do 43 case "$1" in 44 -h|--help) 45 HELP=true 46 shift 47 ;; 48 49 -s|--speed|-S) 50 if [[ -z "$2" ]]; then 51 echo "Error: --speed requires a value (slower, slowerer, slowest)." 52 exit 1 53 fi 54 case "$2" in 55 slower) 56 ((ACCESS_TIME = ACCESS_TIME * 2)) 57 shift 2 58 ;; 59 slowerer) 60 ((ACCESS_TIME = ACCESS_TIME * 3)) 61 shift 2 62 ;; 63 slowest) 64 ((ACCESS_TIME = ACCESS_TIME * 4)) 65 shift 2 66 ;; 67 *) 68 echo "Error: Invalid speed option '$2'. Valid options are: slow, slower, slowest." 69 exit 1 70 ;; 71 esac 72 ;; 73 74 # Invalid option 75 *) 76 echo "Error: Invalid option '$1'. Use --help for usage." 77 exit 1 78 ;; 79 esac 80done 81 82# Show help if requested 83if $HELP; then 84 show_help 85 exit 0 86fi 87 88echo "Selected speed: access = $ACCESS_TIME" 89 90 91diskutil list | awk '/disk image/{print $1}' | tail -r | xargs -L1 diskutil eject # start fresh with no extra volumes 92sysctl debug.didevice_queue_depth=1 93ramdisk_device=$(diskutil image attach "ram://${SIZE_MB}m" | awk '{print $1}') # attach ("create, make visible and mount") disk image ("virtual disk") on RAM (just a disk with no file system) 94diskutil eraseDisk apfs apfs-dmg "$ramdisk_device" # put a file system on it 95 96diskutil image create blank "$RAMDISK_MP/$SLOW_DMG" -size "$((SIZE_MB / 2))m" -volumeName apfs-slow # create another (seemingly regular) disk image ("virtual disk") in the new ramdisk 97slow_di_device=$(diskutil image attach "$RAMDISK_MP/$SLOW_DMG" | awk 'END{print $1}') # attach it ("make it visible and mount") 98 99purge # delete all caches 100 101# configure IO to be slow on the newly created inner volume, and then apply (start): 102dmc configure "$RAMDISK_MP" "$TYPE" "$ACCESS_TIME" "$READ_THROUGHPUT" "$WRITE_THROUGHPUT" "$IOQUEUE_DEPTH" "$MAX_READ_CNT" "$MAX_WRITE_CNT" "$SEG_READ_CNT" "$SEG_WRITE_CNT" 103dmc start "$RAMDISK_MP/" 104 105# Now that the ramdisk exists, find and execute the test: 106SCRIPT_DIR=$(dirname "$(realpath "$0")") 107TEST_EXEC_DIR=$(find "$SCRIPT_DIR/../" -iname "vm_stress" -maxdepth 5 -print -quit) 108"$TEST_EXEC_DIR" config -- topo 6 50 5 5 1 1 -s 109"$TEST_EXEC_DIR" config -- over 6 50 5 5 1 1 -s 110"$TEST_EXEC_DIR" config -- part 6 50 5 5 1 1 -s 111"$TEST_EXEC_DIR" config -- one_to_many 6 50 5 5 1 1 -s 112"$TEST_EXEC_DIR" config -- one_to_many 6 50 5 5 0 0 -s 113dmc stop "$RAMDISK_MP/"