# How Cube-Agent Initializes the Guest Environment in CubeSandbox MicroVMs

> Discover how cube-agent initializes the guest environment in CubeSandbox MicroVMs. Learn about mounted filesystems, cgroup config, PTY setup, hostname setting, and ttrpc server startup.

- Repository: [Tencent Cloud/CubeSandbox](https://github.com/TencentCloud/CubeSandbox)
- Tags: internals
- Published: 2026-07-05

---

**Cube-Agent runs as PID 1 inside every CubeSandbox MicroVM, mounting pseudo-filesystems, configuring cgroups and PTY devices, setting the hostname, and finally starting the ttrpc server to accept commands from the host.**

Cube-Agent serves as the init process for MicroVMs in the TencentCloud/CubeSandbox project, transforming a minimal Linux kernel into a functional container host. When the binary starts as `/sbin/init`, it executes a deterministic initialization sequence defined in [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs) that prepares the guest file system, fixes device nodes, and establishes communication with the CubeShim on the host side via vsock.

## Detecting Init Mode and Early Setup

The initialization path begins with detecting whether the agent is running as the system's first process.

### Checking for PID 1

Immediately after parsing command-line arguments and creating the global `AGENT_CONFIG`, the agent checks its process ID to determine if it should behave as an init system:

```rust
let init_mode = unistd::getpid() == Pid::from_raw(1);   // agent/src/main.rs L58-L60

```

When `init_mode` evaluates to `true`, the agent knows it must mount essential file systems and configure the environment rather than simply connecting to an existing sandbox.

### Early Logger Configuration

Before the regular logger (which depends on parsing `/proc/cmdline`) is ready, the agent creates a temporary logger to capture early initialization messages:

```rust
let (logger, logger_async_guard) = logging::create_logger(NAME, "agent", slog::Level::Info, writer);

```

This ensures that any failures during the critical mount operations or cgroup setup are visible in the logs.

## Mounting Essential Pseudo-Filesystems

With the early logger active, the agent proceeds to prepare the root file system by mounting the kernel pseudo-file systems required for a functional Linux environment.

### The `general_mount` Function

In [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs) at lines 73-77, the agent calls `general_mount` to set up `proc`, `sysfs`, and `tmpfs`:

```rust
general_mount(&logger)?;   // agent/src/main.rs L73-L77

```

This function, typically defined in [`agent/src/mount.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/mount.rs), creates the `/proc`, `/sys`, and `/dev` hierarchies that user-space tools and container runtimes expect.

### Executing `/etc/rc.local`

After basic mounts are complete, the agent checks for and executes any custom initialization script provided by the guest image:

```rust
enable_rc_local().await;   // agent/src/main.rs L80-L88

```

This optional hook allows image builders to perform custom setup before the sandbox RPC server starts.

## Core Guest Initialization via `init_agent_as_init`

The heart of the guest environment bootstrapping occurs in the `init_agent_as_init` function, invoked at lines 86-88 of [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs):

```rust
init_agent_as_init(&logger, AGENT_CONFIG.read().await.unified_cgroup_hierarchy)?; // agent/src/main.rs L86-L88

```

This function, spanning lines 311-342 in [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs), performs several critical system configuration tasks.

### Cgroup Hierarchy Setup

First, the agent mounts the cgroup file system required by container runtimes:

```rust
cgroups_mount(logger, unified_cgroup_hierarchy)?;

```

The `unified_cgroup_hierarchy` boolean, parsed from the kernel command line via `AgentConfig`, determines whether to use cgroup v2 (unified) or a hybrid layout.

### PTY Device Node Fixes

To ensure proper terminal handling, the agent removes the stale `/dev/ptmx` and creates a symbolic link to the correct PTY multiplexor:

```rust
fs::remove_file(Path::new("/dev/ptmx"))?;
unixfs::symlink(Path::new("/dev/pts/ptmx"), Path::new("/dev/ptmx"))?;

```

This fixes the pseudo-terminal infrastructure that containers rely on for interactive shells and log streaming.

### Session and Terminal Configuration

The agent creates a new session, sets the controlling terminal, and establishes a minimal PATH:

```rust
unistd::setsid()?;
unsafe { libc::ioctl(std::io::stdin().as_raw_fd(), libc::TIOCSCTTY, 1); }
env::set_var("PATH", "/bin:/sbin/:/usr/bin/:/usr/sbin/");

```

The `setsid()` call makes the agent a session leader, while the `TIOCSCTTY` ioctl associates the standard input with the controlling terminal, ensuring proper job control and signal handling.

### Hostname and Environment Setup

Finally, the agent reads `/etc/hostname` and sets the system hostname:

```rust
let hostname = std::fs::read_to_string("/etc/hostname")
    .unwrap_or_else(|_| String::from("localhost"))
    .split(' ')
    .next()
    .unwrap_or("localhost")
    .trim();
if unistd::sethostname(OsStr::new(hostname)).is_err() {
    warn!(logger, "failed to set hostname");
}

```

This configures the UTS namespace identity that containers will inherit.

## Launching the Sandbox RPC Server

With the guest environment fully prepared, the agent enters the main async routine `real_main` and starts the sandbox RPC server:

```rust
start_sandbox(&logger, &config, init_mode, &mut tasks, shutdown_rx.clone()).await?; // agent/src/main.rs L236-L240

```

The `start_sandbox` function creates the `Sandbox` object, registers signal handlers, launches the uevent watcher, and starts the ttrpc server listening on the guest-side vsock. At this point, the MicroVM is ready to accept commands from CubeShim on the host, including container creation and execution requests.

## Summary

- **Cube-Agent acts as PID 1** in every CubeSandbox MicroVM, detecting init mode by checking if `unistd::getpid()` equals 1.
- **Early file system setup** involves mounting `proc`, `sysfs`, and `tmpfs` via `general_mount` before parsing kernel command-line arguments.
- **Guest preparation** in `init_agent_as_init` mounts cgroup hierarchies, fixes PTY device nodes at `/dev/ptmx`, establishes a controlling terminal with `setsid()` and `ioctl(TIOCSCTTY)`, and sets the hostname from `/etc/hostname`.
- **RPC initialization** occurs via `start_sandbox`, which creates the sandbox object and starts the ttrpc server for host communication.

## Frequently Asked Questions

### What is the role of cube-agent in CubeSandbox?

Cube-Agent serves as the init process (PID 1) and runtime agent for CubeSandbox MicroVMs. It initializes the guest environment by mounting essential file systems, configuring cgroups and terminals, and maintaining an RPC connection with the host-side CubeShim component to manage container lifecycle operations.

### How does cube-agent detect it is running as the init process?

The agent detects init mode by comparing the current process ID to 1 using `unistd::getpid() == Pid::from_raw(1)` in [`agent/src/main.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/agent/src/main.rs). When this condition is true, the agent executes the full initialization sequence including file system mounts and device node configuration rather than operating in agent-only mode.

### What pseudo-filesystems does cube-agent mount during initialization?

During initialization, cube-agent mounts `proc`, `sysfs`, and `tmpfs` through the `general_mount` function, followed by the cgroup hierarchy via `cgroups_mount`. These mounts provide the kernel interfaces and temporary storage required for process management, hardware discovery, and container resource control.

### Why does cube-agent need to fix the PTY device nodes?

Cube-Agent removes the static `/dev/ptmx` file and replaces it with a symbolic link to `/dev/pts/ptmx` to ensure proper pseudo-terminal multiplexing. This fix is necessary because the initial root file system may contain stale device nodes, and containers require functional PTY infrastructure for interactive terminals and log streaming.