Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 1 | // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 4 | library fuchsia.paver; |
| 5 | |
Suraj Malhotra | 03fb331 | 2019-08-13 05:34:21 +0000 | [diff] [blame] | 6 | using fuchsia.hardware.block; |
Ricardo Vargas | b1b251a3 | 2019-12-14 00:18:33 +0000 | [diff] [blame] | 7 | using fuchsia.hardware.block.volume; |
Suraj Malhotra | 963ce2b4 | 2019-04-23 01:10:37 +0000 | [diff] [blame] | 8 | using fuchsia.io; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 9 | using fuchsia.mem; |
Suraj Malhotra | 963ce2b4 | 2019-04-23 01:10:37 +0000 | [diff] [blame] | 10 | using zx; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 11 | |
| 12 | /// Describes the version of an asset. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 13 | type Configuration = strict enum { |
Suraj Malhotra | 963ce2b4 | 2019-04-23 01:10:37 +0000 | [diff] [blame] | 14 | A = 1; |
| 15 | B = 2; |
| 16 | RECOVERY = 3; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 17 | }; |
| 18 | |
| 19 | /// Describes assets which may be updated. Each asset has 3 versions, each tied to a particular |
| 20 | /// configuration. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 21 | type Asset = strict enum { |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 22 | /// Zircon Boot Image (ZBI) containing the kernel image as well as bootfs. |
Suraj Malhotra | 963ce2b4 | 2019-04-23 01:10:37 +0000 | [diff] [blame] | 23 | KERNEL = 1; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 24 | /// Metadata used for verified boot purposes. |
Suraj Malhotra | 963ce2b4 | 2019-04-23 01:10:37 +0000 | [diff] [blame] | 25 | VERIFIED_BOOT_METADATA = 2; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 26 | }; |
| 27 | |
Suraj Malhotra | 625e788 | 2019-09-26 02:21:17 +0000 | [diff] [blame] | 28 | /// Set of states configuration may be in. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 29 | type ConfigurationStatus = strict enum { |
Suraj Malhotra | 625e788 | 2019-09-26 02:21:17 +0000 | [diff] [blame] | 30 | /// Bootable and health checked. |
| 31 | HEALTHY = 1; |
| 32 | /// Bootable but not yet marked healthy. |
| 33 | PENDING = 2; |
| 34 | /// Unbootable. |
| 35 | UNBOOTABLE = 3; |
| 36 | }; |
| 37 | |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 38 | type ReadInfo = struct { |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 39 | /// Offset into VMO where read data starts. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 40 | offset zx.off; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 41 | /// Size of read data. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 42 | size uint64; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 43 | }; |
| 44 | |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 45 | type ReadResult = strict union { |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 46 | /// Error encountered while reading data. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 47 | 1: err zx.status; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 48 | /// End of file reached. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 49 | 2: eof bool; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 50 | /// Information about location of successfully read data within pre-registered VMO. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 51 | 3: info ReadInfo; |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 52 | }; |
| 53 | |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 54 | type WriteFirmwareResult = strict union { |
David Pursell | 6997bfa | 2020-03-16 19:56:16 +0000 | [diff] [blame] | 55 | /// The result status if a write was attempted. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 56 | 1: status zx.status; |
David Pursell | 6997bfa | 2020-03-16 19:56:16 +0000 | [diff] [blame] | 57 | |
Yecheng Zhao | a5fcd7b | 2020-08-17 17:39:25 +0000 | [diff] [blame] | 58 | /// True if a write was not attempted due to unsupported firmware. This could |
| 59 | /// be either unsupported content type or unsupported A/B configuration. |
David Pursell | 6997bfa | 2020-03-16 19:56:16 +0000 | [diff] [blame] | 60 | /// |
| 61 | /// Callers must not treat this as a fatal error, but instead ignore it and |
| 62 | /// continue to update the device. This is important to be able to add new |
| 63 | /// items to an update package without breaking updates on older devices. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 64 | 2: unsupported bool; |
David Pursell | 6997bfa | 2020-03-16 19:56:16 +0000 | [diff] [blame] | 65 | }; |
| 66 | |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 67 | /// Protocol for streaming the FVM payload. |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 68 | protocol PayloadStream { |
| 69 | /// Registers a VMO to stream into. |
Simon Shields | 4709a9d | 2020-03-06 05:22:06 +0000 | [diff] [blame] | 70 | /// |
| 71 | /// This can be called once per PayloadStream. |
| 72 | /// Any subsequent calls will return ZX_ERR_ALREADY_BOUND. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 73 | RegisterVmo(resource struct { |
| 74 | vmo zx.handle:VMO; |
| 75 | }) -> (struct { |
| 76 | status zx.status; |
| 77 | }); |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 78 | |
| 79 | /// Reads data into the pre-registered vmo. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 80 | ReadData() -> (struct { |
| 81 | result ReadResult; |
| 82 | }); |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 83 | }; |
| 84 | |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 85 | @discoverable |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 86 | protocol Paver { |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 87 | /// Attempts to auto-discover the data sink where assets and volumes will get paved to. |
| 88 | /// On devices with GPT, the partition must have a valid FVM partition in order for |
| 89 | /// auto-discovery to find it. If multiple devices are found suitable, error is returned. |
Suraj Malhotra | 937ac76 | 2019-09-25 17:33:14 -0700 | [diff] [blame] | 90 | /// |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 91 | /// `data_sink` will be closed on error, with an epitaph provided on failure reason. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 92 | FindDataSink(resource struct { |
| 93 | data_sink server_end:DataSink; |
| 94 | }); |
Suraj Malhotra | 937ac76 | 2019-09-25 17:33:14 -0700 | [diff] [blame] | 95 | |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 96 | /// Provide a block device to use as a data sink. Assets and volumes will be paved to |
| 97 | /// partitions within this block device. |
Suraj Malhotra | 937ac76 | 2019-09-25 17:33:14 -0700 | [diff] [blame] | 98 | /// |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 99 | /// It assumes that channel backing `block_device` also implements `fuchsia.io.Node` for now. |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 100 | /// |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 101 | /// `data_sink` will be closed on error, with an epitaph provided on failure reason. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 102 | UseBlockDevice(resource struct { |
| 103 | block_device client_end:fuchsia.hardware.block.Block; |
| 104 | data_sink server_end:DynamicDataSink; |
| 105 | }); |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 106 | |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 107 | /// Attempts to auto-discover the boot manager. |
Suraj Malhotra | 625e788 | 2019-09-26 02:21:17 +0000 | [diff] [blame] | 108 | /// |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 109 | /// `boot_manager` will be closed on error, with an epitaph provided on failure reason. |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 110 | /// ZX_ERR_NOT_SUPPORTED indicates lack of support and configuration A is always booted from. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 111 | FindBootManager(resource struct { |
| 112 | boot_manager server_end:BootManager; |
| 113 | }); |
Yecheng Zhao | 3c40afe | 2020-09-17 18:41:48 +0000 | [diff] [blame] | 114 | |
| 115 | /// Find Sysconfig service. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 116 | FindSysconfig(resource struct { |
| 117 | sysconfig server_end:Sysconfig; |
| 118 | }); |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 119 | }; |
Suraj Malhotra | 625e788 | 2019-09-26 02:21:17 +0000 | [diff] [blame] | 120 | |
Yecheng Zhao | a5fcd7b | 2020-08-17 17:39:25 +0000 | [diff] [blame] | 121 | /// Protocol for reading and writing boot partitions. |
| 122 | /// |
| 123 | /// A note on DataSink.Flush() (and BootManager.Flush() coming after): |
| 124 | /// |
Yecheng Zhao | e3e06c8 | 2020-05-08 16:45:28 +0000 | [diff] [blame] | 125 | /// Some platforms may implement the Flush() fidl interface of DataSink/BootManager. For these |
| 126 | /// platforms, the update of some system images and A/B configuration is not persisted to storage |
| 127 | /// immediately and only buffered internally when the write fidl interfaces return. The data is |
| 128 | /// guaranteed to be persisted only after the Flush() interfaces are called. |
| 129 | /// |
| 130 | /// If not implemented, Flush() is no-op and system images and A/B configuration will be persisted |
| 131 | /// to storage immediately after the write fidl interfaces return. |
| 132 | /// |
| 133 | /// For all platforms, it is guaranteed that if DataSink.Flush() is implemented, BootManager.Flush() |
| 134 | /// is implemented as well. Therefore, in the context of system update, both of the following update |
| 135 | /// sequences are safe in the sense that, new A/B configuration will not be persisted to storage |
| 136 | /// before new system images. |
| 137 | /// DataSink.Write[...]() --> DataSink.Flush() --> BootManager.Set[...]() --> BootManager.Flush() |
| 138 | /// DataSink.Write[...]() --> BootManager.Set[...]() --> DataSink.Flush() --> BootManager.Flush() |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 139 | protocol DataSink { |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 140 | /// Reads partition corresponding to `configuration` and `asset` into a |
Suraj Malhotra | 87515bd | 2019-09-27 05:04:47 +0000 | [diff] [blame] | 141 | /// vmo and returns it. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 142 | ReadAsset(struct { |
| 143 | configuration Configuration; |
| 144 | asset Asset; |
| 145 | }) -> (resource struct { |
| 146 | asset fuchsia.mem.Buffer; |
| 147 | }) error zx.status; |
Suraj Malhotra | 87515bd | 2019-09-27 05:04:47 +0000 | [diff] [blame] | 148 | |
Jeremy Manson | c7918d3 | 2019-06-26 00:54:45 +0000 | [diff] [blame] | 149 | /// Writes partition corresponding to `configuration` and `asset` with data from `payload`. |
Kevin Wells | d46f2c6 | 2019-09-12 19:52:28 +0000 | [diff] [blame] | 150 | /// `payload` may need to be resized to the partition size, so the provided vmo must have |
| 151 | /// been created with `ZX_VMO_RESIZABLE` or must be a child VMO that was created with |
| 152 | /// `ZX_VMO_CHILD_RESIZABLE`. Will zero out rest of the partition if `payload` is smaller |
| 153 | /// than the size of the partition being written. |
| 154 | /// |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 155 | /// |
Jeremy Manson | 437b01e1 | 2019-07-27 05:04:59 +0000 | [diff] [blame] | 156 | /// Returns `ZX_ERR_INVALID_ARGS` if `configuration` specifies active configuration. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 157 | WriteAsset(resource struct { |
| 158 | configuration Configuration; |
| 159 | asset Asset; |
| 160 | payload fuchsia.mem.Buffer; |
| 161 | }) -> (struct { |
| 162 | status zx.status; |
| 163 | }); |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 164 | |
David Pursell | 6997bfa | 2020-03-16 19:56:16 +0000 | [diff] [blame] | 165 | /// Writes firmware data from `payload`. |
| 166 | /// |
Yecheng Zhao | a5fcd7b | 2020-08-17 17:39:25 +0000 | [diff] [blame] | 167 | /// `configuration` represents the A/B/R configuration. For platforms that do not support |
| 168 | /// firmware A/B/R, the parameter will be ignored by the underlying device-specific logic . |
| 169 | /// |
David Pursell | 6997bfa | 2020-03-16 19:56:16 +0000 | [diff] [blame] | 170 | /// `type` is a device-specific string identifying the payload contents, |
| 171 | /// used to select the proper paving logic. For example, a device with |
| 172 | /// multiple bootloader stages might send them as separate calls to |
| 173 | /// `WriteFirmware()`, differentiated by `type`. An empty string |
| 174 | /// indicates the default type. |
| 175 | /// |
| 176 | /// `payload` may need to be resized to the partition size, so the provided |
| 177 | /// vmo must have been created with `ZX_VMO_RESIZABLE` or must be a child |
| 178 | /// VMO that was created with `ZX_VMO_CHILD_RESIZABLE`. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 179 | WriteFirmware(resource struct { |
| 180 | configuration Configuration; |
| 181 | type string:256; |
| 182 | payload fuchsia.mem.Buffer; |
| 183 | }) -> (struct { |
| 184 | result WriteFirmwareResult; |
| 185 | }); |
David Pursell | 6997bfa | 2020-03-16 19:56:16 +0000 | [diff] [blame] | 186 | |
Jeremy Manson | c7918d3 | 2019-06-26 00:54:45 +0000 | [diff] [blame] | 187 | /// Writes FVM with data from streamed via `payload`. This potentially affects all |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 188 | /// configurations. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 189 | WriteVolumes(resource struct { |
| 190 | payload client_end:PayloadStream; |
| 191 | }) -> (struct { |
| 192 | status zx.status; |
| 193 | }); |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 194 | |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 195 | // TODO(fxbug.dev/45606): transition users to `WriteFirmware()` and delete this. |
Jeremy Manson | c7918d3 | 2019-06-26 00:54:45 +0000 | [diff] [blame] | 196 | /// Writes bootloader partition with data from `payload`. |
Kevin Wells | d46f2c6 | 2019-09-12 19:52:28 +0000 | [diff] [blame] | 197 | /// |
| 198 | /// `payload` may need to be resized to the partition size, so the provided vmo must have |
| 199 | /// been created with `ZX_VMO_RESIZABLE` or must be a child VMO that was created with |
| 200 | /// `ZX_VMO_CHILD_RESIZABLE`. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 201 | @deprecated |
| 202 | WriteBootloader(resource struct { |
| 203 | payload fuchsia.mem.Buffer; |
| 204 | }) -> (struct { |
| 205 | status zx.status; |
| 206 | }); |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 207 | |
Jeremy Manson | c7918d3 | 2019-06-26 00:54:45 +0000 | [diff] [blame] | 208 | /// Writes /data/`filename` with data from `payload`. Overwrites file if it already exists. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 209 | WriteDataFile(resource struct { |
| 210 | filename string:fuchsia.io.MAX_PATH; |
| 211 | payload fuchsia.mem.Buffer; |
| 212 | }) -> (struct { |
| 213 | status zx.status; |
| 214 | }); |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 215 | |
| 216 | /// Wipes the FVM partition from the device. Should not be confused with factory reset, which |
Ricardo Vargas | b1b251a3 | 2019-12-14 00:18:33 +0000 | [diff] [blame] | 217 | /// is less intrusive. The result is that the default FVM volumes are re-created, but empty. |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 218 | /// |
| 219 | /// Notable use cases include recovering from corrupted FVM as well as setting device to a |
| 220 | /// "clean" state for automation. |
Suraj Malhotra | 03fb331 | 2019-08-13 05:34:21 +0000 | [diff] [blame] | 221 | /// |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 222 | /// If `block_device` is not provided, the paver will perform a search for the the FVM. |
| 223 | /// If multiple block devices have valid GPT, `block_device` can be provided to specify |
| 224 | /// which one to target. It assumed that channel backing `block_device` also implements |
Ricardo Vargas | 35338ed | 2019-10-29 23:00:11 +0000 | [diff] [blame] | 225 | /// `fuchsia.io.Node` for now. |
| 226 | /// |
| 227 | /// On success, returns a channel to the initialized FVM volume. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 228 | WipeVolume() -> (resource struct { |
| 229 | volume client_end:fuchsia.hardware.block.volume.VolumeManager; |
| 230 | }) error zx.status; |
Yecheng Zhao | e3e06c8 | 2020-05-08 16:45:28 +0000 | [diff] [blame] | 231 | |
| 232 | /// Flush all previously buffered writes to persistent storage. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 233 | Flush() -> (struct { |
| 234 | status zx.status; |
| 235 | }); |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 236 | }; |
Suraj Malhotra | 03fb331 | 2019-08-13 05:34:21 +0000 | [diff] [blame] | 237 | |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 238 | /// Specialized DataSink with dynamic partition tables. |
| 239 | protocol DynamicDataSink { |
| 240 | compose DataSink; |
| 241 | |
| 242 | /// Initializes partitions on given block device. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 243 | InitializePartitionTables() -> (struct { |
| 244 | status zx.status; |
| 245 | }); |
Suraj Malhotra | 8232ba5 | 2019-08-14 02:55:16 +0000 | [diff] [blame] | 246 | |
| 247 | /// Wipes all entries from the partition table of the specified block device. |
| 248 | /// Currently only supported on devices with a GPT. |
| 249 | /// |
Suraj Malhotra | 8232ba5 | 2019-08-14 02:55:16 +0000 | [diff] [blame] | 250 | /// *WARNING*: This API may destructively remove non-fuchsia maintained partitions from |
| 251 | /// the block device. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 252 | WipePartitionTables() -> (struct { |
| 253 | status zx.status; |
| 254 | }); |
Suraj Malhotra | 569edd7 | 2019-04-05 01:13:02 +0000 | [diff] [blame] | 255 | }; |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 256 | |
| 257 | /// Protocol for managing boot configurations. |
Yecheng Zhao | 78ec48b | 2020-03-31 20:02:01 +0000 | [diff] [blame] | 258 | /// |
| 259 | /// All functions will first check the A/B/R metadata and reset it to |
| 260 | /// the default state if it's invalid. |
Yecheng Zhao | e3e06c8 | 2020-05-08 16:45:28 +0000 | [diff] [blame] | 261 | /// The new configuration is not guaranteed to persist to storage before Flush() is called. |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 262 | protocol BootManager { |
Zach Kirschenbaum | 978414b | 2020-09-04 01:43:23 +0000 | [diff] [blame] | 263 | /// Queries the configuration the system is currently running. |
| 264 | /// |
| 265 | /// Returns `ZX_ERR_NOT_SUPPORTED` if the `zvb.current_slot` boot argument cannot be read |
| 266 | /// or is an unexpected value. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 267 | QueryCurrentConfiguration() -> (struct { |
| 268 | configuration Configuration; |
| 269 | }) error zx.status; |
Zach Kirschenbaum | 978414b | 2020-09-04 01:43:23 +0000 | [diff] [blame] | 270 | |
| 271 | /// Queries the configuration which will be used as the default boot choice on a normal cold |
| 272 | /// boot, which may differ from the currently running configuration. `Configuration::RECOVERY` |
| 273 | /// should never be active. |
| 274 | /// |
| 275 | /// Returns `ZX_ERR_NOT_SUPPORTED` if `Configuration.RECOVERY` is active. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 276 | QueryActiveConfiguration() -> (struct { |
| 277 | configuration Configuration; |
| 278 | }) error zx.status; |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 279 | |
Yecheng Zhao | 559948a1 | 2021-08-20 17:12:18 +0000 | [diff] [blame] | 280 | /// Queries the configuration that was last explicitly marked as active by |
| 281 | /// SetConfigurationActive(). The result is not affected by the current status of the slot. |
| 282 | /// |
| 283 | /// A newly updated slot is typically marked as active immediately. Therefore this interface |
| 284 | /// can be used as a way to identify the newest slot. |
| 285 | /// |
| 286 | /// Returns `ZX_ERR_IO` if fail to load abr metadata. Returns `ZX_ERR_INTERNAL` if invalid |
| 287 | /// slot index is returned by libabr routine. |
| 288 | QueryConfigurationLastSetActive() -> (struct { |
| 289 | configuration Configuration; |
| 290 | }) error zx.status; |
| 291 | |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 292 | /// Queries status of `configuration`. |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 293 | /// |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 294 | /// Returns `ZX_ERR_INVALID_ARGS` if `Configuration.RECOVERY` is passed in via `configuration`. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 295 | QueryConfigurationStatus(struct { |
| 296 | configuration Configuration; |
| 297 | }) -> (struct { |
| 298 | status ConfigurationStatus; |
| 299 | }) error zx.status; |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 300 | |
| 301 | /// Updates persistent metadata identifying which configuration should be selected as 'primary' |
| 302 | /// for booting purposes. Should only be called after `KERNEL` as well as optional |
| 303 | /// `VERIFIED_BOOT_METADATA` assets for specified `configuration` were written successfully. |
| 304 | /// |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 305 | /// Returns `ZX_ERR_INVALID_ARGS` if `Configuration.RECOVERY` is passed in via `configuration`. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 306 | SetConfigurationActive(struct { |
| 307 | configuration Configuration; |
| 308 | }) -> (struct { |
| 309 | status zx.status; |
| 310 | }); |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 311 | |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 312 | /// Updates persistent metadata identifying whether `configuration` is bootable. |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 313 | /// Should only be called in the following situations: |
| 314 | /// * Before `KERNEL` as well as optional `VERIFIED_BOOT_METADATA` assets for specified |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 315 | /// `configuration` are written. |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 316 | /// * After successfully booting from a new configuration and marking it healthy. This method |
| 317 | /// would be then called on the old configuration. |
| 318 | /// * After "successfully" booting from a new configuration, but encountering an unrecoverable |
| 319 | /// error during health check. This method would be then called on the new configuration. |
| 320 | /// |
| 321 | /// If the configuration is unbootable, no action is taken. |
| 322 | /// |
Drew Fisher | eaab68a | 2020-02-26 17:07:30 -0800 | [diff] [blame] | 323 | /// Returns `ZX_ERR_INVALID_ARGS` if `Configuration.RECOVERY` is passed in via `configuration`. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 324 | SetConfigurationUnbootable(struct { |
| 325 | configuration Configuration; |
| 326 | }) -> (struct { |
| 327 | status zx.status; |
| 328 | }); |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 329 | |
Hunter Freyer | b3d3b78 | 2020-10-19 21:14:58 +0000 | [diff] [blame] | 330 | /// Updates persistent metadata to mark a [`fuchsia.paver/Configuration`] |
| 331 | /// as successful. |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 332 | /// |
Hunter Freyer | b3d3b78 | 2020-10-19 21:14:58 +0000 | [diff] [blame] | 333 | /// This function is typically used by the OS update system after having |
| 334 | /// confirmed that the configuration works as intended and the "rollback to |
| 335 | /// previous slot" logic is not needed anymore. |
| 336 | /// |
| 337 | /// Compatibility between the newly successful configuration and the other |
| 338 | /// configuration is unknown. Even if the other configuration was |
| 339 | /// successful at one point, it may no longer be. This function adds a |
| 340 | /// success mark to the given configuration but also removes any success |
| 341 | /// mark on the other. |
| 342 | /// |
| 343 | /// If `configuration` is unbootable or is |
| 344 | /// [`fuchsia.paver/Configuration.RECOVERY`], `response` will be |
| 345 | /// `ZX_ERR_INVALID_ARGS`. |
| 346 | /// |
| 347 | /// + request `configuration` the `Configuration` to mark as healthy. Must |
| 348 | /// not be `RECOVERY`. |
| 349 | /// - response `status` a zx_status value indicating success or failure. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 350 | SetConfigurationHealthy(struct { |
| 351 | configuration Configuration; |
| 352 | }) -> (struct { |
| 353 | status zx.status; |
| 354 | }); |
Yecheng Zhao | e3e06c8 | 2020-05-08 16:45:28 +0000 | [diff] [blame] | 355 | |
| 356 | /// Flush all previously buffered writes to persistent storage. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 357 | Flush() -> (struct { |
| 358 | status zx.status; |
| 359 | }); |
Suraj Malhotra | 2774a49 | 2019-12-19 00:35:04 +0000 | [diff] [blame] | 360 | }; |
Yecheng Zhao | 3c40afe | 2020-09-17 18:41:48 +0000 | [diff] [blame] | 361 | |
| 362 | /// Protocol that provides access to sysconfig-data sub-partition in sysconfig partition. |
| 363 | /// The main user of the protocol are pkg-solver and system update-checker, which need to |
| 364 | /// read/write sysconfig-data channel. |
| 365 | protocol Sysconfig { |
| 366 | /// Read from the sub-partition |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 367 | Read() -> (resource struct { |
| 368 | data fuchsia.mem.Buffer; |
| 369 | }) error zx.status; |
Yecheng Zhao | 3c40afe | 2020-09-17 18:41:48 +0000 | [diff] [blame] | 370 | |
| 371 | /// Writes to the sub-partition |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 372 | Write(resource struct { |
| 373 | payload fuchsia.mem.Buffer; |
| 374 | }) -> (struct { |
| 375 | status zx.status; |
| 376 | }); |
Yecheng Zhao | 3c40afe | 2020-09-17 18:41:48 +0000 | [diff] [blame] | 377 | |
| 378 | /// Get sub-partition size. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 379 | GetPartitionSize() -> (struct { |
| 380 | size uint64; |
| 381 | }) error zx.status; |
Yecheng Zhao | 3c40afe | 2020-09-17 18:41:48 +0000 | [diff] [blame] | 382 | |
| 383 | /// Flush all previously buffered data to persistent storage. |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 384 | Flush() -> (struct { |
| 385 | status zx.status; |
| 386 | }); |
Yecheng Zhao | 3c40afe | 2020-09-17 18:41:48 +0000 | [diff] [blame] | 387 | |
| 388 | /// Wipe all data in the sub-partition (write 0 to all bytes). |
Alex Zaslavsky | e3b39f2 | 2021-07-17 18:09:45 +0000 | [diff] [blame] | 389 | Wipe() -> (struct { |
| 390 | status zx.status; |
| 391 | }); |
Yecheng Zhao | 3c40afe | 2020-09-17 18:41:48 +0000 | [diff] [blame] | 392 | }; |