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