github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/cmd/scan/main.go (about)

     1  package main
     2  
     3  // Scan a file-system similar to subd.
     4  
     5  import (
     6  	"bufio"
     7  	"encoding/gob"
     8  	"flag"
     9  	"fmt"
    10  	"os"
    11  	"runtime"
    12  	"syscall"
    13  	"time"
    14  
    15  	"github.com/Cloud-Foundations/Dominator/lib/filter"
    16  	"github.com/Cloud-Foundations/Dominator/lib/flags/loadflags"
    17  	"github.com/Cloud-Foundations/Dominator/lib/format"
    18  	"github.com/Cloud-Foundations/Dominator/lib/fsbench"
    19  	"github.com/Cloud-Foundations/Dominator/lib/fsrateio"
    20  	"github.com/Cloud-Foundations/Dominator/lib/json"
    21  	"github.com/Cloud-Foundations/Dominator/lib/memstats"
    22  	"github.com/Cloud-Foundations/Dominator/sub/scanner"
    23  )
    24  
    25  var (
    26  	debugFile = flag.String("debugFile", "",
    27  		"Name of file to write debugging information to")
    28  	gobFile = flag.String("gobFile", "",
    29  		"Name of file to write GOB-encoded data to")
    30  	interval = flag.Uint("interval", 0, "Seconds to sleep after each scan")
    31  	jsonFile = flag.String("jsonFile", "",
    32  		"Name of file to write JSON-encoded data to")
    33  	numScans = flag.Int("numScans", 1,
    34  		"The number of scans to run (infinite: < 0)")
    35  	objectCache = flag.String("objectCache", "",
    36  		"Name of directory containing the object cache")
    37  	rootDir = flag.String("rootDir", "/",
    38  		"Name of root of directory tree to scan")
    39  	scanSpeed = flag.Uint("scanSpeed", 0,
    40  		"Scan speed in percent of maximum (0: default)")
    41  )
    42  
    43  func main() {
    44  	if err := loadflags.LoadForCli("scan"); err != nil {
    45  		fmt.Fprintln(os.Stderr, err)
    46  		os.Exit(1)
    47  	}
    48  	flag.Parse()
    49  	var err error
    50  	var configuration scanner.Configuration
    51  	configuration.ScanFilter, err = filter.New(nil)
    52  	if err != nil {
    53  		fmt.Fprintf(os.Stderr, "Unable to create empty filter: %s\n", err)
    54  		os.Exit(1)
    55  	}
    56  	if *scanSpeed < 100 {
    57  		bytesPerSecond, blocksPerSecond, err := fsbench.GetReadSpeed(*rootDir)
    58  		if err != nil {
    59  			fmt.Fprintf(os.Stderr, "Error! %s\n", err)
    60  			return
    61  		}
    62  		configuration.FsScanContext = fsrateio.NewReaderContext(bytesPerSecond,
    63  			blocksPerSecond, 0)
    64  		configuration.FsScanContext.GetContext().SetSpeedPercent(*scanSpeed)
    65  		fmt.Println(configuration.FsScanContext)
    66  	}
    67  	syscall.Setpriority(syscall.PRIO_PROCESS, 0, 10)
    68  	var prev_fs *scanner.FileSystem
    69  	for iter := 0; *numScans < 0 || iter < *numScans; iter++ {
    70  		timeStart := time.Now()
    71  		fs, err := scanner.ScanFileSystem(*rootDir, *objectCache,
    72  			&configuration)
    73  		timeStop := time.Now()
    74  		if iter > 0 {
    75  			fmt.Println()
    76  		}
    77  		if err != nil {
    78  			fmt.Fprintf(os.Stderr, "Error! %s\n", err)
    79  			return
    80  		}
    81  		fmt.Print(fs)
    82  		fmt.Printf("Total scanned: %s,\t",
    83  			format.FormatBytes(fs.TotalDataBytes))
    84  		bytesPerSecond := uint64(float64(fs.TotalDataBytes) /
    85  			timeStop.Sub(timeStart).Seconds())
    86  		fmt.Printf("%s/s\n", format.FormatBytes(bytesPerSecond))
    87  		if prev_fs != nil {
    88  			if !scanner.CompareFileSystems(prev_fs, fs, os.Stdout) {
    89  				fmt.Println("Scan results different from last run")
    90  			}
    91  		}
    92  		runtime.GC() // Clean up before showing memory statistics.
    93  		memstats.WriteMemoryStats(os.Stdout)
    94  		if *debugFile != "" {
    95  			file, err := os.Create(*debugFile)
    96  			if err != nil {
    97  				fmt.Fprintf(os.Stderr, "Error! %s\n", err)
    98  				return
    99  			}
   100  			w := bufio.NewWriter(file)
   101  			fs.List(w)
   102  			w.Flush()
   103  			file.Close()
   104  		}
   105  		if *gobFile != "" {
   106  			file, err := os.Create(*gobFile)
   107  			if err != nil {
   108  				fmt.Fprintf(os.Stderr, "Error creating: %s: %s\n",
   109  					*gobFile, err)
   110  				os.Exit(1)
   111  			}
   112  			encoder := gob.NewEncoder(file)
   113  			encoderStartTime := time.Now()
   114  			encoder.Encode(fs)
   115  			fmt.Printf("Encoder time: %s\n", time.Since(encoderStartTime))
   116  			file.Close()
   117  		}
   118  		if *jsonFile != "" {
   119  			file, err := os.Create(*jsonFile)
   120  			if err != nil {
   121  				fmt.Fprintf(os.Stderr, "Error creating: %s: %s\n",
   122  					*jsonFile, err)
   123  				os.Exit(1)
   124  			}
   125  			if err := json.WriteWithIndent(file, "    ", fs); err != nil {
   126  				fmt.Fprintf(os.Stderr, "Error writing JSON: %s\n", err)
   127  				os.Exit(1)
   128  			}
   129  			file.Close()
   130  		}
   131  		prev_fs = fs
   132  		time.Sleep(time.Duration(*interval) * time.Second)
   133  	}
   134  }