Home | History | Annotate | Download | only in payload_generator
      1 //
      2 // Copyright (C) 2015 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_GENERATION_CONFIG_H_
     18 #define UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_GENERATION_CONFIG_H_
     19 
     20 #include <cstddef>
     21 
     22 #include <memory>
     23 #include <string>
     24 #include <vector>
     25 
     26 #include <brillo/key_value_store.h>
     27 
     28 #include "update_engine/payload_consumer/payload_constants.h"
     29 #include "update_engine/payload_generator/filesystem_interface.h"
     30 #include "update_engine/update_metadata.pb.h"
     31 
     32 namespace chromeos_update_engine {
     33 
     34 struct PostInstallConfig {
     35   // Whether the postinstall config is empty.
     36   bool IsEmpty() const;
     37 
     38   // Whether this partition carries a filesystem with post-install program that
     39   // must be run to finalize the update process.
     40   bool run = false;
     41 
     42   // The path to the post-install program relative to the root of this
     43   // filesystem.
     44   std::string path;
     45 
     46   // The filesystem type used to mount the partition in order to run the
     47   // post-install program.
     48   std::string filesystem_type;
     49 
     50   // Whether this postinstall script should be ignored if it fails.
     51   bool optional = false;
     52 };
     53 
     54 struct PartitionConfig {
     55   explicit PartitionConfig(std::string name) : name(name) {}
     56 
     57   // Returns whether the PartitionConfig is not an empty image and all the
     58   // fields are set correctly to a valid image file.
     59   bool ValidateExists() const;
     60 
     61   // Open then filesystem stored in this partition and stores it in
     62   // |fs_interface|. Returns whether opening the filesystem worked.
     63   bool OpenFilesystem();
     64 
     65   // The path to the partition file. This can be a regular file or a block
     66   // device such as a loop device.
     67   std::string path;
     68 
     69   // The path to the .map file associated with |path| if any. The .map file is
     70   // generated by the Android filesystem generation tools when creating a
     71   // filesystem and describes the blocks used by each file.
     72   std::string mapfile_path;
     73 
     74   // The size of the data in |path|. If rootfs verification is used (verity)
     75   // this value should match the size of the verity device for the rootfs, and
     76   // the size of the whole kernel. This value could be smaller than the
     77   // partition and is the size of the data update_engine assumes verified for
     78   // the source image, and the size of that data it should generate for the
     79   // target image.
     80   uint64_t size = 0;
     81 
     82   // The FilesystemInterface implementation used to access this partition's
     83   // files.
     84   std::unique_ptr<FilesystemInterface> fs_interface;
     85 
     86   std::string name;
     87 
     88   PostInstallConfig postinstall;
     89 };
     90 
     91 // The ImageConfig struct describes a pair of binaries kernel and rootfs and the
     92 // metadata associated with the image they are part of, like build number, size,
     93 // etc.
     94 struct ImageConfig {
     95   // Returns whether the ImageConfig is an empty image.
     96   bool ValidateIsEmpty() const;
     97 
     98   // Load |rootfs_size| and |kernel.size| from the respective image files. For
     99   // the kernel, the whole |kernel.path| file is assumed. For the rootfs, the
    100   // size is detected from the filesystem.
    101   // Returns whether the image size was properly detected.
    102   bool LoadImageSize();
    103 
    104   // Load postinstall config from a key value store.
    105   bool LoadPostInstallConfig(const brillo::KeyValueStore& store);
    106 
    107   // Returns whether the |image_info| field is empty.
    108   bool ImageInfoIsEmpty() const;
    109 
    110   // The ImageInfo message defined in the update_metadata.proto file describes
    111   // the metadata of the image.
    112   ImageInfo image_info;
    113 
    114   // The updated partitions.
    115   std::vector<PartitionConfig> partitions;
    116 };
    117 
    118 struct PayloadVersion {
    119   PayloadVersion() : PayloadVersion(0, 0) {}
    120   PayloadVersion(uint64_t major_version, uint32_t minor_version);
    121 
    122   // Returns whether the PayloadVersion is valid.
    123   bool Validate() const;
    124 
    125   // Return whether the passed |operation| is allowed by this payload.
    126   bool OperationAllowed(InstallOperation_Type operation) const;
    127 
    128   // Whether this payload version is a delta payload.
    129   bool IsDelta() const;
    130 
    131   // Tells whether the update is done in-place, that is, whether the operations
    132   // read and write from the same partition.
    133   bool InplaceUpdate() const;
    134 
    135   // The major version of the payload.
    136   uint64_t major;
    137 
    138   // The minor version of the payload.
    139   uint32_t minor;
    140 
    141   // Wheter the IMGDIFF operation is allowed based on the available compressor
    142   // in the delta_generator and the one supported by the target.
    143   bool imgdiff_allowed = false;
    144 };
    145 
    146 // The PayloadGenerationConfig struct encapsulates all the configuration to
    147 // build the requested payload. This includes information about the old and new
    148 // image as well as the restrictions applied to the payload (like minor-version
    149 // and full/delta payload).
    150 struct PayloadGenerationConfig {
    151   // Returns whether the PayloadGenerationConfig is valid.
    152   bool Validate() const;
    153 
    154   // Image information about the new image that's the target of this payload.
    155   ImageConfig target;
    156 
    157   // Image information pertaining the old image, if any. This is only valid
    158   // if is_full is false, so we are requested a delta payload.
    159   ImageConfig source;
    160 
    161   // Wheter the requested payload is a delta payload.
    162   bool is_delta = false;
    163 
    164   // The major/minor version of the payload.
    165   PayloadVersion version;
    166 
    167   // The size of the rootfs partition, that not necessarily is the same as the
    168   // filesystem in either source or target version, since there is some space
    169   // after the partition used to store the verity hashes and or the bootcache.
    170   uint64_t rootfs_partition_size = 0;
    171 
    172   // The |hard_chunk_size| is the maximum size that a single operation should
    173   // write in the destination. Operations bigger than chunk_size should be
    174   // split. A value of -1 means no hard chunk size limit. A very low limit
    175   // means more operations, and less of a chance to reuse the data.
    176   ssize_t hard_chunk_size = -1;
    177 
    178   // The |soft_chunk_size| is the preferred chunk size to use when there's no
    179   // significant impact to the operations. For example, REPLACE, MOVE and
    180   // SOURCE_COPY operations are not significantly impacted by the chunk size,
    181   // except for a few bytes overhead in the manifest to describe extra
    182   // operations. On the other hand, splitting BSDIFF operations impacts the
    183   // payload size since it is not possible to use the redundancy *between*
    184   // chunks.
    185   size_t soft_chunk_size = 2 * 1024 * 1024;
    186 
    187   // TODO(deymo): Remove the block_size member and maybe replace it with a
    188   // minimum alignment size for blocks (if needed). Algorithms should be able to
    189   // pick the block_size they want, but for now only 4 KiB is supported.
    190 
    191   // The block size used for all the operations in the manifest.
    192   size_t block_size = 4096;
    193 };
    194 
    195 }  // namespace chromeos_update_engine
    196 
    197 #endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_PAYLOAD_GENERATION_CONFIG_H_
    198