block: add support for logging to dmesg
[project/fstools.git] / block.c
diff --git a/block.c b/block.c
index a44241d..6eb1933 100644 (file)
--- a/block.c
+++ b/block.c
@@ -19,6 +19,8 @@
 #include <syslog.h>
 #include <libgen.h>
 #include <glob.h>
+#include <dirent.h>
+#include <stdarg.h>
 
 #include <sys/stat.h>
 #include <sys/types.h>
 #include "libubi/libubi.h"
 #endif
 
+static int kmsg = 0;
+
+static void klog(int prio, const char *fmt, ...)
+{
+       va_list ap;
+       FILE *f = fopen("/dev/kmsg", "w");
+
+       if (f) {
+               fprintf(f, "<%d>", prio);
+
+               va_start(ap, fmt);
+               vfprintf(f, fmt, ap);
+               va_end(ap);
+
+               fclose(f);
+       }
+}
+
+#define KINFO(fmt, ...) do { \
+               if (kmsg) klog(LOG_INFO, "block: " fmt, ## __VA_ARGS__); \
+       } while (0)
+
 #define ERROR(fmt, ...) do { \
-               syslog(LOG_ERR, fmt, ## __VA_ARGS__); \
-               fprintf(stderr, "block: "fmt, ## __VA_ARGS__); \
+               if (kmsg) \
+                       klog(LOG_ERR, "block: " fmt, ## __VA_ARGS__); \
+               else { \
+                       syslog(LOG_ERR, fmt, ## __VA_ARGS__); \
+                       fprintf(stderr, "block: "fmt, ## __VA_ARGS__); \
+               } \
        } while (0)
 
 enum {
@@ -885,6 +913,35 @@ static int find_block_ubi_RO(libubi_t libubi, char *name, char *part, int plen)
 }
 #endif
 
+static int find_root_dev(char *buf, int len)
+{
+       DIR *d;
+       dev_t root;
+       struct stat s;
+       struct dirent *e;
+
+       if (stat("/", &s))
+               return -1;
+
+       if (!(d = opendir("/dev")))
+               return -1;
+
+       root = s.st_dev;
+
+       while ((e = readdir(d)) != NULL) {
+               snprintf(buf, len, "/dev/%s", e->d_name);
+
+               if (stat(buf, &s) || s.st_rdev != root)
+                       continue;
+
+               closedir(d);
+               return 0;
+       }
+
+       closedir(d);
+       return -1;
+}
+
 static int check_extroot(char *path)
 {
        struct blkid_struct_probe *pr = NULL;
@@ -902,8 +959,10 @@ static int check_extroot(char *path)
                        return -1;
        }
 #else
-       if (find_block_mtd("rootfs", fs, sizeof(fs)))
-               return -1;
+       if (find_block_mtd("rootfs", fs, sizeof(fs))) {
+               if (find_root_dev(fs, sizeof(fs)))
+                       return -1;
+       }
 #endif
 
        list_for_each_entry(pr, &devices, list) {
@@ -1030,6 +1089,8 @@ static int main_extroot(int argc, char **argv)
                return -1;
        }
 
+       kmsg = 1;
+
        mkblkdev();
        cache_load(1);