Use new arg "-notifypid" for more robust daemonization

No more string matching on the parent command line!
This commit is contained in:
Jakob Unterwurzacher 2015-11-09 23:21:11 +01:00
parent 273d8086ae
commit 51fcf61630
4 changed files with 16 additions and 31 deletions

View File

@ -1,4 +1,3 @@
* More robust daemonization, add cli parameter "--sendusr1=pid"
* Add test filesystem for "--masterkey" containing an "It works!" file * Add test filesystem for "--masterkey" containing an "It works!" file
* Add fcntl file locking to make multiple concurrent mounts safe * Add fcntl file locking to make multiple concurrent mounts safe
* add test case * add test case

View File

@ -21,7 +21,8 @@ func waitForUsr1() {
func daemonize() { func daemonize() {
go waitForUsr1() go waitForUsr1()
name := os.Args[0] name := os.Args[0]
newArgs := []string{"-f"} notifyArg := fmt.Sprintf("-notifypid=%d", os.Getpid())
newArgs := []string{"-f", notifyArg}
newArgs = append(newArgs, os.Args[1:]...) newArgs = append(newArgs, os.Args[1:]...)
c := exec.Command(name, newArgs...) c := exec.Command(name, newArgs...)
c.Stdout = os.Stdout c.Stdout = os.Stdout

10
main.go
View File

@ -68,7 +68,7 @@ type argContainer struct {
plaintextnames, quiet bool plaintextnames, quiet bool
masterkey, mountpoint, cipherdir string masterkey, mountpoint, cipherdir string
cpuprofile *string cpuprofile *string
sendusr1 int notifypid int
} }
var flagSet *flag.FlagSet var flagSet *flag.FlagSet
@ -93,7 +93,7 @@ func main() {
flagSet.BoolVar(&args.quiet, "q", false, "Quiet - silence informational messages") flagSet.BoolVar(&args.quiet, "q", false, "Quiet - silence informational messages")
flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key") flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key")
args.cpuprofile = flagSet.String("cpuprofile", "", "Write cpu profile to specified file") args.cpuprofile = flagSet.String("cpuprofile", "", "Write cpu profile to specified file")
flagSet.IntVar(&args.sendusr1, "sendusr1", 0, flagSet.IntVar(&args.notifypid, "notifypid", 0,
"Send USR1 to the specified process after successful mount - used internally for daemonization") "Send USR1 to the specified process after successful mount - used internally for daemonization")
flagSet.Parse(os.Args[1:]) flagSet.Parse(os.Args[1:])
if args.version { if args.version {
@ -221,8 +221,10 @@ func main() {
} }
cryptfs.Info.Println("Filesystem ready.") cryptfs.Info.Println("Filesystem ready.")
// Send notification to our parent // Send USR1 notification
sendUsr1() if args.notifypid > 0 {
sendUsr1(args.notifypid)
}
// Wait for SIGING in the background and unmount ourselves if we get it // Wait for SIGING in the background and unmount ourselves if we get it
// This prevents a dangling "Transport endpoint is not connected" mountpoint // This prevents a dangling "Transport endpoint is not connected" mountpoint
handleSigint(srv, args.mountpoint) handleSigint(srv, args.mountpoint)

View File

@ -1,38 +1,21 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"io/ioutil"
"os" "os"
"syscall" "syscall"
) )
const ( // Send signal USR1 to "pid" (usually our parent process). This notifies it
wrapperContains = "gocryptfs\000" // that the mounting has completed sucessfully.
) func sendUsr1(pid int) {
p, err := os.FindProcess(pid)
// Send USR1 to the parent process. This notifies it that the
// mounting has completed sucessfully.
//
// Checks /proc/$PPID/cmdline to make sure we do not kill an unrelated process.
func sendUsr1() {
ppid := os.Getppid()
fn := fmt.Sprintf("/proc/%d/cmdline", ppid)
cmdline, err := ioutil.ReadFile(fn)
if err != nil { if err != nil {
fmt.Printf("sendUsr1: ReadFile: %v\n", err) fmt.Printf("sendUsr1: FindProcess: %v\n", err)
return return
} }
if bytes.Contains(cmdline, []byte(wrapperContains)) { err = p.Signal(syscall.SIGUSR1)
p, err := os.FindProcess(ppid) if err != nil {
if err != nil { fmt.Printf("sendUsr1: Signal: %v\n", err)
fmt.Printf("sendUsr1: FindProcess: %v\n", err)
return
}
err = p.Signal(syscall.SIGUSR1)
if err != nil {
fmt.Printf("sendUsr1: Signal: %v\n", err)
}
} }
} }