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.
This commit is contained in:
parent
e827763f2e
commit
70c16fde4c
87
mount.go
87
mount.go
|
@ -2,7 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"fmt"
|
||||||
"log/syslog"
|
"log/syslog"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
@ -107,7 +107,6 @@ func doMount(args *argContainer) int {
|
||||||
// Initialize FUSE server
|
// Initialize FUSE server
|
||||||
srv := initFuseFrontend(masterkey, args, confFile)
|
srv := initFuseFrontend(masterkey, args, confFile)
|
||||||
tlog.Info.Println(tlog.ColorGreen + "Filesystem mounted and ready." + tlog.ColorReset)
|
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
|
// We have been forked into the background, as evidenced by the set
|
||||||
// "notifypid".
|
// "notifypid".
|
||||||
if args.notifypid > 0 {
|
if args.notifypid > 0 {
|
||||||
|
@ -115,38 +114,13 @@ func doMount(args *argContainer) int {
|
||||||
os.Chdir("/")
|
os.Chdir("/")
|
||||||
// Switch to syslog
|
// Switch to syslog
|
||||||
if !args.nosyslog {
|
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
|
// Switch all of our logs and the generic logger to syslog
|
||||||
tlog.Info.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_INFO)
|
tlog.Info.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_INFO)
|
||||||
tlog.Debug.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_DEBUG)
|
tlog.Debug.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_DEBUG)
|
||||||
tlog.Warn.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_WARNING)
|
tlog.Warn.SwitchToSyslog(syslog.LOG_USER | syslog.LOG_WARNING)
|
||||||
tlog.SwitchLoggerToSyslog(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
|
// Daemons should redirect stdin, stdout and stderr
|
||||||
// SIGPIPE if any of those get closed on the other end)
|
redirectStdFds()
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Disconnect from the controlling terminal by creating a new session.
|
// Disconnect from the controlling terminal by creating a new session.
|
||||||
// This prevents us from getting SIGINT when the user presses Ctrl-C
|
// 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)
|
handleSigint(srv, args.mountpoint)
|
||||||
// Jump into server loop. Returns when it gets an umount request from the kernel.
|
// Jump into server loop. Returns when it gets an umount request from the kernel.
|
||||||
srv.Serve()
|
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
|
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
|
// setOpenFileLimit tries to increase the open file limit to 4096 (the default hard
|
||||||
// limit on Linux).
|
// limit on Linux).
|
||||||
func setOpenFileLimit() {
|
func setOpenFileLimit() {
|
||||||
|
|
Loading…
Reference in New Issue