I have a big drive on a fileserver that I store most things on. It’s big enough that it’s hard to search it manually, which is something I do often enough that I don’t really want to do that anymore. So I decided to add it to the locate database (updatedb).
Enable indexing#
First, you have to tell locate that it’s allowed to search mounted filesystems. In my case, it’s an NFS mount; if you’re using CIFS you’ll need to do something slightly different.
- Figure out your file system types. Run:
sudo updatedb --debug-pruningThis gives you information about which filesystems you need to worry about when you’re deciding which to prune.
Edit
/etc/updatedb.confIn the PRUNEFS line, remove autofs, NFS, nfs, and nfs4.
I noticed PRUNENAMES was commented out. It seemed like a good idea to uncomment that. I also added .mozilla to it because that was generating noise.
While you’re in there, it’s probably smart to make sure the filesystem you want to index isn’t in PRUNEPATHS. Because I didn’t want to index all my mounts, just one, I added my other mounts to PRUNEPATHS. I ended up with:
PRUNE_BIND_MOUNTS="yes"
PRUNENAMES=".git .bzr .hg .svn .mozilla"
PRUNEPATHS="/tmp /var/spool /media /var/lib/os-prober /var/lib/ceph /home/.ecryptfs /var/lib/schroot /cifs_share /other_nfs_share"
# PRUNEFS="NFS afs autofs binfmt_misc ceph cgroup cgroup2 cifs coda configfs curlftpfs debugfs devfs devpts devtmpfs ecryptfs ftpfs fuse.ceph fuse.cryfs fuse.encfs fuse.glusterfs fuse.gocryptfs fuse.gvfsd-fuse fuse.mfs fuse.rclone fuse.rozofs fuse.sshfs fusectl fusesmb hugetlbfs iso9660 lustre lustre_lite mfs mqueue ncpfs nfs nfs4 ocfs ocfs2 proc pstore rpc_pipefs securityfs shfs smbfs sysfs tmpfs tracefs udev udf usbfs"
# removed NFS, autofs, nfs, and nfs4
PRUNEFS="afs binfmt_misc ceph cgroup cgroup2 cifs coda configfs curlftpfs debugfs devfs devpts devtmpfs ecryptfs ftpfs fuse.ceph fuse.cryfs fuse.encfs fuse.glusterfs fuse.gocryptfs fuse.gvfsd-fuse fuse.mfs fuse.rclone fuse.rozofs fuse.sshfs fusectl fusesmb hugetlbfs iso9660 lustre lustre_lite mfs mqueue ncpfs ocfs ocfs2 proc pstore rpc_pipefs securityfs shfs smbfs sysfs tmpfs tracefs udev udf usbfs"- Test again with:
sudo updatedb --debug-pruningThat still won’t work#
On my NFS share (and every sensible NFS share), the root_squash option is set. This prevents a privilege escalation attack. Basically, if you have root on a box and can mount someone else’s NFS share, you can do things like chmod and chown. You do not want to turn that off. However, that means the root user that normally does the updatedb won’t be able to see the NFS share.
To get around this, do the following:
- On a non-
rootuser who has access to the share, run:
time updatedb --require-visibility no -o ~/shared.db --database-root /nfs_shareThis does a couple of things. First, you can see how long it takes. On my machine with my file server, it takes 18 minutes to scan my NFS share. Next, it creates a database of the NFS share in the shared.db file in the user’s home directory.
- Copy the database to /var/lib/plocate
sudo cp ~/shared.db /var/lib/plocate
sudo chown root:plocate /var/lib/plocate/shared.db- Test that it works
locate --database=/var/lib/plocate/shared.db file_i_know_exists_on_nfsAutomating this#
In the user’s crontab, add an entry to do the scan sometime late at night. You probably don’t want to do this more than once a day. I saw someone suggest doing it in .bashrc which seems like overkill and will make your logins slow.
- As the user (I used
andrew), edit the crontab:
crontab -e- Add something like this to run every day at 2:30 am:
30 02 * * * updatedb --require-visibility no -o /home/andrew/shared.db --database-root /nfs_share- Next, create a script in /root to copy the file to the right place and give it the right ownership:
#!/bin/bash
# Copy the NFS shared plocate database so everyone can see it
SOURCE=/home/andrew/shared.db
DEST=/var/lib/plocate/shared.db
if [ -s "${SOURCE}" ]; then
/bin/cp "${SOURCE}" "${DEST}"
/bin/chown root:plocate "${DEST}"
/bin/chmod 640 "${DEST}"
/bin/rm "${SOURCE}"
else
echo $0: ${SOURCE} not found or empty.
fi- Edit root’s crontab:
sudo crontab -uroot -e- Add something like:
# Grab the plocate database generated by user andrew and install it in /var/lib/plocate
15 03 * * * /bin/bash /root/copy-shared-plocate-database.shI’m doing it at 3:15 am, well after the 18 minute time I found it took earlier, so there’s plenty of time for the update to finish before I do the copy.
Updating the environment#
By default, I want to search both the regular /var/lib/plocate/plocate.db and /var/lib/plocate/shared.db. Luckily there’s an environment variable that you can add to .bashrc:
# Add /shared to the locate path
export LOCATE_PATH=/var/lib/plocate/plocate.db:/var/lib/plocate/shared.dbYou’ll need to start a new shell (or source ~/.bashrc or logout/login or whatever) for this to work.
Finally! Now you can use locate!#
Now you can do:
locate file_i_am_looking_foror if you’re not sure of the case you used:
locate -i file_i_am_looking_for_When_I_dont_know_the_Case