Linux SSD TRIM Setup
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.
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:
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:
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
Isn’t once a week enough?
“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/
I like the method….a simple check of you log files lets you know everything is working as it should. Thanks
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
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
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
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
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
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.
Unable to self mount drives in the link provided so unable to see if it works ?
Janus, did you verify that the script file works by manually running it first when drives are not mounted?
Which distro are you using?
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
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
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
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.
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
can you post the contents of the file?
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
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
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
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
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
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.
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
I actually was able to fix the problem later on after viewing the answer to this post: http://raspberrypi.stackexchange.com/questions/13358/insserv-warning-script-mathkernel-missing-lsb-tags-and-overrides
To get rid of the error I just had to add those two tags (### BEGIN INIT INFO and ### END INIT INFO) in their appropriate place in the fstrim.sh script.
I hope this helps.
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 ! 🙂
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.
Pingback: Comando TRIM em dispositivos SSD | Blog do Albuquerque
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
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