From nobody@FreeBSD.org  Tue Oct 16 22:38:21 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 2C02895C
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 16 Oct 2012 22:38:21 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 0FED38FC0A
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 16 Oct 2012 22:38:21 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.5/8.14.5) with ESMTP id q9GMcKFG068324
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 16 Oct 2012 22:38:20 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.5/8.14.5/Submit) id q9GMcKPH068323;
	Tue, 16 Oct 2012 22:38:20 GMT
	(envelope-from nobody)
Message-Id: <201210162238.q9GMcKPH068323@red.freebsd.org>
Date: Tue, 16 Oct 2012 22:38:20 GMT
From: Devin Teske <dteske@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: /usr/libexec/locate.updatedb (and therefore locate(1)) does not work inside a jail
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         172801
>Category:       bin
>Synopsis:       [libexec] [patch] /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:  Sat Sep 07 17:49:45 UTC 2013
>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:

From: <dteske@freebsd.org>
To: <bug-followup@FreeBSD.org>, <dteske@FreeBSD.org>
Cc:  
Subject: Re: bin/172801: /usr/libexec/locate.updatedb (and therefore locate(1)) does not work inside a jail
Date: Mon, 11 Mar 2013 12:17:01 -0700

 ------=_NextPart_000_05F7_01CE1E52.568DD3D0
 Content-Type: text/plain; charset="us-ascii"
 Content-Transfer-Encoding: 7bit
 
 The previously attached patch didn't work for me on a virgin jail setup.
 
 I've revised/updated it. Could still use a formal looking at by the respective
 authors however (read: not intended for commit yet)
 
 _____________
 The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
 
 ------=_NextPart_000_05F7_01CE1E52.568DD3D0
 Content-Type: text/plain; name="patch.txt"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment; filename="patch.txt"
 
 --- /usr/libexec/locate.updatedb.orig	2010-07-18 19:24:42.000000000 -0700=0A=
 +++ /usr/libexec/locate.updatedb	2013-03-11 12:12:56.054787039 -0700=0A=
 @@ -59,6 +59,7 @@ PATH=3D$LIBEXECDIR:/bin:/usr/bin:$PATH; ex=0A=
  =0A=
  case X"$SEARCHPATHS" in =0A=
  	X) echo "$0: empty variable SEARCHPATHS"; exit 1;; esac=0A=
 +if [ "$(sysctl -n security.jail.jailed)" =3D "0" ]; then=0A=
  case X"$FILESYSTEMS" in =0A=
  	X) echo "$0: empty variable FILESYSTEMS"; exit 1;; esac=0A=
  =0A=
 @@ -70,12 +71,14 @@ do=0A=
         or=3D"-or"=0A=
  done=0A=
  excludes=3D"$excludes ) -prune"=0A=
 +fi=0A=
  =0A=
  case X"$PRUNEPATHS" in=0A=
  	X) ;;=0A=
  	*) for path in $PRUNEPATHS=0A=
             do =0A=
 -		excludes=3D"$excludes -or -path $path -prune"=0A=
 +		excludes=3D"$excludes $or -path $path -prune"=0A=
 +		or=3D"-or"=0A=
  	   done;;=0A=
  esac=0A=
  =0A=
 
 ------=_NextPart_000_05F7_01CE1E52.568DD3D0--
>Unformatted:
