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 devicelaunch_cvd
# Make some modifications to the deviceadb shell touch /storage/self/primary/Documents/hello
# Check the device stateadb shell ls /storage/self/primary/Documents
From this starting point, you can use the following restart and reset flows:
- If device is responsive, perform a clean restart using
adb reboot
. - If device is unresponsive, perform an unclean restart using
restart_cvd
. - Reset the device state using
powerwash_cvd
. - Stop the device and change the
launch_cvd
arguments while keeping the device state or forcibly clearing the device state.
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