Commit Graph
258 Commits
Author SHA1 Message Date
Jamie LiuandgVisor bot 33513684bc Implement filesystem-only checkpointing.
- `runsc fscheckpoint` saves a filesystem checkpoint, analogous to `runsc
    checkpoint`. `-direct` and `-leave-running` flags are supported for
    compatibility with `runsc checkpoint`. `-save-restore-exec*` is currently
    not supported due to lack of a use case. `-compression` support is not
    planned (specific files in filesystem checkpoint images may use compression
    as appropriate, but this is an implementation detail).
    `-exclude-committed-zero-pages` is inapplicable.

  - `runsc create -fs-restore-image-path` restores a filesystem checkpoint. The
    `-fs-restore-direct` flag has the same effect as `runsc restore -direct`.
    The behavior of `runsc restore -background` is always in effect for
    filesystem checkpoints.

PiperOrigin-RevId: 885914969
2026-03-18 19:44:48 -07:00
Jamie LiuandgVisor bot 84bc4e3f8f Move vfs.RestoreID to checkpoint.ResourceID.
... and use it everywhere in preference to its string. This is to be able to
reliably inspect pgalloc.MemoryFile.ResourceID().Path in cl/879147587.

PiperOrigin-RevId: 883274090
2026-03-13 12:02:56 -07:00
Tao Lin 82961464b9 Add save/restore checks for non-4K page sizes
Add PageSize checks in Kernel.SaveTo() and Kernel.LoadFrom() to return
a clean error when save/restore is attempted with non-4K page sizes.
This is similar to the checks added for KVM and Systrap platforms.

Save/restore serialization has not been adapted for 64K pages yet,
so this gives a clear error message instead of a cryptic failure.
2026-03-04 14:00:13 -08:00
Jamie LiuandgVisor bot d7996a5d9b Remove "AddressSpace activation".
PiperOrigin-RevId: 869302553
2026-02-12 14:55:06 -08:00
Nayana BidariandgVisor bot a41a6099f9 Terminate connections only for restore (not for resume).
Previously, external connections were terminated during both restore and
resume operations, causing a reconnection after every resume. By limiting
termination to the restore only, connections now remain active during resumes
as intended.

Added tests to verify that resume does not terminate the connection.

PiperOrigin-RevId: 868830577
2026-02-12 14:35:26 -08:00
Jamie LiuandgVisor bot 04accba649 Suspend fdnotifier during save/restore.
The correctness of save/restore depends on the kernel object graph remaining
constant while it is being saved/restored. Allowing fdnotifier to send host FD
readiness notifications during save/restore violates this requirement.

PiperOrigin-RevId: 856472612
2026-01-14 21:00:40 -08:00
Jamie LiuandgVisor bot e7c865cc1d Automated rollback of changelist 832558564
PiperOrigin-RevId: 856413560
2026-01-14 16:23:46 -08:00
Shailend ChandandgVisor bot 1b8a025e4a Cleanup creds-related funcs and change CapError behavior
- Introduce Credentials.HasRootCapability().
 - Rename Credentials.HasCapability() to Credentials.HasSelfCapability().
 - Rename Task.HasCapability() to Task.HasSelfCapability().
 - Introduce inet.Namespace.HasCapability(ctx).
 - CapError(), invoked by unimplemented syscalls' stubs, now checks
   against the root userns.

All towards making it less easy to evaluate creds relative to self userns
instead of root userns in the future.

PiperOrigin-RevId: 853942212
2026-01-08 17:23:58 -08:00
Shailend ChandandgVisor bot 4c77fa8b9a Fix creds checks for SO_RCVBUFFORCE and UCOUNT_RLIMIT_NPROC
PiperOrigin-RevId: 853451466
2026-01-07 16:16:29 -08:00
Jimmy TranandgVisor bot 544a60277d kvm: RSEQ: Add RSEQ support
This change adds RSEQ support for platform/kvm. RSEQ is disabled by default.

To support RSEQ, the KVM platform must provide two key capabilities:
 (1) A stable, unique CPU ID.
 (2) A way to detect when a thread as been preempted.

This implementation provides the necessary support as follows:
CPU ID:
  - platform/kvm now advertises the KVM vCPU ID as the cpu_id

Preemption Detection:
  - Compares the last context the CPU ran against the current context being
 scheduled.
  - Compares the context's rseqCPU and CPU ID retrieved by the platform

To facilitate this, several new methods are introduced to the platform
interface and implemented by platform/kvm:
 - HasCpuNumbers()
 - NumCPUs()
 - DetectsCPUPreemption()
 - PreemptCpu()
 - PreemptAllCpus()

A new user-facing KVM specific option, use_cpu_numbers, is introduced to
effectively feature guard RSEQ. When use_cpu_numbers is true, vCPU IDs are
exposed to the guest, enabling RSEQ support. Setting it to false reverts to
the previous behavior and effectively disables RSEQ for applications that
rely on it.

PiperOrigin-RevId: 844846226
2025-12-15 11:14:18 -08:00
Nayana BidariandgVisor bot 725fa24e3e Remove usage of net-disconnect-ok flag.
The net-disconnect-ok flag was previously used only to cause a panic in the
beforeSave() method of TCP and unix connections if it was set to false.

Since this flag is now set to true by default, and this default setting causes
TCP and unix connections to always be aborted during the save operation, the
flag no longer serves its original purpose of conditionally preventing
connection termination. So, the flag's usage is removed.

PiperOrigin-RevId: 840433518
2025-12-04 15:47:30 -08:00
Jing ChenandgVisor bot 5475b737dd Implement /proc/sys/kernel/keys/maxkeys.
PiperOrigin-RevId: 836764402
2025-11-25 12:13:43 -08:00
Jamie LiuandgVisor bot 00290ceb77 Panic if transport.connectionlessEndpoint.baseEndpoint.receiver is mutated during save.
PiperOrigin-RevId: 832558564
2025-11-14 20:23:31 -08:00
Nayana BidariandgVisor bot 54f6111b83 Do not close processors during save, but instead close during restore.
Before this change, the processors were closed in beforeSave which caused the
packet processing for established connections to stop even in the case of
save/resume. Do not close in beforeSave, instead close these processors in
afterLoad for restore.

PiperOrigin-RevId: 821714849
2025-10-20 10:55:13 -07:00
Jamie LiuandgVisor bot 406172e308 pgalloc,stateio: implement async page saving
Aside from improving checkpointing performance by using AIO to better utilize
disk bandwidth, this makes it possible to parallelize writing pages with
scanning for zero pages (in a following CL).

As part of this, update and document ownership semantics for the state file,
pages metadata file, and pages file, with the following goals:

- Since io.WriteCloser.Close() may flush buffers, it must return a nil error
  before write success is reported

- The pages metadata file is closed while async page saving is in progress (to
  hide the latency of the former)

PiperOrigin-RevId: 814315485
2025-10-02 11:32:53 -07:00
gVisor bot 2355941035 Log the raw argv when launching processes
... so ["args", "with spaces"] isn't confused with ["args", "with", "spaces"]

PiperOrigin-RevId: 810144014
2025-09-22 14:00:22 -07:00
Shailend ChandandgVisor bot e5ffc69c6f Fix incorrect lock order in execve(2) around TaskSet.mu
FSContext.mu is made a lockdep mutex. Fixes the following cycle detected by
syzcaller:

goroutine 1 (execve):        fs.mu.Lock() -> ts.mu.Rlock()
goroutine 2 (CreateProcess): ts.mu.Lock() -> t.mu.Lock()
goroutine 3 (unshare):       t.mu.Lock() -> fs.mu.Lock()

PiperOrigin-RevId: 805914251
2025-09-11 11:18:54 -07:00
Nayana BidariandgVisor bot c52821b3e0 Remove old NICs and routes during save/restore.
During restore there will be new NICs and routes created based on the network
config. Close these old NICs and routes in beforeSave() only for save/restore.
For save/resume, do not close them.

As new link endpoints are created during restore, there is no need to start
the associated old processor goroutines in afterLoad. Start them only for
save/resume.

PiperOrigin-RevId: 804994281
2025-09-09 11:33:49 -07:00
gVisor bot 531b34cc6f Merge pull request #12055 from tianyuzhou95:albert/refcount
PiperOrigin-RevId: 800675291
2025-08-28 17:27:42 -07:00
Shailend ChandandgVisor bot 1b546ce933 Fix race between unshare(2) and execve(2).
There are two issues being fixed: 1) checkAndPreventSharingOutsideTG() was
accessing t.fsContext without grabbing t.mu and thus causing a data race with
a concurrent unshare and 2) the concurrent unshare might present an incomplete
view of the shared fscontext and cause execve to incorrectly conclude that it
was shared outside the thread group.

Reported-by: [email protected]
Reported-by: [email protected]
PiperOrigin-RevId: 800327461
2025-08-27 23:52:21 -07:00
Tianyu Zhou 906e81df67 pkg/sentry: add cleanup to avoid refcount leak
Currently, on certain error paths during task creation (e.g., when
"runsc exec" fails), we do not properly handle the refcount of the
mntns/FSContext, leading to a refcount leak. This patch adds cleanup
that would be released before the reference ownership is transferred
to callee, ensuring that the refcount is correctly decremented.

Fixes #12054

Signed-off-by: Tianyu Zhou <[email protected]>
2025-08-20 09:42:27 +08:00
Shailend ChandandgVisor bot 2c6185b9d1 Support privileged executables inside the sandbox
There is already some support for privileged executables before this change:
file capabilities were taken into account when creating new processes inside
the sandbox from external instigation (but not during execve(2)). set-user-id
and set-group-id bits were never taken into account, and the Sentry behaved
as if NO_NEW_PRIVS is always true. After this change, execve(2) and the
external Exec entry point both take the set-user(group)-id bits and file
capabilities into account.

Because NO_NEW_PRIVS can no longer be assumed to be always set, a couple of
extra checks to prevent privilege elevation during execve(2) are needed:
the presence of a ptracer and the use of a shared fsContext. Moreover,
execve had to be serialized with seccomp(2) when it is syncing filters to
all threads in a group. Serializing execve with PTRACE_ATTACH and seccomp
required some Task runState gymnastics.

Task dumpability is reset when privilege elevation takes place and privilege
elevation is denied for binaries living on nosuid mounts. To fix an old bug
where some aux vectors were populated using data from the old pre-execve
creds, the computation of the (file-privilege-augmented) creds during execve
now takes place before the stack for the new program is set up.

gvisor users who thus far have exec'd into the sandbox with UID as (sandbox)
root will lose the caps an all-powerful namespace root'd have if: 1) the binary
is a suid/guid binary 2) the owner of the binary is host root and there is
no mapping for host root in the host user namespace of the sandbox. To avoid
this surprise, the suid/sgid bits are ignored by default. Users can opt-in
via the --allow-suid flag.

One result of this change is that sudo now works inside the sandbox.

PiperOrigin-RevId: 794414101
2025-08-12 23:07:38 -07:00
Ayush RanjanandgVisor bot 575c400d3e Wait for main MF loading to start before writing to it during restore.
When using async page loading (the checkpoint image has compression=none), the
kernel and memory files are loaded in parallel. A step in kernel loading tries
writing to the main MemoryFile. Ensure that step happens after the main
MemoryFile has started being loaded (i.e. mainMF.LoadFrom() method has returned
successfully). MemoryFile.asyncPageLoad field needs to be initialized before
it can be written to.

Fixes #11842

PiperOrigin-RevId: 779995419
2025-07-07 01:22:24 -07:00
Andrei VaginandgVisor bot 49338ea3e5 Implement setns for pid namespaces
PiperOrigin-RevId: 776238354
2025-06-26 12:33:32 -07:00
Lucas ManningandgVisor bot 02c0c4e8bd Add support for executing a binary before saving and after restoring.
PiperOrigin-RevId: 764936811
2025-05-29 16:49:27 -07:00
Nayana BidariandgVisor bot 2276dd10f0 Start TCP dispatchers after endpoints are completely loaded during restore.
- During restore if endpoints' states are not loaded before starting
dispatchers, then the incoming packets will be queued and the dispatcher will
try to send the packets, which will result in a panic as the endpoint might
still be in an invalid state (eg: initial).
- To avoid this, wait for all the endpoints to be loaded completely before
starting the dispatchers by calling AsycnLoading.Wait() in stack.Restore() and
remove this from kernel.LoadFrom()
- Added a test to check save restore of multiple(100) listening sockets.

PiperOrigin-RevId: 762010964
2025-05-22 10:07:11 -07:00
Ayush RanjanandgVisor bot 98e6c3a16b Fix handling of file capabilities.
All the following changes are compatible with what Linux does.
- Do not attempt to apply file capabilities when it is not present.
- If the rootID specified in v3 file capability struct does not own the
  current userns, then file capabilities are not applied.
- While applying file capabilities, EPERM is only returned if
  VFS_CAP_FLAGS_EFFECTIVE is set.
- Re-raise capabilities of root user as per capabilities(7). Compare
  security/commoncap.c:handle_privileged_root().

PiperOrigin-RevId: 761725759
2025-05-21 17:07:56 -07:00
Ayush RanjanandgVisor bot cd9d844650 Use vfs_cap_data and vfs_ns_cap_data structs defined in linux header.
This allows us to use the generated `Marshal/Unmarshal` functions and get rid
of the manual binary encoding/decoding.

Also fixed up vfs.VfsCapDataOf() to emulate Linux behavior more accurately.
It now returns linuxerr errors instead of fmt.Errorf()s, because in future
changes this code will be used on syscall paths.

PiperOrigin-RevId: 754101576
2025-05-02 12:52:31 -07:00
Ayush RanjanandgVisor bot 8334dc5849 Delete PagesFileLoader interface.
This change does not change behavior, but improves readability.
- The PagesFileLoader interface methods were over-fitted to some of their
  implementations. For instance, KickoffPrivate() was very specific to the
  implementation of separatePagesFileLoader and the timing of its creation.
  In PagesFileLoader.Load(), mainMf parameter was only needed by
  singleStateFilePFL implementation and background parameter was only needed
  by separatePagesFileLoader implementation. It is tough to build a clean
  interface around the 2 kinds of page loading we support without leaking
  implementation details to the API.
- It was not readable/obvious why Kernel.LoadFrom() was calling
  pfl.KickoffPrivate() in the beginning of the function. That call depends on
  the fact that main MemoryFile load was already started in the background
  before the call to Kernel.LoadFrom(). Then the call to pfl.Load() was
  confusing, especially because it came after the call to KickoffPrivate().
- singleStateFilePFL did not own the reader (state file FD) while
  separatePagesFileLoader owned and closed the FDs it used to restore the
  MemoryFiles. This created another asymmetry between the two. The FD
  ownership details could not be captured in the interface.
- Removed the interface. Replaced it with concrete type AsyncMFLoader. This
  has the added benefit of avoiding interface method dispatch cost. Only when
  AsyncMFLoader == nil (when MemoryFile contents are in the state file) does
  Kernel.LoadFrom() try loading the memory files using the conventional method
  of loading them from the state file synchronously. This makes sense and is
  readable because all consumption from the state file FD happens in one place
  in a transparent manner.
- separatePagesFileLoader.KickoffPrivate() was being called multiple times due
  to separatePagesFileLoader.Load() also calling it for completeness. Now
  runsc restorer calls it explicitly only for AsyncMFLoader and only calls it
  once. It allows us to get rid of loadPrivateMFs sync.Once.
- AsyncMFLoader provides clear WaitMetadata() and WaitPages() functions. These
  are more readable.

Future work: I think all of MemoryFile saving/loading logic should be moved to
the pgalloc package. It has not dependency on Kernel save/load. Kernel and
MemoryFile save/load happen independently in discrete steps irrespective of
save/load configurations.

PiperOrigin-RevId: 745187478
2025-04-08 10:03:23 -07:00
Etienne PerotandgVisor bot c64198d84b Read pages from the main MemoryFile as early as possible during restore
This change modifies the sandbox restore process such that if the memory
pages are stored as separate files, their contents are optimistically read
from these files as soon as possible during the sandbox restore process,
as opposed to the previous behavior where they were read only after the last
container of the sandbox had been restored.

When memory page data is stored as separate files, the process of restoring
multiple `MemoryFile`s is a bit more intertwined than it appears, for two
reasons:

- The pages metadata file stores data for all `MemoryFile`s one after the
  other. So we must also plumb the pages metadata file reader that is used
  for reading the main `MemoryFile` metadata to the code that also loads the
  private `MemoryFile`s, and ensure that these operations are correctly
  serialized, since the primary `MemoryFile` metadata comes earlier in the
  file.
- The `MemoryFile` page contents are all in the same file, and the byte offset
  within this file at which each each `MemoryFile` begins must be known before
  kicking off async loading of that MemoryFile.

So this change introduces a `PagesFileLoader`, which is meant to be a
thread-safe struct that keeps track of this process. It owns the FDs for the
pages and page metadata files and handles the serialization of the operations
executed using these FDs.

Support for the previous checkpoint/restore format (with all data in a single
file) is maintained using a synchronous alternative that implements the same
interface but simply loads everything from the shared state file reader when
the time to do so comes around.

PiperOrigin-RevId: 743727664
2025-04-03 15:59:05 -07:00
gVisor bot 2504c29b77 Merge pull request #11473 from Champ-Goblem:shim-add-cgroup-v2-metrics-support
PiperOrigin-RevId: 730560110
2025-02-25 14:52:09 -08:00
Fabricio VoznikaandgVisor bot 9c040d7208 Remove checkpoint_count from runsc wait --checkpoint
This is done because external callers are not able to know
the snapshot generation number from the outside.

PiperOrigin-RevId: 707979556
2024-12-19 11:48:10 -08:00
Nayana BidariandgVisor bot 1bc1bb3b81 Restore listening connections when netstack s/r is enabled.
This CL restores the listening connections when netstack s/r is enabled.
The changes include:
- New method as a workaround to replace the new routes and nics to the loaded
stack after restore.
- New Restore() for transport layer protocols to restore the protocol level
background workers.
- Adds afterLoad() method for fdbased processors.
- Adds a test to verify listening connection is restored after checkpointing
with netstack s/r enabled.
- Few other changes to save restore fields to enable netstack s/r.

PiperOrigin-RevId: 698453124
2024-11-20 11:13:57 -08:00
Jamie LiuandgVisor bot cbaca95f5c kernel: improve tcpip.Timer implementation
- Move ktime.VariableTimer to kernel.timekeeperTcpipTimer, its only use case.
  This allows timekeeperTcpipTimer to use concrete types kernel.timekeeperClock
  and ktime.SampledTimer instead of ktime.Clock and ktime.Timer, saving a tiny
  amount of memory (interface values consist of two pointers) and CPU (for
  interface method calls).

- Fix a bug where timekeeperTcpipTimer expiration can cancel a racing call to
  timekeeperTcpipTimer.Reset() (see use of new field
  timekeeperTcpipTimer.resets).

- Define Listener.NotifyTimer directly on timekeeperTcpipTimer (dropping
  ktime.functionNotifier), and move goroutine spawning from the anonymous
  function in ktime.AfterFunc() into timekeeperTcpipTimer.NotifyTimer(). This
  slightly simplifies the control flow and saves an allocation for the
  anonymous function object.

- Use monotonicClock rather than realtimeClock. It doesn't make sense for
  time-of-day clock adjustments to affect netstack timeouts, and this is
  consistent with tcpip.stdClock => time.AfterFunc => runtime.timer.

PiperOrigin-RevId: 695504159
2024-11-11 15:38:55 -08:00
Jamie LiuandgVisor bot b58ec99982 kernel: drive all CPU timers in CPU clock ticker
gVisor currently implements CPU clocks as follows:

- A per-sentry "CPU clock ticker goroutine"
  (task_sched.go:Kernel.runCPUClockTicker()) periodically advances
  Kernel.cpuClock, causing it to serve as a very coarse but inexpensive
  monotonic wall clock (that happens to be suspended when no tasks are
  running).

- Task goroutines observe the most recent value of Kernel.cpuClock when
  changing state (Task.gosched.Timestamp), and use it to compute the number of
  CPU clock ticks that have elapsed in a given state. Thus, task CPU clocks are
  approximately based on the wall time during which they were marked as
  running.

- ITIMER_VIRTUAL, ITIMER_PROF, and RLIMIT_CPU are checked by the CPU clock
  ticker goroutine after advancing Kernel.cpuClock. POSIX interval timers and
  timerfds check CPU clocks (taskClock/tgClock) in ktime.SampledTimer
  goroutines.

This has three major problems:

- ktime.SampledTimer goroutines for CPU clock timers run concurrently with the
  CPU clock ticker, and are not informed as to when corresponding tasks start
  or stop running (due to overhead on the task execution critical path), so
  they can't determine when CPU clocks have/will advance; instead, they simply
  poll CPU clocks on a period equal to that of the represented timer, resulting
  in significant overhead for CPU-clock-based POSIX interval timers and
  timerfds.

- For the same reason, CPU clock interval timers and timerfds may expire much
  later than when the CPU clock is actually incremented; in the interval timer
  case, this can result in notification signals being sent long after tasks
  have stopped running. (This is the same problem as in b/116538398, which
  motivated the special-casing of ITIMER_VIRTUAL and ITIMER_PROF described
  above, but applied to POSIX interval timers.)

- The sentry does not impose a limit on the number of tasks that may be
  concurrently marked running, so if more tasks are marked running than the
  number of CPUs advertised to applications, application CPU utilization can
  appear to exceed 100%.

This CL fixes these problems by introducing explicit per-Task and ThreadGroup
CPU clocks, directly advancing (up to Kernel.applicationCores of) them in the
CPU clock ticker, and directly expiring CPU timers when doing so. Itimer and
RLIMIT_CPU timers lose their special-casing and instead behave like other CPU
timers (see task_acct.go). Kernel.cpuClock is still required, but only for the
sentry watchdog.

Minor cleanup changes:

- Gather all stateify hooks in kernel_state.go.

- Replace kernel.randInt31n() with math/rand/v2, which fixes the same problem
  (https://go.dev/blog/randv2#problem.rand).

Test workload:

```
#include <err.h>
#include <signal.h>
#include <time.h>
#include <chrono>
#include <thread>

constexpr int kNumTimers = 1000;
constexpr long kTimerPeriodNS = 10000000;

int main(int argc, char** argv) {
  for (int i = 0; i < kNumTimers; i++) {
    struct sigevent sev = {.sigev_notify = SIGEV_NONE};
    timer_t timerid;
    if (timer_create(CLOCK_THREAD_CPUTIME_ID, &sev, &timerid) < 0) {
      err(1, "timer_create failed");
    }
    struct itimerspec it = {
      .it_interval = {0, kTimerPeriodNS},
      .it_value = {0, kTimerPeriodNS},
    };
    if (timer_settime(timerid, 0, &it, nullptr) < 0) {
      err(1, "timer_settime failed");
    }
  }
  std::this_thread::sleep_for(std::chrono::seconds(5));
  return 0;
}
```

Before this CL:
```
# /usr/bin/time ./runsc --ignore-cgroups --platform kvm --network none do $(pwd)/workloads/threadcputimers
1.50user 0.17system 0:05.25elapsed 31%CPU (0avgtext+0avgdata 35792maxresident)k
0inputs+184outputs (10major+20889minor)pagefaults 0swaps
```

After this CL:
```
# /usr/bin/time ./runsc --ignore-cgroups --platform kvm --network none do $(pwd)/workloads/threadcputimers
0.10user 0.12system 0:05.22elapsed 4%CPU (0avgtext+0avgdata 34040maxresident)k
0inputs+192outputs (6major+20929minor)pagefaults 0swaps
```

PiperOrigin-RevId: 695198313
2024-11-10 22:19:30 -08:00
Jamie LiuandgVisor bot 5850096133 ktime: support varying Timer implementations
- Rename Timer to SampledTimer.

- Move all Clock methods except Now to new interface SampledClock.

- Move SampledTimer's exported methods (except SetClock) to new interface
  Timer. Combine Swap and SwapAnd into Set to reduce the number of redundant
  methods that must be implemented.

- Add interface method Clock.NewTimer.

This is in preparation for cl/693856539, which adds a second Timer
implementation.

PiperOrigin-RevId: 694299679
2024-11-07 17:19:25 -08:00
Jamie LiuandgVisor bot 19f12e64c8 Move //pkg/sentry/kernel/time to //pkg/sentry/ktime.
This avoids needing to rename it everywhere it's imported.

PiperOrigin-RevId: 693930089
2024-11-06 18:13:51 -08:00
Ayush RanjanandgVisor bot b835273cbe Add more context to errors during restore.
This will help with debugging restore failures.

PiperOrigin-RevId: 693436013
2024-11-05 12:18:57 -08:00
Fabricio VoznikaandgVisor bot 047eac06fa Move S/R code to separate file
Move Kernel S/R code to kernel_restore.go.

PiperOrigin-RevId: 691441815
2024-10-30 09:15:35 -07:00
Ayush RanjanandgVisor bot ad3bb4c82d Rename OCIEnviron to SpecEnviron.
PiperOrigin-RevId: 684626452
2024-10-10 17:12:03 -07:00
cweld510 28252765c4 style feedback: remove newlines, fix import, remove stray comment 2024-10-07 22:39:13 +00:00
cweld510 95341b4758 Add and implement option to close unsaveable gofer-backed unix sockets
on save
2024-10-04 20:13:38 +00:00
Ayush RanjanandgVisor bot 7adf2a41a8 Add kernel.Saver.OCIEnviron().
PiperOrigin-RevId: 682080366
2024-10-03 16:48:03 -07:00
Nicolas LacasseandgVisor bot 1a7df035d8 Clean up host.TTYFileOperations.
We used to track the foreground process group & session on the
TTYFileOperation, but these are already tracked in kernel.TTY.ThreadGroup.

So remove TTYFileOperations.fgProcessGroup and .session, and replace them with
a kernel.TTY.

This is analogous to how sentry-internal tty's already work.

Updates #10925

PiperOrigin-RevId: 681957240
2024-10-03 11:25:52 -07:00
Nicolas LacasseandgVisor bot 70c1021f58 Implement /dev/tty for donated host TTYs
Fixes #10925

PiperOrigin-RevId: 681684673
2024-10-02 19:40:43 -07:00
Jamie LiuandgVisor bot cb0396600e kernel: fix lock order inversion in ThreadGroup.Release()
PiperOrigin-RevId: 681199251
2024-10-01 16:10:15 -07:00
Jamie LiuandgVisor bot 76a011743d kernel: add ThreadGroup.signalLock()
This allows "remote" locking of ThreadGroup.signalHandlers.mu without needing
to lock TaskSet.mu, analogously to Linux's lock_task_sighand().

This reveals a bug: kernel.Task.sendSignal[Timer]Locked() unintentionally
requires TaskSet.mu to be locked since it reads Task.exitState. To fix this,
use atomic memory operations on Task.exitState when required.

PiperOrigin-RevId: 681128063
2024-10-01 12:48:10 -07:00
Jamie LiuandgVisor bot 20bc6bdeb0 pgalloc: integrate async page loading
When a pages file is provided to `runsc restore`, reads from that file are
asynchronous (via statefile.AsyncReader) in order to maximize throughput.
However, all such reads must complete before Kernel.LoadFrom() returns, so
applications cannot execute before MemoryFile loading is complete. The main
objective of this CL is to allow reads to continue after Kernel.LoadFrom()
returns, allowing applications to execute while MemoryFile loading is still in
progress. This behavior is user-visible: it affects whether deleting the pages
file frees disk space immediately on POSIX filesystems, may affect whether
deletion is possible on non-POSIX filesystems, and prevents unmounting
regardless. Thus it is flag-guarded as `runsc restore --background`.

MemoryFile ranges that have yet to be loaded, but that are being waited-for by
applications, should be prioritized over ranges for which no application is
waiting. This requires that application requests for data (calls to
MemoryFile.(memmap.File).DataFD/MapInternal()) are able to determine which
ranges have not yet been loaded, request reads for such ranges with elevated
priority, and wait for only those reads to be completed; none of these are
supported by the existing statefile.AsyncReader.

Thus:

- Add //pkg/sentry/pgalloc/aio, which provides an async I/O API that is
  designed to be easily implementable using a goroutine pool, Linux native AIO,
  or io_uring, though only includes a goroutine pool implementation. (io_uring
  is widely disabled due to security vulnerabilities. In my testing, Linux
  native AIO is slower than the goroutine pool, but this may change with lower
  GOMAXPROCS which needs further testing.)

- Move I/O scheduling into pgalloc: introduce an async page loader goroutine
  that is started by MemoryFile.LoadFrom() when async page loading is requested
  (implicitly, via the existence of a pages file), which is responsible for
  driving submission of read requests and handling their completions.

PiperOrigin-RevId: 679321884
2024-09-26 15:51:13 -07:00
Nayana BidariandgVisor bot 2836a4a651 Mark netstack as save and use it only in tests
- Adds a new flag which will enable netstack s/r. When the flag is not enabled,
there is no change in the existing behavior. The flag will be enabled only in
tests to verify the s/r functionality of netstack.
- Some additional fields in netstack were causing panic when netstack is
save/restored. Such fields are marked as 'save'/'nosave' accordingly to resolve
the panic.

PiperOrigin-RevId: 668566657
2024-08-28 12:49:43 -07:00
Ayush RanjanandgVisor bot c8e4527395 Parallelize MemoryFile save and kernel save.
This compliments f282f9775d ("Load pgalloc.MemoryFile and kernel parallely
with compression=none mode.")

This is a performance optimization. Kernel and MemoryFile are saved
independently. The save can be done in parallel when using --compression=none
because the kernel and MemoryFile are being saved in different files.

PiperOrigin-RevId: 668128205
2024-08-27 14:03:15 -07:00