From e43e703599589273f4efdb7d0f69e3feac63f646 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 15 Jul 2013 21:29:00 +1000 Subject: [PATCH] dev-cammount, cammount: add xterm flag, to bring up a debug xterm in that dir. remove child process mode. not necessary. Change-Id: I4f6e75efe127a2b9e7867dbfac5c42fcc874e3a6 --- cmd/cammount/cammount.go | 147 +++++++++++++++++++++------------------ dev-cammount | 15 ++-- 2 files changed, 89 insertions(+), 73 deletions(-) diff --git a/cmd/cammount/cammount.go b/cmd/cammount/cammount.go index 9eb111f04..d6a4c03e5 100644 --- a/cmd/cammount/cammount.go +++ b/cmd/cammount/cammount.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "errors" "flag" "fmt" "log" @@ -24,7 +25,6 @@ import ( "os" "os/exec" "os/signal" - "path/filepath" "runtime" "strings" "syscall" @@ -38,8 +38,8 @@ import ( ) var ( - debug = flag.Bool("debug", false, "print debugging messages.") - mountInChild = flag.Bool("mount_in_child", false, "Run the cammount in a child process, so the top process can catch SIGINT and such easier. Hack to work around OS X FUSE support.") + debug = flag.Bool("debug", false, "print debugging messages.") + xterm = flag.Bool("xterm", false, "Run an xterm in the mounted directory. Shut down when xterm ends.") ) func usage() { @@ -49,6 +49,8 @@ func usage() { } func main() { + var conn *fuse.Conn + // Scans the arg list and sets up flags client.AddFlags() flag.Parse() @@ -60,60 +62,6 @@ func main() { mountPoint := flag.Arg(0) - // TODO(bradfitz): this is not reliable yet. - if *mountInChild { - log.Printf("Running cammount in child process.") - cmd := exec.Command(os.Args[0], flag.Args()...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Start(); err != nil { - log.Fatalf("Error running child cammount: %v", err) - } - log.Printf("cammount started; awaiting shutdown signals in parent.") - - sigc := make(chan os.Signal, 1) - go func() { - var buf [1]byte - for { - os.Stdin.Read(buf[:]) - if buf[0] == 'q' { - break - } - } - log.Printf("Read 'q' from stdin; shutting down.") - sigc <- syscall.SIGUSR2 - }() - waitc := make(chan error, 1) - go func() { - waitc <- cmd.Wait() - }() - signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM) - - sig := <-sigc - go os.Stat(filepath.Join(mountPoint, ".quitquitquit")) - log.Printf("Signal %s received, shutting down.", sig) - select { - case <-time.After(500 * time.Millisecond): - cmd.Process.Kill() - case <-waitc: - } - if runtime.GOOS == "darwin" { - donec := make(chan bool, 1) - go func() { - defer close(donec) - exec.Command("diskutil", "umount", "force", mountPoint).Run() - log.Printf("Unmounted") - }() - select { - case <-time.After(500 * time.Millisecond): - log.Printf("Unmount timeout.") - case <-donec: - } - } - os.Exit(0) - return - } - errorf := func(msg string, args ...interface{}) { fmt.Fprintf(os.Stderr, msg, args...) fmt.Fprint(os.Stderr, "\n") @@ -164,7 +112,6 @@ func main() { } } else { camfs = fs.NewCamliFileSystem(cl, diskCacheFetcher) - log.Printf("starting with fs %#v", camfs) } if *debug { @@ -173,21 +120,87 @@ func main() { // This doesn't appear to work on OS X: sigc := make(chan os.Signal, 1) - go func() { - log.Fatalf("Signal %s received, shutting down.", <-sigc) - }() - signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM) - conn, err := fuse.Mount(mountPoint) + conn, err = fuse.Mount(mountPoint) if err != nil { if err.Error() == "cannot find load_fusefs" && runtime.GOOS == "darwin" { log.Fatal("FUSE not available; install from http://osxfuse.github.io/") } log.Fatalf("Mount: %v", err) } - err = conn.Serve(camfs) - if err != nil { - log.Fatalf("Serve: %v", err) + + xtermDone := make(chan bool, 1) + if *xterm { + cmd := exec.Command("xterm") + cmd.Dir = mountPoint + if err := cmd.Start(); err != nil { + log.Printf("Error starting xterm: %v", err) + } else { + go func() { + cmd.Wait() + xtermDone <- true + }() + } } - log.Printf("fuse process ending.") + + signal.Notify(sigc, syscall.SIGQUIT, syscall.SIGTERM) + + doneServe := make(chan error, 1) + go func() { + doneServe <- conn.Serve(camfs) + }() + + quitKey := make(chan bool, 1) + go awaitQuitKey(quitKey) + + select { + case err := <-doneServe: + log.Printf("conn.Serve returned %v", err) + case sig := <-sigc: + log.Printf("Signal %s received, shutting down.", sig) + case <-quitKey: + log.Printf("Quit key pressed. Shutting down.") + case <-xtermDone: + log.Printf("xterm done") + } + + time.AfterFunc(2*time.Second, func() { + os.Exit(1) + }) + log.Printf("Unmounting...") + err = unmount(mountPoint) + log.Printf("Unmount = %v", err) + + log.Printf("cammount FUSE processending.") +} + +func awaitQuitKey(done chan<- bool) { + var buf [1]byte + for { + _, err := os.Stdin.Read(buf[:]) + if err != nil { + return + } + if buf[0] == 'q' { + done <- true + return + } + } +} + +func unmount(point string) error { + if runtime.GOOS == "darwin" { + errc := make(chan error, 1) + go func() { + errc <- exec.Command("diskutil", "umount", "force", point).Run() + }() + select { + case <-time.After(1 * time.Second): + return errors.New("unmount timeout") + case err := <-errc: + log.Printf("diskutil unmount = %v", err) + return err + } + } + return errors.New("unmount: unimplemented") } diff --git a/dev-cammount b/dev-cammount index db11bb186..8e83d7581 100755 --- a/dev-cammount +++ b/dev-cammount @@ -6,6 +6,11 @@ use Getopt::Long; require "$Bin/misc/devlib.pl"; my @blobref_arg; +my $opt_xterm; + +GetOptions( + "xterm" => \$opt_xterm, +) or usage(); if (@ARGV) { my $blobref = shift; @@ -35,13 +40,11 @@ $ENV{"CAMLI_KEYID"} = "26F5ABDA"; $ENV{"CAMLI_DEV_KEYBLOBS"} = "$Bin/config/dev-client-dir/keyblobs"; $ENV{"CAMLI_AUTH"} = "userpass:camlistore:pass3179"; -my $in_child = "false"; -if ($^O eq "darwin") { - $in_child = "true"; - print "############################################################################\n## Press 'q' to shut down.\n##\n"; -} +print "############################################################################\n## Press 'q' to shut down.\n##\n"; -exec("$cammount", "--mount_in_child=$in_child", "--server=http://localhost:3179/bs", $dir, @blobref_arg) +exec("$cammount", + "--xterm=" . ($opt_xterm ? "true" : "false"), + "--server=http://localhost:3179/bs", $dir, @blobref_arg) and warn "cammount failure: $!\n"; warn "Failed to unmount\n" unless try_unmount();