Linux SSD TRIM Setup

 

Linux SSD

 

If you are installing an SSD in Linux, you must setup TRIM in order to keep the drive  performing at peak performance. Also, I believe fstrim only works on ext4, someone correct me if I am wrong.

You can install Linux just fine right out of the box, you just need to make sure AHCI is enabled in the BIOS. If your BIOS does not have an option to set it, then chances are it will detect it automatically.

Once you have your SSD installed and your OS loaded onto it, you just just need to make sure the TRIM function is enabled. The program that does this is called “fstrim”.

According to the MAN page;
fstrim is used on a mounted filesystem to discard (or “trim”) blocks which are not in use by the filesystem. This is useful for solid- state drives (SSDs) and thinly-provisioned storage.”

So basically, fstrim goes around picking up the garbage left behind by the file system so that when it is time to write to a block again, you don’t have to take out the trash every time. This can obviously speed things up as the drive gets more and more use.

Linux SSD trim

The problem is that by default, fstrim is usually installed but there is no automated way to trigger it.

You can manually do by typing the following command:

sudo fstrim -v /

and should return the following:

joao@D630:/etc$ sudo fstrim -v /
/: 825077760 bytes were trimmed
joao@D630:/etc$

In my system, the root “/” folder is the SSD, but you can change the path to wherever the SSD is mounted. For example, if your home directory was where the SSD is stored, then you command would look like this;

sudo fstrim -v /home

So, it’s great that we can do this manually but this should be automated, no?

There are many tutorials out there but I have decided to share how I did it and why I did it. Because there are people with laptops and some with desktops and most solutions are either or but mine I think satisfies either or both and it is fairly easy to set up.

Let’s look at some of the scenarios, if you have a laptop then we can write a simple script to run fstrim at boot but if you have a desktop, you may not reboot very often so this solution is not very good for desktops. If you run a desktop, you could just run a CRON job periodically and this may satisfy a laptop user as well. The best combination is both! I believe that fstrim should run more often to clean smaller amounts because, let’s say you ran your laptop for a few days, and fstrim only ran at boot, then the next boot time would be increased because it would have to wait for fstrim to do its work.

So, we are going to add a script to four places:

/etc/rc.local = This will run at every boot  no matter what.
/etc/rc0.d/ = This will run at shutdown only.
/etc/rc6.d/ = This will run on restart only.
/etc/cron.hourly/ = This will run every hour the system is running.

We will edit the rc.local directly and add the command there. We will then create a script and add it to /etc/init.d/ and create links to rc0.d, rc6.d and cron.hourly.

Here is my reasoning for doing this. Running a cron job every hour should not tax the system for normal use, this will keep the fstrim load in check. When you shut down, rc0.d will run fstrim during a shutdown and this should have cleaned most of the file system. When the system starts, rc.local will catch any little thing left with little to no delay in booting. If instead of a shut down your reboot the machine, the same process will occur except that rc6.d will execute instead of rc0.d. Now, in the event of weird things happening to your system and a clean shutdown or restart was not done, rc.local will catch it all, but might add more time to your boot. So, once this is all set in place, it should be completely automated.

Fire up your favorite terminal and edit the rc.local file.
(note: I am running Elementary OS, so scratch is my editor. replace with your favorite editor,  Gedit etc.. In Elementary OS the actual command for scratch is “scratch-text-editor”, I just created a symbolic link in /usr/bin to “scratch” to shorten the command)

sudo scratch /etc/rc.local

Your file should look like this:
rc.local

Now, add the following  right above the “exit 0”

#
#Run “fstrim” at boot
LOG=/var/log/trim.log
fstrim -v / >>$LOG
echo “Time: $(date)” >>$LOG

The file should now look like this:
rc.local _after

Now, every time you start or reboot, fstrim will run!
Notice, I added a log command, you can always see the log at /var/log/trim.log

Next,  create a folder in your Home directory called “Scripts” and inside there create an empty file called fstrim.sh

now edit that file and copy the following;

#!/bin/sh
#
#
#
#Run “fstrim” command
LOG=/var/log/trim.log
fstrim -v / >>$LOG
echo “Time: $(date)” >>$LOG
exit 0

Save and close the file. Open a terminal and navigate to the Scripts directory. Next, we need to make the file executable:

chmod +x fstrim.sh

Next, copy the file to /etc/init.d/ using the following command.

sudo cp fstrim.sh /etc/init.d/fstrim.sh

Next, change the permissions on the file with the following command:

sudo chmod 755 /etc/init.d/fstrim.sh

Next, we make the three symbolic links and will be finished.

sudo ln -s /etc/init.d/fstrim.sh /etc/rc0.d/K30fstrim
sudo ln -s /etc/init.d/fstrim.sh /etc/rc6.d/K30fstrim
sudo ln -s /etc/init.d/fstrim.sh /etc/cron.hourly/fstrim

Restart your machine and it should work, you can verify by looking in /var/log/trim.log

30 thoughts on “Linux SSD TRIM setup – ubuntu/debian

    1. Joao Post author

      “Isn’t once a week enough?”, sure, it all depends on your needs/situation, you have to make that decision.
      Based on what I understand of how an SSD operates, it would seem to me that to keep the pages that have been marked for deletion to a mininum would be ideal, that way, the block is freed and ready to be written to. Also, it would seem that the more a drive is used and filled, the more crucial to use TRIM more often versus a drive that is only say 10% full.

      Here is an interesting post on NAND FLASH type memory..
      http://site.aleratec.com/blog/2011/09/22/overview-pages-blocks-ftls-solidstate-drive-ssd/

  1. Bill R

    I like the method….a simple check of you log files lets you know everything is working as it should. Thanks

  2. sabin chacko

    I too like the method

    incidentally “sudo scratch /etc/rc.local” not opened the text editor for me and I thought Scratch is not installed on my freya beta.
    So tried an “apt-get install Scratch” and ends up installing another application called Scratch ( http://scratch.mit.edu/about)

    later learned “gksudo scratch-text-editor /etc/cron.daily/trim” is the command to open the file in text editor.

    “scratch-text-editor” too much for cli, Hope eos developers are listening

    Anyway my /var/log/trim shows it works perfectly. Thanks a lot

    1. Joao Post author

      Sabin, yes, you are correct! I had forgotten that I had created a symbolic link in /usr/bin from scratch-text-editor to scratch precisely for that reason, the command is too long 🙂 I made a note in the post to reflect that. Good catch!

      Joao

  3. Janus

    Hi Joao

    i was wondering if this script could be modified to suit my needs – (i would have no idea how )

    Basically i have three drives – sda – sdb – sdc

    Sda & sdb are both SSD Drives & sdc is a hybrid drive SSD/hdd that still needs trim support

    My Os is on Sda so i could use your method above (great method by the way and the log is extra Bonus)

    sdb & sdc are not auto mounted at boot and i usually mount when required to use them and then have to manually trim (pain in the rear)

    Sdc is split into three partition – Data – Music – Video

    if it helps – sda btrfs – sdb & c are ext4

    sda was created vis mdos & sdb & c gpt

    Any imput you may have on this would be greatly appreciated

    Thanks

    1. Joao Post author

      Hi Janus,
      You can have TRIM run on multiple drives in the same script by just adding another fstrim command,
      or as many as you need, in the script file.
      So for instance:

      LOG=/var/log/trim.log
      fstrim -v / >>$LOG
      echo “Time: $(date)” >>$LOG
      fstrim -v /media/**your sdb drive here**
      echo “Time: $(date)” >>$LOG
      fstrim -v /media/**your sdc drive here**

      As for the Hybrid drive, I have not used one and I do not know if it will work. If it does work,
      you may have to create an fstrim command for each partition, for example:

      fstrim -v /media/**your sdc drive here**/Music
      fstrim -v /media/**your sdc drive here**/Data
      fstrim -v /media/**your sdc drive here**/Video

      Note, in order for fstrim to work the drive must be mounted, so if you set the script
      to run periodically but the drive is mounted only manually, it will not run. To
      have your drives mounted at login, see this post:
      http://joao.machado-family.com/2014/04/14/linux-mount-external-drives-login/

      If you get the hybrid drive to work with fstrim, please post back on here the results.
      This post gets about 800 hits per month and that would be helpful to someone, I am sure.

      Hope this helps…

      Joao

  4. Janus

    Thanks Joao for replying much appreciated

    I will post back the results – i know the hybrid needs trim as when i manually run it returns the trim results

    Just so i get the Rc.local correct – DOES THIS LOOK CORRECT (assuming all disc are mounted)

    LOG=/var/log/trim.log
    fstrim -v / >>$LOG
    echo “Time: $(date)” >>$LOG
    fstrim -v /media/sdb
    echo “Time: $(date)” >>$LOG
    fstrim -v /media/sdc/Data
    fstrim -v /media/sdc/Music
    fstrim -v /media/sdc/Video
    echo “Time: $(date)” >>$LOG

    Thank You again

  5. Joao Post author

    Hi Janus,

    If sdc is mounted as “Data”, then it should be as follows: fstrim -v /media/Data
    You will have to make the changes to Music and Video as well…

    Remember sdc is a device not a file system.

    Let us know if it works.

  6. janus

    Unable to self mount drives in the link provided so unable to see if it works ?

    1. Joao Post author

      Janus, did you verify that the script file works by manually running it first when drives are not mounted?
      Which distro are you using?

  7. janus

    Yes – I followed it to a tee – unmounted all the drives – ran the sh MountDrives.sh

    didn’t work and didnt mount the drives

    Linux Mint 17 Cinnamon 64 Bit

    1. Joao Post author

      OK, then you have to recheck the script file… make sure it is executable. Run “ls -l” in the directory of where the file is and the permissions should be -rwxr-xr-x

  8. janus

    Hi Joao

    Yes you are correct the MountDrives.sh = -rwxrwxr– 1
    fstrim.sh = -rwxr-xr-x 1

    How to change This ? I Tried sudo chmod 774 MountDrives.sh but this gave the same results

  9. Joao Post author

    I think your problem is that you used “sudo”, which may have made the owner of the file root. Right click on the file >properties and see who the owner is. When you login, it can’t execute a root file. You can also just check off “Make executable” when right clicking on the file properties once you change the file ownership back.

  10. janus

    no i only tried sudo after it didnt work as chmod 774 MountDrives.sh

    properties say i own the file and execute is ticked but it still dont work

  11. janus

    i decided to try it just with one drive and still wont work

    #!/bin/bash
    /usr/bin/udisks –mount /dev/disk/by-uuid/341f120e-2f13-4679-9a92-a780790d0fba

    exit 0

    1. Joao Post author

      Looks like your problem is the mount command “–mount” , it needs to be --mount two dashes.
      But it looks like my site theme is merging the two dashes. If UDISKS is installed, and the file has the correct ownership and permissions it should work. Does it give an error at the command line when executing?

      Double check that the owner=you and that the group=you

  12. janus

    Hi Joao

    Yes you are correct – i copied it from the script in the link provided and it did put a – instead of a —

    after altering to — i confirm it does mount the drive on both the manual & at boot ways

    only issue i have now is the trim log although it does show two time stamps for the date it doesnt show an ammount trimmed so im unsure if it worked or not

    here is the /etc/rc/local

    #Run “fstrim” at boot
    LOG=/var/log/trim.log
    fstrim -v / >>$LOG
    echo “Time: $(date)” >>$LOG
    fstrim -v /media/SSD2
    echo “Time: $(date)” >>$LOG
    exit 0

    the SSD2 = sdb1 and im triming the whole drive

  13. janus

    i have answered my own quoestion

    fstrim – v media/SSD2 should have had >>$LOG adding

    i can now confirm after the great help from Joao this now works – mounts the drive and trims on both start & shutdown – i never did the hourly as i was unsure if this would effect encoding which i occasionally do

    Thanks Joao – Great Help

  14. Joao Post author

    Great to hear Janus, as for the hourly cron job that is what your use case calls for. That is one of the reasons I like this method… flexible.

    Nice job on being persistent

  15. zk

    Thank you for the tutorial. It is very instructive. But I got the following errors after I removed some packages:

    insserv: warning: script ‘K30fstrim’ missing LSB tags and overrides
    insserv: warning: script ‘fstrim.sh’ missing LSB tags and overrides

    Is this anything to be concerned about? (I’m using the latest version of Debian)

    Thank you.

    1. Joao Post author

      Hi Zach,

      It looks like Debian is implementing some kind of Linux Standard Base protocols in initd scripts.
      If the scripts are executing properly then you can possibly ignore it. I found this link that looks like it shows how they would like the script to function
      https://wiki.debian.org/LSBInitScripts

      If you get it working, please post back how you were able to fix the error message, I am sure someone could benefit from it.

      Good luck…

      Joao

  16. liam

    Hi,

    hoping someone can put my mind at ease, followed instructions above and ive just checked the log after a few days.

    the trim thats happening on startup seems to be way too high acording to my understanding ? ive only got a 120gb SSD, and the trim on startup is about 95GB!? is this correct or is something amiss ?

    log for a few days below:

    “Time: Sun Nov 23 19:17:14 GMT 2014”
    /: 419.1 MiB (439468032 bytes) trimmed
    “Time: Sun Nov 23 20:17:08 GMT 2014”
    /: 445.2 MiB (466812928 bytes) trimmed
    “Time: Sun Nov 23 21:17:10 GMT 2014”
    /: 95.4 GiB (102447734784 bytes) trimmed
    “Time: Mon Nov 24 17:42:53 GMT 2014”
    /: 1.5 GiB (1592672256 bytes) trimmed
    “Time: Mon Nov 24 18:17:22 GMT 2014”
    /: 521.7 MiB (547061760 bytes) trimmed
    “Time: Mon Nov 24 19:17:14 GMT 2014”
    /: 373.9 MiB (392032256 bytes) trimmed
    “Time: Mon Nov 24 20:17:05 GMT 2014”
    /: 456.6 MiB (478777344 bytes) trimmed
    “Time: Mon Nov 24 21:17:11 GMT 2014”
    /: 95.1 GiB (102093762560 bytes) trimmed
    “Time: Tue Nov 25 17:52:22 GMT 2014”
    /: 95.1 GiB (102095519744 bytes) trimmed
    “Time: Tue Nov 25 17:54:54 GMT 2014”
    /: 1.6 GiB (1665331200 bytes) trimmed
    “Time: Tue Nov 25 18:17:20 GMT 2014”

    thanks in advance ! 🙂

  17. Joao Post author

    Hi Liam, I never noticed it before but I just looked at my log and when I boot it is trimmming 167 GiB, I have a 250GB SSD. So it appears that is normal.

  18. Pingback: Comando TRIM em dispositivos SSD | Blog do Albuquerque

  19. marvinudy

    Joao,

    Thanks for the article. Used information to set up my new 240Gb SSD running Mint 17.3. I run VB VDI’s for evaluation and needed to keep ‘things clean’. Added my modified root install structure to the rc.local including the partition on which I store the VB vdi’s. Good learning tool for an old man, me.

    best regards,

    marvinudy

  20. janus

    Hi im back again

    this method now seems to not work with mint 18 as it really slow doen the boot process due to systemd (or so i have heard) i tried it and it just hangs

    would you know how to adapt this to Mint 18 ?

    Thanks

What's on your mind?