chiark / gitweb /
units: use OOMScoreAdjust= in the unit files to set OOM score adjust
[elogind.git] / src / readahead / readahead-collect.c
index 7e6c243b5e1be0ddb5321df5a9558cc19c7bec4b..a88e7f2d70f2e1a1d2733bf8e53872ad6b2b8b61 100644 (file)
@@ -6,16 +6,16 @@
   Copyright 2010 Lennart Poettering
 
   systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
+  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
-  General Public License for more details.
+  Lesser General Public License for more details.
 
-  You should have received a copy of the GNU General Public License
+  You should have received a copy of the GNU Lesser General Public License
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
@@ -233,10 +233,25 @@ static int collect(const char *root) {
         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);
 
-        write_one_line_file("/proc/self/oom_score_adj", "1000");
+        if (asprintf(&pack_fn, "%s/.readahead", root) < 0) {
+                log_error("Out of memory");
+                r = -ENOMEM;
+                goto finish;
+        }
+
+        /* 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");
@@ -458,10 +473,7 @@ done:
         on_btrfs = statfs(root, &sfs) >= 0 && (long) sfs.f_type == (long) BTRFS_SUPER_MAGIC;
         log_debug("On btrfs: %s", yes_no(on_btrfs));
 
-        asprintf(&pack_fn, "%s/.readahead", root);
-        asprintf(&pack_fn_new, "%s/.readahead.new", root);
-
-        if (!pack_fn || !pack_fn_new) {
+        if (asprintf(&pack_fn_new, "%s/.readahead.new", root) < 0) {
                 log_error("Out of memory");
                 r = -ENOMEM;
                 goto finish;
@@ -551,7 +563,6 @@ finish:
                 fclose(pack);
                 unlink(pack_fn_new);
         }
-
         free(pack_fn_new);
         free(pack_fn);
 
@@ -560,6 +571,16 @@ finish:
 
         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;
 }
 
@@ -660,11 +681,17 @@ int main(int argc, char *argv[]) {
 
         umask(0022);
 
-        if ((r = parse_argv(argc, argv)) <= 0)
+        r = parse_argv(argc, argv);
+        if (r <= 0)
                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
         root = optind < argc ? argv[optind] : "/";
 
+        /* 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 0;
@@ -675,12 +702,8 @@ int main(int argc, char *argv[]) {
                 return 0;
         }
 
-        if (detect_virtualization(NULL) > 0) {
-                log_info("Disabling readahead collector due to execution in virtualized environment.");
-                return 0;
-        }
-
-        if (!(shared = shared_get()))
+        shared = shared_get();
+        if (!shared)
                 return 1;
 
         shared->collect = getpid();