| /* |
| * 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)) |
| } |
| } |