bin/172801: /usr/libexec/locate.updatedb (and therefore locate(1)) does not work inside a jail
Devin Teske
dteske at FreeBSD.org
Tue Oct 16 22:40:01 UTC 2012
>Number: 172801
>Category: bin
>Synopsis: /usr/libexec/locate.updatedb (and therefore locate(1)) does not work inside a jail
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Oct 16 22:40:01 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Devin Teske
>Release: FreeBSD 8.1-RELEASE-p6 amd64
>Organization:
FIS Global, Inc.
>Environment:
FreeBSD ipm0.jbsd.vicor.com 8.1-RELEASE-p6 FreeBSD 8.1-RELEASE-p6 #6: Mon Oct 17 11:57:29 PDT 2011 dteske at oos0a.vbsd.vicor.com:/usr/src/sys/amd64/compile/FIS-amd64 amd64
>Description:
Executing 'locate' in a jail returns "locate: database too small: /var/db/locate.database"
The database file is 0 length:
-r--r--r-- 1 nobody wheel 0 Aug 20 04:15 /var/db/locate.database
The script /usr/libexec/locate.updatedb is responsible for generating the locate(1) database (above file). Executing '/usr/libexec/locate.updatedb' in a jail returns "/usr/libexec/locate.updatedb: empty variable FILESYSTEMS".
One might be fooled into thinking this is a configuration issue with /etc/locate.rc but it is not. The root-cause is that /usr/libexec/locate.updatedb uses the lsvfs(1) command to get a list of local/non-synthetic filesystem types (and uses this as the default-value for $FILESYSTEMS). Within a jail, the lsvfs(1) output is redacted (see below):
Filesystem Refs Flags
-------------------------------- ----- ---------------
1
29542
0
0
4
12342
0
0
7
115
0
0
10
This redacted output results in a NULL default-value for $FILESYSTEMS, resulting in the odd, but true, fatal error message "/usr/libexec/locate.updatedb: empty variable FILESYSTEMS".
ASIDE: The value of $FILESYSTEMS is used by /usr/libexec/locate.updatedb, enumerated to find(1) as a list of "-fstype" arguments when generating the locate(1) database.
It then uses this list to build a series of "-fstype" excludes to pass to find(1) when generating the locate(1) database.
>How-To-Repeat:
Execute 'locate' in a jail. Get the following error:
locate: database too small: /var/db/locate.database
Naturally, try and generate /var/db/locate.database by then executing:
/usr/libexec/locate.updatedb
Only to get the following fatal error:
/usr/libexec/locate.updatedb: empty variable FILESYSTEMS
NOTE: The error is misleading and caused by a bug. Please read "Full Description" for further explanation.
>Fix:
At the low-level, the problem is two-fold:
1. lsvfs(1) as-used by /usr/libexec/locate.updatedb returns a redacted list within a jail
2. find(1)'s "-fstype" flag does not work within a jail.
At the high-level, the problem is simpler to solve:
1. Make /usr/libexec/locate.updatedb not use lsvfs(1) or the "-fstype" flag of find(1) when running in a jail.
A patch has been attached that applys the above-described "high-level" change, allowing /usr/libexec/locate.db to function properly within a jail (thus allowing locate(1) to work as-expected within a jail).
Patch attached with submission follows:
--- /usr/libexec/locate.updatedb.orig 2012-09-28 16:03:47.000000000 -0700
+++ /usr/libexec/locate.updatedb 2012-09-28 16:07:54.000000000 -0700
@@ -63,6 +63,7 @@ case X"$FILESYSTEMS" in
X) echo "$0: empty variable FILESYSTEMS"; exit 1;; esac
# Make a list a paths to exclude in the locate run
+if [ "$(sysctl -n security.jail.jailed)" = "0" ]; then
excludes="! (" or=""
for fstype in $FILESYSTEMS
do
@@ -70,12 +71,14 @@ do
or="-or"
done
excludes="$excludes ) -prune"
+fi
case X"$PRUNEPATHS" in
X) ;;
*) for path in $PRUNEPATHS
do
- excludes="$excludes -or -path $path -prune"
+ excludes="$excludes $or -path $path -prune"
+ or="-or"
done;;
esac
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list