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

Commit 4fc76596 authored by Tao Bao's avatar Tao Bao Committed by Gerrit Code Review
Browse files

Merge "updater: Minor clean up to EnumerateStash()."

parents 06f6227f ec8272f6
Loading
Loading
Loading
Loading
+50 −73
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <unistd.h>
#include <fec/io.h>

#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
@@ -473,19 +474,13 @@ static std::string GetStashFileName(const std::string& base, const std::string&
    return fn;
}

typedef void (*StashCallback)(const std::string&, void*);
// Does a best effort enumeration of stash files. Ignores possible non-file items in the stash
// directory and continues despite of errors. Calls the 'callback' function for each file.
static void EnumerateStash(const std::string& dirname,
                           const std::function<void(const std::string&)>& callback) {
  if (dirname.empty()) return;

// Does a best effort enumeration of stash files. Ignores possible non-file
// items in the stash directory and continues despite of errors. Calls the
// 'callback' function for each file and passes 'data' to the function as a
// parameter.

static void EnumerateStash(const std::string& dirname, StashCallback callback, void* data) {
    if (dirname.empty() || callback == nullptr) {
        return;
    }

    std::unique_ptr<DIR, int(*)(DIR*)> directory(opendir(dirname.c_str()), closedir);
  std::unique_ptr<DIR, decltype(&closedir)> directory(opendir(dirname.c_str()), closedir);

  if (directory == nullptr) {
    if (errno != ENOENT) {
@@ -494,61 +489,33 @@ static void EnumerateStash(const std::string& dirname, StashCallback callback, v
    return;
  }

    struct dirent* item;
  dirent* item;
  while ((item = readdir(directory.get())) != nullptr) {
        if (item->d_type != DT_REG) {
            continue;
        }

        std::string fn = dirname + "/" + std::string(item->d_name);
        callback(fn, data);
    }
}

static void UpdateFileSize(const std::string& fn, void* data) {
  if (fn.empty() || !data) {
    return;
  }

  struct stat sb;
  if (stat(fn.c_str(), &sb) == -1) {
    PLOG(ERROR) << "stat \"" << fn << "\" failed";
    return;
    if (item->d_type != DT_REG) continue;
    callback(dirname + "/" + item->d_name);
  }

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

// Deletes the stash directory and all files in it. Assumes that it only
// contains files. There is nothing we can do about unlikely, but possible
// errors, so they are merely logged.
static void DeleteFile(const std::string& fn) {
  if (fn.empty()) return;

static void DeleteFile(const std::string& fn, void* /* data */) {
    if (!fn.empty()) {
  LOG(INFO) << "deleting " << fn;

  if (unlink(fn.c_str()) == -1 && errno != ENOENT) {
    PLOG(ERROR) << "unlink \"" << fn << "\" failed";
  }
}
}

static void DeletePartial(const std::string& fn, void* data) {
    if (android::base::EndsWith(fn, ".partial")) {
        DeleteFile(fn, data);
    }
}

static void DeleteStash(const std::string& base) {
    if (base.empty()) {
        return;
    }
  if (base.empty()) return;

  LOG(INFO) << "deleting stash " << base;

  std::string dirname = GetStashFileName(base, "", "");
    EnumerateStash(dirname, DeleteFile, nullptr);
  EnumerateStash(dirname, DeleteFile);

  if (rmdir(dirname.c_str()) == -1) {
    if (errno != ENOENT && errno != ENOTDIR) {
@@ -624,7 +591,7 @@ static int LoadStash(CommandParameters& params, const std::string& base, const s

    if (verify && VerifyBlocks(id, buffer, *blocks, true) != 0) {
        LOG(ERROR) << "unexpected contents in " << fn;
        DeleteFile(fn, nullptr);
        DeleteFile(fn);
        return -1;
    }

@@ -750,13 +717,24 @@ static int CreateStash(State* state, size_t maxblocks, const std::string& blockd

  LOG(INFO) << "using existing stash " << dirname;

  // If the directory already exists, calculate the space already allocated to
  // stash files and check if there's enough for all required blocks. Delete any
  // partially completed stash files first.
  // If the directory already exists, calculate the space already allocated to stash files and check
  // if there's enough for all required blocks. Delete any partially completed stash files first.
  EnumerateStash(dirname, [](const std::string& fn) {
    if (android::base::EndsWith(fn, ".partial")) {
      DeleteFile(fn);
    }
  });

  EnumerateStash(dirname, DeletePartial, nullptr);
  size_t existing = 0;
  EnumerateStash(dirname, UpdateFileSize, &existing);
  EnumerateStash(dirname, [&existing](const std::string& fn) {
    if (fn.empty()) return;
    struct stat sb;
    if (stat(fn.c_str(), &sb) == -1) {
      PLOG(ERROR) << "stat \"" << fn << "\" failed";
      return;
    }
    existing += static_cast<size_t>(sb.st_size);
  });

  if (max_stash_size > existing) {
    size_t needed = max_stash_size - existing;
@@ -821,8 +799,7 @@ static int FreeStash(const std::string& base, const std::string& id) {
    return -1;
  }

    std::string fn = GetStashFileName(base, id, "");
    DeleteFile(fn, nullptr);
  DeleteFile(GetStashFileName(base, id, ""));

  return 0;
}