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  }