mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-22 23:21:11 +02:00
67 lines
1.5 KiB
Go
67 lines
1.5 KiB
Go
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package main
|
|
|
|
import (
|
|
"os"
|
|
|
|
"github.com/mdlayher/genetlink"
|
|
"github.com/mdlayher/netlink"
|
|
"github.com/pkg/errors"
|
|
"golang.org/x/sys/unix"
|
|
)
|
|
|
|
const (
|
|
// See https://github.com/torvalds/linux/blob/master/drivers/acpi/event.c
|
|
acpiGenlFamilyName = "acpi_event"
|
|
acpiGenlMcastGroupName = "acpi_mc_group"
|
|
)
|
|
|
|
func listenForPowerButton() (err error) {
|
|
// Get the acpi_event family.
|
|
|
|
genconn, err := genetlink.Dial(nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// nolint: errcheck
|
|
defer genconn.Close()
|
|
var f genetlink.Family
|
|
if f, err = genconn.GetFamily(acpiGenlFamilyName); os.IsNotExist(err) {
|
|
return errors.Wrap(err, acpiGenlFamilyName+" not available")
|
|
}
|
|
|
|
// Listen for ACPI event.
|
|
|
|
conn, err := netlink.Dial(unix.NETLINK_GENERIC, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// nolint: errcheck
|
|
defer conn.Close()
|
|
var id uint32
|
|
for _, group := range f.Groups {
|
|
if group.Name == acpiGenlMcastGroupName {
|
|
id = group.ID
|
|
}
|
|
}
|
|
if err = conn.JoinGroup(id); err != nil {
|
|
return err
|
|
}
|
|
msgs, err := conn.Receive()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(msgs) > 0 {
|
|
// TODO(andrewrynhard): Stop all running containerd tasks.
|
|
// See http://man7.org/linux/man-pages/man2/reboot.2.html.
|
|
unix.Sync()
|
|
// nolint: errcheck
|
|
unix.Reboot(unix.LINUX_REBOOT_CMD_POWER_OFF)
|
|
}
|
|
|
|
return nil
|
|
}
|