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;
}

File diff suppressed because it is too large Load Diff

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;
}

Some files were not shown because too many files have changed in this diff Show More