aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-05-24 19:57:45 +0200
committerJakob Unterwurzacher2017-05-24 19:57:45 +0200
commit70c16fde4c908414f6af53c3193a89fa296ef732 (patch)
treed7acaec8628e4c0594376009747232512c7908ab
parente827763f2e6226d9f5778d56c28270264950c0f5 (diff)
main: replace paniclog with logger(1)
Instead of redirecting stdout and stderr to /tmp/gocryptfs_paniclog, where it is hard to find, redirect them to a newly spawned logger(1) instance that forwards the messages to syslog. See https://github.com/rfjakob/gocryptfs/issues/109 for an example where the paniclog was lost due to a reboot. Also, instead of closing stdin, redirect it to /dev/null, like most daemons seem to do.
-rw-r--r--mount.go87
1 files changed, 44 insertions, 43 deletions
diff --git a/mount.go b/mount.go
index 5a28640..c10f90b 100644
--- a/mount.go
+++ b/mount.go
@@ -2,7 +2,7 @@ package main
import (
"encoding/json"
- "io/ioutil"
+ "fmt"
"log/syslog"
"net"
"os"
@@ -107,7 +107,6 @@ func doMount(args *argContainer) int {
// Initialize FUSE server
srv := initFuseFrontend(masterkey, args, confFile)
tlog.Info.Println(tlog.ColorGreen + "Filesystem mounted and ready." + tlog.ColorReset)
- var paniclog *os.File
// We have been forked into the background, as evidenced by the set
// "notifypid".
if args.notifypid > 0 {
@@ -115,38 +114,13 @@ func doMount(args *argContainer) int {
os.Chdir("/")
// Switch to syslog
if !args.nosyslog {
- paniclog, err = ioutil.TempFile("", "gocryptfs_paniclog.")
- if err != nil {
- tlog.Warn.Printf("Failed to create paniclog: %v."+
- " Carrying on, but fatal errors will not be logged.", err)
- }
// Switch all of our logs and the generic logger to syslog
tlog.Info.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_INFO)
tlog.Debug.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_DEBUG)
tlog.Warn.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_WARNING)
tlog.SwitchLoggerToSyslog(syslog.LOG_USER | syslog.LOG_WARNING)
- // Daemons should close all fds (and we don't want to get killed by
- // SIGPIPE if any of those get closed on the other end)
- os.Stdin.Close()
- // Redirect stdout and stderr to /tmp/gocryptfs_paniclog.NNNNNN
- // instead of closing them so users have a chance to get the
- // backtrace on a panic.
- // https://github.com/golang/go/issues/325#issuecomment-66049178
- if paniclog != nil {
- err = syscall.Dup2(int(paniclog.Fd()), 1)
- if err != nil {
- tlog.Warn.Printf("paniclog stdout dup error: %v\n", err)
- }
- syscall.Dup2(int(paniclog.Fd()), 2)
- if err != nil {
- tlog.Warn.Printf("paniclog stderr dup error: %v\n", err)
- }
- // No need for the extra FD anymore, we have copies in Stdout and Stderr
- err = paniclog.Close()
- if err != nil {
- tlog.Warn.Printf("paniclog close error: %v\n", err)
- }
- }
+ // Daemons should redirect stdin, stdout and stderr
+ redirectStdFds()
}
// Disconnect from the controlling terminal by creating a new session.
// This prevents us from getting SIGINT when the user presses Ctrl-C
@@ -167,23 +141,50 @@ func doMount(args *argContainer) int {
handleSigint(srv, args.mountpoint)
// Jump into server loop. Returns when it gets an umount request from the kernel.
srv.Serve()
- // Delete empty paniclogs
- if paniclog != nil {
- // The paniclog FD is saved in Stdout and Stderr
- fi, err := os.Stderr.Stat()
- if err != nil {
- tlog.Warn.Printf("paniclog fstat error: %v", err)
- } else if fi.Size() > 0 {
- tlog.Warn.Printf("paniclog at %q is not empty (size %d). Not deleting it.",
- paniclog.Name(), fi.Size())
- return exitcodes.PanicLogNotEmpty
- } else {
- syscall.Unlink(paniclog.Name())
- }
- }
return 0
}
+// redirectStdFds redirects stderr and stdout to syslog; stdin to /dev/null
+func redirectStdFds() {
+ // stderr and stdout
+ pr, pw, err := os.Pipe()
+ if err != nil {
+ tlog.Warn.Printf("redirectStdFds: could not create pipe: %v\n", err)
+ return
+ }
+ tag := fmt.Sprintf("gocryptfs-%d-logger", os.Getpid())
+ cmd := exec.Command("logger", "-t", tag)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.Stdin = pr
+ err = cmd.Start()
+ if err != nil {
+ tlog.Warn.Printf("redirectStdFds: could not start logger: %v\n", err)
+ }
+ pr.Close()
+ err = syscall.Dup2(int(pw.Fd()), 1)
+ if err != nil {
+ tlog.Warn.Printf("redirectStdFds: stdout dup error: %v\n", err)
+ }
+ syscall.Dup2(int(pw.Fd()), 2)
+ if err != nil {
+ tlog.Warn.Printf("redirectStdFds: stderr dup error: %v\n", err)
+ }
+ pw.Close()
+
+ // stdin
+ nullFd, err := os.Open("/dev/null")
+ if err != nil {
+ tlog.Warn.Printf("redirectStdFds: could not open /dev/null: %v\n", err)
+ return
+ }
+ err = syscall.Dup2(int(nullFd.Fd()), 0)
+ if err != nil {
+ tlog.Warn.Printf("redirectStdFds: stdin dup error: %v\n", err)
+ }
+ nullFd.Close()
+}
+
// setOpenFileLimit tries to increase the open file limit to 4096 (the default hard
// limit on Linux).
func setOpenFileLimit() {