lib9p

Go 9P library.
Log | Files | Refs | LICENSE

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 }