readahead: wipe out readahead

This commit is contained in:
Daniel Buch 2014-08-26 21:17:22 +02:00 committed by Tom Gundersen
parent 4a3bb59960
commit d6bc8348d5
54 changed files with 24 additions and 2676 deletions

View File

@ -1141,34 +1141,6 @@ man/systemd-random-seed.html: man/systemd-random-seed.service.html
endif
if ENABLE_READAHEAD
MANPAGES += \
man/sd-readahead.3 \
man/sd_readahead.3 \
man/systemd-readahead-replay.service.8
MANPAGES_ALIAS += \
man/systemd-readahead-collect.service.8 \
man/systemd-readahead-done.service.8 \
man/systemd-readahead-done.timer.8 \
man/systemd-readahead.8
man/systemd-readahead-collect.service.8: man/systemd-readahead-replay.service.8
man/systemd-readahead-done.service.8: man/systemd-readahead-replay.service.8
man/systemd-readahead-done.timer.8: man/systemd-readahead-replay.service.8
man/systemd-readahead.8: man/systemd-readahead-replay.service.8
man/systemd-readahead-collect.service.html: man/systemd-readahead-replay.service.html
$(html-alias)
man/systemd-readahead-done.service.html: man/systemd-readahead-replay.service.html
$(html-alias)
man/systemd-readahead-done.timer.html: man/systemd-readahead-replay.service.html
$(html-alias)
man/systemd-readahead.html: man/systemd-readahead-replay.service.html
$(html-alias)
endif
if ENABLE_RESOLVED
MANPAGES += \
man/resolved.conf.5 \
@ -1549,7 +1521,6 @@ EXTRA_DIST += \
man/sd-id128.xml \
man/sd-journal.xml \
man/sd-login.xml \
man/sd-readahead.xml \
man/sd_booted.xml \
man/sd_bus_creds_get_pid.xml \
man/sd_bus_creds_new_from_pid.xml \
@ -1591,7 +1562,6 @@ EXTRA_DIST += \
man/sd_login_monitor_new.xml \
man/sd_notify.xml \
man/sd_pid_get_session.xml \
man/sd_readahead.xml \
man/sd_seat_get_active.xml \
man/sd_session_is_active.xml \
man/sd_uid_get_state.xml \
@ -1647,7 +1617,6 @@ EXTRA_DIST += \
man/systemd-path.xml \
man/systemd-quotacheck.service.xml \
man/systemd-random-seed.service.xml \
man/systemd-readahead-replay.service.xml \
man/systemd-remount-fs.service.xml \
man/systemd-resolved.service.xml \
man/systemd-rfkill@.service.xml \

View File

@ -2346,8 +2346,7 @@ systemctl_LDADD = \
# ------------------------------------------------------------------------------
systemd_notify_SOURCES = \
src/notify/notify.c \
src/readahead/sd-readahead.c
src/notify/notify.c
systemd_notify_LDADD = \
libsystemd-internal.la \
@ -4332,57 +4331,6 @@ endif
EXTRA_DIST += \
units/systemd-vconsole-setup.service.in
# ------------------------------------------------------------------------------
if ENABLE_READAHEAD
systemd_readahead_SOURCES = \
src/readahead/readahead.c \
src/readahead/readahead-collect.c \
src/readahead/readahead-replay.c \
src/readahead/readahead-analyze.c \
src/readahead/readahead-common.c \
src/readahead/readahead-common.h
systemd_readahead_LDADD = \
libsystemd-internal.la \
libudev-internal.la \
libsystemd-shared.la
dist_doc_DATA += \
src/readahead/sd-readahead.c \
src/systemd/sd-readahead.h
rootlibexec_PROGRAMS += \
systemd-readahead
dist_systemunit_DATA += \
units/systemd-readahead-drop.service \
units/systemd-readahead-done.timer
nodist_systemunit_DATA += \
units/systemd-readahead-collect.service \
units/systemd-readahead-replay.service \
units/systemd-readahead-done.service
manual_tests += \
test-ssd
test_ssd_SOURCES = \
src/readahead/test-ssd.c \
src/readahead/readahead-common.c \
src/readahead/readahead-common.h
test_ssd_LDADD = \
libsystemd-internal.la \
libudev-internal.la \
libsystemd-shared.la
endif
EXTRA_DIST += \
units/systemd-readahead-collect.service.in \
units/systemd-readahead-replay.service.in \
units/systemd-readahead-done.service.in
# ------------------------------------------------------------------------------
if ENABLE_BOOTCHART
systemd_bootchart_SOURCES = \

View File

@ -841,14 +841,6 @@ if test "x$enable_vconsole" != "xno"; then
fi
AM_CONDITIONAL(ENABLE_VCONSOLE, [test "$have_vconsole" = "yes"])
# ------------------------------------------------------------------------------
have_readahead=no
AC_ARG_ENABLE(readahead, AS_HELP_STRING([--disable-readahead], [disable readahead tools]))
if test "x$enable_readahead" != "xno"; then
have_readahead=yes
fi
AM_CONDITIONAL(ENABLE_READAHEAD, [test "$have_readahead" = "yes"])
# ------------------------------------------------------------------------------
have_bootchart=no
AC_ARG_ENABLE(bootchart, AS_HELP_STRING([--disable-bootchart], [disable bootchart tool]))
@ -1341,7 +1333,6 @@ AC_MSG_RESULT([
ELFUTILS: ${have_elfutils}
binfmt: ${have_binfmt}
vconsole: ${have_vconsole}
readahead: ${have_readahead}
bootchart: ${have_bootchart}
quotacheck: ${have_quotacheck}
tmpfiles: ${have_tmpfiles}

View File

@ -140,7 +140,6 @@
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>fprintf</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -131,7 +131,6 @@
<citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -1,117 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
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/>.
-->
<refentry id="sd-readahead" conditional='ENABLE_READAHEAD'>
<refentryinfo>
<title>sd-readahead</title>
<productname>systemd</productname>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>Lennart</firstname>
<surname>Poettering</surname>
<email>lennart@poettering.net</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>sd-readahead</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>sd-readahead</refname>
<refpurpose>Reference implementation of APIs for
controlling boot-time read-ahead</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include "sd-readahead.h"</funcsynopsisinfo>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><filename>sd-readahead.c</filename> and
<filename>sd-readahead.h</filename> provide a
reference implementation for APIs for controlling boot-time
read-ahead, as implemented by the read-ahead subsystem
of the
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
init system.</para>
<para>See
<citerefentry><refentrytitle>sd_readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for more information about the function
implemented.</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>This interface is provided by the reference
implementation of APIs for controlling boot-time
read-ahead and distributed with the systemd
package. The algorithms it implements are simple, and
can easily be reimplemented in daemons if it is
important to support this interface without using the
reference implementation. See the respective function
man pages for details.</para>
<para>In addition, for details about the algorithms,
check the liberally licensed reference implementation
sources:
<ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c"/>
and <ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h"/></para>
<para>These APIs are implemented in the reference
implementation's drop-in
<filename>sd-readahead.c</filename> and
<filename>sd-readahead.h</filename> files. It is
recommended that applications consuming these APIs copy
the implementation into their source tree, either
verbatim or in excerpts. These interfaces are
currently not available in a dynamic library.</para>
<para>The functions provided by this interface become
NOPs when -DDISABLE_SYSTEMD is set during
compilation. In addition, if
<filename>sd-readhead.c</filename> is compiled on
non-Linux systems it becomes NOPs.</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -1,178 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
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/>.
-->
<refentry id="sd_readahead" conditional='ENABLE_READAHEAD'>
<refentryinfo>
<title>sd_readahead</title>
<productname>systemd</productname>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>Lennart</firstname>
<surname>Poettering</surname>
<email>lennart@poettering.net</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>sd_readahead</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>sd_readahead</refname>
<refpurpose>Control ongoing disk boot-time read-ahead operations</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include "sd-readahead.h"</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_readahead</function></funcdef>
<paramdef>const char *<parameter>action</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>sd_readahead()</function> may be
called by programs involved with early boot-up to
control ongoing boot-time disk read-ahead operations. It may be
used to terminate read-ahead operations in case an
uncommon disk access pattern is to be expected and
hence read-ahead replay or collection is unlikely to
have the desired speed-up effect on the current or
future boot-ups.</para>
<para>The <parameter>action</parameter> should be one
of the following strings:</para>
<variablelist>
<varlistentry>
<term>cancel</term>
<listitem><para>Terminates read-ahead
data collection, and drops all
read-ahead data collected during this
boot-up.</para></listitem>
</varlistentry>
<varlistentry>
<term>done</term>
<listitem><para>Terminates read-ahead
data collection, but keeps all
read-ahead data collected during this
boot-up around for use during
subsequent boot-ups.</para></listitem>
</varlistentry>
<varlistentry>
<term>noreplay</term>
<listitem><para>Terminates read-ahead
replay.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Return Value</title>
<para>On failure, these calls return a negative
errno-style error code. It is generally recommended to
ignore the return value of this call.</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>This function is provided by the reference
implementation of APIs for controlling boot-time
read-ahead and distributed with the systemd
package. The algorithm it implements is simple, and
can easily be reimplemented in daemons if it is
important to support this interface without using the
reference implementation.</para>
<para>Internally, this function creates a file in
<filename>/run/systemd/readahead/</filename> which is
then used as flag file to notify the read-ahead
subsystem.</para>
<para>For details about the algorithm check the
liberally licensed reference implementation sources:
<ulink url="http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c"/>
and <ulink
url="http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h"/></para>
<para><function>sd_readahead()</function> is
implemented in the reference implementation's drop-in
<filename>sd-readahead.c</filename> and
<filename>sd-readahead.h</filename> files. It is
recommended that applications consuming this API copy
the implementation into their source tree. For more
details about the reference implementation, see
<citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry></para>
<para>If -DDISABLE_SYSTEMD is set during compilation,
this function will always return 0 and otherwise
become a NOP.</para>
</refsect1>
<refsect1>
<title>Examples</title>
<example>
<title>Cancelling all read-ahead operations</title>
<para>During boots where SELinux has to
relabel the file system hierarchy, it will
create a large amount of disk accesses that
are not necessary during normal boots. Hence
it is a good idea to disable both read-ahead replay and read-ahead collection.
</para>
<programlisting>sd_readahead("cancel");
sd_readahead("noreplay");</programlisting>
</example>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -141,17 +141,6 @@
<citerefentry><refentrytitle>sd_booted</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--readahead=</option></term>
<listitem><para>Controls disk
read-ahead operations. The argument
must be a string, and either "cancel",
"done" or "noreplay". For details
about the semantics of this option see
<citerefentry><refentrytitle>sd_readahead</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>

View File

@ -1,203 +0,0 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
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/>.
-->
<refentry id="systemd-readahead-replay.service" conditional='ENABLE_READAHEAD'
xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>systemd-readahead-replay.service</title>
<productname>systemd</productname>
<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>Lennart</firstname>
<surname>Poettering</surname>
<email>lennart@poettering.net</email>
</author>
</authorgroup>
</refentryinfo>
<refmeta>
<refentrytitle>systemd-readahead-replay.service</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>systemd-readahead-replay.service</refname>
<refname>systemd-readahead-collect.service</refname>
<refname>systemd-readahead-done.service</refname>
<refname>systemd-readahead-done.timer</refname>
<refname>systemd-readahead</refname>
<refpurpose>Disk read ahead logic</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>systemd-readahead-replay.service</filename></para>
<para><filename>systemd-readahead-collect.service</filename></para>
<para><filename>systemd-readahead-done.service</filename></para>
<para><filename>systemd-readahead-done.timer</filename></para>
<cmdsynopsis>
<command>/usr/lib/systemd/systemd-readahead/systemd-readahead</command>
<arg choice="opt" rep="repeat">OPTIONS</arg>
<arg choice="plain">COMMAND</arg>
<arg choice="opt">DIRECTORY | FILE</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><filename>systemd-readahead-collect.service</filename>
is a service that collects disk usage patterns at boot
time. <filename>systemd-readahead-replay.service</filename>
is a service that replays this access data collected
at the subsequent boot. Since disks tend to be
magnitudes slower than RAM, this is intended to improve
boot speeds by pre-loading early at boot all data on
disk that is known to be read for the complete boot
process.</para>
<para><filename>systemd-readahead-done.service</filename>
is executed a short while after boot completed and signals
<filename>systemd-readahead-collect.service</filename>
to end data collection. On this signal, this service
will then sort the collected disk accesses and store
information about them in
<filename>/.readahead</filename>.</para>
<para>Normally, both
<filename>systemd-readahead-collect.service</filename>
and
<filename>systemd-readahead-replay.service</filename>
are activated at boot so that access patterns from the
preceding boot are replayed and new data collected
for the subsequent boot. However, on read-only media
where the collected data cannot be stored, it might
be a good idea to disable
<filename>systemd-readahead-collect.service</filename>.</para>
<para>On rotating media, when replaying disk accesses
at early boot,
<filename>systemd-readahead-replay.service</filename>
will order read requests by their location on disk. On
non-rotating media, they will be ordered by their
original access timestamp. If the file system supports
it,
<filename>systemd-readahead-collect.service</filename>
will also defragment and rearrange files on disk to
optimize subsequent boot times.</para>
</refsect1>
<refsect1>
<title>Options</title>
<para><filename>systemd-readahead</filename> understands
the following options:</para>
<variablelist>
<varlistentry>
<term><option>--files-max=</option></term>
<listitem><para>Maximum number of
files to read ahead. Only valid
for thes <command>collect</command>
command.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--file-size-max=</option></term>
<listitem><para>Maximum size of files
in bytes to read ahead. Only valid
for the <command>collect</command>
and <command>replay</command>
commands.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--timeout=</option></term>
<listitem><para>Maximum time in microseconds
to spend collecting data. Only valid
for the <command>collect</command>
command.</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>
</refsect1>
<refsect1>
<title>Commands</title>
<para>The following commands are understood by
<filename>systemd-readahead</filename>:</para> <variablelist>
<varlistentry>
<term><command>collect
[<replaceable>DIRECTORY</replaceable>]</command></term>
<listitem>
<para>Collect read-ahead data on
early boot. When terminating, it will
write out a pack file to the indicated
directory containing the read-ahead
data. </para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>replay
[<replaceable>DIRECTORY</replaceable>]</command></term>
<listitem>
<para>Perform read-ahead on the
specified directory tree.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><command>analyze
[<replaceable>FILE</replaceable>]</command></term>
<listitem>
<para>Dumps the content of the
read-ahead pack file to the
terminal. For each file, the
output lists approximately how
much will be read ahead by
the <command>replay</command>
command.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -17,6 +17,5 @@ src/hostname/hostnamed.c
src/locale/localed.c
src/core/org.freedesktop.systemd1.policy.in
src/timedate/timedated.c
units/systemd-readahead-done.service.in
units/user@.service.in
units/debug-shell.service.in

View File

@ -63,8 +63,7 @@ case "$service" in
'--ready[Inform the init system about service start-up completion.]' \
'--pid=[Inform the init system about the main PID of the daemon]' \
'--status=[Send a free-form status string for the daemon to the init systemd]' \
'--booted[Returns 0 if the system was booted up with systemd]' \
'--readahead=[Controls disk read-ahead operations]:arguments:(cancel done noreply)'
'--booted[Returns 0 if the system was booted up with systemd]'
;;
systemd-tty-ask-password-agent)
_arguments \

View File

@ -131,7 +131,7 @@ static int create_disk(
"Conflicts=umount.target\n"
"BindsTo=dev-mapper-%i.device\n"
"IgnoreOnIsolate=true\n"
"After=systemd-readahead-collect.service systemd-readahead-replay.service cryptsetup-pre.target\n",
"After=cryptsetup-pre.target\n",
f);
if (!nofail)

View File

@ -144,7 +144,6 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, char **devi
"Before=umount.target cryptsetup.target\n"
"After=%s\n"
"IgnoreOnIsolate=true\n"
"After=systemd-readahead-collect.service systemd-readahead-replay.service\n\n"
"[Service]\n"
"Type=oneshot\n"
"RemainAfterExit=yes\n"

View File

@ -31,7 +31,6 @@
#include "strv.h"
#include "util.h"
#include "log.h"
#include "sd-readahead.h"
#include "build.h"
#include "env-util.h"
@ -39,7 +38,6 @@ static bool arg_ready = false;
static pid_t arg_pid = 0;
static const char *arg_status = NULL;
static bool arg_booted = false;
static const char *arg_readahead = NULL;
static void help(void) {
printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n\n"
@ -49,8 +47,7 @@ static void help(void) {
" --ready Inform the init system about service start-up completion\n"
" --pid[=PID] Set main pid of daemon\n"
" --status=TEXT Set status text\n"
" --booted Returns 0 if the system was booted up with systemd, non-zero otherwise\n"
" --readahead=ACTION Controls read-ahead operations\n",
" --booted Returns 0 if the system was booted up with systemd, non-zero otherwise\n",
program_invocation_short_name);
}
@ -62,7 +59,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_PID,
ARG_STATUS,
ARG_BOOTED,
ARG_READAHEAD
};
static const struct option options[] = {
@ -72,7 +68,6 @@ static int parse_argv(int argc, char *argv[]) {
{ "pid", optional_argument, NULL, ARG_PID },
{ "status", required_argument, NULL, ARG_STATUS },
{ "booted", no_argument, NULL, ARG_BOOTED },
{ "readahead", required_argument, NULL, ARG_READAHEAD },
{}
};
@ -118,10 +113,6 @@ static int parse_argv(int argc, char *argv[]) {
arg_booted = true;
break;
case ARG_READAHEAD:
arg_readahead = optarg;
break;
case '?':
return -EINVAL;
@ -134,8 +125,7 @@ static int parse_argv(int argc, char *argv[]) {
!arg_ready &&
!arg_status &&
!arg_pid &&
!arg_booted &&
!arg_readahead) {
!arg_booted) {
help();
return -EINVAL;
}
@ -160,14 +150,6 @@ int main(int argc, char* argv[]) {
if (arg_booted)
return sd_booted() <= 0;
if (arg_readahead) {
r = sd_readahead(arg_readahead);
if (r < 0) {
log_error("Failed to issue read-ahead control command: %s", strerror(-r));
goto finish;
}
}
if (arg_ready)
our_env[i++] = (char*) "READY=1";

View File

@ -1 +0,0 @@
../Makefile

View File

@ -1,146 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2012 Auke Kok <auke-jan.h.kok@intel.com>
systemd is free software; you can redistribute it and/or modify it
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 <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <inttypes.h>
#include <linux/limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include "readahead-common.h"
int main_analyze(const char *pack_path) {
char line[LINE_MAX];
_cleanup_fclose_ FILE *pack = NULL;
int a;
int missing = 0;
size_t tsize = 0;
if (!pack_path)
pack_path = "/.readahead";
pack = fopen(pack_path, "re");
if (!pack) {
log_error("Pack file missing.");
goto fail;
}
if (!fgets(line, sizeof(line), pack)) {
log_error("Pack file corrupt.");
goto fail;
}
char_array_0(line);
if (!endswith(line, READAHEAD_PACK_FILE_VERSION)) {
log_error("Pack file version incompatible with this parser.");
goto fail;
}
if ((a = getc(pack)) == EOF) {
log_error("Pack file corrupt.");
goto fail;
}
fputs(" pct sections size: path\n"
" === ======== ====: ====\n", stdout);
for (;;) {
char path[PATH_MAX];
struct stat st;
uint64_t inode;
int pages = 0;
int sections = 0;
if (!fgets(path, sizeof(path), pack))
break; /* done */
path[strlen(path)-1] = 0;
if (fread(&inode, sizeof(inode), 1, pack) != 1) {
log_error("Pack file corrupt.");
goto fail;
}
for (;;) {
uint32_t b, c;
if (fread(&b, sizeof(b), 1, pack) != 1 ||
fread(&c, sizeof(c), 1, pack) != 1) {
log_error("Pack file corrupt.");
goto fail;
}
if ((b == 0) && (c == 0))
break;
/* Uncomment this to get all the chunks separately
printf(" %d: %d %d\n", sections, b, c);
*/
pages += (c - b);
sections++;
}
if (stat(path, &st) == 0) {
off_t size;
if (sections == 0)
size = st.st_size;
else
size = pages * page_size();
tsize += size;
printf(" %4jd%% (%2d) %12jd: %s\n",
(intmax_t) (sections && st.st_size ? size * 100 / st.st_size : 100),
sections ? sections : 1,
(intmax_t) size,
path);
} else {
printf(" %4dp (%2d) %12s: %s (MISSING)\n",
sections ? pages : -1,
sections ? sections : 1,
"???",
path);
missing++;
}
}
printf("\nHOST: %s"
"TYPE: %c\n"
"MISSING: %d\n"
"TOTAL: %zu\n",
line,
a,
missing,
tsize);
return EXIT_SUCCESS;
fail:
return EXIT_FAILURE;
}

View File

@ -1,650 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
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 <linux/limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fanotify.h>
#include <sys/signalfd.h>
#include <sys/poll.h>
#include <sys/mman.h>
#include <linux/fs.h>
#include <linux/fiemap.h>
#include <sys/ioctl.h>
#include <sys/vfs.h>
#include <getopt.h>
#include <sys/inotify.h>
#include <math.h>
#ifdef HAVE_LINUX_BTRFS_H
#include <linux/btrfs.h>
#endif
#ifdef HAVE_FANOTIFY_INIT
#include <sys/fanotify.h>
#endif
#include "systemd/sd-daemon.h"
#include "missing.h"
#include "util.h"
#include "set.h"
#include "ioprio.h"
#include "readahead-common.h"
#include "virt.h"
/* fixme:
*
* - detect ssd on btrfs/lvm...
* - read ahead directories
* - gzip?
* - remount rw?
* - handle files where nothing is in mincore
* - does ioprio_set work with fadvise()?
*/
static ReadaheadShared *shared = NULL;
static usec_t starttime;
/* Avoid collisions with the NULL pointer */
#define SECTOR_TO_PTR(s) ULONG_TO_PTR((s)+1)
#define PTR_TO_SECTOR(p) (PTR_TO_ULONG(p)-1)
static int btrfs_defrag(int fd) {
struct btrfs_ioctl_vol_args data = { .fd = fd };
return ioctl(fd, BTRFS_IOC_DEFRAG, &data);
}
static int pack_file(FILE *pack, const char *fn, bool on_btrfs) {
struct stat st;
void *start = MAP_FAILED;
uint8_t *vec;
uint32_t b, c;
uint64_t inode;
size_t l, pages;
bool mapped;
int r = 0, fd = -1, k;
assert(pack);
assert(fn);
fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW);
if (fd < 0) {
if (errno == ENOENT)
return 0;
if (errno == EPERM || errno == EACCES)
return 0;
log_warning("open(%s) failed: %m", fn);
r = -errno;
goto finish;
}
k = file_verify(fd, fn, arg_file_size_max, &st);
if (k <= 0) {
r = k;
goto finish;
}
if (on_btrfs)
btrfs_defrag(fd);
l = PAGE_ALIGN(st.st_size);
start = mmap(NULL, l, PROT_READ, MAP_SHARED, fd, 0);
if (start == MAP_FAILED) {
log_warning("mmap(%s) failed: %m", fn);
r = -errno;
goto finish;
}
pages = l / page_size();
vec = alloca0(pages);
if (mincore(start, l, vec) < 0) {
log_warning("mincore(%s) failed: %m", fn);
r = -errno;
goto finish;
}
fputs(fn, pack);
fputc('\n', pack);
/* Store the inode, so that we notice when the file is deleted */
inode = (uint64_t) st.st_ino;
fwrite(&inode, sizeof(inode), 1, pack);
mapped = false;
for (c = 0; c < pages; c++) {
bool new_mapped = !!(vec[c] & 1);
if (!mapped && new_mapped)
b = c;
else if (mapped && !new_mapped) {
fwrite(&b, sizeof(b), 1, pack);
fwrite(&c, sizeof(c), 1, pack);
log_debug("%s: page %u to %u", fn, b, c);
}
mapped = new_mapped;
}
/* We don't write any range data if we should read the entire file */
if (mapped && b > 0) {
fwrite(&b, sizeof(b), 1, pack);
fwrite(&c, sizeof(c), 1, pack);
log_debug("%s: page %u to %u", fn, b, c);
}
/* End marker */
b = 0;
fwrite(&b, sizeof(b), 1, pack);
fwrite(&b, sizeof(b), 1, pack);
finish:
if (start != MAP_FAILED)
munmap(start, l);
safe_close(fd);
return r;
}
static unsigned long fd_first_block(int fd) {
struct {
struct fiemap fiemap;
struct fiemap_extent extent;
} data = {
.fiemap.fm_length = ~0ULL,
.fiemap.fm_extent_count = 1,
};
if (ioctl(fd, FS_IOC_FIEMAP, &data) < 0)
return 0;
if (data.fiemap.fm_mapped_extents <= 0)
return 0;
if (data.fiemap.fm_extents[0].fe_flags & FIEMAP_EXTENT_UNKNOWN)
return 0;
return (unsigned long) data.fiemap.fm_extents[0].fe_physical;
}
struct item {
const char *path;
unsigned long block;
unsigned long bin;
};
static int qsort_compare(const void *a, const void *b) {
const struct item *i, *j;
i = a;
j = b;
/* sort by bin first */
if (i->bin < j->bin)
return -1;
if (i->bin > j->bin)
return 1;
/* then sort by sector */
if (i->block < j->block)
return -1;
if (i->block > j->block)
return 1;
return strcmp(i->path, j->path);
}
static int collect(const char *root) {
enum {
FD_FANOTIFY, /* Get the actual fs events */
FD_SIGNAL,
FD_INOTIFY, /* We get notifications to quit early via this fd */
_FD_MAX
};
struct pollfd pollfd[_FD_MAX] = {};
int fanotify_fd = -1, signal_fd = -1, inotify_fd = -1, r = 0;
pid_t my_pid;
Hashmap *files = NULL;
Iterator i;
char *p, *q;
sigset_t mask;
FILE *pack = NULL;
char *pack_fn_new = NULL, *pack_fn = NULL;
bool on_ssd, on_btrfs;
struct statfs sfs;
usec_t not_after;
uint64_t previous_block_readahead;
bool previous_block_readahead_set = false;
assert(root);
if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
r = log_oom();
goto finish;
}
starttime = now(CLOCK_MONOTONIC);
/* If there's no pack file yet we lower the kernel readahead
* so that mincore() is accurate. If there is a pack file
* already we assume it is accurate enough so that kernel
* readahead is never triggered. */
previous_block_readahead_set =
access(pack_fn, F_OK) < 0 &&
block_get_readahead(root, &previous_block_readahead) >= 0 &&
block_set_readahead(root, 8*1024) >= 0;
if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)) < 0)
log_warning("Failed to set IDLE IO priority class: %m");
assert_se(sigemptyset(&mask) == 0);
sigset_add_many(&mask, SIGINT, SIGTERM, -1);
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
log_error("signalfd(): %m");
r = -errno;
goto finish;
}
files = hashmap_new(&string_hash_ops);
if (!files) {
log_error("Failed to allocate set.");
r = -ENOMEM;
goto finish;
}
fanotify_fd = fanotify_init(FAN_CLOEXEC|FAN_NONBLOCK, O_RDONLY|O_LARGEFILE|O_CLOEXEC|O_NOATIME);
if (fanotify_fd < 0) {
log_error("Failed to create fanotify object: %m");
r = -errno;
goto finish;
}
if (fanotify_mark(fanotify_fd, FAN_MARK_ADD|FAN_MARK_MOUNT, FAN_OPEN, AT_FDCWD, root) < 0) {
log_error("Failed to mark %s: %m", root);
r = -errno;
goto finish;
}
inotify_fd = open_inotify();
if (inotify_fd < 0) {
r = inotify_fd;
goto finish;
}
not_after = now(CLOCK_MONOTONIC) + arg_timeout;
my_pid = getpid();
pollfd[FD_FANOTIFY].fd = fanotify_fd;
pollfd[FD_FANOTIFY].events = POLLIN;
pollfd[FD_SIGNAL].fd = signal_fd;
pollfd[FD_SIGNAL].events = POLLIN;
pollfd[FD_INOTIFY].fd = inotify_fd;
pollfd[FD_INOTIFY].events = POLLIN;
sd_notify(0,
"READY=1\n"
"STATUS=Collecting readahead data");
log_debug("Collecting...");
if (access("/run/systemd/readahead/cancel", F_OK) >= 0) {
log_debug("Collection canceled");
r = -ECANCELED;
goto finish;
}
if (access("/run/systemd/readahead/done", F_OK) >= 0) {
log_debug("Got termination request");
goto done;
}
for (;;) {
union {
struct fanotify_event_metadata metadata;
char buffer[4096];
} data;
ssize_t n;
struct fanotify_event_metadata *m;
usec_t t;
int h;
if (hashmap_size(files) > arg_files_max) {
log_debug("Reached maximum number of read ahead files, ending collection.");
break;
}
t = now(CLOCK_MONOTONIC);
if (t >= not_after) {
log_debug("Reached maximum collection time, ending collection.");
break;
}
if ((h = poll(pollfd, _FD_MAX, (int) ((not_after - t) / USEC_PER_MSEC))) < 0) {
if (errno == EINTR)
continue;
log_error("poll(): %m");
r = -errno;
goto finish;
}
if (h == 0) {
log_debug("Reached maximum collection time, ending collection.");
break;
}
if (pollfd[FD_SIGNAL].revents) {
log_debug("Got signal.");
break;
}
if (pollfd[FD_INOTIFY].revents) {
uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
struct inotify_event *e;
if ((n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
log_error("Failed to read inotify event: %m");
r = -errno;
goto finish;
}
e = (struct inotify_event*) inotify_buffer;
while (n > 0) {
size_t step;
if ((e->mask & IN_CREATE) && streq(e->name, "cancel")) {
log_debug("Collection canceled");
r = -ECANCELED;
goto finish;
}
if ((e->mask & IN_CREATE) && streq(e->name, "done")) {
log_debug("Got termination request");
goto done;
}
step = sizeof(struct inotify_event) + e->len;
assert(step <= (size_t) n);
e = (struct inotify_event*) ((uint8_t*) e + step);
n -= step;
}
}
n = read(fanotify_fd, &data, sizeof(data));
if (n < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
/* fanotify sometimes returns EACCES on read()
* where it shouldn't. For now let's just
* ignore it here (which is safe), but
* eventually this should be
* dropped when the kernel is fixed.
*
* https://bugzilla.redhat.com/show_bug.cgi?id=707577 */
if (errno == EACCES)
continue;
log_error("Failed to read event: %m");
r = -errno;
goto finish;
}
for (m = &data.metadata; FAN_EVENT_OK(m, n); m = FAN_EVENT_NEXT(m, n)) {
char fn[sizeof("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
int k;
if (m->fd < 0)
goto next_iteration;
if (m->pid == my_pid)
goto next_iteration;
__sync_synchronize();
if (m->pid == shared->replay)
goto next_iteration;
snprintf(fn, sizeof(fn), "/proc/self/fd/%i", m->fd);
k = readlink_malloc(fn, &p);
if (k >= 0) {
if (startswith(p, "/tmp") ||
endswith(p, " (deleted)") ||
hashmap_get(files, p))
/* Not interesting, or
* already read */
free(p);
else {
unsigned long ul;
usec_t entrytime;
struct item *entry;
entry = new0(struct item, 1);
if (!entry) {
r = log_oom();
goto finish;
}
ul = fd_first_block(m->fd);
entrytime = now(CLOCK_MONOTONIC);
entry->block = ul;
entry->path = strdup(p);
if (!entry->path) {
free(entry);
r = log_oom();
goto finish;
}
entry->bin = (entrytime - starttime) / 2000000;
k = hashmap_put(files, p, entry);
if (k < 0) {
log_warning("hashmap_put() failed: %s", strerror(-k));
free(p);
}
}
} else
log_warning("readlink(%s) failed: %s", fn, strerror(-k));
next_iteration:
safe_close(m->fd);
}
}
done:
fanotify_fd = safe_close(fanotify_fd);
log_debug("Writing Pack File...");
on_ssd = fs_on_ssd(root) > 0;
log_debug("On SSD: %s", yes_no(on_ssd));
on_btrfs = statfs(root, &sfs) >= 0 && F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC);
log_debug("On btrfs: %s", yes_no(on_btrfs));
if (asprintf(&pack_fn_new, "%s/.readahead.new", root) < 0) {
r = log_oom();
goto finish;
}
pack = fopen(pack_fn_new, "we");
if (!pack) {
log_error("Failed to open pack file: %m");
r = -errno;
goto finish;
}
fputs(CANONICAL_HOST READAHEAD_PACK_FILE_VERSION, pack);
putc(on_ssd ? 'S' : 'R', pack);
if (on_ssd || on_btrfs) {
/* On SSD or on btrfs, just write things out in the
* order the files were accessed. */
HASHMAP_FOREACH_KEY(q, p, files, i)
pack_file(pack, p, on_btrfs);
} else {
unsigned n;
/* On rotating media, order things by the block
* numbers */
log_debug("Ordering...");
n = hashmap_size(files);
if (n) {
_cleanup_free_ struct item *ordered;
struct item *j;
unsigned k;
ordered = new(struct item, n);
if (!ordered) {
r = log_oom();
goto finish;
}
j = ordered;
HASHMAP_FOREACH_KEY(q, p, files, i) {
memcpy(j, q, sizeof(struct item));
j++;
}
assert(ordered + n == j);
qsort(ordered, n, sizeof(struct item), qsort_compare);
for (k = 0; k < n; k++)
pack_file(pack, ordered[k].path, on_btrfs);
} else
log_warning("No pack files");
}
log_debug("Finalizing...");
fflush(pack);
if (ferror(pack)) {
log_error("Failed to write pack file.");
r = -EIO;
goto finish;
}
if (rename(pack_fn_new, pack_fn) < 0) {
log_error("Failed to rename readahead file: %m");
r = -errno;
goto finish;
}
fclose(pack);
pack = NULL;
log_debug("Done.");
finish:
safe_close(fanotify_fd);
safe_close(signal_fd);
safe_close(inotify_fd);
if (pack) {
fclose(pack);
unlink(pack_fn_new);
}
free(pack_fn_new);
free(pack_fn);
while ((p = hashmap_steal_first_key(files)))
free(p);
hashmap_free(files);
if (previous_block_readahead_set) {
uint64_t bytes;
/* Restore the original kernel readahead setting if we
* changed it, and nobody has overwritten it since
* yet. */
if (block_get_readahead(root, &bytes) >= 0 && bytes == 8*1024)
block_set_readahead(root, previous_block_readahead);
}
return r;
}
int main_collect(const char *root) {
if (!root)
root = "/";
/* Skip this step on read-only media. Note that we check the
* underlying block device here, not he read-only flag of the
* file system on top, since that one is most likely mounted
* read-only anyway at boot, even if the underlying block
* device is theoretically writable. */
if (fs_on_read_only(root) > 0) {
log_info("Disabling readahead collector due to read-only media.");
return EXIT_SUCCESS;
}
if (!enough_ram()) {
log_info("Disabling readahead collector due to low memory.");
return EXIT_SUCCESS;
}
shared = shared_get();
if (!shared)
return EXIT_FAILURE;
shared->collect = getpid();
__sync_synchronize();
if (collect(root) < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}

View File

@ -1,398 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
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 <stdlib.h>
#include <string.h>
#include <sys/sysinfo.h>
#include <sys/inotify.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include "log.h"
#include "readahead-common.h"
#include "util.h"
#include "missing.h"
#include "fileio.h"
#include "libudev.h"
#include "udev-util.h"
int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st) {
assert(fd >= 0);
assert(fn);
assert(st);
if (fstat(fd, st) < 0) {
log_warning("fstat(%s) failed: %m", fn);
return -errno;
}
if (!S_ISREG(st->st_mode)) {
log_debug("Not preloading special file %s", fn);
return 0;
}
if (st->st_size <= 0 || st->st_size > file_size_max) {
assert_cc(sizeof(st->st_size) == 8);
log_debug("Not preloading file %s with size out of bounds %"PRIu64,
fn, st->st_size);
return 0;
}
return 1;
}
int fs_on_ssd(const char *p) {
struct stat st;
_cleanup_udev_unref_ struct udev *udev = NULL;
_cleanup_udev_device_unref_ struct udev_device *udev_device = NULL;
struct udev_device *look_at = NULL;
const char *devtype, *rotational, *model, *id;
int r;
assert(p);
if (stat(p, &st) < 0)
return -errno;
if (major(st.st_dev) == 0) {
_cleanup_fclose_ FILE *f = NULL;
int mount_id;
union file_handle_union h = { .handle.handle_bytes = MAX_HANDLE_SZ, };
/* Might be btrfs, which exposes "ssd" as mount flag if it is on ssd.
*
* We first determine the mount ID here, if we can,
* and then lookup the mount ID in mountinfo to find
* the mount options. */
r = name_to_handle_at(AT_FDCWD, p, &h.handle, &mount_id, AT_SYMLINK_FOLLOW);
if (r < 0)
return false;
f = fopen("/proc/self/mountinfo", "re");
if (!f)
return false;
for (;;) {
char line[LINE_MAX], *e;
_cleanup_free_ char *opts = NULL;
int mid;
if (!fgets(line, sizeof(line), f))
return false;
truncate_nl(line);
if (sscanf(line, "%i", &mid) != 1)
continue;
if (mid != mount_id)
continue;
e = strstr(line, " - ");
if (!e)
continue;
if (sscanf(e+3, "%*s %*s %ms", &opts) != 1)
continue;
if (streq(opts, "ssd") || startswith(opts, "ssd,") || endswith(opts, ",ssd") || strstr(opts, ",ssd,"))
return true;
}
return false;
}
udev = udev_new();
if (!udev)
return -ENOMEM;
udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev);
if (!udev_device)
return false;
devtype = udev_device_get_property_value(udev_device, "DEVTYPE");
if (devtype && streq(devtype, "partition"))
look_at = udev_device_get_parent(udev_device);
else
look_at = udev_device;
if (!look_at)
return false;
/* First, try high-level property */
id = udev_device_get_property_value(look_at, "ID_SSD");
if (id)
return streq(id, "1");
/* Second, try kernel attribute */
rotational = udev_device_get_sysattr_value(look_at, "queue/rotational");
if (rotational)
return streq(rotational, "0");
/* Finally, fallback to heuristics */
look_at = udev_device_get_parent(look_at);
if (!look_at)
return false;
model = udev_device_get_sysattr_value(look_at, "model");
if (model)
return !!strstr(model, "SSD");
return false;
}
int fs_on_read_only(const char *p) {
struct stat st;
_cleanup_udev_unref_ struct udev *udev = NULL;
_cleanup_udev_device_unref_ struct udev_device *udev_device = NULL;
const char *read_only;
assert(p);
if (stat(p, &st) < 0)
return -errno;
if (major(st.st_dev) == 0)
return false;
udev = udev_new();
if (!udev)
return -ENOMEM;
udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev);
if (!udev_device)
return false;
read_only = udev_device_get_sysattr_value(udev_device, "ro");
if (read_only)
return streq(read_only, "1");
return false;
}
bool enough_ram(void) {
struct sysinfo si;
assert_se(sysinfo(&si) >= 0);
/* Enable readahead only with at least 128MB memory */
return si.totalram > 127 * 1024*1024 / si.mem_unit;
}
static void mkdirs(void) {
if (mkdir("/run/systemd", 0755) && errno != EEXIST)
log_warning("Failed to create /run/systemd: %m");
if (mkdir("/run/systemd/readahead", 0755) && errno != EEXIST)
log_warning("Failed to create /run/systemd: %m");
}
int open_inotify(void) {
int fd;
fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
if (fd < 0) {
log_error("Failed to create inotify handle: %m");
return -errno;
}
mkdirs();
if (inotify_add_watch(fd, "/run/systemd/readahead", IN_CREATE) < 0) {
log_error("Failed to watch /run/systemd/readahead: %m");
safe_close(fd);
return -errno;
}
return fd;
}
ReadaheadShared *shared_get(void) {
_cleanup_close_ int fd = -1;
ReadaheadShared *m = NULL;
mkdirs();
fd = open("/run/systemd/readahead/shared", O_CREAT|O_RDWR|O_CLOEXEC, 0644);
if (fd < 0) {
log_error("Failed to create shared memory segment: %m");
return NULL;
}
if (ftruncate(fd, sizeof(ReadaheadShared)) < 0) {
log_error("Failed to truncate shared memory segment: %m");
return NULL;
}
m = mmap(NULL, sizeof(ReadaheadShared), PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
if (m == MAP_FAILED) {
log_error("Failed to mmap shared memory segment: %m");
return NULL;
}
return m;
}
/* We use 20K instead of the more human digestable 16K here. Why?
Simply so that it is more unlikely that users end up picking this
value too so that we can recognize better whether the user changed
the value while we had it temporarily bumped. */
#define BUMP_REQUEST_NR (20*1024u)
int block_bump_request_nr(const char *p) {
struct stat st;
uint64_t u;
char *ap = NULL, *line = NULL;
int r;
dev_t d;
assert(p);
if (stat(p, &st) < 0)
return -errno;
if (major(st.st_dev) == 0)
return 0;
d = st.st_dev;
block_get_whole_disk(d, &d);
if (asprintf(&ap, "/sys/dev/block/%u:%u/queue/nr_requests", major(d), minor(d)) < 0) {
r= -ENOMEM;
goto finish;
}
r = read_one_line_file(ap, &line);
if (r < 0) {
if (r == -ENOENT)
r = 0;
goto finish;
}
r = safe_atou64(line, &u);
if (r >= 0 && u >= BUMP_REQUEST_NR) {
r = 0;
goto finish;
}
free(line);
line = NULL;
if (asprintf(&line, "%u", BUMP_REQUEST_NR) < 0) {
r = -ENOMEM;
goto finish;
}
r = write_string_file(ap, line);
if (r < 0)
goto finish;
log_info("Bumped block_nr parameter of %u:%u to %u. This is a temporary hack and should be removed one day.", major(d), minor(d), BUMP_REQUEST_NR);
r = 1;
finish:
free(ap);
free(line);
return r;
}
int block_get_readahead(const char *p, uint64_t *bytes) {
struct stat st;
char *ap = NULL, *line = NULL;
int r;
dev_t d;
uint64_t u;
assert(p);
assert(bytes);
if (stat(p, &st) < 0)
return -errno;
if (major(st.st_dev) == 0)
return 0;
d = st.st_dev;
block_get_whole_disk(d, &d);
if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) {
r = -ENOMEM;
goto finish;
}
r = read_one_line_file(ap, &line);
if (r < 0)
goto finish;
r = safe_atou64(line, &u);
if (r < 0)
goto finish;
*bytes = u * 1024ULL;
finish:
free(ap);
free(line);
return r;
}
int block_set_readahead(const char *p, uint64_t bytes) {
struct stat st;
char *ap = NULL, *line = NULL;
int r;
dev_t d;
assert(p);
assert(bytes);
if (stat(p, &st) < 0)
return -errno;
if (major(st.st_dev) == 0)
return 0;
d = st.st_dev;
block_get_whole_disk(d, &d);
if (asprintf(&ap, "/sys/dev/block/%u:%u/bdi/read_ahead_kb", major(d), minor(d)) < 0) {
r = -ENOMEM;
goto finish;
}
if (asprintf(&line, "%llu", bytes / 1024ULL) < 0) {
r = -ENOMEM;
goto finish;
}
r = write_string_file(ap, line);
if (r < 0)
goto finish;
finish:
free(ap);
free(line);
return r;
}

View File

@ -1,61 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#pragma once
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
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 <sys/stat.h>
#include <sys/types.h>
#include "macro.h"
#include "util.h"
#define READAHEAD_FILE_SIZE_MAX (10*1024*1024)
#define READAHEAD_PACK_FILE_VERSION ";VERSION=2\n"
extern unsigned arg_files_max;
extern off_t arg_file_size_max;
extern usec_t arg_timeout;
int file_verify(int fd, const char *fn, off_t file_size_max, struct stat *st);
int fs_on_ssd(const char *p);
int fs_on_read_only(const char *p);
bool enough_ram(void);
int open_inotify(void);
typedef struct ReadaheadShared {
pid_t collect;
pid_t replay;
} _packed_ ReadaheadShared;
ReadaheadShared *shared_get(void);
int block_bump_request_nr(const char *p);
int block_get_readahead(const char *p, uint64_t *bytes);
int block_set_readahead(const char *p, uint64_t bytes);
int main_collect(const char *root);
int main_replay(const char *root);
int main_analyze(const char *pack_path);

View File

@ -1,281 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
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 <linux/limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/inotify.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"
static ReadaheadShared *shared = NULL;
static int unpack_file(FILE *pack) {
_cleanup_close_ int fd = -1;
char fn[PATH_MAX];
bool any = false;
struct stat st;
uint64_t inode;
assert(pack);
if (!fgets(fn, sizeof(fn), pack))
return 0;
char_array_0(fn);
truncate_nl(fn);
fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOATIME|O_NOCTTY|O_NOFOLLOW);
if (fd < 0) {
if (errno != ENOENT && errno != EPERM && errno != EACCES && errno != ELOOP)
log_warning("open(%s) failed: %m", fn);
} else if (file_verify(fd, fn, arg_file_size_max, &st) <= 0)
fd = safe_close(fd);
if (fread(&inode, sizeof(inode), 1, pack) != 1) {
log_error("Premature end of pack file.");
return -EIO;
}
if (fd >= 0) {
/* If the inode changed the file got deleted, so just
* ignore this entry */
if (st.st_ino != (uint64_t) inode)
fd = safe_close(fd);
}
for (;;) {
uint32_t b, c;
if (fread(&b, sizeof(b), 1, pack) != 1 ||
fread(&c, sizeof(c), 1, pack) != 1) {
log_error("Premature end of pack file.");
return -EIO;
}
if (b == 0 && c == 0)
break;
if (c <= b) {
log_error("Invalid pack file.");
return -EIO;
}
log_debug("%s: page %u to %u", fn, b, c);
any = true;
if (fd >= 0) {
if (posix_fadvise(fd, b * page_size(), (c - b) * page_size(), POSIX_FADV_WILLNEED) < 0) {
log_warning("posix_fadvise() failed: %m");
return -errno;
}
}
}
if (!any && fd >= 0) {
/* if no range is encoded in the pack file this is
* intended to mean that the whole file shall be
* read */
if (posix_fadvise(fd, 0, st.st_size, POSIX_FADV_WILLNEED) < 0) {
log_warning("posix_fadvise() failed: %m");
return -errno;
}
}
return 0;
}
static int replay(const char *root) {
_cleanup_close_ int inotify_fd = -1;
_cleanup_free_ char *pack_fn = NULL;
_cleanup_fclose_ FILE *pack = NULL;
bool on_ssd, ready = false;
char line[LINE_MAX];
int prio, c;
assert(root);
block_bump_request_nr(root);
if (asprintf(&pack_fn, "%s/.readahead", root) < 0)
return log_oom();
pack = fopen(pack_fn, "re");
if (!pack) {
if (errno == ENOENT) {
log_debug("No pack file found.");
return 0;
}
log_error("Failed to open pack file: %m");
return -errno;
}
posix_fadvise(fileno(pack), 0, 0, POSIX_FADV_WILLNEED);
inotify_fd = open_inotify();
if (inotify_fd < 0)
return inotify_fd;
if (!fgets(line, sizeof(line), pack)) {
log_error("Premature end of pack file.");
return -EIO;
}
char_array_0(line);
if (!streq(line, CANONICAL_HOST READAHEAD_PACK_FILE_VERSION)) {
log_debug("Pack file host or version type mismatch.");
goto done;
}
c = getc(pack);
if (c == EOF) {
log_debug("Premature end of pack file.");
return -EIO;
}
/* We do not retest SSD here, so that we can start replaying
* before udev is up.*/
on_ssd = c == 'S';
log_debug("On SSD: %s", yes_no(on_ssd));
if (on_ssd)
prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
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) */
prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 2);
if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), prio) < 0)
log_warning("Failed to set IDLE IO priority class: %m");
sd_notify(0, "STATUS=Replaying readahead data");
log_debug("Replaying...");
if (access("/run/systemd/readahead/noreplay", F_OK) >= 0) {
log_debug("Got termination request");
goto done;
}
while (!feof(pack) && !ferror(pack)) {
uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
int k;
ssize_t n;
n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer));
if (n < 0) {
if (errno != EINTR && errno != EAGAIN) {
log_error("Failed to read inotify event: %m");
return -errno;
}
} else {
struct inotify_event *e = (struct inotify_event*) inotify_buffer;
while (n > 0) {
size_t step;
if ((e->mask & IN_CREATE) && streq(e->name, "noreplay")) {
log_debug("Got termination request");
goto done;
}
step = sizeof(struct inotify_event) + e->len;
assert(step <= (size_t) n);
e = (struct inotify_event*) ((uint8_t*) e + step);
n -= step;
}
}
k = unpack_file(pack);
if (k < 0)
return k;
if (!ready) {
/* We delay the ready notification until we
* queued at least one read */
sd_notify(0, "READY=1");
ready = true;
}
}
done:
if (ferror(pack)) {
log_error("Failed to read pack file.");
return -EIO;
}
if (!ready)
sd_notify(0, "READY=1");
log_debug("Done.");
return 0;
}
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;
shared->replay = getpid();
__sync_synchronize();
if (replay(root) < 0)
return EXIT_FAILURE;
return EXIT_SUCCESS;
}

View File

@ -1,163 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2012 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
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 <stdio.h>
#include <getopt.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "util.h"
#include "def.h"
#include "build.h"
#include "readahead-common.h"
unsigned arg_files_max = 16*1024;
off_t arg_file_size_max = READAHEAD_FILE_SIZE_MAX;
usec_t arg_timeout = 2*USEC_PER_MINUTE;
static void help(void) {
printf("%1$s [OPTIONS...] collect [DIRECTORY]\n\n"
"Collect read-ahead data on early boot.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --files-max=INT Maximum number of files to read ahead\n"
" --file-size-max=BYTES Maximum size of files to read ahead\n"
" --timeout=USEC Maximum time to spend collecting data\n"
"\n\n"
"%1$s [OPTIONS...] replay [DIRECTORY]\n\n"
"Replay collected read-ahead data on early boot.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --file-size-max=BYTES Maximum size of files to read ahead\n"
"\n\n"
"%1$s [OPTIONS...] analyze [PACK-FILE]\n\n"
"Analyze collected read-ahead data.\n\n"
" -h --help Show this help\n"
" --version Show package version\n",
program_invocation_short_name);
}
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_FILES_MAX,
ARG_FILE_SIZE_MAX,
ARG_TIMEOUT
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "files-max", required_argument, NULL, ARG_FILES_MAX },
{ "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX },
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
{}
};
int c;
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
switch (c) {
case 'h':
help();
return 0;
case ARG_VERSION:
puts(PACKAGE_STRING);
puts(SYSTEMD_FEATURES);
return 0;
case ARG_FILES_MAX:
if (safe_atou(optarg, &arg_files_max) < 0 || arg_files_max <= 0) {
log_error("Failed to parse maximum number of files %s.", optarg);
return -EINVAL;
}
break;
case ARG_FILE_SIZE_MAX: {
unsigned long long ull;
if (safe_atollu(optarg, &ull) < 0 || ull <= 0) {
log_error("Failed to parse maximum file size %s.", optarg);
return -EINVAL;
}
arg_file_size_max = (off_t) ull;
break;
}
case ARG_TIMEOUT:
if (parse_sec(optarg, &arg_timeout) < 0 || arg_timeout <= 0) {
log_error("Failed to parse timeout %s.", optarg);
return -EINVAL;
}
break;
case '?':
return -EINVAL;
default:
assert_not_reached("Unhandled option");
}
if (optind != argc-1 &&
optind != argc-2) {
log_error("%s: wrong number of arguments.",
program_invocation_short_name);
return -EINVAL;
}
return 1;
}
int main(int argc, char *argv[]) {
int r;
log_set_target(LOG_TARGET_SAFE);
log_parse_environment();
log_open();
umask(0022);
r = parse_argv(argc, argv);
if (r <= 0)
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
if (streq(argv[optind], "collect"))
return main_collect(argv[optind+1]);
else if (streq(argv[optind], "replay"))
return main_replay(argv[optind+1]);
else if (streq(argv[optind], "analyze"))
return main_analyze(argv[optind+1]);
log_error("Unknown verb %s.", argv[optind]);
return EXIT_FAILURE;
}

View File

@ -1,89 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
Copyright 2010 Lennart Poettering
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
***/
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include "sd-readahead.h"
#if (__GNUC__ >= 4)
# ifdef SD_EXPORT_SYMBOLS
/* Export symbols */
# define _sd_export_ __attribute__ ((visibility("default")))
# else
/* Don't export the symbols */
# define _sd_export_ __attribute__ ((visibility("hidden")))
# endif
#else
# define _sd_export_
#endif
static int touch(const char *path) {
#if !defined(DISABLE_SYSTEMD) && defined(__linux__)
int fd;
mkdir("/run/systemd", 0755);
mkdir("/run/systemd/readahead", 0755);
fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0666);
if (fd < 0)
return -errno;
for (;;) {
if (close(fd) >= 0)
break;
if (errno != EINTR)
return -errno;
}
#endif
return 0;
}
_sd_export_ int sd_readahead(const char *action) {
if (!action)
return -EINVAL;
if (strcmp(action, "cancel") == 0)
return touch("/run/systemd/readahead/cancel");
else if (strcmp(action, "done") == 0)
return touch("/run/systemd/readahead/done");
else if (strcmp(action, "noreplay") == 0)
return touch("/run/systemd/readahead/noreplay");
return -EINVAL;
}

View File

@ -1,41 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Zbigniew Jędrzejewski-Szmek
systemd is free software; you can redistribute it and/or modify it
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 "readahead-common.h"
int main(int argc, char *argv[]) {
int i;
for (i = 1; i < argc; i++) {
char *name = argv[i];
int r;
r = fs_on_ssd(name);
if (r < 0) {
log_error("%s: %s", name, strerror(-r));
return EXIT_FAILURE;
}
log_info("%s: %s", name, r ? "SSD" : "---");
}
return EXIT_SUCCESS;
}

View File

@ -1,73 +0,0 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
#ifndef foosdreadaheadhfoo
#define foosdreadaheadhfoo
/***
Copyright 2010 Lennart Poettering
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
***/
#ifdef __cplusplus
extern "C" {
#endif
/*
Reference implementation of a few boot read-ahead-related
interfaces. These interfaces are trivial to implement. To simplify
porting, we provide this reference implementation. Applications are
welcome to reimplement the algorithms described here if they do not
want to include these two source files.
You may compile this with -DDISABLE_SYSTEMD to disable systemd
support. This makes all calls NOPs.
Because this is drop-in code, we don't want any of our symbols to be
exported in any case. Hence, we declare hidden visibility for all of
them.
You may find an up-to-date version of these source files online:
http://cgit.freedesktop.org/systemd/systemd/plain/src/systemd/sd-readahead.h
http://cgit.freedesktop.org/systemd/systemd/plain/src/readahead/sd-readahead.c
This should compile on non-Linux systems too, but all functions
will become NOPs.
See sd-readahead(3) for more information.
*/
/*
Controls on-going disk read-ahead operations during boot-up. The argument
must be one of the following strings: "cancel", "done", or "noreplay".
cancel = terminate read-ahead data collection, and drop collected information
done = terminate read-ahead data collection, and keep collected information
noreplay = terminate read-ahead replay
*/
int sd_readahead(const char *action);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -10,7 +10,6 @@
enable remote-fs.target
enable getty@.service
enable systemd-readahead-*
enable systemd-timesyncd.service
enable systemd-networkd.service
enable systemd-resolved.service

3
units/.gitignore vendored
View File

@ -47,9 +47,6 @@
/systemd-poweroff.service
/systemd-quotacheck.service
/systemd-random-seed.service
/systemd-readahead-collect.service
/systemd-readahead-done.service
/systemd-readahead-replay.service
/systemd-reboot.service
/systemd-remount-fs.service
/systemd-resolved.service

View File

@ -10,7 +10,7 @@ Description=Rebuild Dynamic Linker Cache
Documentation=man:ldconfig(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
After=systemd-remount-fs.service
Before=sysinit.target shutdown.target systemd-update-done.service
ConditionNeedsUpdate=/etc

View File

@ -9,7 +9,7 @@
Description=Enable File System Quotas
Documentation=man:quotaon(8)
DefaultDependencies=no
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-quotacheck.service
After=systemd-quotacheck.service
Before=local-fs.target shutdown.target
ConditionPathExists=@QUOTAON@

View File

@ -10,7 +10,7 @@ Description=System Update
Documentation=http://freedesktop.org/wiki/Software/systemd/SystemUpdates
Documentation=man:systemd.special(7) man:systemd-system-update-generator(8)
Requires=sysinit.target
Conflicts=shutdown.target systemd-readahead-collect.service systemd-readahead-replay.service
Conflicts=shutdown.target
After=sysinit.target
Before=shutdown.target
AllowIsolate=yes

View File

@ -11,7 +11,7 @@ Documentation=man:systemd-backlight@.service(8)
DefaultDependencies=no
RequiresMountsFor=/var/lib/systemd/backlight
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
After=systemd-remount-fs.service
Before=sysinit.target shutdown.target
[Service]

View File

@ -11,7 +11,7 @@ Documentation=man:systemd-binfmt.service(8) man:binfmt.d(5)
Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service proc-sys-fs-binfmt_misc.automount
After=proc-sys-fs-binfmt_misc.automount
Before=sysinit.target shutdown.target
ConditionPathIsReadWrite=/proc/sys/
ConditionDirectoryNotEmpty=|/lib/binfmt.d

View File

@ -10,7 +10,7 @@ Description=First Boot Wizard
Documentation=man:systemd-firstboot(1)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service systemd-sysusers.service
After=systemd-remount-fs.service systemd-sysusers.service
Before=sysinit.target shutdown.target
ConditionPathIsReadWrite=/etc
ConditionFirstBoot=yes

View File

@ -9,7 +9,6 @@
Description=File System Check on Root Device
Documentation=man:systemd-fsck-root.service(8)
DefaultDependencies=no
After=systemd-readahead-collect.service systemd-readahead-replay.service
Before=local-fs.target shutdown.target
ConditionPathIsReadWrite=!/

View File

@ -10,7 +10,7 @@ Description=File System Check on %f
Documentation=man:systemd-fsck@.service(8)
DefaultDependencies=no
BindsTo=%i.device
After=systemd-readahead-collect.service systemd-readahead-replay.service %i.device systemd-fsck-root.service local-fs-pre.target
After=%i.device systemd-fsck-root.service local-fs-pre.target
Before=shutdown.target
[Service]

View File

@ -10,7 +10,7 @@ Description=Rebuild Journal Catalog
Documentation=man:systemd-journald.service(8) man:journald.conf(5)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
After=local-fs.target
Before=sysinit.target shutdown.target systemd-update-done.service
ConditionNeedsUpdate=/etc

View File

@ -10,7 +10,6 @@ Description=Load Kernel Modules
Documentation=man:systemd-modules-load.service(8) man:modules-load.d(5)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service
Before=sysinit.target shutdown.target
ConditionCapability=CAP_SYS_MODULE
ConditionDirectoryNotEmpty=|/lib/modules-load.d

View File

@ -9,7 +9,7 @@
Description=File System Quota Check
Documentation=man:systemd-quotacheck.service(8)
DefaultDependencies=no
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
After=systemd-remount-fs.service
Before=local-fs.target shutdown.target
ConditionPathExists=@QUOTACHECK@

View File

@ -11,7 +11,7 @@ Documentation=man:systemd-random-seed.service(8) man:random(4)
DefaultDependencies=no
RequiresMountsFor=@RANDOM_SEED@
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
After=systemd-remount-fs.service
Before=sysinit.target shutdown.target
[Service]

View File

@ -1,28 +0,0 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# 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.
[Unit]
Description=Collect Read-Ahead Data
Documentation=man:systemd-readahead-replay.service(8)
DefaultDependencies=no
Wants=systemd-readahead-done.timer
Conflicts=shutdown.target
Before=sysinit.target shutdown.target
ConditionPathExists=!/run/systemd/readahead/cancel
ConditionPathExists=!/run/systemd/readahead/done
ConditionVirtualization=no
[Service]
Type=notify
ExecStart=@rootlibexecdir@/systemd-readahead collect
RemainAfterExit=yes
StandardOutput=null
OOMScoreAdjust=1000
[Install]
WantedBy=default.target
Also=systemd-readahead-drop.service

View File

@ -1,22 +0,0 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# 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.
[Unit]
Description=Stop Read-Ahead Data Collection
Documentation=man:systemd-readahead-replay.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=default.target
Before=shutdown.target
ConditionVirtualization=no
[Service]
Type=oneshot
ExecStart=@SYSTEMD_NOTIFY@ --readahead=done
[Install]
Also=systemd-readahead-collect.service

View File

@ -1,22 +0,0 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# 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.
[Unit]
Description=Stop Read-Ahead Data Collection 10s After Completed Startup
Documentation=man:systemd-readahead-replay.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=default.target
Before=shutdown.target
ConditionVirtualization=no
[Timer]
OnActiveSec=30s
AccuracySec=1s
[Install]
Also=systemd-readahead-collect.service

View File

@ -1,19 +0,0 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# 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.
[Unit]
Description=Drop Read-Ahead Data
Documentation=man:systemd-readahead-replay.service(8)
ConditionPathExists=/.readahead
[Service]
Type=oneshot
ExecStart=/bin/rm -f /.readahead
[Install]
WantedBy=system-update.target
Also=systemd-readahead-collect.service

View File

@ -1,26 +0,0 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# 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.
[Unit]
Description=Replay Read-Ahead Data
Documentation=man:systemd-readahead-replay.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
Before=sysinit.target shutdown.target
ConditionPathExists=!/run/systemd/readahead/noreplay
ConditionPathExists=/.readahead
ConditionVirtualization=no
[Service]
Type=notify
ExecStart=@rootlibexecdir@/systemd-readahead replay
RemainAfterExit=yes
StandardOutput=null
OOMScoreAdjust=1000
[Install]
WantedBy=default.target

View File

@ -11,7 +11,7 @@ Documentation=man:systemd-remount-fs.service(8)
Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-fsck-root.service
After=systemd-fsck-root.service
Before=local-fs-pre.target local-fs.target shutdown.target
Wants=local-fs-pre.target
ConditionPathExists=/etc/fstab

View File

@ -11,7 +11,7 @@ Documentation=man:systemd-rfkill@.service(8)
DefaultDependencies=no
RequiresMountsFor=/var/lib/systemd/rfkill
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
After=systemd-remount-fs.service
Before=sysinit.target shutdown.target
[Service]

View File

@ -10,7 +10,6 @@ Description=Apply Kernel Variables
Documentation=man:systemd-sysctl.service(8) man:sysctl.d(5)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service
After=systemd-modules-load.service
Before=sysinit.target shutdown.target
ConditionPathIsReadWrite=/proc/sys/

View File

@ -10,7 +10,7 @@ Description=Create System Users
Documentation=man:sysusers.d(5) man:systemd-sysusers.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
After=systemd-remount-fs.service
Before=sysinit.target shutdown.target systemd-update-done.service
ConditionNeedsUpdate=/etc

View File

@ -10,7 +10,7 @@ Description=Cleanup of Temporary Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target time-sync.target
After=local-fs.target time-sync.target
Before=shutdown.target
[Service]

View File

@ -10,7 +10,7 @@ Description=Create Static Device Nodes in /dev
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-sysusers.service
After=systemd-sysusers.service
Before=sysinit.target local-fs-pre.target systemd-udevd.service shutdown.target
ConditionCapability=CAP_SYS_MODULE

View File

@ -10,7 +10,7 @@ Description=Create Volatile Files and Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target systemd-sysusers.service
After=local-fs.target systemd-sysusers.service
Before=sysinit.target shutdown.target
RefuseManualStop=yes

View File

@ -10,7 +10,7 @@ Description=Rebuild Hardware Database
Documentation=man:udev(7) man:systemd-udevd.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
After=systemd-remount-fs.service
Before=sysinit.target shutdown.target systemd-update-done.service
ConditionNeedsUpdate=/etc

View File

@ -10,7 +10,7 @@ Description=Update is Completed
Documentation=man:systemd-update-done.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
After=local-fs.target
Before=sysinit.target shutdown.target
ConditionNeedsUpdate=|/etc
ConditionNeedsUpdate=|/var

View File

@ -11,7 +11,7 @@ Documentation=man:systemd-update-utmp.service(8) man:utmp(5)
DefaultDependencies=no
RequiresMountsFor=/var/log/wtmp
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service
After=systemd-remount-fs.service systemd-tmpfiles-setup.service auditd.service
Before=sysinit.target shutdown.target
[Service]

View File

@ -10,7 +10,6 @@ Description=Setup Virtual Console
Documentation=man:systemd-vconsole-setup.service(8) man:vconsole.conf(5)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-readahead-collect.service systemd-readahead-replay.service
Before=sysinit.target shutdown.target
ConditionPathExists=/dev/tty0