Skip to content

LC-X5 Configuration and lzc-thor Usage ​

After flashing the Lc-X5, you can use lzc-thor to complete system initialization, MGBE network testing, VNC configuration, and disk management.

Except for viewing help, all commands in this document are recommended to be executed using sudo. First, use the following command to verify the current system's supported commands:

bash
sudo lzc-thor help

Command Quick Reference ​

Use scenariosCommand
Complete the routine initialization of the new devicesudo lzc-thor all
Install JetPack and monitoring tools separatelysudo lzc-thor packages
Fix the machine and network card identities of the cloned systemsudo lzc-thor clone-identity
Install Docker and NVIDIA Container Runtimesudo lzc-thor docker
Install the standalone docker-compose commandsudo lzc-thor docker-compose
Disable Ubuntu automatic upgradessudo lzc-thor disable-upgrades
Configure MGBE performance parameterssudo lzc-thor mgbe
Configure or execute MGBE bandwidth testsudo lzc-thor mgbe serve ...、sudo lzc-thor mgbe client ...
Configure timezone, time synchronization, maximum frequency, and Firefoxsudo lzc-thor startup
Install and start lzc-ai-agentsudo lzc-thor agent
Configure desktop VNCsudo lzc-thor vnc ...
Expand the root filesystem on the current system disksudo lzc-thor resizefs
Establish a read-only APP recovery system and LVM runtime systemsudo lzc-thor provision ...
Add a new NVMe whole disk to the root filesystemsudo lzc-thor expand-lvm ...
Recover factory operating system from APP recoverysudo lzc-thor factory-reset ...

vnc- MGBE test, resizefs, provision, expand-lvm, and factory-reset are not included in all; they must be executed separately as needed.

Rapid Initialization for New Devices ​

Using Default User ​

bash
sudo lzc-thor all

The command executes in the following order:

  1. Install JetPack, compilation tools, and GPU monitoring tools.
  2. Regenerate the machine identity of the cloned system and configure a stable, unique Ethernet MAC address for each device.
  3. Install Docker CE, Buildx, Compose plugin, and NVIDIA Container Toolkit.
  4. Install the independent /usr/bin/docker-compose.
  5. Disable Ubuntu automatic upgrades.
  6. Configure threaded NAPI and IOMMU DMA-FQ for all discovered MGBE interfaces, and run jetson_clocks.
  7. Configure the timezone, network time synchronization, enable jetson_clocks and Firefox to start at boot.
  8. Install and start lzc-ai-agent.

By default, the nvidia user is added to the docker group. After full initialization, it is recommended to restart the device to ensure that machine identity, network interface identity, and user group configurations take effect. After re-login, you can execute docker ps to verify Docker permissions.

Specify Docker User ​

If the regular login user on the system is not nvidia, use --docker-user to specify the user:

bash
sudo lzc-thor all --docker-user ubuntu

Also supports the following equivalent formulations:

bash
sudo lzc-thor all --user ubuntu
sudo lzc-thor all ubuntu

lzc-thor-init-all The equivalent entry point for lzc-thor all:

bash
sudo lzc-thor-init-all --docker-user ubuntu

General Configuration Commands ​

help: View command help ​

bash
sudo lzc-thor help
sudo lzc-thor --help

When viewing the detailed usage of a command with parameters, place --help after the corresponding command:

bash
sudo lzc-thor clone-identity --help
sudo lzc-thor mgbe serve --help
sudo lzc-thor provision --help
sudo lzc-thor expand-lvm --help
sudo lzc-thor factory-reset --help

packages: Install Jetson Software Package ​

bash
sudo lzc-thor packages

This command installs the following packages via apt:

  • nvidia-jetpack: Jetson platform software stack.
  • build-essential: Common compilation tools.
  • nvitop, gpustat, nvtop: GPU status monitoring tools.

This command is suitable for scenarios where only these packages need to be reinstalled or repaired, without performing a full initialization. The command has no additional parameters.

clone-identity: Repair cloned device identity ​

After cloning multiple LC-X5 devices from the same source disk, devices may share identical /etc/machine-id, NetworkManager keys, or wired network identities, leading to DHCP and local network device recognition issues.

Preview the operations that will be performed:

bash
sudo lzc-thor clone-identity --dry-run

Confirm and execute the repair, then restart after completion:

bash
sudo lzc-thor clone-identity
sudo reboot

This command will regenerate /etc/machine-id, delete the NetworkManager host key introduced by cloning, and configure the existing Ethernet connection to use a stable local management MAC generated per-device. By default, it only reloads the NetworkManager configuration and does not restart active network connections.

If operating directly from the local console and acceptable to have the network temporarily interrupted, this can be applied directly:

bash
sudo lzc-thor clone-identity --apply-now

--apply-now will restart NetworkManager, and the SSH session may disconnect immediately. When operating via SSH, prefer commands without this parameter, and then restart the device.

Available parameters:

ParametersDescription
--apply-nowRestart NetworkManager immediately after writing the configuration.
--no-machine-idDo not regenerate /etc/machine-id.
--no-profile-updateDo not modify the existing NetworkManager connection configuration.
--dry-runShow only the schedule, do not modify the system.

When maintaining a cloned system that is mounted but not running, use LZC_THOR_ROOT to specify its root directory. In offline mode, only files under this directory are modified, and NetworkManager of the current system is not affected.

bash
sudo LZC_THOR_ROOT=/mnt/thor-root lzc-thor clone-identity

docker: Install Docker and NVIDIA Runtime ​

Install only Docker without modifying any user groups:

bash
sudo lzc-thor docker

Allow specifying users to use Docker without sudo:

bash
sudo lzc-thor docker --docker-user ubuntu

--user ubuntu And writing ubuntu directly is an equivalent approach. This command does the following:

  • Configures the Docker official apt software repository.
  • Installs Docker CE, Docker CLI, containerd, Buildx, and Compose plugins.
  • Installs NVIDIA Container Toolkit and configures the NVIDIA runtime as the default Docker runtime.
  • Enables and restarts docker.service.
  • When specified, adds the user to the docker group.

After modifying the user group, existing login sessions typically require exiting and relogging in to obtain the new permissions.

docker-compose: Install standalone Compose command ​

bash
sudo lzc-thor docker-compose
docker-compose version

This command downloads the Linux aarch64 binary from the latest GitHub release of Docker Compose, verifies .sha256, and installs it into /usr/bin/docker-compose. It coexists with the docker compose plugin provided by the Docker package.

The device must have access to GitHub. This command always retrieves the latest version available at runtime and does not support version selection parameters.

disable-upgrades: Disable automatic upgrades ​

bash
sudo lzc-thor disable-upgrades

This command shuts down and disables apt scheduled updates, unattended-upgrades, and update-notifier services, while uninstalling the related packages. It is suitable for devices requiring a fixed JetPack, kernel, and driver environment.

After disabling automatic upgrades, the system will not automatically install security updates; compatibility validation must be arranged by administrators and updates must be performed manually.

startup: Configure the boot-up environment ​

bash
sudo lzc-thor startup

This command will:

  • Query the time zone using the current public IP; if the query fails, use Asia/Shanghai.
  • Enable systemd-timesyncd, and configure NTP services such as Cloudflare and Alibaba Cloud.
  • Create and enable lzc-jetson-clocks.service, locking the Jetson to maximum frequency at boot time.
  • Install Firefox via Snap.

This command requires access to the time zone query service, the Ubuntu software repository, and Snap services. It has no additional parameters.

agent: Install AI Pod proxy

bash
sudo lzc-thor agent
sudo systemctl status lzc-ai-agent.service

This command installs the ARM64 client from the package included in lzc-ai-agent, then enables and restarts lzc-ai-agent.service. It is used for standalone reinstallation or repair of the AI Pod agent. The command has no additional parameters.

MGBE Configuration and Bandwidth Testing ​

mgbe: Configure MGBE Performance Parameters ​

bash
sudo lzc-thor mgbe

This command automatically discovers all physical MGBE interfaces with names similar to mgbe0_0 and performs the following configuration:

  • Enables threaded NAPI.
  • Runs jetson_clocks.
  • Sets the IOMMU group of each interface to DMA-FQ.

This command only handles performance parameters; it does not assign test IPs or start iperf3. It is included in lzc-thor all.

How MGBE Testing Works ​

MGBE testing requires two devices: one running the server command and the other running the client command. Before testing, both devices must execute:

bash
sudo lzc-thor mgbe
sudo apt install -y iperf3

The test assistance commands are divided into three steps:

  1. Assign static IPs to each link via serve config and client config, write the configuration to /etc/netplan/99-mgbe-test.yaml, and save the link allocation to /var/lib/lzc-thor/mgbe-test.
  2. serve run starts iperf3 from the stored server configuration; client run initiates the test from the stored client configuration.
  3. Both ends execute clean to stop the test process and delete temporary network configurations and states.

config and run must be used together on the same end, in accordance with their respective roles. After modifying the IP address or the number of test links, the corresponding config must be re-executed.

The parameters and purposes of each test command are as follows:

CommandParametersUsage
mgbe serve configMust provide --base-ip IP; optional --mode 3x|4x, --dry-runAssign IP to server interface, apply netplan, and save server state.
mgbe serve runOptional --dry-runRead the server status and start iperf3 services on 8 different ports for each link.
mgbe client configMust provide --server-base-ip IP and --local-suffix 1-254; optional --mode 3x|4x, --dry-runCalculate the endpoint addresses based on the server-side baseline IP, apply the client's netplan, and save the state.
mgbe client runOptional --duration SEC, --parallel N, --udp, --dry-runCheck if each link is reachable, and simultaneously run all iperf3 clients, and aggregate the sender bandwidth.
mgbe cleanOptional --dry-runStop recorded service processes, delete test netplan and both end states.

The following example applies to a scenario where T4000 and T5000 are connected using three 25GbE links.

Server-side execution:

bash
sudo lzc-thor mgbe clean
sudo lzc-thor mgbe serve config --base-ip 192.168.100.10 --mode 3x
sudo lzc-thor mgbe serve run

Client executes:

bash
sudo lzc-thor mgbe clean
sudo lzc-thor mgbe client config \
  --server-base-ip 192.168.100.10 \
  --local-suffix 20 \
  --mode 3x
sudo lzc-thor mgbe client run

The IP address will increment by one in the third octet along the chain:

linkServer-side IPClient IP
Article 1192.168.100.10192.168.100.20
Article 2192.168.101.10192.168.101.20
Article 3192.168.102.10192.168.102.20

--local-suffix The last segment of the client IP is in the range from 1 to 254, and must not match the last segment of the server IP.

Choose 3x, 4x, or auto mode ​

--mode is only for serve config and client config:

Writing methodUsed interfaces
Do not write --modeauto mode, uses all automatically discovered MGBE interfaces.
--mode 3xUse the first 3 interfaces sorted by interface name.
--mode 4xUse the first 4 interfaces after sorting by interface name.

Both ends must use the same mode. Example of four-link test:

bash
# 服务端
sudo lzc-thor mgbe serve config --base-ip 192.168.100.10 --mode 4x
sudo lzc-thor mgbe serve run

# 客户端
sudo lzc-thor mgbe client config \
  --server-base-ip 192.168.100.10 \
  --local-suffix 20 \
  --mode 4x
sudo lzc-thor mgbe client run

run Will load the mode saved by config, and does not accept --mode. The old lzc-thor mgbe test has been removed.

Adjust Test Parameters ​

The client defaults to 10 seconds of testing, with each iperf3 client process using 24 parallel streams:

bash
sudo lzc-thor mgbe client run --duration 30 --parallel 32

UDP Test:

bash
sudo lzc-thor mgbe client run --udp

Each MGBE link uses 8 TOS values to start 8 client processes. Thus, 3x mode launches 24 client processes concurrently, and 4x mode launches 32; --parallel is the number of parallel streams within each process, not the total number of processes.

When executing run, the tool checks the saved interface's MTU 9000, threaded NAPI, IOMMU DMA-FQ, and the corresponding ODMDATA 25GbE configuration; a warning is issued if jetson_clocks or ODMDATA cannot be confirmed. If the check fails, re-run sudo lzc-thor mgbe and verify the device's link mode before using incomplete test results.

After the test completes, Concurrent aggregate sender bandwidth is output. This value only summarizes the send-side results resolvable within a single concurrent test window and should not be calculated by summing up sequential test results across multiple rounds and treated as link bandwidth.

Preview and Cleanup of Test Configuration ​

The test auxiliary command supports --dry-run, which allows checking the planned configuration without modifying the host.

bash
sudo lzc-thor mgbe serve config --base-ip 192.168.100.10 --mode 3x --dry-run
sudo lzc-thor mgbe client run --dry-run
sudo lzc-thor mgbe clean --dry-run

After official beta testing, perform the following on both the server and client sides:

bash
sudo lzc-thor mgbe clean

clean Will stop the iperf3 service process, delete the states from /etc/netplan/99-mgbe-test.yaml and /var/lib/lzc-thor/mgbe-test, and reapply network configuration.

VNC Configuration ​

vnc is not included in all. Configure VNC for the default nvidia desktop user:

bash
sudo lzc-thor vnc --password '<VNC密码>'

Configure for other desktop users:

bash
sudo lzc-thor vnc --user ubuntu --password '<VNC密码>'

The user and password can also be passed in via environment variables:

bash
sudo LZC_THOR_VNC_USER=ubuntu \
  LZC_THOR_VNC_PASSWORD='<VNC密码>' \
  lzc-thor vnc
Parameters or variablesDescription
--user USERTarget desktop user; defaults to read LZC_THOR_VNC_USER, defaults to nvidia when not set.
--password PASSWORDThe required VNC password, which can also be provided via LZC_THOR_VNC_PASSWORD.

This command installs Vino on demand, enables its desktop startup item, and writes VNC configuration to the user's settings. A device restart is required afterward. When desktop automatic login is not configured, the target user typically needs to log in locally to the graphical desktop before VNC can connect.

Storage Commands ​

resizefs, provision, expand-lvm, and factory-reset manipulate partitions, filesystems, LVM, or boot configurations. Before execution, important data should be backed up, and the device name and current root filesystem should be verified.

bash
findmnt /
lsblk -o NAME,PATH,SIZE,TYPE,FSTYPE,PARTLABEL,MOUNTPOINTS
sudo pvs
sudo vgs
sudo lvs

resizefs: Use remaining space on current system disk ​

After cloning a smaller system disk to a larger disk, you can execute:

bash
sudo lzc-thor resizefs

This command automatically selects the appropriate handling method based on the current / layout:

  • For a standard ext4 root partition: extend the partition to occupy the remaining disk space, then online-extend the ext4 filesystem.
  • For a standard aipod_vg/lv_root with a single partitioned PV: extend the partition containing the PV and the PV itself, allocate all free space in the VG to lv_root, then online-extend the ext4 filesystem.

This command does not support multi-PV, encrypted storage, full-disk filesystems, non-ext4 root filesystems, or non-standard LVM layouts. For multi-disk LVM systems, when adding a new disk, use expand-lvm instead of resizefs.

provision: Set up APP recovery and LVM runtime ​

provision is used to convert a LC-X5 with APP and DATA_PV partitions into the following layout:

  • APP: a read-only factory system and recovery environment, preserving the L4TLauncher boot files.
  • aipod_vg/lv_root: a writable ext4 root filesystem for daily use.

This is a two-stage process, with each stage automatically restarting the system.

Stage 1: Prepare in the writable APP ​

First, check the current state and plan:

bash
sudo lzc-thor provision status
sudo lzc-thor provision --dry-run

Confirmed. Proceeding to prepare.

bash
sudo lzc-thor provision --yes

Stage 1: Installs storage and initramfs tools, expands DATA_PV, checks LVM support in the initrd, writes managed boot entries, sets the APP configuration to read-only, and sets the next boot target to LZC Thor APP recovery, then reboots.

Stage 2: Creates the running system in APP recovery ​

After the device restarts and logs into LZC Thor APP recovery, execute:

bash
sudo lzc-thor provision --maintenance --yes

Stage 2 will verify that the current root directory is indeed a read-only APP, create aipod_vg/lv_root, clone the APP block-wise to the logical volume, extend the ext4 filesystem, generate a new filesystem UUID and machine identity, and then switch to the LVM runtime before restarting.

After entering the runtime system, you can check:

bash
sudo lzc-thor provision status
findmnt /
findmnt /factory

Under normal circumstances, / comes from /dev/aipod_vg/lv_root, and the APP is mounted in read-only mode on /factory. The software package corresponding to the current boot file is held, so online updates to the kernel, DTB, and initrd are not supported.

provision will modify the partition and boot configuration. Do not skip --dry-run, and do not forcibly execute this on devices that do not meet the layout requirements of APP and DATA_PV.

expand-lvm: Adding an NVMe Drive to the Root File System ​

This command is only applicable when the root directory is already writable (/dev/aipod_vg/lv_root), and is used to add a complete NVMe disk to the root file system.

First, verify the target disk based on capacity, model, and serial number:

bash
lsblk -d -o NAME,PATH,SIZE,MODEL,SERIAL

Perform a read-only check and preview on the empty disk first:

bash
sudo lzc-thor expand-lvm --disk /dev/nvme1n1 --dry-run

Confirm the target is correct, then proceed with scaling.

bash
sudo lzc-thor expand-lvm --disk /dev/nvme1n1

An empty disk will create a GPT and establish a partition marked as LZC_THOR_PV. Then, the commands pvcreate, vgextend, lvextend, and resize2fs will be executed to expand the root file system online.

If partitions or filesystems already exist on the disk, the operation is rejected by default. To proceed, explicitly confirm that all data can be completely erased, and then use:

bash
# 交互式确认时,按提示完整输入目标磁盘路径
sudo lzc-thor expand-lvm --disk /dev/nvme1n1 --force-wipe

# 无人值守确认;会直接清空目标盘
sudo lzc-thor expand-lvm --disk /dev/nvme1n1 --force-wipe --yes
ParametersDescription
--disk /dev/nvmeXnYRequired; must be a complete NVMe device, not a partition.
--dry-runExecute runtime environment and disk security checks, display the plan, do not write to disk.
--force-wipeAuthorize clearing non-empty target disk; prompt for interaction when --yes is not provided.
--yesCan only be used together with --force-wipe, skip interactive confirmation.

After expansion, each member disk becomes a permanent part of the root file system. Removing any member disk may cause the system to fail to boot. When performing a factory reset later, all DATA_PV and LZC_THOR_PV member disks will be cleared and rebuilt.

The command supports resuming from completed pvcreate, vgextend, or expansion steps. Member disks that have already been fully joined and allocated space will not be expanded again during subsequent executions.

factory-reset: Restore LVM Runtime System ​

factory-reset can only be executed in a manually selected read-only LZC Thor APP recovery and cannot be run during normal LVM runtime.

  1. Reboot the device and manually select LZC Thor APP recovery in the extlinux menu.

  2. If the system uses multiple LVM member disks, ensure all expanded disks are connected.

  3. Enter recovery mode, check the status, and perform a dry run first:

    bash
    sudo lzc-thor factory-reset status
    sudo lzc-thor factory-reset --dry-run
  4. Confirm and execute recovery:

    bash
    sudo lzc-thor factory-reset --yes

This command checks whether the system was booted from a read-only APP, whether the LVM topology matches expectations, whether all member disks are online, and whether each PV supports discard. It then clears all DATA_PV and LZC_THOR_PV, rebuilds aipod_vg/lv_root with the original total capacity, clones a fresh runtime system from the APP, and restarts. The APP, the /etc/fstab within the APP, and the extlinux default boot entry remain unchanged.

factory-reset --yes permanently deletes the runtime system, Docker data, models, applications, and user files. --dry-run does not write to disk, but still performs environment recovery, member disk, and discard capability checks.

Common Issues ​

Why is there still a permission denied error after running Docker? ​

After joining the docker group, the current session does not automatically refresh group information. Exit the SSH or desktop session and log back in, then run:

bash
docker ps

Why do mgbe serve run or client run show no status? ​

run Do not receive IP addresses and --mode; instead, read the most recent state saved by the same role during config. First re-execute serve config or client config, then proceed to execute the corresponding run.

When to use resizefs and expand-lvm? ​

  • The original system disk has grown larger; wish to use the remaining space at the end of the same disk: use resizefs.
  • Already running on aipod_vg/lv_root, want to add another complete NVMe to the root file system: using expand-lvm.

How to view only the current storage layout? ​

bash
sudo lzc-thor provision status

provision status Both factory-reset status and /factory output only the current root directory, /boot, block devices, LVM, and extlinux default boot entries, without modifying the system.