github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/evtlog/pfsevtlogd/main.go (about) 1 // Copyright (c) 2015-2021, NVIDIA CORPORATION. 2 // SPDX-License-Identifier: Apache-2.0 3 4 package main 5 6 import ( 7 "fmt" 8 "log" 9 "os" 10 "os/signal" 11 "syscall" 12 "time" 13 14 "golang.org/x/sys/unix" 15 16 "github.com/swiftstack/ProxyFS/conf" 17 "github.com/swiftstack/ProxyFS/evtlog" 18 "github.com/swiftstack/ProxyFS/transitions" 19 ) 20 21 func usage() { 22 fmt.Println("pfsevtlogd -?") 23 fmt.Println(" Prints this help text") 24 fmt.Println("pfsevtlogd [-D] ConfFile [ConfFileOverrides]*") 25 fmt.Println(" -D requests that just the Shared Memory Object be deleted") 26 fmt.Println(" ConfFile specifies the .conf file as also passed to proxyfsd et. al.") 27 fmt.Println(" ConfFileOverrides is an optional list of modifications to ConfFile to apply") 28 } 29 30 func main() { 31 var ( 32 args []string 33 confMap conf.ConfMap 34 err error 35 formattedRecord string 36 justDeleteSharedMemoryObject bool 37 numDroppedRecords uint64 38 outputFile *os.File 39 outputPath string 40 pollDelay time.Duration 41 signalChan chan os.Signal 42 ) 43 44 if (2 == len(os.Args)) && ("-?" == os.Args[1]) { 45 usage() 46 os.Exit(0) 47 } 48 49 if (1 < len(os.Args)) && ("-D" == os.Args[1]) { 50 justDeleteSharedMemoryObject = true 51 args = os.Args[2:] 52 } else { 53 justDeleteSharedMemoryObject = false 54 args = os.Args[1:] 55 } 56 57 if len(args) < 1 { 58 log.Fatalf("no .conf file specified") 59 } 60 61 confMap, err = conf.MakeConfMapFromFile(args[0]) 62 if nil != err { 63 log.Fatalf("failed to load config: %v", err) 64 } 65 66 err = confMap.UpdateFromStrings(args[1:]) 67 if nil != err { 68 log.Fatalf("failed to apply config overrides: %v", err) 69 } 70 71 // Upgrade confMap if necessary 72 err = transitions.UpgradeConfMapIfNeeded(confMap) 73 if nil != err { 74 log.Fatalf("Failed to upgrade config: %v", err) 75 } 76 77 err = transitions.Up(confMap) 78 if nil != err { 79 log.Fatalf("transitions.Up() failed: %v", err) 80 } 81 82 if justDeleteSharedMemoryObject { 83 evtlog.MarkForDeletion() 84 err = transitions.Down(confMap) 85 if nil != err { 86 log.Fatalf("transitions.Down() failed: %v", err) 87 } 88 os.Exit(0) 89 } 90 91 pollDelay, err = confMap.FetchOptionValueDuration("EventLog", "DaemonPollDelay") 92 if nil != err { 93 log.Fatalf("confMap.FetchOptionValueDuration(\"EventLog\", \"DaemonPollDelay\") failed: %v", err) 94 } 95 96 outputPath, err = confMap.FetchOptionValueString("EventLog", "DaemonOutputPath") 97 if nil == err { 98 outputFile, err = os.OpenFile(outputPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, syscall.S_IRUSR|syscall.S_IWUSR) 99 } else { 100 outputFile = os.Stdout 101 } 102 103 signalChan = make(chan os.Signal, 1) 104 105 signal.Notify(signalChan, unix.SIGINT, unix.SIGTERM) 106 107 for { 108 formattedRecord, numDroppedRecords = evtlog.Retrieve() 109 110 if 0 != numDroppedRecords { 111 fmt.Fprintf(outputFile, "*** numDroppedRecords == 0x%016X\n", numDroppedRecords) 112 } 113 114 if "" == formattedRecord { 115 select { 116 case _ = <-signalChan: 117 err = outputFile.Close() 118 if nil != err { 119 log.Fatalf("outputFile.Close() failed: %v", err) 120 } 121 122 err = transitions.Down(confMap) 123 if nil != err { 124 log.Fatalf("transitions.Down() failed: %v", err) 125 } 126 127 os.Exit(0) 128 case _ = <-time.After(pollDelay): 129 // Just loop back to attempt evtlog.Retrieve() 130 } 131 } else { 132 fmt.Fprintf(outputFile, "%s\n", formattedRecord) 133 } 134 } 135 }