func main() { cli.Initialize(appName, &config.BaseConfig) eventLog := cli.NewEventLog(appName, "") defer eventLog.Finish() config.InitializePaths() eventLog.Infof("using mount root %s", config.MountRoot) deviceWatcher := goadb.NewDeviceWatcher(config.ClientConfig()) defer deviceWatcher.Shutdown() signals := make(chan os.Signal) signal.Notify(signals, os.Kill, os.Interrupt) processes := cli.NewProcessTracker() defer processes.Shutdown() cli.Log.Info("automounter ready.") defer cli.Log.Info("exiting.") for { select { case event := <-deviceWatcher.C(): if event.CameOnline() { eventLog.Debugf("device connected: %s", event.Serial) processes.Go(event.Serial, mountDevice) } else if event.WentOffline() { eventLog.Debugf("device disconnected: %s", event.Serial) } else { eventLog.Debugf("unknown device event: %+v", event) } case signal := <-signals: eventLog.Debugf("got signal %v", signal) if signal == os.Kill || signal == os.Interrupt { eventLog.Infof("shutting down all mount processes…") processes.Shutdown() eventLog.Infof("all processes shutdown.") return } } } }
func mountDevice(serial string, context context.Context) { eventLog := cli.NewEventLog(appName, "device:"+serial) defer func() { eventLog.Debugf("device mount process finished: %s", serial) eventLog.Finish() }() adbClient := goadb.NewDeviceClient(config.ClientConfig(), goadb.DeviceWithSerial(serial)) deviceInfo, err := adbClient.GetDeviceInfo() if err != nil { eventLog.Errorf("error getting device info for %s: %s", serial, err) return } mountpoint, err := cli.NewMountpointForDevice(deviceInfo, config.MountRoot, serial) if err != nil { eventLog.Errorf("error creating mountpoint for %s: %s", serial, err) return } defer RemoveLoggingError(mountpoint) eventLog.Infof("mounting %s on %s", serial, mountpoint) cmd := NewMountProcess(config.PathToAdbfs, cli.AdbfsConfig{ BaseConfig: config.BaseConfig, DeviceSerial: serial, Mountpoint: mountpoint, }) eventLog.Debugf("launching adbfs: %s", CommandLine(cmd)) if err := cmd.Start(); err != nil { eventLog.Errorf("error starting adbfs process: %s", err) return } eventLog.Infof("device %s mounted with PID %d", serial, cmd.Process.Pid) // If we're told to stop, kill the mount process. go func() { <-context.Done() cmd.Process.Kill() }() handlerBinding := map[string]string{ cli.PathHandlerVar: mountpoint, cli.SerialHandlerVar: serial, cli.ModelHandlerVar: deviceInfo.Model, } cli.FireHandlers(config.OnMountHandlers, handlerBinding) defer cli.FireHandlers(config.OnUnmountHandlers, handlerBinding) if err := cmd.Wait(); err != nil { if err, ok := err.(*exec.ExitError); ok { eventLog.Errorf("adbfs exited with %+v", err) } else { eventLog.Errorf("lost connection with adbfs process:", err) } return } eventLog.Infof("mount process for device %s stopped", serial) }