blob: 1d068d4185d0b297779453796bc7c0a8da07ffb5 [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()
Leopold Schabel68c58752019-11-14 21:00:59 +010039 // TODO(lorenz): Switch this to Reboot when init panics are less likely
40 // Best effort, nothing we can do if this fails except printing the error to the console.
41 if err := unix.Reboot(unix.LINUX_REBOOT_CMD_POWER_OFF); err != nil {
42 panic(fmt.Sprintf("failed to halt node: %v\n", err))
43 }
Lorenz Brunf95909d2019-09-11 19:48:26 +020044 }()
Lorenz Brunae0d90d2019-09-05 17:53:56 +020045 logger, err := zap.NewDevelopment()
46 if err != nil {
47 panic(err)
48 }
49 logger.Info("Starting Smalltown Init")
50
51 // Set up bare minimum mounts
52 if err := os.Mkdir("/sys", 0755); err != nil {
53 panic(err)
54 }
55 if err := unix.Mount("sysfs", "/sys", "sysfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
56 panic(err)
57 }
58
59 if err := os.Mkdir("/proc", 0755); err != nil {
60 panic(err)
61 }
62 if err := unix.Mount("procfs", "/proc", "proc", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
63 panic(err)
64 }
65
66 signalChannel := make(chan os.Signal, 2)
67 signal.Notify(signalChannel)
68
Lorenz Brunae0d90d2019-09-05 17:53:56 +020069 if err := tpm.Initialize(logger.With(zap.String("component", "tpm"))); err != nil {
70 logger.Panic("Failed to initialize TPM 2.0", zap.Error(err))
71 }
72
Lorenz Brunf95909d2019-09-11 19:48:26 +020073 networkSvc, err := network.NewNetworkService(network.Config{}, logger.With(zap.String("component", "network")))
74 if err != nil {
75 panic(err)
76 }
Leopold Schabel68c58752019-11-14 21:00:59 +010077
78 if err := networkSvc.Start(); err != nil {
79 logger.Panic("Failed to start network service", zap.Error(err))
80 }
Lorenz Brunf95909d2019-09-11 19:48:26 +020081
Lorenz Brundd8c80e2019-10-07 16:19:49 +020082 nodeInstance, err := node.NewSmalltownNode(logger, 7833, 7834)
Lorenz Brunae0d90d2019-09-05 17:53:56 +020083 if err != nil {
84 panic(err)
85 }
86
Lorenz Brundd8c80e2019-10-07 16:19:49 +020087 err = nodeInstance.Start()
Lorenz Brunae0d90d2019-09-05 17:53:56 +020088 if err != nil {
89 panic(err)
90 }
91
92 // We're PID1, so orphaned processes get reparented to us to clean up
93 for {
94 sig := <-signalChannel
95 switch sig {
96 case unix.SIGCHLD:
97 var status unix.WaitStatus
98 var rusage unix.Rusage
99 for {
Lorenz Brunf95909d2019-09-11 19:48:26 +0200100 res, err := unix.Wait4(-1, &status, unix.WNOHANG, &rusage)
101 if err != nil && err != unix.ECHILD {
Lorenz Brunae0d90d2019-09-05 17:53:56 +0200102 logger.Error("Failed to wait on orphaned child", zap.Error(err))
103 break
104 }
105 if res <= 0 {
106 break
107 }
108 }
109 // TODO(lorenz): We can probably get more than just SIGCHLD as init, but I can't think
110 // of any others right now, just log them in case we hit any of them.
111 default:
112 logger.Warn("Got unexpected signal", zap.String("signal", sig.String()))
113 }
114 }
115}