From c3ccee650604e6cd8d471a1d7b68a51b3a8f363c Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Sat, 4 Nov 2023 23:58:33 +0000 Subject: [PATCH] preinit: print errno (in hex, it's easier) for failures --- pkgs/preinit/parseopts.c | 39 +++++++++++++++++++++++++++++++++++++-- pkgs/preinit/preinit.c | 19 +++++++++++-------- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/pkgs/preinit/parseopts.c b/pkgs/preinit/parseopts.c index d21255ae..0523924b 100644 --- a/pkgs/preinit/parseopts.c +++ b/pkgs/preinit/parseopts.c @@ -1,3 +1,5 @@ +#include +#include #include #include @@ -12,6 +14,33 @@ static int begins_with(char * str, char * prefix) return 1; } +char * pr_u32(int32_t input) { + static char buf[9]; + const char *digits = "0123456789abcdef"; + int i=0; + + buf[i] = digits[(input & 0xf0000000) >> 28]; + buf[i+1] = digits[(input & 0x0f000000) >> 24]; + if(buf[i] != '0' || buf[i+1] != '0') i+=2; + + buf[i] = digits[(input & 0x00f00000) >> 20]; + buf[i+1] = digits[(input & 0x000f0000) >> 16]; + if(buf[i] != '0' || buf[i+1] != '0') i+=2; + + buf[i] = digits[(input & 0x0000f000) >> 12]; + buf[i+1] = digits[(input & 0x00000f00) >> 8]; + if(buf[i] != '0' || buf[i+1] != '0') i+=2; + + buf[i] = digits[(input & 0x000000f0) >> 4]; + buf[i+1] = digits[(input & 0x0000000f)]; + i+=2; + + buf[i] ='\0'; + write(2, buf, i); + + return buf; +} + void parseopts(char * cmdline, char **root, char **rootfstype) { *root = 0; @@ -21,7 +50,7 @@ void parseopts(char * cmdline, char **root, char **rootfstype) { if(begins_with(p, "root=")) { *root = p + strlen("root="); while(*p && (*p != ' ')) p++; - + if(*p) { *p = '\0'; p++; @@ -43,6 +72,8 @@ void parseopts(char * cmdline, char **root, char **rootfstype) { #include #include +// cc -DTESTS -o parseopts parseopts.c && ./parseopts + #define die(fmt, ...) do { printf(fmt, __VA_ARGS__); exit(1); } while(0) #define S(x) #x #define expect_equal(actual, expected) \ @@ -91,7 +122,11 @@ int main() if(strlen(rootfstype)) die("expected empty rootfstype, got \"%s\"", rootfstype); if(strlen(root)) die("expected null root, got \"%s\"", root); + expect_equal("01", pr_u32(1)); + expect_equal("ab", pr_u32(0xab)); + expect_equal("0abc", pr_u32(0xabc)); + expect_equal("aabc", pr_u32(0xaabc)); + expect_equal("deadcafe", pr_u32(0xdeadcafe)); } - #endif diff --git a/pkgs/preinit/preinit.c b/pkgs/preinit/preinit.c index 89afb97e..f6236ec6 100644 --- a/pkgs/preinit/preinit.c +++ b/pkgs/preinit/preinit.c @@ -13,7 +13,9 @@ void parseopts(char * cmdline, char **root, char **rootfstype); #define ERR(x) write(2, x, strlen(x)) -#define AVER(c) do { if(c < 0) ERR("failed: " #c); } while(0) +#define AVER(c) do { if(c < 0) { ERR("failed: " #c ": error=0x" ); pr_u32(errno); ERR("\n"); } } while(0) + +char * pr_u32(int32_t input); static void die() { /* if init exits, it causes a kernel panic. On the Turris @@ -52,7 +54,7 @@ int main(int argc, char *argv[], char *envp[]) write(1, banner, strlen(banner)); - mount("none", "/proc", "proc", 0, NULL); + AVER(mount("none", "/proc", "proc", 0, NULL)); int cmdline = open("/proc/cmdline", O_RDONLY, 0); @@ -66,18 +68,19 @@ int main(int argc, char *argv[], char *envp[]) write(1, "cmdline: \"", 10); write(1, buf, len); write(1, "\"\n", 2); - }; - + } else { + ERR("failed: open(\"/proc/cmdline\")\n"); + die(); + } parseopts(buf, &rootdevice, &rootfstype); - + if(rootdevice) { if(!rootfstype) rootfstype = "jffs2"; /* backward compatibility */ write(1, "rootdevice ", 11); write(1, rootdevice, strlen(rootdevice)); write(1, " (", 2); write(1, rootfstype, strlen(rootfstype)); - write(1, ")\n", 1); - + write(1, ")\n", 2); AVER(mount(rootdevice, "/target/persist", rootfstype, 0, NULL)); AVER(mount("/target/persist/nix", "/target/nix", "bind", MS_BIND, NULL)); @@ -87,7 +90,7 @@ int main(int argc, char *argv[], char *envp[]) AVER(chdir("/target")); AVER(mount("/target", "/", "bind", MS_BIND | MS_REC, NULL)); - AVER(chroot(".")); + AVER(chroot(".")); argv[0] = "init"; argv[1] = NULL;