Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Oct 2012 22:38:20 GMT
From:      Devin Teske <dteske@FreeBSD.org>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/172801: /usr/libexec/locate.updatedb (and therefore locate(1)) does not work inside a jail
Message-ID:  <201210162238.q9GMcKPH068323@red.freebsd.org>
Resent-Message-ID: <201210162240.q9GMe1Ia009589@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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@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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210162238.q9GMcKPH068323>