readahead-replay.c revision 87ce22cc0d097d9cd0297d0141eadba6c573c299
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <errno.h>
#include <inttypes.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <systemd/sd-daemon.h>
#include "missing.h"
#include "util.h"
#include "set.h"
#include "ioprio.h"
#include "readahead-common.h"
#include "virt.h"
int r = 0, fd = -1;
bool any = false;
return 0;
if (fd < 0) {
fd = -1;
}
log_error("Premature end of pack file.");
r = -EIO;
goto finish;
}
if (fd >= 0) {
/* If the inode changed the file got deleted, so just
* ignore this entry */
fd = -1;
}
}
for (;;) {
uint32_t b, c;
log_error("Premature end of pack file.");
r = -EIO;
goto finish;
}
if (b == 0 && c == 0)
break;
if (c <= b) {
log_error("Invalid pack file.");
r = -EIO;
goto finish;
}
any = true;
if (fd >= 0)
log_warning("posix_fadvise() failed: %m");
goto finish;
}
}
/* if no range is encoded in the pack file this is
* intended to mean that the whole file shall be
* read */
log_warning("posix_fadvise() failed: %m");
goto finish;
}
}
if (fd >= 0)
return r;
}
int r = 0;
int c;
int prio;
int inotify_fd = -1;
log_error("Out of memory");
r = -ENOMEM;
goto finish;
}
log_debug("No pack file found.");
else {
log_error("Failed to open pack file: %m");
r = -errno;
}
goto finish;
}
if ((inotify_fd = open_inotify()) < 0) {
r = inotify_fd;
goto finish;
}
log_error("Premature end of pack file.");
r = -EIO;
goto finish;
}
log_debug("Pack file host or version type mismatch.");
goto finish;
}
log_debug("Premature end of pack file.");
r = -EIO;
goto finish;
}
/* We do not retest SSD here, so that we can start replaying
* before udev is up.*/
on_ssd = c == 'S';
if (on_ssd)
else
/* We are not using RT here, since we'd starve IO that
we didn't record (which is for example blkid, since
its disk accesses go directly to the block device and
are thus not visible in fallocate) to death. However,
we do ask for an IO prio that is slightly higher than
the default (which is BE. 4) */
log_warning("Failed to set IDLE IO priority class: %m");
sd_notify(0, "STATUS=Replaying readahead data");
log_debug("Replaying...");
log_debug("Got termination request");
goto done;
}
int k;
ssize_t n;
log_error("Failed to read inotify event: %m");
r = -errno;
goto finish;
}
} else {
while (n > 0) {
log_debug("Got termination request");
goto done;
}
n -= step;
}
}
if ((k = unpack_file(pack)) < 0) {
r = k;
goto finish;
}
if (!ready) {
/* We delay the ready notification until we
* queued at least one read */
sd_notify(0, "READY=1");
ready = true;
}
}
done:
if (!ready)
sd_notify(0, "READY=1");
log_error("Failed to read pack file.");
r = -EIO;
goto finish;
}
log_debug("Done.");
if (pack)
if (inotify_fd >= 0)
return r;
}
int main_replay(const char *root) {
if (!root)
root = "/";
if (!enough_ram()) {
log_info("Disabling readahead replay due to low memory.");
return EXIT_SUCCESS;
}
shared = shared_get();
if (!shared)
return EXIT_FAILURE;
return EXIT_FAILURE;
return EXIT_SUCCESS;
}