/* * Copyright (c) 2021 Cisco Systems and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Copyright 2016 the Go-FUSE Authors. All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ // This file is the main program driver to mount the stats segment filesystem. package main import ( "flag" "fmt" "log" "log/syslog" "os" "os/signal" "runtime" "strings" "syscall" "git.fd.io/govpp.git/adapter/statsclient" "git.fd.io/govpp.git/core" "github.com/hanwen/go-fuse/v2/fs" ) func LogMsg(msg string) { fmt.Fprint(os.Stderr, msg) log.Print(msg) } func main() { syslogger, err := syslog.New(syslog.LOG_ERR|syslog.LOG_DAEMON, "statsfs") if err != nil { log.Fatalln(err) } log.SetOutput(syslogger) statsSocket := flag.String("socket", statsclient.DefaultSocketName, "Path to VPP stats socket") debug := flag.Bool("debug", false, "print debugging messages.") flag.Parse() if flag.NArg() < 1 { LogMsg(fmt.Sprintf("usage: %s MOUNTPOINT\n", os.Args[0])) os.Exit(2) } //Conection to the stat segment socket. sc := statsclient.NewStatsClient(*statsSocket) fmt.Println("Waiting for the VPP socket to be available. Be sure a VPP instance is running.") c, err := core.ConnectStats(sc) if err != nil { LogMsg(fmt.Sprintf("Failed to connect to the stats socket: %v\n", err)) os.Exit(1) } defer c.Disconnect() fmt.Printf("Connected to the socket\n") //Creating the filesystem instance root, err := NewStatsFileSystem(sc) if err != nil { LogMsg(fmt.Sprintf("NewStatsFileSystem failed: %v\n", err)) os.Exit(1) } //Mounting the filesystem. opts := &fs.Options{} opts.Debug = *debug opts.AllowOther = true server, err := fs.Mount(flag.Arg(0), root, opts) if err != nil { LogMsg(fmt.Sprintf("Mount fail: %v\n", err)) os.Exit(1) } sigs := make(chan os.Signal) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) fmt.Printf("Successfully mounted the file system in directory: %s\n", flag.Arg(0)) runtime.GC() for { go server.Wait() <-sigs fmt.Println("Unmounting...") err := server.Unmount() if err == nil || !strings.Contains(err.Error(), "Device or resource busy") { break } LogMsg(fmt.Sprintf("Unmount fail: %v\n", err)) } }