init: remount to tmpfs

runsc needs to be able to pivot_root. According to @lorenz this does not
work from initramfs. This introduces a temporary fix to re-mount and
re-exec into a new root based on tmpfs.

A proper fix would be to use a real filesystem instead of initramfs
(like squashfs), but this will do for now.

We also use this opportunity to use devtmpfs instead of manually
managing /dev. This collides with the storage manager that tries to
create all storage nodes - we just remove that.

Test Plan: shouldn't change behaviour

X-Origin-Diff: phab/D433
GitOrigin-RevId: aa59fec6551bab1b1b9c2fe037dce410e550981b
diff --git a/core/cmd/init/main.go b/core/cmd/init/main.go
index 82ba033..f4ff871 100644
--- a/core/cmd/init/main.go
+++ b/core/cmd/init/main.go
@@ -55,23 +55,15 @@
 	if err != nil {
 		panic(err)
 	}
+
+	// Remount onto a tmpfs and re-exec if needed. Otherwise, keep running.
+	err = switchRoot(logger)
+	if err != nil {
+		panic(fmt.Errorf("could not remount root: %w", err))
+	}
+
 	logger.Info("Starting Smalltown Init")
 
-	// Set up bare minimum mounts
-	if err := os.Mkdir("/sys", 0755); err != nil {
-		panic(err)
-	}
-	if err := unix.Mount("sysfs", "/sys", "sysfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
-		panic(err)
-	}
-
-	if err := os.Mkdir("/proc", 0755); err != nil {
-		panic(err)
-	}
-	if err := unix.Mount("procfs", "/proc", "proc", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
-		panic(err)
-	}
-
 	signalChannel := make(chan os.Signal, 2)
 	signal.Notify(signalChannel)
 
@@ -81,7 +73,7 @@
 
 	storageManager, err := storage.Initialize(logger.With(zap.String("component", "storage")))
 	if err != nil {
-		panic(err)
+		panic(fmt.Errorf("could not initialize storage: %w", err))
 	}
 
 	networkSvc, err := network.NewNetworkService(network.Config{}, logger.With(zap.String("component", "network")))