chiark / gitweb /
readahead: disable collector automatically on read-only media
authorLennart Poettering <lennart@poettering.net>
Thu, 3 Mar 2011 22:03:26 +0000 (23:03 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 3 Mar 2011 22:03:26 +0000 (23:03 +0100)
TODO
src/readahead-collect.c
src/readahead-common.c
src/readahead-common.h
src/readahead-replay.c

diff --git a/TODO b/TODO
index b7c1bacb578a7ef596df4e97e863568dfccd0be8..848ea2138d0825571ee120f50f6da300a62ddc50 100644 (file)
--- a/TODO
+++ b/TODO
@@ -40,8 +40,6 @@ Features:
 
 * invoke vhangup() before and after invoking getty
 
-* skip readahead on physically r/o media
-
 * support "auto" and "comment=systemd.automount" at the same time for an fstab entry
 
 * Make use of UnknownInterface, UnknownObject
index 330d10776fc209609896aceac67a58b3ef41e8ac..0970b584197faeb63d4be162dfe88d3ce75f282b 100644 (file)
@@ -639,6 +639,7 @@ static int parse_argv(int argc, char *argv[]) {
 
 int main(int argc, char *argv[]) {
         int r;
+        const char *root;
 
         log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
         log_parse_environment();
@@ -647,6 +648,13 @@ int main(int argc, char *argv[]) {
         if ((r = parse_argv(argc, argv)) <= 0)
                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
+        root = optind < argc ? argv[optind] : "/";
+
+        if (fs_on_read_only(root) > 0) {
+                log_info("Disabling readahead collector due to read-only media.");
+                return 0;
+        }
+
         if (!enough_ram()) {
                 log_info("Disabling readahead collector due to low memory.");
                 return 0;
@@ -663,7 +671,7 @@ int main(int argc, char *argv[]) {
         shared->collect = getpid();
         __sync_synchronize();
 
-        if (collect(optind < argc ? argv[optind] : "/") < 0)
+        if (collect(root) < 0)
                 return 1;
 
         return 0;
index 85e3227f6e50d520e7972a0b1d23fe2b9905d323..e991dfd05d69d130e4aee283acfa83a257b95c8b 100644 (file)
@@ -114,6 +114,41 @@ finish:
         return b;
 }
 
+int fs_on_read_only(const char *p) {
+        struct stat st;
+        struct udev *udev = NULL;
+        struct udev_device *udev_device = NULL;
+        bool b = false;
+        const char *read_only;
+
+        assert(p);
+
+        if (stat(p, &st) < 0)
+                return -errno;
+
+        if (major(st.st_dev) == 0)
+                return false;
+
+        if (!(udev = udev_new()))
+                return -ENOMEM;
+
+        if (!(udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev)))
+                goto finish;
+
+        if ((read_only = udev_device_get_sysattr_value(udev_device, "ro")))
+                if ((b = streq(read_only, "1")))
+                        goto finish;
+
+finish:
+        if (udev_device)
+                udev_device_unref(udev_device);
+
+        if (udev)
+                udev_unref(udev);
+
+        return b;
+}
+
 bool enough_ram(void) {
         struct sysinfo si;
 
index 964ca1f2fa976dbb705b8b75a0c1a1273f45ba24..167df316d93da5b8aa83f98e632dd2c56d7a7a78 100644 (file)
@@ -32,6 +32,7 @@
 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);
 
index cd89654f983d105e7731b9d2dd7ae4ec7a9ad7ba..3bea9295fc6795a2e4896388ba164424a9a94338 100644 (file)
@@ -333,6 +333,7 @@ static int parse_argv(int argc, char *argv[]) {
 
 int main(int argc, char*argv[]) {
         int r;
+        const char *root;
 
         log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
         log_parse_environment();
@@ -341,6 +342,8 @@ int main(int argc, char*argv[]) {
         if ((r = parse_argv(argc, argv)) <= 0)
                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
+        root = optind < argc ? argv[optind] : "/";
+
         if (!enough_ram()) {
                 log_info("Disabling readahead replay due to low memory.");
                 return 0;
@@ -357,7 +360,7 @@ int main(int argc, char*argv[]) {
         shared->replay = getpid();
         __sync_synchronize();
 
-        if (replay(optind < argc ? argv[optind] : "/") < 0)
+        if (replay(root) < 0)
                 return 1;
 
         return 0;