Commit Graph
88 Commits
Author SHA1 Message Date
Ayush RanjanandgVisor bot f8e29b59d7 Mark newly created directories in merged parents in overlay as opaque.
This is an optimization that will prevent needless lookups on lower layers for
directories. This is analogous to the Linux commit 97c684cc9110 ("ovl: create
directories inside merged parent opaque").

If mkdir(2) does succeed, then none of the lower layers have a file at that
position, otherwise mkdir(2) would have failed with EEXIST.

Changes on the lower layer underneath a new upper layer directory are not
visible. See the following for example:
```
$ sudo mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=workdir none overlay
$ mkdir -p overlay/dir/dir1
$ mkdir -p lower/dir/dir2
$ ls overlay/dir/
dir1
```

Benchmarking shows that this change cuts ABSL build time by 9.5%!
```
goos: linux
goarch: amd64
cpu: Intel(R) Xeon(R) CPU @ 2.20GHz
                                                  │ /tmp/benchout.runsc │     /tmp/benchout.runsc-opt      │
                                                  │       sec/op        │   sec/op    vs base              │
BuildABSL/page_cache.clean/filesystem.bindfs-8              71.16 ± 12%   64.40 ± 3%  -9.50% (p=0.003 n=8)
BuildGRPC/page_cache.clean/filesystem.bindfs-8              418.2 ±  1%   419.9 ± 1%       ~ (p=0.721 n=8)
RubySpecTest/page_cache.clean/filesystem.bindfs-8           76.67 ±  5%   75.17 ± 1%       ~ (p=0.382 n=8)
geomean                                                     131.6         126.7       -3.78%

                                                  │ /tmp/benchout.runsc │   /tmp/benchout.runsc-opt   │
                                                  │      load.sec       │  load.sec   vs base         │
RubySpecTest/page_cache.clean/filesystem.bindfs-8            12.95 ± 6%   12.80 ± 5%  ~ (p=0.625 n=8)
```

PiperOrigin-RevId: 538823897
2023-06-08 10:33:25 -07:00
Etienne PerotandgVisor bot c6d19db4e4 Update unimpl.EmitUnimplementedEvent interface to add the syscall number.
This catches up the interface to the `EmitUnimplementedEvent` method signature
on `kernel.Kernel`.

Also add build-time test to verify that `kernel.Kernel` implements this
interface, in order to catch such breakages at build time in the future.

PiperOrigin-RevId: 519000411
2023-03-23 17:01:37 -07:00
Adin ScannellandgVisor bot 2911d8c3b8 Add default_applicable_licenses rules to packages.
PiperOrigin-RevId: 513581243
2023-03-02 10:50:04 -08:00
Ayush RanjanandgVisor bot b16662ccad Hide root overlay filestore from container using whiteout.
PiperOrigin-RevId: 507355437
2023-02-05 19:36:11 -08:00
Ayush RanjanandgVisor bot 73667dc455 Handle terminal symlinks correctly in OpenAt() implementations.
All filesystems except tmpfs had the same bug regarding handling symlinks
in the terminal path component. When they tried to open(2) such a symlink
file, these implementations called into stepLocked() with
Then these implementations also called vfs.HandleSymlink() which would
also advance rp (when rp.Done() was already true).

This was tripping the invariants checks in sentry/vfs/debug.go.

PiperOrigin-RevId: 504098263
2023-01-23 15:35:15 -08:00
Andrei VaginandgVisor bot 2d940c16b6 overlayfs: don't call SetStat and StatAt under dentry.mapsMu
This allows to avoid lock order inversions with inodeMutex and
filesystemRWMutex.

PiperOrigin-RevId: 495629138
2022-12-15 10:16:06 -08:00
Ayush RanjanandgVisor bot 8431399462 Add ENAMETOOLONG checks in overlayfs.
Linux overlayfs uses the max of all layers' filename length limit. Do the same
in gVisor.

This is needed to get PHP runtime test ext/standard/tests/strings/007.phpt to
pass with overlayfs.

PiperOrigin-RevId: 493942515
2022-12-08 11:04:37 -08:00
Ayush RanjanandgVisor bot d937df6218 Replace pkg/refs with pkg/refsvfs2.
All VFS1 only bits have been deleted.

Updates #1624

PiperOrigin-RevId: 492273183
2022-12-01 12:46:11 -08:00
Etienne PerotandgVisor bot 5f9231cd71 Lockdep: Print more info in the "unbalanced unlock" case.
This CL does the following:

- Add the ability for nested locks to have names.
- Give names to all current uses of nested locks in the codebase.
- Truncate `lockdep` debug stack traces to avoid the clutter from the
  `lockdep` code itself
- Simplify `lockdep` to not longer require `classMap`.

PiperOrigin-RevId: 491486620
2022-11-28 17:53:09 -08:00
Ayush RanjanandgVisor bot ee523cfbc7 Delete VFS1 filesystem implementations.
Updates #1624

PiperOrigin-RevId: 488986080
2022-11-16 11:05:10 -08:00
Kevin KrakauerandgVisor bot 3a76efe831 convert uses of interface{} to any
Done via:
  find . -name "*.go" | xargs sed -i -E 's/interface\{\}/any/g'

PiperOrigin-RevId: 487033228
2022-11-08 13:14:06 -08:00
Ayush RanjanandgVisor bot bca0e23074 Copy up consistently for all file types if open mode is writable.
Earlier, we were only copying up regular files. We were missing
out device files. ensureOpenableLocked() should ensure that
files are copied up if mode is writable. Without this, we
violate the preconditions for openCopiedUp().

Also, without this, open(file, O_WRONLY) on a lower layer pipe
returns EROFS, which is confusing because the upper layer is
still writable. Now it will return EPERM which indicates that
the pipe can not be copied up.

PiperOrigin-RevId: 465838606
2022-08-07 00:08:24 -07:00
Ayush RanjanandgVisor bot 02c52eed68 Lower layer files that can not be copied up are not writable.
Make access(W_OK) return EACCES in overlayfs if file exists only
on lower layer and can not be copied up. Earlier, access(W_OK)
was succeeding but operations that cause copy-up (like
open(WR_ONLY)) were failing. This is likely to confuse
applications.

PiperOrigin-RevId: 465818314
2022-08-06 20:01:51 -07:00
Ayush RanjanandgVisor bot e40196a811 Add name length checks to renameat(2).
In Linux, the callers of fs/namei.c:do_renameat2() do this check
by calling fs/namei.c:getname().

This is important of consistency with Linux. Also, without this
we can see panics in overlayfs rename if new file's name is too
long. Because upperlayer RenameAt operation would succeed but
SetXattr operation will fail leading to an inconsistent state.

PiperOrigin-RevId: 464173793
2022-07-29 15:48:41 -07:00
Ayush RanjanandgVisor bot a9181cfe67 Move all InotifyWithParent() callers in FDImpl to VFS layer.
`vfs.FileDescription` in general handles all inotify work. Only
SetStat, SetXattr, RemoveXattr and Iterdirents require FDImpls to
handle the Inotify work. This leads to repeated code. And for
kernfs users, there are too many FD implementors. So it becomes
difficult plumbing Inotify consistenly through all FDImpls.

So make it consistent that all Inotify work is handled by
`vfs.FileDescription`, not FDImpls.

PiperOrigin-RevId: 461751122
2022-07-18 17:13:41 -07:00
Ayush RanjanandgVisor bot 2b795d6ea9 Add vfs.Dentry.Evictable support.
This change does 3 things:
- Adds `IsEvictable() bool` and `MarkEvictable()` methods to
  vfs.Dentry. A dentry's "evictability" is just a hint to filesystem
  implementations that this dentry will not be accessed again
  (from the caller of Dentry.MarkEvictable()). So filesystem
  implementation can choose to release resources for such evictable
  dentries. For example, caching such dentries is no longer useful.
- In VFS2, only 2 filesystem implementations have a LRU dentry
  cache: kernfs and gofer. Dentries with 0 refs are cached here.
  Updated both these filesystem implementations to evict dentries
  that have 0 refs and are evictable.
- Updated overlayfs to mark lower layer dentries for
  non-directory files as evictable when either a dentry is copied up
  or a dentry is deleted. In both cases if there is a dentry in
  the lower layer, it is no longer visible from the overlayfs.
  Note that the file "replaced" by rename(2) is also considered
  deleted.

Motivation:
We were observing elevated memory usage in VFS2 when using
overlayfs because VFS2 gofer client has a dentry cache and was
holding on to lower layer dentries which were anyways not
accessible from the overlayfs. The file mappings for these stale
dentries were responsible for holding up so much sentry memory.
PiperOrigin-RevId: 460325860
2022-07-11 16:27:49 -07:00
Ayush RanjanandgVisor bot c9354f1d37 Preserve directory inode number after copy up in overlayfs.
Earlier we were using the topmost inode and device number to
compute the directory inode number. But the topmost layer changes
after a copy up which causes a new inode number to be generated
after a copy up.

This confuses some applications like GNU's FTS library. See
fts_safe_changedir() for example which errors out with ENOENT if
it observes that the dirctory inode or device number has changed.

Now we use the bottommost layer's inode and device numbers. Linux
and VFS1 also preserve the directory's inode number after copy up.

PiperOrigin-RevId: 456147019
2022-06-20 18:36:14 -07:00
Andrei VaginandgVisor bot cfca6ec84e overlay: use lockdep mutexes
PiperOrigin-RevId: 455478722
2022-06-16 15:23:00 -07:00
Ayush RanjanandgVisor bot f28763c31e Automated rollback of changelist 359350716
PiperOrigin-RevId: 449414348
2022-05-18 00:49:33 -07:00
Ayush RanjanandgVisor bot 2026e1f078 Reformat codebase.
PiperOrigin-RevId: 449358041
2022-05-17 17:48:35 -07:00
Jamie LiuandgVisor bot 1c9b108577 Check file permissions before VFS2 overlayfs open.
PiperOrigin-RevId: 446565359
2022-05-04 15:23:31 -07:00
Kevin KrakauerandgVisor bot 3e7fcef1df switch fsimpl/ from sync/atomic to atomicbitops for 32 bit values
PiperOrigin-RevId: 443535714
2022-04-21 18:32:04 -07:00
Kevin KrakauerandgVisor bot b8dd528b97 prohibit direct use of sync/atomic (u)int64 functions
All atomic 64 bit ints are changed to atomicbitops.(Ui|I)nt64. A nogo checker
enforces that sync/atomic 64 bit functions are not called.

For reviewers: the interesting changes are in the atomicbitops and checkaligned
packages.

Why do this?
- It is very easy to accidentally use atomic values without sync/atomic funcs.
- We have checkatomics, but this is optional and is forgotten in several places.
  - Using a type+checker to enforce this seems less error prone and simpler.
- We get NoCopy protection.
- Use of 64 bit atomics can break 32 bit builds. We have types to handle this
  without any runtime cost, so we might as well use them.

PiperOrigin-RevId: 440473398
2022-04-08 16:06:26 -07:00
Jamie LiuandgVisor bot 6f83b4957a Check mount writability in VFS2 [f]access[at][2] implementations.
Linux exempts special files (sockets, named pipes, and character/block device
special files) from mount writability checks in both open
(fs/open.c:do_dentry_open()) and access (fs/open.c:do_faccessat()) paths. We
don't currently do so in open (in VFS1 or VFS2) or access (in VFS1), so we
don't do so in VFS2 access either.

PiperOrigin-RevId: 439398002
2022-04-04 13:33:02 -07:00
Jamie LiuandgVisor bot e557bf457c Don't panic in overlay.filesystem.UnlinkAt unless necessary.
PiperOrigin-RevId: 432496516
2022-03-04 11:42:54 -08:00
Jamie LiuandgVisor bot b0e2a53020 Ensure that open(O_RDWR) doesn't copy-up on read-only VFS2 overlay mounts.
PiperOrigin-RevId: 430765773
2022-02-24 12:28:49 -08:00
Fabricio VoznikaandgVisor bot 9725ff1d9b Fix epoll_ctl(2) regular files and dirs
Linux behaves differently for regular files and dirs for poll(2)/select(2)
compared to epoll_ctl(2). The latter returns EPERM for file and dirs.
I've also changed host FDs to behave like the underlying FD in regards
to epoll to keep it compatible with docker.

Fixes #7134

PiperOrigin-RevId: 429412692
2022-02-17 15:12:36 -08:00
Jamie LiuandgVisor bot 7f3775687b Don't copy up event registrations in VFS2 overlay.
Doing so can deadlock, and regular files and symlinks usually shouldn't be
event-registerable anyway (especially after cl/426516504).

PiperOrigin-RevId: 429117155
2022-02-16 12:47:43 -08:00
Fabricio VoznikaandgVisor bot cecd7315bc Don't eat error from epoll_ctl EPOLL_CTL_ADD
Docker maps stdin to `/dev/null` which doesn't support epoll. Host FD
was ignoring the error and suceeding the epoll_ctl call from the
container, giving false impressing that epoll would be notified.

This required plumbing failure to all waiter.Waitable.EventRegister
callers and implementers.

Closes #6795

PiperOrigin-RevId: 414797621
2021-12-07 12:36:00 -08:00
Adin ScannellandgVisor bot 4967b16af9 Update Waitable API.
Instead of passing the event mask at registratrion time, pass the mask as part
of the waiter. This makes the mask immutable and simplifies the architecture of
waiters. This is also necessary for a future fix that will allow the fdnotifier
to keep persistent entries, as opposed to requiring constant updates.

This change is intended to be a no-op in terms of function. The only exception
is signalfd, where this mask was abused. To handle this case, the operation of
signalfd changed to allow one layer of indirection.

PiperOrigin-RevId: 409702998
2021-11-13 12:54:39 -08:00
Ayush RanjanandgVisor bot 185be70bd4 Simplify vfs.NewDisconnectedMount signature and callpoints.
vfs.NewDisconnectedMount has no error paths. Its much prettier without the
error return value.

Also simplify MountDisconnected which would immediately drop the refs taken by
NewDisconnectedMount. Instead make it directly call newMount.

PiperOrigin-RevId: 405767966
2021-10-26 17:00:07 -07:00
Adin ScannellandgVisor bot e877a7046d Support distinction for RWMutex and read-only locks.
Fixes #6590

PiperOrigin-RevId: 404007524
2021-10-18 11:09:39 -07:00
Jamie LiuandgVisor bot 5a8130c286 Propagate vfs.MkdirOptions.ForSyntheticMountpoint to overlay copy-up.
PiperOrigin-RevId: 394296687
2021-09-01 13:09:00 -07:00
Zach KoopmansandgVisor bot 83bf514e27 [syserror] Remove pkg syserror.
Removes package syserror and moves still relevant code to either linuxerr
or to syserr (to be later removed).

Internal errors are converted from random types to *errors.Error types used
in linuxerr. Internal errors are in linuxerr/internal.go.

PiperOrigin-RevId: 390724202
2021-08-13 17:16:52 -07:00
Zach KoopmansandgVisor bot f26a93e634 [syserror] Convert remaining syserror definitions to linuxerr.
Convert remaining public errors (e.g. EINTR) from syserror to linuxerr.

PiperOrigin-RevId: 390471763
2021-08-12 15:19:12 -07:00
Zach KoopmansandgVisor bot 5e6d494c2f [syserror] Update syserror to linuxerr for more errors.
Update the following from syserror to the linuxerr equivalent:
EEXIST
EFAULT
ENOTDIR
ENOTTY
EOPNOTSUPP
ERANGE
ESRCH

PiperOrigin-RevId: 384329869
2021-07-12 15:26:20 -07:00
Adin ScannellandgVisor bot 0f15e2418e Mix checklocks and atomic analyzers.
This change makes the checklocks analyzer considerable more powerful, adding:
* The ability to traverse complex structures, e.g. to have multiple nested
  fields as part of the annotation.
* The ability to resolve simple anonymous functions and closures, and perform
  lock analysis across these invocations. This does not apply to closures that
  are passed elsewhere, since it is not possible to know the context in which
  they might be invoked.
* The ability to annotate return values in addition to receivers and other
  parameters, with the same complex structures noted above.
* Ignoring locking semantics for "fresh" objects, i.e. objects that are
  allocated in the local frame (typically a new-style function).
* Sanity checking of locking state across block transitions and returns, to
  ensure that no unexpected locks are held.

Note that initially, most of these findings are excluded by a comprehensive
nogo.yaml. The findings that are included are fundamental lock violations.
The changes here should be relatively low risk, minor refactorings to either
include necessary annotations to simplify the code structure (in general
removing closures in favor of methods) so that the analyzer can be easily
track the lock state.

This change additional includes two changes to nogo itself:
* Sanity checking of all types to ensure that the binary and ast-derived
  types have a consistent objectpath, to prevent the bug above from occurring
  silently (and causing much confusion). This also requires a trick in
  order to ensure that serialized facts are consumable downstream. This can
  be removed with https://go-review.googlesource.com/c/tools/+/331789 merged.
* A minor refactoring to isolation the objdump settings in its own package.
  This was originally used to implement the sanity check above, but this
  information is now being passed another way. The minor refactor is preserved
  however, since it cleans up the code slightly and is minimal risk.

PiperOrigin-RevId: 382613300
2021-07-01 15:07:56 -07:00
Zach KoopmansandgVisor bot f033577349 [syserror] Update several syserror errors to linuxerr equivalents.
Update/remove most syserror errors to linuxerr equivalents. For list
of removed errors, see //pkg/syserror/syserror.go.

PiperOrigin-RevId: 382574582
2021-07-01 12:05:19 -07:00
Zach KoopmansandgVisor bot 895c2eaa09 [syserror] Update syserror to linuxerr for EACCES, EBADF, and EPERM.
Update all instances of the above errors to the faster linuxerr implementation.
With the temporary linuxerr.Equals(), no logical changes are made.

PiperOrigin-RevId: 382306655
2021-06-30 08:18:59 -07:00
Zach KoopmansandgVisor bot cd84634cc0 [syserror] Change syserror to linuxerr for E2BIG, EADDRINUSE, and EINVAL
Remove three syserror entries duplicated in linuxerr. Because of the
linuxerr.Equals method, this is a mere change of return values from
syserror to linuxerr definitions.

Done with only these three errnos as CLs removing all grow to a significantly
large size.

PiperOrigin-RevId: 382173835
2021-06-29 15:08:46 -07:00
Zach KoopmansandgVisor bot 45b64220cb [syserror] Add conversions to linuxerr with temporary Equals method.
Add Equals method to compare syserror and unix.Errno errors to linuxerr errors.
This will facilitate removal of syserror definitions in a followup, and
finding needed conversions from unix.Errno to linuxerr.

PiperOrigin-RevId: 380909667
2021-06-22 15:53:32 -07:00
Jamie LiuandgVisor bot 0e30fa99f7 Implement RENAME_NOREPLACE for all VFS2 filesystem implementations.
PiperOrigin-RevId: 377966969
2021-06-07 11:42:34 -07:00
Kevin KrakauerandgVisor bot d2eb68438d setgid directories for VFS1 tmpfs, overlayfs, and goferfs
PiperOrigin-RevId: 375780659
2021-05-25 13:21:52 -07:00
Zach KoopmansandgVisor bot d8f34027b3 [syserror] Split usermem package
Split usermem package to help remove syserror dependency in go_marshal.
New hostarch package contains code not dependent on syserror.

PiperOrigin-RevId: 365651233
2021-03-29 13:30:21 -07:00
Kevin KrakauerandgVisor bot e17fde45e5 setgid directory support in overlayfs
PiperOrigin-RevId: 363276495
2021-03-16 14:55:29 -07:00
Rahat MahmoodandgVisor bot 0aba93a173 Report filesystem-specific mount options.
PiperOrigin-RevId: 362406813
2021-03-11 16:49:36 -08:00
Bhasker HariharanandgVisor bot 311ac90a8a Add checklocks analyzer.
This validates that struct fields if annotated with "// checklocks:mu" where
"mu" is a mutex field in the same struct then access to the field is only
done with "mu" locked.

All types that are guarded by a mutex must be annotated with

// +checklocks:<mutex field name>

For more details please refer to README.md.

PiperOrigin-RevId: 360729328
2021-03-03 12:24:21 -08:00
Jamie LiuandgVisor bot d586c8b418 Use mapped device number + topmost inode number for all files in VFS2 overlay.
Before this CL, VFS2's overlayfs uses a single private device number and an
autoincrementing generated inode number for directories; this is consistent
with Linux's overlayfs in the non-samefs non-xino case. However, this breaks
some applications more consistently than on Linux due to more aggressive
caching of Linux overlayfs dentries.

Switch from using mapped device numbers + the topmost layer's inode number for
just non-copied-up non-directory files, to doing so for all files. This still
allows directory dev/ino numbers to change across copy-up, but otherwise keeps
them consistent.

Fixes #5545:
```
$ docker run --runtime=runsc-vfs2-overlay --rm ubuntu:focal bash -c "mkdir -p 1/2/3/4/5/6/7/8 && rm -rf 1 && echo done"
done
```

PiperOrigin-RevId: 359350716
2021-02-24 13:00:59 -08:00
Jamie LiuandgVisor bot d02c044eec Unconditionally check for directory-ness in overlay.filesystem.UnlinkAt().
PiperOrigin-RevId: 357106080
2021-02-11 19:10:22 -08:00
Ayush RanjanandgVisor bot 0d48402cbc [vfs] Make sticky bit check consistent with Linux.
Our implementation of vfs.CheckDeleteSticky was not consistent with Linux,
specifically not consistent with fs/linux.h:check_sticky().

One of the biggest differences was that the vfs implementation did not
allow the owner of the sticky directory to delete files inside it that belonged
to other users.

This change makes our implementation consistent with Linux.

Also adds an integration test to check for this. This bug is also present in
VFS1.

Updates #3027

PiperOrigin-RevId: 355557425
2021-02-03 22:44:51 -08:00