Advertisement
Tritonio

Testing TRIM for SSDs on Linux

Jul 28th, 2019
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.47 KB | None | 0 0
  1. There is a way to test it answered at unix.stackexchange.com by frostschutz (this answer is his merit so thanks him), copied below:
  2.  
  3. "Create a test file: (not random on purpose)
  4.  
  5. # yes | dd iflag=fullblock bs=1M count=1 of=trim.test
  6. Get the address: (exact command may have to differ depending on filefrag version)
  7.  
  8. # filefrag -s -v trim.test
  9. File size of trim.test is 1048576 (256 blocks, blocksize 4096)
  10. ext logical physical expected length flags
  11. 0 0 34048 256 eof
  12. trim.test: 1 extent found
  13. Get the device:
  14.  
  15. # df trim.test
  16. /dev/mapper/something 32896880 11722824 20838512 37% /
  17. With this set up, you have a file trim.test filles with yes-pattern on /dev/mapper/something at address 34048 with length of 256 blocks of 4096 bytes.
  18.  
  19. Reading that from the device directly should produce the yes-pattern:
  20.  
  21. # dd bs=4096 skip=34048 count=256 if=/dev/mapper/something | hexdump -C
  22. 00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.|
  23. *
  24. 00100000
  25. If TRIM is enabled, this pattern should change when you delete the file. Note that caches need to be dropped also, otherwise dd will not re-read the data from disk.
  26.  
  27. # rm trim.test
  28. # sync
  29. # fstrim -v /mount/point/ # when not using 'discard' mount option
  30. # echo 1 > /proc/sys/vm/drop_caches
  31. # dd bs=4096 skip=34048 count=256 if=/dev/mapper/something | hexdump -C
  32. On most SSD that would result in a zero pattern:
  33.  
  34. 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
  35. *
  36. 00100000
  37. If encryption is involved, you will see a random pattern instead:
  38.  
  39. 00000000 1f c9 55 7d 07 15 00 d1 4a 1c 41 1a 43 84 15 c0 |..U}....J.A.C...|
  40. 00000010 24 35 37 fe 05 f7 43 93 1e f4 3c cc d8 83 44 ad |$57...C...<...D.|
  41. 00000020 46 80 c2 26 13 06 dc 20 7e 22 e4 94 21 7c 8b 2c |F..&... ~"..!|.,|
  42. That's because physically trimmed, the crypto layer reads zeroes and decrypts those zeroes to "random" data.
  43.  
  44. If the yes-pattern persists, most likely no trimming has been done."
  45.  
  46. This is my automated script:
  47.  
  48. #!/bin/bash
  49. #
  50. # This script is provided "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement.
  51. #
  52. # License GPL2
  53. #
  54. # by desgua 2014/04/29
  55.  
  56. function CLEAN {
  57. cd "$pasta"
  58. [ -f test-trim-by-desgua ] && rm test-trim-by-desgua && echo "Temp file removed"
  59. echo "Goodbye"
  60. exit 0
  61. }
  62.  
  63. trap 'echo ; echo "Aborted." ; CLEAN; echo ; exit 0' INT HUP
  64.  
  65. if [[ "$(echo $USER)" != "root" ]]; then
  66.  
  67. read -n 1 -p 'Become root? [Y/n]' a
  68. if [[ $a == "Y" || $a == "y" || $a == "" ]]; then
  69. sudo $0 $1
  70. exit 0
  71. else
  72. echo "
  73. This script needs root privilege.
  74. "
  75. exit 1
  76.  
  77. fi
  78.  
  79. fi
  80.  
  81.  
  82. name=$(echo $0 | sed 's/.*\///')
  83. if [ $# -ne 1 ]; then
  84.  
  85. echo "
  86. Usage: $name /folder/to/test/
  87.  
  88. "
  89. exit 1
  90. fi
  91.  
  92. pasta=$1
  93.  
  94. read -n 1 -p 'Use fstrim? [y/N]' a
  95. if [[ $a == "Y" || $a == "y" ]]; then
  96. fs=1
  97. fi
  98.  
  99. method=
  100. while [[ "$method" != "1" && "$method" != "2" ]]; do
  101. read -n 1 -s -p 'Choose a method:
  102. [1] hdparm (will fail in LUKS on LVM)
  103. [2] filefrag (warning: you may have to force quit - close the terminal - in some cases of success trim if you see an output that never ends)
  104. ' method
  105. done
  106.  
  107. function SDATEST {
  108. disk=$(fdisk -l | grep /dev/sda)
  109. if [ "$disk" == "" ]; then
  110. echo "
  111. fdisk did not found /dev/sda
  112. "
  113. exit 1
  114. fi
  115. }
  116.  
  117. function TEST {
  118. echo "Entrying /" ; echo
  119. cd $pasta
  120. echo "Creating the file test-trim-by-desgua at $pasta" ; echo
  121. dd if=/dev/urandom of=test-trim-by-desgua count=10 bs=512k
  122. echo "Syncing and sleeping 2 seconds." ; echo
  123. sync
  124. sleep 2
  125.  
  126. hdparm --fibmap test-trim-by-desgua
  127. lbab=$(hdparm --fibmap test-trim-by-desgua | tail -n1 | awk '{ print $2 }')
  128.  
  129. echo "As you can see, the file was created and its LBA begins at $lbab" ; echo
  130.  
  131. echo "Syncing and sleeping 2 seconds." ; echo
  132. sync
  133. sleep 2
  134.  
  135. echo "Removing file test-trim-by-desgua" ; echo
  136. rm test-trim-by-desgua
  137.  
  138. trap 'echo ; echo ; echo "Aborted." ; echo ; exit 0' INT
  139. echo "Syncing and sleeping 2 seconds." ; echo
  140. sync
  141. sleep 2
  142.  
  143. if [[ "$fs" == "1" ]]; then
  144. echo "fstrim $pasta && sleep 2" ; echo
  145. fstrim $pasta
  146. sleep 2
  147. fi
  148.  
  149. echo "This is readed from sector $lbab: "
  150. hdparm --read-sector $lbab /dev/sda
  151.  
  152. pass=$(hdparm --read-sector $lbab /dev/sda | grep "0000 0000 0000 0000")
  153.  
  154. if [[ $pass == "" ]]; then
  155. echo "
  156. Trim failed...
  157. You should see only 0000 0000 0000 0000 ...
  158. "
  159. else
  160. echo "Success!!!"
  161. fi
  162. exit 0
  163.  
  164. }
  165.  
  166. function LUKSTEST {
  167. # Reference: https://unix.stackexchange.com/questions/85865/trim-with-lvm-and-dm-crypt#
  168. echo 1 > /proc/sys/vm/drop_caches
  169. cd $pasta
  170. echo "Creating a \"yes\" file."
  171. yes | dd iflag=fullblock bs=1M count=1 of=test-trim-by-desgua
  172.  
  173. #position=`filefrag -s -v test-trim-by-desgua | grep "eof" | awk '{ print $3 }'`
  174. position=`filefrag -s -v test-trim-by-desgua | grep "eof" | sed 's| ||g ; s|.*255:|| ; s|\.\..*||'`
  175. [[ "$position" == "" ]] && echo "Could not find the position of the file. Are you on a LUKS on LVM?" && CLEAN;
  176.  
  177. device=`df test-trim-by-desgua | grep "dev/" | awk '{ print $1 }'`
  178.  
  179. yes=`dd bs=4096 skip=$position count=256 if=$device | hexdump -C`
  180.  
  181. echo "In the next line you should see a pattern like:
  182. 00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.|
  183. $yes
  184. "
  185.  
  186. if [[ "`echo "$yes" | grep "y.y.y"`" == "" ]]; then
  187. echo "The pattern could not be checked. Something went wrong. Exiting."
  188. CLEAN;
  189. else
  190. echo "Pattern confirmed."
  191. fi
  192.  
  193. echo "Removing the temp file."
  194. rm test-trim-by-desgua
  195.  
  196. echo "Syncing."
  197. sync
  198. sleep 1
  199.  
  200. if [[ "$fs" == "1" ]]; then
  201. echo "fstrim -v $pasta && sleep 2" ; echo
  202. fstrim -v $pasta
  203. sleep 2
  204. fi
  205.  
  206. # Drop cache
  207. echo 1 > /proc/sys/vm/drop_caches
  208.  
  209. echo "In the next line you should **NOT** see a yes pattern like:
  210. 00000000 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a 79 0a |y.y.y.y.y.y.y.y.|
  211. If you see, then trim is not working:
  212. `dd bs=4096 skip=$position count=256 if=$device | hexdump -C`"
  213.  
  214. yes=`dd bs=4096 skip=$position count=256 if=$device | hexdump -C`
  215. if [[ "`echo "$yes" | grep "y.y.y"`" != "" ]]; then
  216. echo "TRIM not working."
  217. else
  218. echo "TRIM is working!"
  219. fi
  220. CLEAN;
  221. }
  222.  
  223. if [[ "$method" == "1" ]]; then
  224. SDATEST;
  225. TEST;
  226. elif [[ "$method" == "2" ]]; then
  227. LUKSTEST;
  228. fi
  229. exit 0
  230. shareedit
  231. edited Apr 13 '17 at 12:37
  232.  
  233. Community♦
  234. 1
  235. answered Apr 29 '14 at 11:51
  236.  
  237. desgua
  238. 28.4k88 gold badges8383 silver badges114
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement