Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91f74c82 authored by Tao Bao's avatar Tao Bao Committed by Gerrit Code Review
Browse files

Merge "updater: Clean up CreateStash()."

parents 3b828d87 51412212
Loading
Loading
Loading
Loading
+84 −83
Original line number Diff line number Diff line
@@ -41,27 +41,26 @@
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <applypatch/applypatch.h>
#include <openssl/sha.h>
#include <ziparchive/zip_archive.h>

#include "applypatch/applypatch.h"
#include "edify/expr.h"
#include "error_code.h"
#include "updater/install.h"
#include "openssl/sha.h"
#include "ota_io.h"
#include "print_sha1.h"
#include "updater/updater.h"

static constexpr size_t BLOCKSIZE = 4096;

// Set this to 0 to interpret 'erase' transfers to mean do a
// BLKDISCARD ioctl (the normal behavior).  Set to 1 to interpret
// erase to mean fill the region with zeroes.
#define DEBUG_ERASE  0

#define STASH_DIRECTORY_BASE "/cache/recovery"
#define STASH_DIRECTORY_MODE 0700
#define STASH_FILE_MODE 0600
static constexpr size_t BLOCKSIZE = 4096;
static constexpr const char* STASH_DIRECTORY_BASE = "/cache/recovery";
static constexpr mode_t STASH_DIRECTORY_MODE = 0700;
static constexpr mode_t STASH_FILE_MODE = 0600;

struct RangeSet {
  size_t count;  // Limit is INT_MAX.
@@ -517,7 +516,7 @@ static void UpdateFileSize(const std::string& fn, void* data) {
    return;
  }

    int* size = reinterpret_cast<int*>(data);
  size_t* size = static_cast<size_t*>(data);
  *size += sb.st_size;
}

@@ -708,8 +707,9 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks
// hash enough space for the expected amount of blocks we need to store. Returns
// >0 if we created the directory, zero if it existed already, and <0 of failure.

static int CreateStash(State* state, int maxblocks, const char* blockdev, std::string& base) {
    if (blockdev == nullptr) {
static int CreateStash(State* state, size_t maxblocks, const std::string& blockdev,
                       std::string& base) {
  if (blockdev.empty()) {
    return -1;
  }

@@ -717,29 +717,31 @@ static int CreateStash(State* state, int maxblocks, const char* blockdev, std::s
  // when updating multiple partitions at the same time, so we use the hash of
  // the block device name as the base directory
  uint8_t digest[SHA_DIGEST_LENGTH];
    SHA1(reinterpret_cast<const uint8_t*>(blockdev), strlen(blockdev), digest);
  SHA1(reinterpret_cast<const uint8_t*>(blockdev.data()), blockdev.size(), digest);
  base = print_sha1(digest);

  std::string dirname = GetStashFileName(base, "", "");
  struct stat sb;
  int res = stat(dirname.c_str(), &sb);
  size_t max_stash_size = maxblocks * BLOCKSIZE;

  if (res == -1 && errno != ENOENT) {
        ErrorAbort(state, kStashCreationFailure, "stat \"%s\" failed: %s\n",
                   dirname.c_str(), strerror(errno));
    ErrorAbort(state, kStashCreationFailure, "stat \"%s\" failed: %s\n", dirname.c_str(),
               strerror(errno));
    return -1;
  } else if (res != 0) {
    LOG(INFO) << "creating stash " << dirname;
    res = mkdir(dirname.c_str(), STASH_DIRECTORY_MODE);

    if (res != 0) {
            ErrorAbort(state, kStashCreationFailure, "mkdir \"%s\" failed: %s\n",
                       dirname.c_str(), strerror(errno));
      ErrorAbort(state, kStashCreationFailure, "mkdir \"%s\" failed: %s\n", dirname.c_str(),
                 strerror(errno));
      return -1;
    }

        if (CacheSizeCheck(maxblocks * BLOCKSIZE) != 0) {
            ErrorAbort(state, kStashCreationFailure, "not enough space for stash\n");
    if (CacheSizeCheck(max_stash_size) != 0) {
      ErrorAbort(state, kStashCreationFailure, "not enough space for stash (%zu needed)\n",
                 max_stash_size);
      return -1;
    }

@@ -753,16 +755,17 @@ static int CreateStash(State* state, int maxblocks, const char* blockdev, std::s
  // partially completed stash files first.

  EnumerateStash(dirname, DeletePartial, nullptr);
    int size = 0;
    EnumerateStash(dirname, UpdateFileSize, &size);
  size_t existing = 0;
  EnumerateStash(dirname, UpdateFileSize, &existing);

    size = maxblocks * BLOCKSIZE - size;

    if (size > 0 && CacheSizeCheck(size) != 0) {
        ErrorAbort(state, kStashCreationFailure, "not enough space for stash (%d more needed)\n",
                   size);
  if (max_stash_size > existing) {
    size_t needed = max_stash_size - existing;
    if (CacheSizeCheck(needed) != 0) {
      ErrorAbort(state, kStashCreationFailure, "not enough space for stash (%zu more needed)\n",
                 needed);
      return -1;
    }
  }

  return 0;  // Using existing directory
}
@@ -1384,8 +1387,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
        return StringValue("");
    }

    UpdaterInfo* ui = reinterpret_cast<UpdaterInfo*>(state->cookie);

    UpdaterInfo* ui = static_cast<UpdaterInfo*>(state->cookie);
    if (ui == nullptr) {
        return StringValue("");
    }
@@ -1443,7 +1445,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
    }

    // First line in transfer list is the version number
    if (!android::base::ParseInt(lines[0].c_str(), &params.version, 1, 4)) {
    if (!android::base::ParseInt(lines[0], &params.version, 1, 4)) {
        LOG(ERROR) << "unexpected transfer list version [" << lines[0] << "]";
        return StringValue("");
    }
@@ -1451,8 +1453,8 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
    LOG(INFO) << "blockimg version is " << params.version;

    // Second line in transfer list is the total number of blocks we expect to write
    int total_blocks;
    if (!android::base::ParseInt(lines[1].c_str(), &total_blocks, 0)) {
    size_t total_blocks;
    if (!android::base::ParseUint(lines[1], &total_blocks)) {
        ErrorAbort(state, kArgsParsingFailure, "unexpected block count [%s]\n", lines[1].c_str());
        return StringValue("");
    }
@@ -1473,14 +1475,14 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
        LOG(INFO) << "maximum stash entries " << lines[2];

        // Fourth line is the maximum number of blocks that will be stashed simultaneously
        int stash_max_blocks;
        if (!android::base::ParseInt(lines[3].c_str(), &stash_max_blocks, 0)) {
        size_t stash_max_blocks;
        if (!android::base::ParseUint(lines[3], &stash_max_blocks)) {
            ErrorAbort(state, kArgsParsingFailure, "unexpected maximum stash blocks [%s]\n",
                       lines[3].c_str());
            return StringValue("");
        }

        int res = CreateStash(state, stash_max_blocks, blockdev_filename->data.c_str(), params.stashbase);
        int res = CreateStash(state, stash_max_blocks, blockdev_filename->data, params.stashbase);
        if (res == -1) {
            return StringValue("");
        }
@@ -1505,15 +1507,13 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg

    // Subsequent lines are all individual transfer commands
    for (auto it = lines.cbegin() + start; it != lines.cend(); it++) {
        const std::string& line_str(*it);
        if (line_str.empty()) {
            continue;
        }
        const std::string& line(*it);
        if (line.empty()) continue;

        params.tokens = android::base::Split(line_str, " ");
        params.tokens = android::base::Split(line, " ");
        params.cpos = 0;
        params.cmdname = params.tokens[params.cpos++].c_str();
        params.cmdline = line_str.c_str();
        params.cmdline = line.c_str();

        if (cmd_map.find(params.cmdname) == cmd_map.end()) {
            LOG(ERROR) << "unexpected command [" << params.cmdname << "]";
@@ -1523,7 +1523,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
        const Command* cmd = cmd_map[params.cmdname];

        if (cmd->f != nullptr && cmd->f(params) == -1) {
            LOG(ERROR) << "failed to execute command [" << line_str << "]";
            LOG(ERROR) << "failed to execute command [" << line << "]";
            goto pbiudone;
        }

@@ -1533,7 +1533,8 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
                PLOG(ERROR) << "fsync failed";
                goto pbiudone;
            }
            fprintf(cmd_pipe, "set_progress %.4f\n", (double) params.written / total_blocks);
            fprintf(cmd_pipe, "set_progress %.4f\n",
                    static_cast<double>(params.written) / total_blocks);
            fflush(cmd_pipe);
        }
    }