summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2017-01-19 04:52:23 -0500
committerLuke Shumaker <lukeshu@sbcglobal.net>2017-01-19 04:52:23 -0500
commit1e4db61fd42019dcf98cc08ca747f0692ec88ba2 (patch)
treeac2185854deaf066533768b97ac150d506039b8d
parent58861a7cbcd8f745ec0cc99e7dced13da07eff68 (diff)
Fix.
-rw-r--r--systemd-timesyncd-wait.go97
-rw-r--r--systemd-timesyncd-wait.socket4
-rw-r--r--systemd-timesyncd-wrap.go37
-rw-r--r--systemd-timesyncd.service.d-wait.conf4
4 files changed, 119 insertions, 23 deletions
diff --git a/systemd-timesyncd-wait.go b/systemd-timesyncd-wait.go
index 9275502..f5327ff 100644
--- a/systemd-timesyncd-wait.go
+++ b/systemd-timesyncd-wait.go
@@ -1,29 +1,100 @@
+// Copyright 2017 Luke Shumaker
+//
+// For just ListenFds:
+//
+// Copyright 2015 CoreOS, Inc.
+// Copyright 2015-2016 Luke Shumaker
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
package main
import (
+ "fmt"
"net"
"os"
+ "strconv"
+ "strings"
+
+ unix "syscall"
)
+// ListenFds returns a list of file descriptors passed in by the
+// service manager as part of the socket-based activation logic.
+//
+// If unsetEnv is true, then (regardless of whether the function call
+// itself succeeds or not) it will unset the environmental variables
+// LISTEN_FDS and LISTEN_PID, which will cause further calls to this
+// function to fail.
+//
+// In the case of an error, this function returns nil.
+func ListenFds(unsetEnv bool) []*os.File {
+ if unsetEnv {
+ defer func() {
+ _ = os.Unsetenv("LISTEN_PID")
+ _ = os.Unsetenv("LISTEN_FDS")
+ _ = os.Unsetenv("LISTEN_FDNAMES")
+ }()
+ }
+
+ pid, err := strconv.Atoi(os.Getenv("LISTEN_PID"))
+ if err != nil || pid != os.Getpid() {
+ return nil
+ }
+
+ nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS"))
+ if err != nil || nfds < 1 {
+ return nil
+ }
+
+ names := strings.Split(os.Getenv("LISTEN_FDNAMES"), ":")
+
+ files := make([]*os.File, 0, nfds)
+ for i := 0; i < nfds; i++ {
+ fd := i + 3
+ unix.CloseOnExec(fd)
+ name := "unknown"
+ if i < len(names) {
+ name = names[i]
+ }
+ files = append(files, os.NewFile(uintptr(fd), name))
+ }
+
+ return files
+}
+
func main() {
- sync_sockname := "/run/timesyncd/time-sync.sock"
+ files := ListenFds(false)
+ if len(files) != 1 {
+ fmt.Fprintf(os.Stderr, "expected 1 fd, got %d\n", len(files))
+ os.Exit(1)
+ }
- sync_sock, err := net.ListenUnixgram("unixgram", &net.UnixAddr{Net: "unixgram", Name: sync_sockname})
+ sync_sock, err := net.FileConn(files[0])
if err != nil {
- os.Stderr.WriteString(err.Error())
- os.Stderr.Write([]byte{'\n'})
+ fmt.Fprintln(os.Stderr, err)
os.Exit(127)
}
var dat [4096]byte
- n, err := sync_sock.Read(dat[:])
- if err != nil {
- os.Stderr.WriteString(err.Error())
- os.Stderr.Write([]byte{'\n'})
- os.Exit(127)
- }
- if string(dat[:n]) != "READY=1" {
- os.Exit(127)
+ for {
+ n, err := sync_sock.Read(dat[:])
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(127)
+ }
+ if n > 0 {
+ os.Exit(0)
+ }
}
- os.Exit(0)
}
diff --git a/systemd-timesyncd-wait.socket b/systemd-timesyncd-wait.socket
index 3112218..f7a35c8 100644
--- a/systemd-timesyncd-wait.socket
+++ b/systemd-timesyncd-wait.socket
@@ -1,7 +1,9 @@
[Unit]
Description=Network Time Synchronized Socket
DefaultDependencies=no
-After=systemd-remount-fs.service systemd-tmpfiles-setup.service
+After=systemd-remount-fs.service systemd-tmpfiles-setup.service systemd-sysusers.service
[Socket]
ListenDatagram=/run/timesyncd/time-sync.sock
+SocketUser=systemd-timesync
+SocketMode=0200
diff --git a/systemd-timesyncd-wrap.go b/systemd-timesyncd-wrap.go
index 3d5971b..76914a4 100644
--- a/systemd-timesyncd-wrap.go
+++ b/systemd-timesyncd-wrap.go
@@ -1,8 +1,11 @@
package main
import (
+ "fmt"
"net"
"os"
+ "os/user"
+ "strconv"
"strings"
"sync"
"syscall"
@@ -35,18 +38,27 @@ func main() {
fake_sockname := "/run/timesyncd/notify.sock"
real_sockname := os.Getenv("NOTIFY_SOCKET")
+ user, err := user.Lookup("systemd-timesync")
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(127)
+ }
+ uid, _ := strconv.Atoi(user.Uid)
+ gid, _ := strconv.Atoi(user.Gid)
+
+ umask := syscall.Umask(0577)
fake_sock, err := net.ListenUnixgram("unixgram", &net.UnixAddr{Net: "unixgram", Name: fake_sockname})
+ syscall.Umask(umask)
if err != nil {
- os.Stderr.WriteString(err.Error())
- os.Stderr.Write([]byte{'\n'})
+ fmt.Fprintln(os.Stderr, err)
os.Exit(127)
}
+ os.Chown(fake_sockname, uid, gid)
os.Setenv("NOTIFY_SOCKET", fake_sockname)
- proc, err := os.StartProcess(os.Args[1], os.Args[1:], &os.ProcAttr{})
+ proc, err := os.StartProcess(os.Args[1], os.Args[1:], &os.ProcAttr{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}})
if err != nil {
- os.Stderr.WriteString(err.Error())
- os.Stderr.Write([]byte{'\n'})
+ fmt.Fprintln(os.Stderr, err)
os.Exit(127)
}
@@ -59,21 +71,29 @@ func main() {
for {
n, oobn, flags, _, err := fake_sock.ReadMsgUnix(dat[:], oob[:])
if err != nil {
+ fmt.Fprintln(os.Stderr, err)
break
}
if flags&syscall.MSG_TRUNC != 0 {
+ fmt.Fprintln(os.Stderr, "Received notify message exceeded maximum size. Ignoring.")
continue
}
if !synced {
for _, line := range strings.Split(string(dat[:n]), "\n") {
if strings.HasPrefix(line, "STATUS=Synchronized") {
- _ = sendmsg([]byte(line), nil, sync_sockname)
+ err = sendmsg([]byte(line), nil, sync_sockname)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ }
synced = true
break
}
}
}
- _ = sendmsg(dat[:n], oob[:oobn], real_sockname)
+ err = sendmsg(dat[:n], oob[:oobn], real_sockname)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ }
}
wg.Done()
}()
@@ -83,8 +103,7 @@ func main() {
wg.Wait()
if err != nil {
- os.Stderr.WriteString(err.Error())
- os.Stderr.Write([]byte{'\n'})
+ fmt.Println(os.Stderr, err)
os.Exit(127)
}
status := state.Sys().(syscall.WaitStatus)
diff --git a/systemd-timesyncd.service.d-wait.conf b/systemd-timesyncd.service.d-wait.conf
index 8342e53..2775888 100644
--- a/systemd-timesyncd.service.d-wait.conf
+++ b/systemd-timesyncd.service.d-wait.conf
@@ -4,4 +4,8 @@ After=systemd-timesyncd-wait.socket
[Service]
Sockets=
+ExecStart=
ExecStart=/usr/lib/systemd/systemd-timesyncd-wrap /usr/lib/systemd/systemd-timesyncd
+ExecStopPost=/usr/bin/rm -f -- /run/timesyncd/notify.sock
+ExecStartPre=/usr/bin/rm -f -- /run/timesyncd/notify.sock
+NotifyAccess=all