chiark / gitweb /
mount: add nosuid,nodev,noexec switches to /var/lock and /var/run
[elogind.git] / src / readahead-collect.c
index aa136ce50ec82e3ba6a84aa360d74532bf876bf9..a9f544dd3ac4a29e30df58b139642a3ef88daa9b 100644 (file)
@@ -54,7 +54,6 @@
  *
  * - detect ssd on btrfs/lvm...
  * - read ahead directories
- * - sd_readahead_cancel
  * - gzip?
  * - remount rw?
  * - handle files where nothing is in mincore
@@ -65,6 +64,12 @@ static unsigned arg_files_max = 16*1024;
 static off_t arg_file_size_max = READAHEAD_FILE_SIZE_MAX;
 static usec_t arg_timeout = 2*USEC_PER_MINUTE;
 
+static ReadaheadShared *shared = NULL;
+
+/* 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;
 
@@ -201,7 +206,7 @@ static int qsort_compare(const void *a, const void *b) {
 
 static int collect(const char *root) {
         enum {
-                FD_FANOTIFY,  /* Get the actualy fs events */
+                FD_FANOTIFY,  /* Get the actual fs events */
                 FD_SIGNAL,
                 FD_INOTIFY,   /* We get notifications to quit early via this fd */
                 _FD_MAX
@@ -376,36 +381,44 @@ static int collect(const char *root) {
                 }
 
                 for (m = &data.metadata; FAN_EVENT_OK(m, n); m = FAN_EVENT_NEXT(m, n)) {
+                        char fn[PATH_MAX];
+                        int k;
 
-                        if (m->pid != my_pid && m->fd >= 0) {
-                                char fn[PATH_MAX];
-                                int k;
+                        if (m->fd < 0)
+                                goto next_iteration;
 
-                                snprintf(fn, sizeof(fn), "/proc/self/fd/%i", m->fd);
-                                char_array_0(fn);
+                        if (m->pid == my_pid)
+                                goto next_iteration;
 
-                                if ((k = readlink_malloc(fn, &p)) >= 0) {
+                        __sync_synchronize();
+                        if (m->pid == shared->replay)
+                                goto next_iteration;
 
-                                        if (startswith(p, "/tmp") ||
-                                            hashmap_get(files, p))
-                                                /* Not interesting, or
-                                                 * already read */
-                                                free(p);
-                                        else {
-                                                unsigned long ul;
+                        snprintf(fn, sizeof(fn), "/proc/self/fd/%i", m->fd);
+                        char_array_0(fn);
 
-                                                ul = fd_first_block(m->fd);
+                        if ((k = readlink_malloc(fn, &p)) >= 0) {
+                                if (startswith(p, "/tmp") ||
+                                    endswith(p, " (deleted)") ||
+                                    hashmap_get(files, p))
+                                        /* Not interesting, or
+                                         * already read */
+                                        free(p);
+                                else {
+                                        unsigned long ul;
 
-                                                if ((k = hashmap_put(files, p, ULONG_TO_PTR(ul))) < 0) {
-                                                        log_warning("set_put() failed: %s", strerror(-k));
-                                                        free(p);
-                                                }
+                                        ul = fd_first_block(m->fd);
+
+                                        if ((k = hashmap_put(files, p, SECTOR_TO_PTR(ul))) < 0) {
+                                                log_warning("set_put() failed: %s", strerror(-k));
+                                                free(p);
                                         }
+                                }
 
-                                } else
-                                        log_warning("readlink(%s) failed: %s", fn, strerror(-k));
-                        }
+                        } else
+                                log_warning("readlink(%s) failed: %s", fn, strerror(-k));
 
+                next_iteration:
                         if (m->fd)
                                 close_nointr_nofail(m->fd);
                 }
@@ -419,10 +432,10 @@ done:
 
         log_debug("Writing Pack File...");
 
-        on_ssd = fs_on_ssd(root);
+        on_ssd = fs_on_ssd(root) > 0;
         log_debug("On SSD: %s", yes_no(on_ssd));
 
-        on_btrfs = statfs(root, &sfs) >= 0 && sfs.f_type == BTRFS_SUPER_MAGIC;
+        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);
@@ -469,7 +482,7 @@ done:
                 j = ordered;
                 HASHMAP_FOREACH_KEY(q, p, files, i) {
                         j->path = p;
-                        j->block = PTR_TO_ULONG(q);
+                        j->block = PTR_TO_SECTOR(q);
                         j++;
                 }
 
@@ -632,6 +645,12 @@ int main(int argc, char *argv[]) {
                 return 0;
         }
 
+        if (!(shared = shared_get()))
+                return 1;
+
+        shared->collect = getpid();
+        __sync_synchronize();
+
         if (collect(optind < argc ? argv[optind] : "/") < 0)
                 return 1;