dev-cammount, cammount: add xterm flag, to bring up a debug xterm in that dir.

remove child process mode. not necessary.

Change-Id: I4f6e75efe127a2b9e7867dbfac5c42fcc874e3a6
This commit is contained in:
Brad Fitzpatrick 2013-07-15 21:29:00 +10:00
parent 4949d1201f
commit e43e703599
2 changed files with 89 additions and 73 deletions

View File

@ -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")
}

View File

@ -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' <enter> to shut down.\n##\n";
}
print "############################################################################\n## Press 'q' <enter> 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();