readahead-replay.c revision 07faed4f99d0c798f92de3032b9c20ca31388494
d657c51f14601d0235434ffb78cf6ac0f27cc83cLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering This file is part of systemd.
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering Copyright 2010 Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering systemd is free software; you can redistribute it and/or modify it
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering under the terms of the GNU General Public License as published by
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering the Free Software Foundation; either version 2 of the License, or
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering (at your option) any later version.
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering systemd is distributed in the hope that it will be useful, but
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering General Public License for more details.
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering You should have received a copy of the GNU General Public License
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poetteringstatic off_t arg_file_size_max = READAHEAD_FILE_SIZE_MAX;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if ((fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW)) < 0) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (errno != ENOENT && errno != EPERM && errno != EACCES)
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering } else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (fread(&b, sizeof(b), 1, pack) != 1 ||
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_error("Premature end of pack file.");
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (b == 0 && c == 0)
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_debug("%s: page %u to %u", fn, b, c);
4ef6e535e30c67d4ff34b2ca785e555dbaeac14eKay Sievers if (posix_fadvise(fd, b * PAGE_SIZE, (c - b) * PAGE_SIZE, POSIX_FADV_WILLNEED) < 0) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_warning("posix_fadvise() failed: %m");
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering /* if no range is encoded in the pack file this is
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering * intended to mean that the whole file shall be
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED) < 0) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_warning("posix_fadvise() failed: %m");
67dd87c51b1ba254dc6a0eeae41762aace40addaLennart Poettering write_one_line_file("/proc/self/oom_score_adj", "1000");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering posix_fadvise(fileno(pack), 0, 0, POSIX_FADV_WILLNEED);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (!(fgets(line, sizeof(line), pack))) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_error("Premature end of pack file.");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_debug("Pack file host type mismatch.");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_debug("Premature end of pack file.");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering /* We do not retest SSD here, so that we can start replaying
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering * before udev is up.*/
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, 7);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), prio) < 0)
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_warning("Failed to set IDLE IO priority class: %m");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering sd_notify(0, "STATUS=Replaying readahead data");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (access("/dev/.systemd/readahead/noreplay", F_OK) >= 0) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering log_error("Failed to read inotify event: %m");
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering struct inotify_event *e = (struct inotify_event*) inotify_buffer;
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering while (n > 0) {
ed28905eecf631916f03edd0a7dfad8b0a177990Kay Sievers if ((e->mask & IN_CREATE) && streq(e->name, "noreplay")) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering step = sizeof(struct inotify_event) + e->len;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering e = (struct inotify_event*) ((uint8_t*) e + step);
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John /* We delay the ready notification until we
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John * queued at least one read */
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. Johnstatic int help(void) {
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmek "Replay collected read-ahead data on early boot.\n\n"
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmek " -h --help Show this help\n"
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmek " --max-file-size=BYTES Maximum size of files to read ahead\n",
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmekstatic int parse_argv(int argc, char *argv[]) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX },
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering unsigned long long ull;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if (safe_atollu(optarg, &ull) < 0 || ull <= 0) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_error("Failed to parse maximum file size %s.", optarg);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_info("Disabling readahead replay due to low memory.");
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_info("Disabling readahead replay due to execution in virtualized environment.");
8e420494bc59d8b9d43e6d34d8ec8bb765946c74Lennart Poettering if (replay(optind < argc ? argv[optind] : "/") < 0)