OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Update file format: A delta update file contains all the deltas needed | 5 // Update file format: A delta update file contains all the deltas needed |
6 // to update a system from one specific version to another specific | 6 // to update a system from one specific version to another specific |
7 // version. The update format is represented by this struct pseudocode: | 7 // version. The update format is represented by this struct pseudocode: |
8 // struct delta_update_file { | 8 // struct delta_update_file { |
9 // char magic[4] = "CrAU"; | 9 // char magic[4] = "CrAU"; |
10 // uint64 bom_offset; // Offset of protobuf DeltaArchiveManifest | 10 // uint32 file_format_version = 1; |
11 // uint64 bom_size; // Sise of protobuf DeltaArchiveManifest | 11 // uint64 manifest_size; // Size of protobuf DeltaArchiveManifest |
12 // // The Bzip2 compressed DeltaArchiveManifest | |
13 // char manifest[]; | |
12 // | 14 // |
13 // // Data blobs for files, no specific format. The specific offset | 15 // // Data blobs for files, no specific format. The specific offset |
14 // // and length of each data blob is recorded in the DeltaArchiveManifest. | 16 // // and length of each data blob is recorded in the DeltaArchiveManifest. |
15 // struct { | 17 // struct { |
16 // char data[]; | 18 // char data[]; |
17 // } blobs[]; | 19 // } blobs[]; |
18 // | 20 // |
19 // // The Gzip compressed DeltaArchiveManifest | |
20 // char bom[]; | |
21 // }; | 21 // }; |
22 | 22 |
23 // The DeltaArchiveManifest protobuf is an ordered list of File objects. | 23 // The DeltaArchiveManifest protobuf is an ordered list of InstallOperation |
24 // These File objects are stored in a linear array in the | 24 // objects. These objects are stored in a linear array in the |
25 // DeltaArchiveManifest, each with a specific index. Each File object | 25 // DeltaArchiveManifest. Each operation is applied in order by the client. |
26 // can contain children in its children list. Each child in the list | |
27 // has a name and an index. The index refers to the index within | |
28 // DeltaArchiveManifest.files. Thus, the DeltaArchiveManifest.files | |
29 // can be seen as a tree structure that mimicks the filesystem. | |
30 // The root object (the object an index 0) has no name, since names | |
31 // for children are stored in the parent. | |
32 | 26 |
33 // The DeltaArchiveManifest will contain one File entry for each | 27 // The DeltaArchiveManifest also contains the initial and final |
34 // file that will be on the resultant filesystem. Because we have | 28 // checksums for the device. |
35 // a tree structure, and children are ordered alphabetically within | |
36 // a parent, we can do log-time˜path lookup on a DeltaArchiveManifest | |
37 // object. We can also iterate through a DeltaArchiveManifest object | |
38 // using a preorder tree traversal to see each file in the | |
39 // DeltaArchiveManifest, seeing each directory before any of its children; | |
40 // this takes linear time. | |
41 | 29 |
42 // Here's an example from Dan Erat showing DeltaArchiveManifest | 30 // The client will perform each InstallOperation in order, beginning even |
43 // for a filesystem with files /bin/cat and /bin/ls.: | 31 // before the entire delta file is downloaded (but after at least the |
44 | 32 // protobuf is downloaded). The types of operations are explained: |
45 // files[0] { // "/" directory | 33 // - REPLACE: Replace the dst_extents on the drive with the attached data, |
46 // children[0] { | 34 // zero padding out to block size. |
47 // name "bin" | 35 // - REPLACE_BZ: bzip2-uncompress the attached data and write it into |
48 // index 1 | 36 // dst_extents on the drive, zero padding to block size. |
49 // } | 37 // - MOVE: Copy the data in src_extents to dst_extents. Extents may overlap, |
50 // } | 38 // so it may be desirable to read all src_extents data into memory before |
51 // files[1] { // "/bin" directory | 39 // writing it out. |
52 // children[0] { | 40 // - BSDIFF: Read src_length bytes from src_extents into memory, perform |
53 // name "cat" | 41 // bspatch with attached data, write new data to dst_extents, zero padding |
54 // index 2 | 42 // to block size. |
55 // } | |
56 // children[1] { | |
57 // name "ls" | |
58 // index 3 | |
59 // } | |
60 // } | |
61 // files[2] { // "/bin/cat" | |
62 // } | |
63 // files[3] { // "/bin/ls" | |
64 // } | |
65 | |
66 // If a file has a data_format set, it should also have data_offset and | |
67 // data_length set. data_offset and data_length refer to a range of bytes | |
68 // in the delta update file itself which have the format specified by | |
69 // data_format. FULL and FULL_GZ mean the entire file is present (FULL_GZ, | |
70 // gzip compressed). BSDIFF means the old file with the same path should be | |
71 // patched with 'bspatch' to produce the desired output file. COURGETTE | |
72 // is not yet used, but it will be another binary diff format. | |
73 | |
74 // Directories should not have any data. | |
75 | |
76 // There are other types of files, too: symlinks, block and character devices, | |
77 // fifos, and sockets. Fifos and sockets contain no data. Block and | |
78 // character devices have data. It must be the format FULL or FULL_GZ, and | |
79 // the contents are a serialized LinuxDevice protobuf. Symlinks must either | |
80 // be FULL, FULL_GZ, or have no data. A symlink with no data is unchanged, | |
81 // and with data it's set to that data. | |
82 | |
83 // TODO(adlr): Add support for hard links; CL is prepared already. | |
84 // Extended attributes are unsupported at this time. | |
85 | 43 |
86 package chromeos_update_engine; | 44 package chromeos_update_engine; |
87 | 45 |
88 message DeltaArchiveManifest { | 46 // Data is packed into blocks on disk, always starting from the beginning |
89 message File { | 47 // of the block. If a file's data is too large for one block, it overflows |
90 // This is st_mode from struct stat. It includes file type and permission | 48 // into another block, which may or may not be the following block on the |
91 // bits. | 49 // physical partition. An ordered list of extents is another |
92 optional uint32 mode = 1; | 50 // representation of an ordered list of blocks. For example, a file stored |
93 optional uint32 uid = 2; | 51 // in blocks 9, 10, 11, 2, 18, 12 (in that order) would be stored in |
94 optional uint32 gid = 3; | 52 // extents { {9, 3}, {2, 1}, {18, 1}, {12, 1} } (in that order). |
53 // In general, files are stored sequentially on disk, so it's more efficient | |
54 // to use extents to encode the block lists (this is effectively | |
55 // run-length encoding). | |
56 // A seminal value (kuint64max) as the start block denotes a sparse-hole | |
Daniel Erat
2010/01/22 22:51:33
s/seminal/sentinel/
| |
57 // in a file whose block-length is specified by num_blocks. | |
95 | 58 |
96 // File Data, not for directories | 59 message Extent { |
97 enum DataFormat { | 60 optional uint64 start_block = 1; |
98 FULL = 0; // The data is the complete file | 61 optional uint64 num_blocks = 2; |
99 FULL_GZ = 1; // The data is the complete file gzipped | |
100 BSDIFF = 2; // The data is a bsdiff binary diff | |
101 COURGETTE = 3; // The data is a courgette binary diff | |
102 } | |
103 // If present, there is data associated with this File object and | |
104 // data_offset and data_size must be set. | |
105 // If a file object doesn't have this set, it means the data is | |
106 // unchanged from the old version of the file. | |
107 optional DataFormat data_format = 4; | |
108 // The offset into the delta file where the data (if any) is stored | |
109 optional uint32 data_offset = 5; | |
110 // The length of the data in the delta file | |
111 optional uint32 data_length = 6; | |
112 | |
113 // When a file is a hard link, hardlink_path exists and | |
114 // is the path within the DeltaArchiveManifest to the "original" file. | |
115 // When iterating through a DeltaArchiveManifest, you will be guaranteed | |
116 // to hit a hardlink only after you've hit the path to the first file. | |
117 // Directories can't be hardlinked. | |
118 optional string hardlink_path = 8; | |
119 | |
120 message Child { | |
121 // A File that's a directory (and only those types of File objects) | |
122 // will have exactly one Child submessage per child. | |
123 required string name = 1; // File name of child | |
124 | |
125 // Index into DeltaArchiveManifest.files for the File object of the child. | |
126 required uint32 index = 2; | |
127 } | |
128 repeated Child children = 9; | |
129 } | |
130 repeated File files = 1; | |
131 } | 62 } |
132 | 63 |
133 message LinuxDevice { | 64 message DeltaArchiveManifest { |
134 required int32 major = 1; | 65 message InstallOperation { |
135 required int32 minor = 2; | 66 enum Type { |
136 } | 67 REPLACE = 0; // Replace destination extents w/ attached data |
68 REPLACE_BZ = 1; // Replace destination extents w/ attached bzipped data | |
69 MOVE = 2; // Move source extents to destination extents | |
70 BSDIFF = 3; // The data is a bsdiff binary diff | |
71 } | |
72 required Type type = 1; | |
73 // The offset into the delta file (after the protobuf) | |
74 // where the data (if any) is stored | |
75 optional uint32 data_offset = 2; | |
76 // The length of the data in the delta file | |
77 optional uint32 data_length = 3; | |
78 | |
79 // Ordered list of extents that are read from (if any) and written to. | |
80 repeated Extent src_extents = 4; | |
81 // Byte length of src, not necessarily block aligned. It's only used for | |
82 // BSDIFF, because we need to pass that external program the number | |
83 // of bytes to read from the blocks we pass it. | |
84 optional uint64 src_length = 5; | |
85 | |
86 repeated Extent dst_extents = 6; | |
87 // byte length of dst, not necessarily block aligned. It's only used for | |
88 // BSDIFF, because we need to fill in the rest of the last block | |
89 // that bsdiff writes with '\0' bytes. | |
90 optional uint64 dst_length = 7; | |
91 } | |
92 repeated InstallOperation install_operations = 1; | |
93 // The checksums of the install device before and after the install process. | |
94 optional string src_checksum = 2; | |
95 optional string dst_checksum = 3; | |
96 | |
97 // (At time of writing) usually 4096 | |
98 optional uint32 block_size = 5 [default = 4096]; | |
99 } | |
OLD | NEW |