Chromium Code Reviews| Index: src/platform/update_engine/update_metadata.proto |
| diff --git a/src/platform/update_engine/update_metadata.proto b/src/platform/update_engine/update_metadata.proto |
| index 42880dae3b2062cb66ffb32b840c6a1cb1e652dc..ce635cec5758a4e8f5926286b5e703cc116fb728 100644 |
| --- a/src/platform/update_engine/update_metadata.proto |
| +++ b/src/platform/update_engine/update_metadata.proto |
| @@ -7,8 +7,10 @@ |
| // version. The update format is represented by this struct pseudocode: |
| // struct delta_update_file { |
| // char magic[4] = "CrAU"; |
| -// uint64 bom_offset; // Offset of protobuf DeltaArchiveManifest |
| -// uint64 bom_size; // Sise of protobuf DeltaArchiveManifest |
| +// uint32 file_format_version = 1; |
| +// uint64 manifest_size; // Size of protobuf DeltaArchiveManifest |
| +// // The Bzip2 compressed DeltaArchiveManifest |
| +// char manifest[]; |
| // |
| // // Data blobs for files, no specific format. The specific offset |
| // // and length of each data blob is recorded in the DeltaArchiveManifest. |
| @@ -16,121 +18,82 @@ |
| // char data[]; |
| // } blobs[]; |
| // |
| -// // The Gzip compressed DeltaArchiveManifest |
| -// char bom[]; |
| // }; |
| -// The DeltaArchiveManifest protobuf is an ordered list of File objects. |
| -// These File objects are stored in a linear array in the |
| -// DeltaArchiveManifest, each with a specific index. Each File object |
| -// can contain children in its children list. Each child in the list |
| -// has a name and an index. The index refers to the index within |
| -// DeltaArchiveManifest.files. Thus, the DeltaArchiveManifest.files |
| -// can be seen as a tree structure that mimicks the filesystem. |
| -// The root object (the object an index 0) has no name, since names |
| -// for children are stored in the parent. |
| +// The DeltaArchiveManifest protobuf is an ordered list of InstallOperation |
| +// objects. These objects are stored in a linear array in the |
| +// DeltaArchiveManifest. Each operation is applied in order by the client. |
| -// The DeltaArchiveManifest will contain one File entry for each |
| -// file that will be on the resultant filesystem. Because we have |
| -// a tree structure, and children are ordered alphabetically within |
| -// a parent, we can do log-time˜path lookup on a DeltaArchiveManifest |
| -// object. We can also iterate through a DeltaArchiveManifest object |
| -// using a preorder tree traversal to see each file in the |
| -// DeltaArchiveManifest, seeing each directory before any of its children; |
| -// this takes linear time. |
| +// The DeltaArchiveManifest also contains the initial and final |
| +// checksums for the device. |
| -// Here's an example from Dan Erat showing DeltaArchiveManifest |
| -// for a filesystem with files /bin/cat and /bin/ls.: |
| +// The client will perform each InstallOperation in order, beginning even |
| +// before the entire delta file is downloaded (but after at least the |
| +// protobuf is downloaded). The types of operations are explained: |
| +// - REPLACE: Replace the dst_extents on the drive with the attached data, |
| +// zero padding out to block size. |
| +// - REPLACE_BZ: bzip2-uncompress the attached data and write it into |
| +// dst_extents on the drive, zero padding to block size. |
| +// - MOVE: Copy the data in src_extents to dst_extents. Extents may overlap, |
| +// so it may be desirable to read all src_extents data into memory before |
| +// writing it out. |
| +// - BSDIFF: Read src_length bytes from src_extents into memory, perform |
| +// bspatch with attached data, write new data to dst_extents, zero padding |
| +// to block size. |
| -// files[0] { // "/" directory |
| -// children[0] { |
| -// name "bin" |
| -// index 1 |
| -// } |
| -// } |
| -// files[1] { // "/bin" directory |
| -// children[0] { |
| -// name "cat" |
| -// index 2 |
| -// } |
| -// children[1] { |
| -// name "ls" |
| -// index 3 |
| -// } |
| -// } |
| -// files[2] { // "/bin/cat" |
| -// } |
| -// files[3] { // "/bin/ls" |
| -// } |
| - |
| -// If a file has a data_format set, it should also have data_offset and |
| -// data_length set. data_offset and data_length refer to a range of bytes |
| -// in the delta update file itself which have the format specified by |
| -// data_format. FULL and FULL_GZ mean the entire file is present (FULL_GZ, |
| -// gzip compressed). BSDIFF means the old file with the same path should be |
| -// patched with 'bspatch' to produce the desired output file. COURGETTE |
| -// is not yet used, but it will be another binary diff format. |
| - |
| -// Directories should not have any data. |
| - |
| -// There are other types of files, too: symlinks, block and character devices, |
| -// fifos, and sockets. Fifos and sockets contain no data. Block and |
| -// character devices have data. It must be the format FULL or FULL_GZ, and |
| -// the contents are a serialized LinuxDevice protobuf. Symlinks must either |
| -// be FULL, FULL_GZ, or have no data. A symlink with no data is unchanged, |
| -// and with data it's set to that data. |
| +package chromeos_update_engine; |
| -// TODO(adlr): Add support for hard links; CL is prepared already. |
| -// Extended attributes are unsupported at this time. |
| +// Data is packed into blocks on disk, always starting from the beginning |
| +// of the block. If a file's data is too large for one block, it overflows |
| +// into another block, which may or may not be the following block on the |
| +// physical partition. An ordered list of extents is another |
| +// representation of an ordered list of blocks. For example, a file stored |
| +// in blocks 9, 10, 11, 2, 18, 12 (in that order) would be stored in |
| +// extents { {9, 3}, {2, 1}, {18, 1}, {12, 1} } (in that order). |
| +// In general, files are stored sequentially on disk, so it's more efficient |
| +// to use extents to encode the block lists (this is effectively |
| +// run-length encoding). |
| +// A seminal value (kuint64max) as the start block denotes a sparse-hole |
|
Daniel Erat
2010/01/22 22:51:33
s/seminal/sentinel/
|
| +// in a file whose block-length is specified by num_blocks. |
| -package chromeos_update_engine; |
| +message Extent { |
| + optional uint64 start_block = 1; |
| + optional uint64 num_blocks = 2; |
| +} |
| message DeltaArchiveManifest { |
| - message File { |
| - // This is st_mode from struct stat. It includes file type and permission |
| - // bits. |
| - optional uint32 mode = 1; |
| - optional uint32 uid = 2; |
| - optional uint32 gid = 3; |
| - |
| - // File Data, not for directories |
| - enum DataFormat { |
| - FULL = 0; // The data is the complete file |
| - FULL_GZ = 1; // The data is the complete file gzipped |
| - BSDIFF = 2; // The data is a bsdiff binary diff |
| - COURGETTE = 3; // The data is a courgette binary diff |
| + message InstallOperation { |
| + enum Type { |
| + REPLACE = 0; // Replace destination extents w/ attached data |
| + REPLACE_BZ = 1; // Replace destination extents w/ attached bzipped data |
| + MOVE = 2; // Move source extents to destination extents |
| + BSDIFF = 3; // The data is a bsdiff binary diff |
| } |
| - // If present, there is data associated with this File object and |
| - // data_offset and data_size must be set. |
| - // If a file object doesn't have this set, it means the data is |
| - // unchanged from the old version of the file. |
| - optional DataFormat data_format = 4; |
| - // The offset into the delta file where the data (if any) is stored |
| - optional uint32 data_offset = 5; |
| + required Type type = 1; |
| + // The offset into the delta file (after the protobuf) |
| + // where the data (if any) is stored |
| + optional uint32 data_offset = 2; |
| // The length of the data in the delta file |
| - optional uint32 data_length = 6; |
| - |
| - // When a file is a hard link, hardlink_path exists and |
| - // is the path within the DeltaArchiveManifest to the "original" file. |
| - // When iterating through a DeltaArchiveManifest, you will be guaranteed |
| - // to hit a hardlink only after you've hit the path to the first file. |
| - // Directories can't be hardlinked. |
| - optional string hardlink_path = 8; |
| + optional uint32 data_length = 3; |
| - message Child { |
| - // A File that's a directory (and only those types of File objects) |
| - // will have exactly one Child submessage per child. |
| - required string name = 1; // File name of child |
| + // Ordered list of extents that are read from (if any) and written to. |
| + repeated Extent src_extents = 4; |
| + // Byte length of src, not necessarily block aligned. It's only used for |
| + // BSDIFF, because we need to pass that external program the number |
| + // of bytes to read from the blocks we pass it. |
| + optional uint64 src_length = 5; |
| - // Index into DeltaArchiveManifest.files for the File object of the child. |
| - required uint32 index = 2; |
| - } |
| - repeated Child children = 9; |
| + repeated Extent dst_extents = 6; |
| + // byte length of dst, not necessarily block aligned. It's only used for |
| + // BSDIFF, because we need to fill in the rest of the last block |
| + // that bsdiff writes with '\0' bytes. |
| + optional uint64 dst_length = 7; |
| } |
| - repeated File files = 1; |
| -} |
| + repeated InstallOperation install_operations = 1; |
| + // The checksums of the install device before and after the install process. |
| + optional string src_checksum = 2; |
| + optional string dst_checksum = 3; |
| -message LinuxDevice { |
| - required int32 major = 1; |
| - required int32 minor = 2; |
| -} |
| + // (At time of writing) usually 4096 |
| + optional uint32 block_size = 5 [default = 4096]; |
| +} |