Mount checking can now hash /proc/mounts
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 13 Feb 2011 17:12:16 +0000 (17:12 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 13 Feb 2011 17:12:16 +0000 (17:12 +0000)
(chroots might not have /etc/mtab).
Check interval is now always 5s.

configure.ac
server/disorder-server.h
server/mount.c

index 6b894b9..ee96f21 100644 (file)
@@ -108,6 +108,7 @@ case "$host" in
  ;;
 *linux* | *Linux* )
   AC_MSG_RESULT([Linux])
+  AC_DEFINE_UNQUOTED([PATH_PROC_MOUNTS],["/proc/mounts"],[path to kernel mount list])
   ;;
 *-apple-darwin* )
   AC_MSG_RESULT([Mac OS X])
index 7cd1cf6..2e7374e 100644 (file)
@@ -374,15 +374,8 @@ int play_background(ev_source *ev,
 
 void periodic_mount_check(ev_source *ev_);
 
-#ifndef MOUNT_CHECK_INTERVAL
-# ifdef PATH_MTAB
-// statting a file is really cheap so check once a second
-#  define MOUNT_CHECK_INTERVAL 1
-# else
-// hashing getfsstat() output could be more expensive so be less aggressive
-#  define MOUNT_CHECK_INTERVAL 5
-# endif
-#endif
+/** @brief How often to check for new (or old) filesystems */
+# define MOUNT_CHECK_INTERVAL 5         /* seconds */
 
 #endif /* DISORDER_SERVER_H */
 
index fff1feb..6c3da7a 100644 (file)
@@ -77,8 +77,46 @@ void periodic_mount_check(ev_source *ev_) {
   memcpy(last, current, sizeof last);
   first = 0;
   gcry_md_close(h);
+#elif defined PATH_PROC_MOUNTS
+  /* On Linux we hash /proc/mounts */
+  static int first = 1;
+  static unsigned char last[20];
+
+  unsigned char *current;
+  int fd = -1, n;
+  gcrypt_hash_handle h = 0;
+  gcry_error_t e;
+  char buffer[1024];
+
+  if((e = gcry_md_open(&h, GCRY_MD_SHA1, 0))) {
+    disorder_error(0, "gcry_md_open: %s", gcry_strerror(e));
+    goto done;
+  }
+  if((fd = open(PATH_PROC_MOUNTS, O_RDONLY)) < 0) {
+    disorder_error(errno, "open %s", PATH_PROC_MOUNTS);
+    goto done;
+  }
+  for(;;) {
+    n = read(fd, buffer, sizeof buffer);
+    if(n > 0)
+      gcry_md_write(h, buffer, n);
+    else if(n == 0)
+      break;
+    else if(errno != EINTR) {
+      disorder_error(errno, "reading %s", PATH_PROC_MOUNTS);
+      goto done;
+    }
+  }
+  current = gcry_md_read(h, GCRY_MD_SHA1);
+  if(!first && memcmp(current, last, sizeof last))
+    trackdb_rescan(ev_, 1/*check*/, 0, 0);
+  memcpy(last, current, sizeof last);
+  first = 0;
+ done:
+  if(h) gcry_md_close(h);
+  if(fd != -1) close(fd);
 #elif defined PATH_MTAB
-  /* On Linux we keep track of the modification time of /etc/mtab */
+  /* As a further alternative we track the modification time of /etc/mtab */
   static time_t last_mount;
   struct stat sb;