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

Commit d97a1710 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "init: add option to read file fully on readahead"

parents 2b8a95a2 02628f3b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -453,8 +453,9 @@ Commands
`rmdir <path>`
> Calls rmdir(2) on the given path.

`readahead <file|dir>`
`readahead <file|dir> [--fully]`
> Calls readahead(2) on the file or files within given directory.
  Use option --fully to read the full file content.

`setprop <name> <value>`
> Set system property _name_ to _value_. Properties are expanded
+42 −17
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@
#include <selinux/android.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
#include <system/thread_defs.h>

#include "action.h"
#include "bootchart.h"
@@ -670,6 +671,29 @@ static Result<Success> do_write(const std::vector<std::string>& args) {
    return Success();
}

static Result<Success> readahead_file(const std::string& filename, bool fully) {
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY)));
    if (fd == -1) {
        return ErrnoError() << "Error opening file";
    }
    if (posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED)) {
        return ErrnoError() << "Error posix_fadvise file";
    }
    if (readahead(fd, 0, std::numeric_limits<size_t>::max())) {
        return ErrnoError() << "Error readahead file";
    }
    if (fully) {
        char buf[BUFSIZ];
        ssize_t n;
        while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
        }
        if (n != 0) {
            return ErrnoError() << "Error reading file";
        }
    }
    return Success();
}

static Result<Success> do_readahead(const std::vector<std::string>& args) {
    struct stat sb;

@@ -677,6 +701,10 @@ static Result<Success> do_readahead(const std::vector<std::string>& args) {
        return ErrnoError() << "Error opening " << args[1];
    }

    bool readfully = false;
    if (args.size() == 3 && args[2] == "--fully") {
        readfully = true;
    }
    // We will do readahead in a forked process in order not to block init
    // since it may block while it reads the
    // filesystem metadata needed to locate the requested blocks.  This
@@ -685,15 +713,16 @@ static Result<Success> do_readahead(const std::vector<std::string>& args) {
    // the requested data has been read.
    pid_t pid = fork();
    if (pid == 0) {
        if (setpriority(PRIO_PROCESS, 0, static_cast<int>(ANDROID_PRIORITY_LOWEST)) != 0) {
            PLOG(WARNING) << "setpriority failed";
        }
        if (android_set_ioprio(0, IoSchedClass_IDLE, 7)) {
            PLOG(WARNING) << "ioprio_get failed";
        }
        android::base::Timer t;
        if (S_ISREG(sb.st_mode)) {
            android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(args[1].c_str(), O_RDONLY)));
            if (fd == -1) {
                PLOG(ERROR) << "Error opening file: " << args[1];
                _exit(EXIT_FAILURE);
            }
            if (readahead(fd, 0, std::numeric_limits<size_t>::max())) {
                PLOG(ERROR) << "Error readahead file: " << args[1];
            if (auto result = readahead_file(args[1], readfully); !result) {
                LOG(WARNING) << "Unable to readahead '" << args[1] << "': " << result.error();
                _exit(EXIT_FAILURE);
            }
        } else if (S_ISDIR(sb.st_mode)) {
@@ -708,19 +737,15 @@ static Result<Success> do_readahead(const std::vector<std::string>& args) {
            for (FTSENT* ftsent = fts_read(fts.get()); ftsent != nullptr;
                 ftsent = fts_read(fts.get())) {
                if (ftsent->fts_info & FTS_F) {
                    android::base::unique_fd fd(
                        TEMP_FAILURE_RETRY(open(ftsent->fts_accpath, O_RDONLY)));
                    if (fd == -1) {
                        PLOG(ERROR) << "Error opening file: " << args[1];
                        continue;
                    }
                    if (readahead(fd, 0, std::numeric_limits<size_t>::max())) {
                        PLOG(ERROR) << "Unable to readahead on file: " << ftsent->fts_accpath;
                    const std::string filename = ftsent->fts_accpath;
                    if (auto result = readahead_file(filename, readfully); !result) {
                        LOG(WARNING)
                            << "Unable to readahead '" << filename << "': " << result.error();
                    }
                }
            }
        }
        LOG(INFO) << "Readahead " << args[1] << " took " << t;
        LOG(INFO) << "Readahead " << args[1] << " took " << t << " asynchronously";
        _exit(0);
    } else if (pid < 0) {
        return ErrnoError() << "Fork failed";
@@ -949,7 +974,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
        {"mount_all",               {1,     kMax, do_mount_all}},
        {"mount",                   {3,     kMax, do_mount}},
        {"umount",                  {1,     1,    do_umount}},
        {"readahead",               {1,     1,    do_readahead}},
        {"readahead",               {1,     2,    do_readahead}},
        {"restart",                 {1,     1,    do_restart}},
        {"restorecon",              {1,     kMax, do_restorecon}},
        {"restorecon_recursive",    {1,     kMax, do_restorecon_recursive}},