Cuttlefish: Restart and reset

This page describes how to restart and reset Cuttlefish virtual devices. Resetting a Cuttlefish device to its initial disk state is referred to as powerwashing in the command line tool.

When running automated or manual workflows with multiple different procedures, such as test suites, resetting the Cuttlefish device between procedures ensures that the behavior of each procedure is independent. If the disk state isn't reset, one procedure can affect the behavior of the following procedure.

The restart and reset procedures described on this page assumes that you have created a Cuttlefish device and have set some state on the disk.

# Launch a device
launch_cvd
# Make some modifications to the device
adb shell touch /storage/self/primary/Documents/hello
# Check the device state
adb shell ls /storage/self/primary/Documents

From this starting point, you can use the following restart and reset flows:

Cuttlefish quick reset implementation

Cuttlefish uses a quick reset implementation that's dependent on protecting the disks behind qcow2 disk overlays. By default, Cuttlefish treats original disks as read-only and uses overlays to capture disk writes.

However there are drawbacks to using copy-on-write overlays. Notably, external changes to the underlying disks break compatibility with existing overlays, and cause an inconsistent disk state. Cuttlefish forcibly recreates the overlays when it detects incompatible changes.

Forcibly recreating the overlays is undesirable when developing a feature that requires keeping part of the disk in a particular initialized state while swapping out a different part of the disk. For example, installing an app with a particular user configuration and then repeatedly swapping out the kernel to test the interaction between the app and different kernel builds. In this case, it might be worth disabling the overlays.

Reset devices

The following sections describe ways to reset a Cuttlefish device to its initial disk state.

Reset one device

To reset one Cuttlefish device to its initial disk state, run:

powerwash_cvd

powerwash_cvd shuts down the virtual machine, resets any changes made to the virtual machine disk, restarts the virtual machine, and waits until it finishes booting. The instance preserves the original flags given to launch_cvd.

In a multi-tenant configuration, powerwash_cvd restarts a single instance out of the instance group:

powerwash_cvd --instance_num=N

Reset all devices

To stop and reset one or more devices to their initial disk states, run:

stop_cvd
launch_cvd --resume=false

stop_cvd performs an unclean shutdown and stops the device.

Adding --resume=false to launch_cvd makes Cuttlefish destroy all files related to the previously running instance before starting the next run. It's safe to add any additional launch_cvd flags.

In a multi-tenant configuration, stop_cvd shuts down the entire instance group.

Restart devices

The following sections describe ways of restarting a device without resetting the device to its initial disk state.

Clean restart

To do a clean restart of the device when the device is responsive, run:

adb reboot

adb reboot takes the device through the full shutdown procedure, syncing changes to the disk and making sure processes shut down. Cuttlefish host processes aren't involved. This procedure could be unavailable if the device has entered a bad state and become unresponsive.

To do a clean restart of a single Cuttlefish device in a multi-tenant configuration, specify the serial number of the target device when running adb-reboot. If no target device is specified, adb doesn't restart any device.

adb -s SERIAL reboot

Unclean restart

To perform an unclean restart when the device is unresponsive, run:

restart_cvd

restart_cvd performs an unclean shutdown by instantly shutting down the Cuttlefish device. restart_cvd is the equivalent of disconnecting and reconnecting the battery to a physical device. Disk writes might not persist if they were in progress. restart_cvd waits until the device has fully booted again before exiting.

In a multi-tenant configuration, restart_cvd restarts a single instance out of the instance group. To specify which Cuttlefish instance to restart, use the instance_num flag.

restart_cvd --instance_num=N

If --instance_num isn't used, the instance number defaults to 1.

Restart using different launch_cvd flags

To stop one or more devices and relaunch with different launch_cvd flags, run:

stop_cvd
launch_cvd NEW_FLAG

stop_cvd performs an unclean shutdown similar to restart_cvd. It leaves the device in a dormant state that can be started again later with a different launch_cvd command. As with restart_cvd, disk writes might not persist if they aren't fully synced to the disk. To safely save data to disk, run adb reboot first.

adb reboot
stop_cvd
launch_cvd NEW_FLAG

If changes to launch_cvd flags force a change to the disk layout that's incompatible with the copy-on-write implementation, launch_cvd ignores the old disk modifications and resets to the original disk state. For a full list of flags, see Flags.

Run without an overlay

To opt out of quick-reset support, run:

launch_cvd --use_overlay=false

--use_overlay=false treats the Cuttlefish disk files as read-write, and changes are propagated into those files.

Changing between --use_overlay=false and the default can cause compatibility errors. To forcibly clean up the prior device state, run:

stop_cvd
rm $HOME/cuttlefish $HOME/cuttlefish_runtime $HOME/cuttlefish_assembly

Cuttlefish can't safely navigate the transition between the flows with and without overlays, so this change deletes all the Cuttlefish management state. If external disk files are modified and are reused later together with overlays, the earlier modifications are considered part of the baseline state.

Flags

You can add arguments using flags when launching a Cuttlefish device using launch_cvd. However, for certain flags (Flags that must stay the same), data loss can occur if flags are changed between launch_cvd commands. To ensure no data loss occurs when running a sequence of commands that include launch_cvd, stop_cvd, and then launch_cvd again, use the same flags for every launch_cvd command. For example, if the first launch_cvd flag includes the argument --kernel_path=KERNEL_PATH, the second launch_cvd invocation must also include the same --kernel_path=KERNEL_PATH argument, or any file system changes made before stop_cvd are lost in the second launch_cvd invocation. The file referenced by KERNEL_PATH must also have the same contents.

Some flags are safe to change between launch_cvd invocations. The following sections list the flags that must stay the same to avoid data loss and flags that can be safely changed without data loss. For details on individual flags, refer to the source ( flags.cc , disk_flags.cc ) or run launch_cvd --help.

Flags that must stay the same

These flags must stay the same from one launch_cvd invocation to the next to avoid data loss:

  • --data_policy
  • --blank_data_image_mb
  • --kernel_path
  • --initramfs_path
  • --vm_manager
  • --enable_minimal_mode
  • --bootloader
  • --protected_vm
  • --userdata_format
  • --use_overlay
  • --system_image_dir
  • --boot_image
  • --init_boot_image
  • --data_image
  • --super_image
  • --misc_image
  • --misc_info_txt
  • --metadata_image
  • --vendor_boot_image
  • --vbmeta_image
  • --vbmeta_system_image
  • --linux_kernel_path
  • --linux_initramfs_path
  • --linux_root_image
  • --fuchsia_zedboot_path
  • --fuchsia_multiboot_bin_path
  • --fuchsia_root_image
  • --custom_partition_path
  • --blank_metadata_image_mb

Flags that can change

These flags can be safely changed between launch_cvd invocations without causing data loss:

  • --displays_textproto
  • --displays_binproto
  • --cpus
  • --gdb_port
  • --display0
  • --display1
  • --display2
  • --display3
  • --x_res
  • --y_res
  • --dpi
  • --refresh_rate_hz
  • --extra_kernel_cmdline
  • --extra_bootconfig_args
  • --guest_enforce_security
  • --memory_mb
  • --serial_number
  • --use_random_serial
  • --gpu_mode
  • --hwcomposer
  • --gpu_capture_binary
  • --enable_gpu_udmabuf
  • --enable_gpu_angle
  • --use_allocd
  • --pause_in_bootloader
  • --enable_host_bluetooth
  • --rootcanal_instance_num
  • --rootcanal_args
  • --netsim
  • --netsim_bt
  • --bluetooth_controller_properties_file
  • --bluetooth_commands_file
  • --enable_sandbox
  • --seccomp_policy_dir
  • --start_webrtc
  • --webrtc_assets_dir
  • --webrtc_certs_dir
  • --start_webrtc_sig_server
  • --webrtc_sig_server_addr
  • --webrtc_sig_server_port
  • --tcp_port_range
  • --udp_port_range
  • --webrtc_sig_server_path
  • --webrtc_sig_server_secure
  • --verify_sig_server_certificate
  • --webrtc_device_id
  • --uuid
  • --daemon
  • --setupwizard_mode
  • --enable_bootanimation
  • --qemu_binary_dir
  • --crosvm_binary
  • --gem5_binary_dir
  • --gem5_checkpoint_dir
  • --gem5_debug_file
  • --gem5_debug_flags
  • --restart_subprocesses
  • --enable_vehicle_hal_grpc_server
  • --boot_slot
  • --num_instances
  • --report_anonymous_usage_stats
  • --ril_dns
  • --kgdb
  • --start_gnss_proxy
  • --gnss_file_path
  • --fixed_location_file_path
  • --enable_modem_simulator
  • --modem_simulator_sim_type
  • --console
  • --enable_kernel_log
  • --vhost_net
  • --vhost_user_mac80211_hwim
  • --wmediumd_config
  • --ap_rootfs_image
  • --ap_kernel_image
  • --record_screen
  • --smt
  • --vsock_guest_cid
  • --secure_hals
  • --use_sdcard
  • --enable_audio
  • --camera_server_port
  • --modem_simulator_count
  • --blank_sdcard_image_mb
  • --adb_mode