readahead-replay.c revision 07faed4f99d0c798f92de3032b9c20ca31388494
d657c51f14601d0235434ffb78cf6ac0f27cc83cLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
220a21d38f675eb835f5758e3d23e896573aa5eaLennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering/***
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering This file is part of systemd.
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering Copyright 2010 Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart 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
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
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 Poettering***/
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <errno.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <inttypes.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <fcntl.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <linux/limits.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <stdbool.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <stdio.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <stdlib.h>
4ef6e535e30c67d4ff34b2ca785e555dbaeac14eKay Sievers#include <string.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <sys/select.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <sys/time.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <sys/types.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <sys/stat.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <unistd.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <getopt.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include <sys/inotify.h>
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include "missing.h"
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include "util.h"
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include "set.h"
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include "sd-daemon.h"
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include "ioprio.h"
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering#include "readahead-common.h"
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poetteringstatic off_t arg_file_size_max = READAHEAD_FILE_SIZE_MAX;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poetteringstatic ReadaheadShared *shared = NULL;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poetteringstatic int unpack_file(FILE *pack) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering char fn[PATH_MAX];
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering int r = 0, fd = -1;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering bool any = false;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering struct stat st;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering assert(pack);
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (!fgets(fn, sizeof(fn), pack))
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering return 0;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering char_array_0(fn);
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering truncate_nl(fn);
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if ((fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW)) < 0) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (errno != ENOENT && errno != EPERM && errno != EACCES)
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_warning("open(%s) failed: %m", fn);
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering } else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering close_nointr_nofail(fd);
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering fd = -1;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering }
4ef6e535e30c67d4ff34b2ca785e555dbaeac14eKay Sievers
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering for (;;) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering uint32_t b, c;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (fread(&b, sizeof(b), 1, pack) != 1 ||
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering fread(&c, sizeof(c), 1, pack) != 1) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_error("Premature end of pack file.");
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering r = -EIO;
4ef6e535e30c67d4ff34b2ca785e555dbaeac14eKay Sievers goto finish;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering }
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (b == 0 && c == 0)
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering break;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (c <= b) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_error("Invalid pack file.");
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering r = -EIO;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering goto finish;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering }
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_debug("%s: page %u to %u", fn, b, c);
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering any = true;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (fd >= 0)
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 goto finish;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering }
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering }
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (!any && fd >= 0) {
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 * read */
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED) < 0) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering log_warning("posix_fadvise() failed: %m");
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering goto finish;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering }
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering }
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poetteringfinish:
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering if (fd >= 0)
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering close_nointr_nofail(fd);
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering return r;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering}
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poetteringstatic int replay(const char *root) {
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering FILE *pack = NULL;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering char line[LINE_MAX];
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering int r = 0;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering char *pack_fn = NULL, c;
699b6b3491dc265ead79602404ad67ccdacae302Lennart Poettering bool on_ssd, ready = false;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering int prio;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering int inotify_fd = -1;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering assert(root);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
67dd87c51b1ba254dc6a0eeae41762aace40addaLennart Poettering write_one_line_file("/proc/self/oom_score_adj", "1000");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering bump_request_nr(root);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_error("Out of memory");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering r = -ENOMEM;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering goto finish;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if ((!(pack = fopen(pack_fn, "re")))) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (errno == ENOENT)
ed28905eecf631916f03edd0a7dfad8b0a177990Kay Sievers log_debug("No pack file found.");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering else {
ed28905eecf631916f03edd0a7dfad8b0a177990Kay Sievers log_error("Failed to open pack file: %m");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering r = -errno;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering }
ed28905eecf631916f03edd0a7dfad8b0a177990Kay Sievers
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering goto finish;
ed28905eecf631916f03edd0a7dfad8b0a177990Kay Sievers }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering posix_fadvise(fileno(pack), 0, 0, POSIX_FADV_WILLNEED);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if ((inotify_fd = open_inotify()) < 0) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering r = inotify_fd;
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering goto finish;
949138ccc3417748b0978980e4a1c67955dd4ba4Ansgar Burchardt }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (!(fgets(line, sizeof(line), pack))) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_error("Premature end of pack file.");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering r = -EIO;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering goto finish;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering char_array_0(line);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (!streq(line, CANONICAL_HOST "\n")) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_debug("Pack file host type mismatch.");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering goto finish;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if ((c = getc(pack)) == EOF) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_debug("Premature end of pack file.");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering r = -EIO;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering goto finish;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering /* We do not retest SSD here, so that we can start replaying
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering * before udev is up.*/
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering on_ssd = c == 'S';
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_debug("On SSD: %s", yes_no(on_ssd));
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (on_ssd)
ed28905eecf631916f03edd0a7dfad8b0a177990Kay Sievers prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering else
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, 7);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
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
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering sd_notify(0, "STATUS=Replaying readahead data");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_debug("Replaying...");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (access("/dev/.systemd/readahead/noreplay", F_OK) >= 0) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering log_debug("Got termination request");
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering goto done;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering while (!feof(pack) && !ferror(pack)) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering int k;
ed28905eecf631916f03edd0a7dfad8b0a177990Kay Sievers ssize_t n;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if (errno != EINTR && errno != EAGAIN) {
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering log_error("Failed to read inotify event: %m");
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering r = -errno;
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering goto finish;
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering }
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering } else {
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering struct inotify_event *e = (struct inotify_event*) inotify_buffer;
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering while (n > 0) {
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering size_t step;
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering
ed28905eecf631916f03edd0a7dfad8b0a177990Kay Sievers if ((e->mask & IN_CREATE) && streq(e->name, "noreplay")) {
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering log_debug("Got termination request");
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering goto done;
d27893efdf652c6d85ea590fa0b7c2b88f817083Lennart Poettering }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering step = sizeof(struct inotify_event) + e->len;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering assert(step <= (size_t) n);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering e = (struct inotify_event*) ((uint8_t*) e + step);
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering n -= step;
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering }
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering if ((k = unpack_file(pack)) < 0) {
43c71255b3db02916f4f70afa18bab196c6f4a45Lennart Poettering r = k;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering goto finish;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering }
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if (!ready) {
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John /* We delay the ready notification until we
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John * queued at least one read */
4670e9d5f23fc39360c086fb58eadf8b157ee205Jan Engelhardt sd_notify(0, "READY=1");
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John ready = true;
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John }
4670e9d5f23fc39360c086fb58eadf8b157ee205Jan Engelhardt }
1e190502e78cea1f8bcb62e6d390305c89e41e6aZbigniew Jędrzejewski-Szmek
4670e9d5f23fc39360c086fb58eadf8b157ee205Jan Engelhardtdone:
1e190502e78cea1f8bcb62e6d390305c89e41e6aZbigniew Jędrzejewski-Szmek if (!ready)
1e190502e78cea1f8bcb62e6d390305c89e41e6aZbigniew Jędrzejewski-Szmek sd_notify(0, "READY=1");
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if (ferror(pack)) {
4c2413bffa7861bd3c4b3589c821ab7e0ac51c83Jan Engelhardt log_error("Failed to read pack file.");
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering r = -EIO;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering goto finish;
4c2413bffa7861bd3c4b3589c821ab7e0ac51c83Jan Engelhardt }
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_debug("Done.");
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poetteringfinish:
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John if (pack)
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John fclose(pack);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if (inotify_fd >= 0)
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering close_nointr_nofail(inotify_fd);
4c2413bffa7861bd3c4b3589c821ab7e0ac51c83Jan Engelhardt
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering free(pack_fn);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering return r;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering}
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John
4c2413bffa7861bd3c4b3589c821ab7e0ac51c83Jan Engelhardt
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. Johnstatic int help(void) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering printf("%s [OPTIONS...] [DIRECTORY]\n\n"
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-Szmek program_invocation_short_name);
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmek
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmek return 0;
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmek}
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmek
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmekstatic int parse_argv(int argc, char *argv[]) {
dfb08b058401d56c395f4f2d20ff214d31a277e5Zbigniew Jędrzejewski-Szmek
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering enum {
4c2413bffa7861bd3c4b3589c821ab7e0ac51c83Jan Engelhardt ARG_FILE_SIZE_MAX
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering };
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering static const struct option options[] = {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering { "help", no_argument, NULL, 'h' },
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX },
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering { NULL, 0, NULL, 0 }
4c2413bffa7861bd3c4b3589c821ab7e0ac51c83Jan Engelhardt };
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering int c;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering assert(argc >= 0);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering assert(argv);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering switch (c) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering case 'h':
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John help();
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering return 0;
1e190502e78cea1f8bcb62e6d390305c89e41e6aZbigniew Jędrzejewski-Szmek
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering case ARG_FILE_SIZE_MAX: {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering unsigned long long ull;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if (safe_atollu(optarg, &ull) < 0 || ull <= 0) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_error("Failed to parse maximum file size %s.", optarg);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering return -EINVAL;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering }
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering arg_file_size_max = (off_t) ull;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering break;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering }
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering case '?':
b97610038a122ff30e60b1996369ca4b979d8b19Kay Sievers return -EINVAL;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering default:
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_error("Unknown option code %c", c);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering return -EINVAL;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering }
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering }
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if (optind != argc &&
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering optind != argc-1) {
7e95eda5b36f4a5259e1e86989b5aee824d83d03Patrik Flykt help();
7e95eda5b36f4a5259e1e86989b5aee824d83d03Patrik Flykt return -EINVAL;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering }
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
4c2413bffa7861bd3c4b3589c821ab7e0ac51c83Jan Engelhardt return 1;
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John}
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. Johnint main(int argc, char*argv[]) {
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John int r;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_parse_environment();
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_open();
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if ((r = parse_argv(argc, argv)) <= 0)
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if (!enough_ram()) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_info("Disabling readahead replay due to low memory.");
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering return 0;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering }
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering if (detect_virtualization(NULL) > 0) {
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering log_info("Disabling readahead replay due to execution in virtualized environment.");
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering return 0;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering }
4c2413bffa7861bd3c4b3589c821ab7e0ac51c83Jan Engelhardt
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John if (!(shared = shared_get()))
8b7d0494a3fe35209d4db0d1b9e065e7e5cc9875Jason St. John return 1;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering shared->replay = getpid();
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering __sync_synchronize();
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
8e420494bc59d8b9d43e6d34d8ec8bb765946c74Lennart Poettering if (replay(optind < argc ? argv[optind] : "/") < 0)
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering return 1;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering return 0;
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering}
e49b5aada0df13c9e8fce7338ae34e075dd7ccd1Lennart Poettering