blob: a69de2ccd49c5acafbda0d54848e14217eec845f [file] [log] [blame]
Lorenz Brunae0d90d2019-09-05 17:53:56 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package main
18
19import (
Lorenz Brundd8c80e2019-10-07 16:19:49 +020020 "fmt"
Hendrik Hofstadt0d7c91e2019-10-23 21:44:47 +020021 "git.monogon.dev/source/nexantic.git/core/internal/network"
22 "git.monogon.dev/source/nexantic.git/core/internal/node"
23 "git.monogon.dev/source/nexantic.git/core/pkg/tpm"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020024 "os"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020025 "os/signal"
Lorenz Brunf95909d2019-09-11 19:48:26 +020026 "runtime/debug"
Lorenz Brunae0d90d2019-09-05 17:53:56 +020027
28 "go.uber.org/zap"
29 "golang.org/x/sys/unix"
30)
31
32func main() {
Lorenz Brunf95909d2019-09-11 19:48:26 +020033 defer func() {
34 if r := recover(); r != nil {
35 fmt.Println("Init panicked:", r)
36 debug.PrintStack()
37 }
38 unix.Sync()
Lorenz Brundd8c80e2019-10-07 16:19:49 +020039 // TODO: Switch this to Reboot when init panics are less likely
Lorenz Brunf95909d2019-09-11 19:48:26 +020040 unix.Reboot(unix.LINUX_REBOOT_CMD_POWER_OFF)
41 }()
Lorenz Brunae0d90d2019-09-05 17:53:56 +020042 logger, err := zap.NewDevelopment()
43 if err != nil {
44 panic(err)
45 }
46 logger.Info("Starting Smalltown Init")
47
48 // Set up bare minimum mounts
49 if err := os.Mkdir("/sys", 0755); err != nil {
50 panic(err)
51 }
52 if err := unix.Mount("sysfs", "/sys", "sysfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
53 panic(err)
54 }
55
56 if err := os.Mkdir("/proc", 0755); err != nil {
57 panic(err)
58 }
59 if err := unix.Mount("procfs", "/proc", "proc", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
60 panic(err)
61 }
62
63 signalChannel := make(chan os.Signal, 2)
64 signal.Notify(signalChannel)
65
Lorenz Brunae0d90d2019-09-05 17:53:56 +020066 if err := tpm.Initialize(logger.With(zap.String("component", "tpm"))); err != nil {
67 logger.Panic("Failed to initialize TPM 2.0", zap.Error(err))
68 }
69
Lorenz Brunf95909d2019-09-11 19:48:26 +020070 networkSvc, err := network.NewNetworkService(network.Config{}, logger.With(zap.String("component", "network")))
71 if err != nil {
72 panic(err)
73 }
74 networkSvc.Start()
75
Lorenz Brundd8c80e2019-10-07 16:19:49 +020076 nodeInstance, err := node.NewSmalltownNode(logger, 7833, 7834)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020077 if err != nil {
78 panic(err)
79 }
80
Lorenz Brundd8c80e2019-10-07 16:19:49 +020081 err = nodeInstance.Start()
Lorenz Brunae0d90d2019-09-05 17:53:56 +020082 if err != nil {
83 panic(err)
84 }
85
86 // We're PID1, so orphaned processes get reparented to us to clean up
87 for {
88 sig := <-signalChannel
89 switch sig {
90 case unix.SIGCHLD:
91 var status unix.WaitStatus
92 var rusage unix.Rusage
93 for {
Lorenz Brunf95909d2019-09-11 19:48:26 +020094 res, err := unix.Wait4(-1, &status, unix.WNOHANG, &rusage)
95 if err != nil && err != unix.ECHILD {
Lorenz Brunae0d90d2019-09-05 17:53:56 +020096 logger.Error("Failed to wait on orphaned child", zap.Error(err))
97 break
98 }
99 if res <= 0 {
100 break
101 }
102 }
103 // TODO(lorenz): We can probably get more than just SIGCHLD as init, but I can't think
104 // of any others right now, just log them in case we hit any of them.
105 default:
106 logger.Warn("Got unexpected signal", zap.String("signal", sig.String()))
107 }
108 }
109}