github.com/swiftstack/proxyfs@v0.0.0-20201223034610-5434d919416e/halter/api.go (about)

     1  package halter
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"syscall"
     7  
     8  	"github.com/swiftstack/ProxyFS/evtlog"
     9  )
    10  
    11  // Note 1: Following const block and HaltLabelStrings should be kept in sync
    12  // Note 2: HaltLabelStrings should be easily parseable as URL components
    13  
    14  const (
    15  	apiTestHaltLabel1 = iota
    16  	apiTestHaltLabel2
    17  	InodeFlushInodesEntry
    18  	InodeFlushInodesExit
    19  )
    20  
    21  var (
    22  	HaltLabelStrings = []string{
    23  		"halter.testHaltLabel1",
    24  		"halter.testHaltLabel2",
    25  		"inode.flushInodes_Entry",
    26  		"inode.flushInodes_Exit",
    27  	}
    28  )
    29  
    30  // Arm sets up a HALT on the haltAfterCount'd call to Trigger()
    31  func Arm(haltLabelString string, haltAfterCount uint32) {
    32  	globals.Lock()
    33  	haltLabel, ok := globals.triggerNamesToNumbers[haltLabelString]
    34  	if !ok {
    35  		err := fmt.Errorf("halter.Arm(haltLabelString='%v',) - label unknown", haltLabelString)
    36  		haltWithErr(err)
    37  	}
    38  	if 0 == haltAfterCount {
    39  		err := fmt.Errorf("halter.Arm(haltLabel==%v,) called with haltAfterCount==0", haltLabelString)
    40  		haltWithErr(err)
    41  	}
    42  	globals.armedTriggers[haltLabel] = haltAfterCount
    43  	globals.Unlock()
    44  	evtlog.Record(evtlog.FormatHalterArm, haltLabelString, haltAfterCount)
    45  }
    46  
    47  // Disarm removes a previously armed trigger via a call to Arm()
    48  func Disarm(haltLabelString string) {
    49  	globals.Lock()
    50  	haltLabel, ok := globals.triggerNamesToNumbers[haltLabelString]
    51  	if !ok {
    52  		err := fmt.Errorf("halter.Disarm(haltLabelString='%v') - label unknown", haltLabelString)
    53  		haltWithErr(err)
    54  	}
    55  	delete(globals.armedTriggers, haltLabel)
    56  	globals.Unlock()
    57  	evtlog.Record(evtlog.FormatHalterDisarm, haltLabelString)
    58  }
    59  
    60  // Trigger decrements the haltAfterCount if armed and, should it reach 0, HALTs
    61  func Trigger(haltLabel uint32) {
    62  	globals.Lock()
    63  	numTriggersRemaining, armed := globals.armedTriggers[haltLabel]
    64  	if !armed {
    65  		globals.Unlock()
    66  		return
    67  	}
    68  	numTriggersRemaining--
    69  	if 0 == numTriggersRemaining {
    70  		haltLabelString := globals.triggerNumbersToNames[haltLabel]
    71  		evtlog.Record(evtlog.FormatHalterDisarm, haltLabelString)
    72  		err := fmt.Errorf("halter.TriggerArm(haltLabelString==%v) triggered HALT", haltLabelString)
    73  		haltWithErr(err)
    74  	}
    75  	globals.armedTriggers[haltLabel] = numTriggersRemaining
    76  	globals.Unlock()
    77  }
    78  
    79  // Dump returns a map of currently armed triggers and their remaining trigger count
    80  func Dump() (armedTriggers map[string]uint32) {
    81  	armedTriggers = make(map[string]uint32)
    82  	for k, v := range globals.armedTriggers {
    83  		armedTriggers[globals.triggerNumbersToNames[k]] = v
    84  	}
    85  	return
    86  }
    87  
    88  // List returns a slice of available triggers
    89  func List() (availableTriggers []string) {
    90  	availableTriggers = make([]string, 0, len(globals.triggerNumbersToNames))
    91  	for k := range globals.triggerNamesToNumbers {
    92  		availableTriggers = append(availableTriggers, k)
    93  	}
    94  	return
    95  }
    96  
    97  // Stat returns the remaining haltAfterCount for the specified haltLabelString
    98  func Stat(haltLabelString string) (haltAfterCount uint32, err error) {
    99  	globals.Lock()
   100  	haltLabel, ok := globals.triggerNamesToNumbers[haltLabelString]
   101  	if !ok {
   102  		globals.Unlock()
   103  		err = fmt.Errorf("halter.Stat(haltLabelString='%v') - label unknown", haltLabelString)
   104  		return
   105  	}
   106  	haltAfterCount, ok = globals.armedTriggers[haltLabel]
   107  	if !ok {
   108  		haltAfterCount = 0
   109  	}
   110  	globals.Unlock()
   111  	return
   112  }
   113  
   114  func haltWithErr(err error) {
   115  	if nil == globals.testModeHaltCB {
   116  		fmt.Println(err)
   117  		os.Exit(int(syscall.SIGKILL))
   118  	} else {
   119  		globals.testModeHaltCB(err)
   120  	}
   121  }