carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1//go:build unix
2
3package hostexec
4
5import (
6 "errors"
7
8 "golang.org/x/sys/unix"
9)
10
11// Observers, including root and adopt, never create or repair an agent's
12// lifetime locks. Missing locks deny admission without changing the namespace.
13func probeLifetime(dir, host string) (func(), error) { return probeExisting(dir, host, ".lock") }
14func probeLive(dir, host string) (func(), error) { return probeExisting(dir, host, ".live") }
15func probeExisting(dir, host, suffix string) (func(), error) {
16 if _, err := Key(host, "check"); err != nil {
17 return nil, err
18 }
19 fd, err := openDir(dir)
20 if err != nil {
21 return nil, err
22 }
23 defer unix.Close(fd)
24 lock, err := unix.Openat(fd, host+suffix, unix.O_RDONLY|unix.O_NOFOLLOW|unix.O_CLOEXEC|unix.O_NONBLOCK, 0)
25 if err != nil {
26 return nil, err
27 }
28 fail := func(err error) (func(), error) { _ = unix.Close(lock); return nil, err }
29 var st unix.Stat_t
30 if err = unix.Fstat(lock, &st); err != nil {
31 return fail(err)
32 }
33 if st.Mode&unix.S_IFMT != unix.S_IFREG || st.Nlink != 1 {
34 return fail(ErrState)
35 }
36 if err = unix.Flock(lock, unix.LOCK_EX|unix.LOCK_NB); err == nil {
37 return func() { _ = unix.Flock(lock, unix.LOCK_UN); _ = unix.Close(lock) }, nil
38 }
39 if errors.Is(err, unix.EWOULDBLOCK) || errors.Is(err, unix.EAGAIN) {
40 return fail(ErrControllerBusy)
41 }
42 return fail(err)
43}
44