make package fails in chroot: tar: getvfsbyname failed: No such
file or directory
Bernhard Fröhlich
decke at FreeBSD.org
Mon Aug 20 15:17:00 UTC 2012
On Mon, Aug 20, 2012 at 2:31 PM, Konstantin Belousov
<kostikbel at gmail.com> wrote:
> On Mon, Aug 20, 2012 at 01:42:31PM +0200, Bernhard Fr?hlich wrote:
>> On Sun, Aug 19, 2012 at 10:01 PM, Tim Kientzle <tim at kientzle.com> wrote:
>> >
>> > On Aug 19, 2012, at 12:17 PM, Garrett Cooper wrote:
>> >
>> >> On Sun, Aug 19, 2012 at 9:45 AM, Tim Kientzle <tim at kientzle.com> wrote:
>> >>>
>> >>> On Aug 12, 2012, at 6:20 AM, Paul Schenkeveld wrote:
>> >>>
>> >>>> Hi,
>> >>>>
>> >>>> I have a wrapper script that builds packages in a chroot environment
>> >>>> which happily runs on release 6 thru 9 and earlier 10 but fails with:
>> >>>>
>> >>>> tar: getvfsbyname failed: No such file or directory
>> >>>>
>> >>>> on a recent -CURRENT.
>> >>>
>> >>> libarchive does do an initial getvfsbyname() when you ask it
>> >>> to traverse a directory tree so that it can accurately handle later
>> >>> requests about mountpoints and filesystem types. This code
>> >>> is admittedly a little intricate.
>> >>
>> >> The problem most likely is the fact that all mountpoints are
>> >> exposed via chroot, thus, if it's checking to see if a mountpoint
>> >> exists, it may exist outside of the chroot.
>> >>
>> >
>> > I reviewed the code to refresh my memory. Some
>> > of what I said before was not quite right.
>> >
>> > Libarchive's directory traversal tracks information about
>> > the filesystem type so that clients such as bsdtar can
>> > efficiently skip synthetic filesystems (/dev or /proc) or
>> > network filesystems (NFS or SMB mounts).
>> >
>> > The net effect is something like this:
>> >
>> > For each file:
>> > stat() or lstat() or fstat() the file
>> > look up dev number in an internal cache
>> > if the dev number is new:
>> > fstatfs() the open fd to get the FS name
>> > getvfsbyname() to identify the FS type
>> >
>> > Unless there's a logic error in libarchive itself, this
>> > would suggest that somehow fstatfs() is returning
>> > a filesystem type that getvfsbyname() can't
>> > identify.
>> >
>> > Paul:
>> > What filesystem are you using?
>> >
>> > What does "mount" show?
>> >
>> > Does it work outside the chroot?
>>
>> I also see the same on the redports.org build machines.
>> It builds within a jail there which is completely on a tmpfs.
>> Interestinly everything is fine with a 10-CURRENT/amd64
>> jail but it breaks in a 10-CURRENT/i386 jail. Both are
>> running on the same 10-CURRENT/amd64 which is
>> around 2 months old.
>>
>> https://redports.org/buildarchive/20120814130205-56327/
>
> Try this.
>
> diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
> index 1d6136a..631d3f2 100644
> --- a/sys/kern/vfs_subr.c
> +++ b/sys/kern/vfs_subr.c
> @@ -41,6 +41,7 @@
> #include <sys/cdefs.h>
> __FBSDID("$FreeBSD$");
>
> +#include "opt_compat.h"
> #include "opt_ddb.h"
> #include "opt_watchdog.h"
>
> @@ -3111,21 +3112,49 @@ DB_SHOW_COMMAND(mount, db_show_mount)
> /*
> * Fill in a struct xvfsconf based on a struct vfsconf.
> */
> -static void
> -vfsconf2x(struct vfsconf *vfsp, struct xvfsconf *xvfsp)
> +static int
> +vfsconf2x(struct sysctl_req *req, struct vfsconf *vfsp)
> {
> + struct xvfsconf xvfsp;
>
> - strcpy(xvfsp->vfc_name, vfsp->vfc_name);
> - xvfsp->vfc_typenum = vfsp->vfc_typenum;
> - xvfsp->vfc_refcount = vfsp->vfc_refcount;
> - xvfsp->vfc_flags = vfsp->vfc_flags;
> + bzero(&xvfsp, sizeof(xvfsp));
> + strcpy(xvfsp.vfc_name, vfsp->vfc_name);
> + xvfsp.vfc_typenum = vfsp->vfc_typenum;
> + xvfsp.vfc_refcount = vfsp->vfc_refcount;
> + xvfsp.vfc_flags = vfsp->vfc_flags;
> /*
> * These are unused in userland, we keep them
> * to not break binary compatibility.
> */
> - xvfsp->vfc_vfsops = NULL;
> - xvfsp->vfc_next = NULL;
> + xvfsp.vfc_vfsops = NULL;
> + xvfsp.vfc_next = NULL;
> + return (SYSCTL_OUT(req, &xvfsp, sizeof(xvfsp)));
> +}
> +
> +#ifdef COMPAT_FREEBSD32
> +struct xvfsconf32 {
> + uint32_t vfc_vfsops;
> + char vfc_name[MFSNAMELEN];
> + int32_t vfc_typenum;
> + int32_t vfc_refcount;
> + int32_t vfc_flags;
> + uint32_t vfc_next;
> +};
> +
> +static int
> +vfsconf2x32(struct sysctl_req *req, struct vfsconf *vfsp)
> +{
> + struct xvfsconf32 xvfsp;
> +
> + strcpy(xvfsp.vfc_name, vfsp->vfc_name);
> + xvfsp.vfc_typenum = vfsp->vfc_typenum;
> + xvfsp.vfc_refcount = vfsp->vfc_refcount;
> + xvfsp.vfc_flags = vfsp->vfc_flags;
> + xvfsp.vfc_vfsops = 0;
> + xvfsp.vfc_next = 0;
> + return (SYSCTL_OUT(req, &xvfsp, sizeof(xvfsp)));
> }
> +#endif
>
> /*
> * Top level filesystem related information gathering.
> @@ -3134,14 +3163,16 @@ static int
> sysctl_vfs_conflist(SYSCTL_HANDLER_ARGS)
> {
> struct vfsconf *vfsp;
> - struct xvfsconf xvfsp;
> int error;
>
> error = 0;
> TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) {
> - bzero(&xvfsp, sizeof(xvfsp));
> - vfsconf2x(vfsp, &xvfsp);
> - error = SYSCTL_OUT(req, &xvfsp, sizeof xvfsp);
> +#ifdef COMPAT_FREEBSD32
> + if (req->flags & SCTL_MASK32)
> + error = vfsconf2x32(req, vfsp);
> + else
> +#endif
> + error = vfsconf2x(req, vfsp);
> if (error)
> break;
> }
> @@ -3161,7 +3192,6 @@ vfs_sysctl(SYSCTL_HANDLER_ARGS)
> int *name = (int *)arg1 - 1; /* XXX */
> u_int namelen = arg2 + 1; /* XXX */
> struct vfsconf *vfsp;
> - struct xvfsconf xvfsp;
>
> log(LOG_WARNING, "userland calling deprecated sysctl, "
> "please rebuild world\n");
> @@ -3185,9 +3215,12 @@ vfs_sysctl(SYSCTL_HANDLER_ARGS)
> break;
> if (vfsp == NULL)
> return (EOPNOTSUPP);
> - bzero(&xvfsp, sizeof(xvfsp));
> - vfsconf2x(vfsp, &xvfsp);
> - return (SYSCTL_OUT(req, &xvfsp, sizeof(xvfsp)));
> +#ifdef COMPAT_FREEBSD32
> + if (req->flags & SCTL_MASK32)
> + return (vfsconf2x32(req, vfsp));
> + else
> +#endif
> + return (vfsconf2x(req, vfsp));
> }
> return (EOPNOTSUPP);
> }
Wow that was fast! It will take a few days until I am able to give it a try
because I'm traveling for the next few days but I will report back as
soon as possible.
--
Bernhard Froehlich
http://www.bluelife.at/
More information about the freebsd-current
mailing list