mirror of
https://github.com/jetkvm/kvm.git
synced 2026-05-21 05:20:35 +00:00
d1027206bc
* Enhance synctrace logging. Switched the maps to be indexed by the .Pointer (not a string) Grouped the lockCount, unlockCount ,and lastLock in an trackingEntry so we can detect unlocks of something that wasn't ever locked and excessive unlocks and also tracks the first time locked and the last unlock time. Added LogDangledLocks for debugging use. Added a panic handler to the Main so we can log out panics * Switch to traceable sync for most everything * More documentation * Update internal/sync/log.go * Update DEVELOPMENT.md * Resolve merge issue. * Applied review comments * Restore --enable-sync-trace option. * Use WithLevel so we can re-panic as desired
118 lines
2.6 KiB
Go
118 lines
2.6 KiB
Go
package kvm
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/jetkvm/kvm/internal/ota"
|
|
"github.com/jetkvm/kvm/internal/sync"
|
|
)
|
|
|
|
func extractSerialNumber() (string, error) {
|
|
content, err := os.ReadFile("/proc/cpuinfo")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
r, err := regexp.Compile(`Serial\s*:\s*(\S+)`)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to compile regex: %w", err)
|
|
}
|
|
|
|
matches := r.FindStringSubmatch(string(content))
|
|
if len(matches) < 2 {
|
|
return "", fmt.Errorf("no serial found")
|
|
}
|
|
|
|
return matches[1], nil
|
|
}
|
|
|
|
func hwReboot(force bool, postRebootAction *ota.PostRebootAction, delay time.Duration) error {
|
|
logger.Info().Dur("delayMs", delay).Msg("reboot requested")
|
|
|
|
writeJSONRPCEvent("willReboot", postRebootAction, currentSession)
|
|
time.Sleep(1 * time.Second) // Wait for the JSONRPCEvent to be sent
|
|
|
|
nativeInstance.SwitchToScreenIfDifferent("rebooting_screen")
|
|
if delay > 1*time.Second {
|
|
time.Sleep(delay - 1*time.Second) // wait requested extra settle time
|
|
}
|
|
|
|
args := []string{}
|
|
if force {
|
|
args = append(args, "-f")
|
|
}
|
|
|
|
cmd := exec.Command("reboot", args...)
|
|
err := cmd.Start()
|
|
if err != nil {
|
|
logger.Error().Err(err).Msg("failed to reboot")
|
|
switchToMainScreen()
|
|
return fmt.Errorf("failed to reboot: %w", err)
|
|
}
|
|
|
|
// If the reboot command is successful, exit the program after 5 seconds
|
|
go func() {
|
|
time.Sleep(5 * time.Second)
|
|
os.Exit(0)
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
var deviceID string
|
|
var deviceIDOnce sync.Once
|
|
|
|
func GetDeviceID() string {
|
|
deviceIDOnce.Do(func() {
|
|
serial, err := extractSerialNumber()
|
|
if err != nil {
|
|
logger.Warn().Msg("unknown serial number, the program likely not running on RV1106")
|
|
deviceID = "unknown_device_id"
|
|
} else {
|
|
deviceID = serial
|
|
}
|
|
})
|
|
return deviceID
|
|
}
|
|
|
|
func GetDefaultHostname() string {
|
|
deviceId := GetDeviceID()
|
|
if deviceId == "unknown_device_id" {
|
|
return "jetkvm"
|
|
}
|
|
|
|
return fmt.Sprintf("jetkvm-%s", strings.ToLower(deviceId))
|
|
}
|
|
|
|
func runWatchdog() {
|
|
file, err := os.OpenFile("/dev/watchdog", os.O_WRONLY, 0)
|
|
if err != nil {
|
|
watchdogLogger.Warn().Err(err).Msg("unable to open /dev/watchdog, skipping watchdog reset")
|
|
return
|
|
}
|
|
defer file.Close()
|
|
ticker := time.NewTicker(10 * time.Second)
|
|
defer ticker.Stop()
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
_, err = file.Write([]byte{0})
|
|
if err != nil {
|
|
watchdogLogger.Warn().Err(err).Msg("error writing to /dev/watchdog, system may reboot")
|
|
}
|
|
case <-appCtx.Done():
|
|
//disarm watchdog with magic value
|
|
_, err := file.Write([]byte("V"))
|
|
if err != nil {
|
|
watchdogLogger.Warn().Err(err).Msg("failed to disarm watchdog, system may reboot")
|
|
}
|
|
return
|
|
}
|
|
}
|
|
}
|