main.go (2627B)
1 // Diskfs exports the file system on the disk. 2 // 3 // Usage: 4 // 5 // diskfs [-D] [-P profport] [-a addr] [-p port] root 6 // 7 // Diskfs exports file system on the disk rooted at root. 8 // By default it listens to 127.0.0.1:5640. 9 // You can change the address and port number with -a and -p flags. 10 // The -D flag enables very chatty log messages. 11 // The -P flag enables the pprof web interface at the the port profport. 12 // The address the pprof listens to is the same as addr (or 127.0.0.1 if 13 // -a flag is not specified). 14 package main 15 16 import ( 17 "context" 18 "flag" 19 "fmt" 20 "log" 21 "net" 22 "net/http" 23 _ "net/http/pprof" 24 "os" 25 "os/signal" 26 "runtime" 27 "sync" 28 "time" 29 30 "git.mtkn.jp/lib9p" 31 "git.mtkn.jp/lib9p/diskfs" 32 ) 33 34 var dFlag = flag.Bool("D", false, "Prints chatty message to the stderr.") 35 var aFlag = flag.String("a", "127.0.0.1", "Address the server listens to.") 36 var fFlag = flag.String("f", "", "Rpc file of factotum to be used for authentication") 37 var pFlag = flag.Int("p", 5640, "Port number the server listens to.") 38 var PFlag = flag.Int("P", 0, "Enables pprof over http on this port.") 39 var gFlag = flag.Bool("g", false, "Prints goroutin count once per second.") 40 41 func main() { 42 flag.Parse() 43 if flag.NArg() != 1 { 44 fmt.Fprintf(os.Stderr, "usage: %s [-D] [-P profport] [-f rpcfile] [-a addr] [-p port] root\n", os.Args[0]) 45 os.Exit(1) 46 } 47 if *gFlag { 48 go func() { 49 for { 50 log.Printf("num goroutine: %d", runtime.NumGoroutine()) 51 time.Sleep(1 * time.Second) 52 } 53 }() 54 } 55 if *PFlag != 0 { 56 go func() { 57 log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", *aFlag, *PFlag), nil)) 58 }() 59 } 60 listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", *aFlag, *pFlag)) 61 if err != nil { 62 log.Fatalf("listen tcp: %v", err) 63 } 64 ctx := runSignalHandler() 65 go func() { 66 <-ctx.Done() 67 listener.Close() 68 }() 69 wg := new(sync.WaitGroup) 70 disk, err := diskfs.Open(flag.Arg(0)) 71 if err != nil { 72 log.Fatalf("open file tree.") 73 } 74 s := lib9p.NewServer(disk) 75 if *dFlag { 76 s.Chatty() 77 } 78 if *fFlag != "" { 79 if err := lib9p.SetFactotum(s, *fFlag); err != nil { 80 log.Fatalf("setfactotum: %v", err) 81 } 82 } 83 L: 84 for { 85 conn, err := listener.Accept() 86 if err != nil { 87 select { 88 case <-ctx.Done(): 89 break L 90 default: 91 log.Printf("accept connection: %v", err) 92 continue L 93 } 94 } 95 wg.Add(1) 96 go func() { 97 defer conn.Close() 98 defer wg.Done() 99 s.Serve(ctx, conn, conn) 100 }() 101 } 102 wg.Wait() 103 } 104 105 func runSignalHandler() context.Context { 106 quit := make(chan os.Signal, 1) 107 signal.Notify(quit, os.Interrupt) 108 ctx, cancel := context.WithCancel(context.Background()) 109 go func() { 110 <-quit 111 cancel() 112 }() 113 return ctx 114 }