|
1 | 1 | package runtimehandlerhooks |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bufio" |
| 5 | + "fmt" |
| 6 | + "os" |
| 7 | + |
4 | 8 | . "github.com/onsi/ginkgo/v2" |
5 | 9 | . "github.com/onsi/gomega" |
6 | 10 | ) |
@@ -45,5 +49,92 @@ var _ = Describe("Utils", func() { |
45 | 49 | expected: Expected{mask: "0000ffff,ffffffff", invMask: "00000000,00000000"}, |
46 | 50 | }), |
47 | 51 | ) |
| 52 | + |
| 53 | + Context("UpdateIRQBalanceConfigFile", func() { |
| 54 | + It("Should not let the file grow unbounded", func() { |
| 55 | + fakeFile, err := writeTempFile(confTemplate) |
| 56 | + Expect(err).ToNot(HaveOccurred()) |
| 57 | + defer os.Remove(fakeFile) |
| 58 | + |
| 59 | + fakeData := "000000000,0000000fa" // doesn't need to be valid |
| 60 | + err = updateIrqBalanceConfigFile(fakeFile, fakeData) |
| 61 | + Expect(err).ToNot(HaveOccurred()) |
| 62 | + |
| 63 | + refLineCount, err := countLines(fakeFile) |
| 64 | + Expect(err).ToNot(HaveOccurred()) |
| 65 | + |
| 66 | + attempts := 10 // random number, no special meaning |
| 67 | + for idx := 0; idx < attempts; idx++ { |
| 68 | + data := fmt.Sprintf("000000000,0000000%02x", idx) |
| 69 | + err = updateIrqBalanceConfigFile(fakeFile, data) |
| 70 | + Expect(err).ToNot(HaveOccurred()) |
| 71 | + |
| 72 | + curLineCount, err := countLines(fakeFile) |
| 73 | + Expect(err).ToNot(HaveOccurred()) |
| 74 | + |
| 75 | + // we should replace the line in place |
| 76 | + Expect(curLineCount).To(Equal(refLineCount), "irqbalance file grown from %d to %d lines", refLineCount, curLineCount) |
| 77 | + } |
| 78 | + }) |
| 79 | + }) |
48 | 80 | }) |
49 | 81 | }) |
| 82 | + |
| 83 | +func countLines(fileName string) (int, error) { |
| 84 | + file, err := os.Open(fileName) |
| 85 | + if err != nil { |
| 86 | + return -1, err |
| 87 | + } |
| 88 | + defer file.Close() |
| 89 | + fileScanner := bufio.NewScanner(file) |
| 90 | + lineCount := 0 |
| 91 | + for fileScanner.Scan() { |
| 92 | + lineCount++ |
| 93 | + } |
| 94 | + return lineCount, nil |
| 95 | +} |
| 96 | + |
| 97 | +func writeTempFile(content string) (string, error) { |
| 98 | + f, err := os.CreateTemp("", "test-irqbalance-conf") |
| 99 | + if err != nil { |
| 100 | + return "", err |
| 101 | + } |
| 102 | + |
| 103 | + if _, err := f.WriteString(confTemplate); err != nil { |
| 104 | + return "", err |
| 105 | + } |
| 106 | + if err := f.Close(); err != nil { |
| 107 | + return "", err |
| 108 | + } |
| 109 | + return f.Name(), nil |
| 110 | +} |
| 111 | + |
| 112 | +const confTemplate = `# irqbalance is a daemon process that distributes interrupts across |
| 113 | +# CPUS on SMP systems. The default is to rebalance once every 10 |
| 114 | +# seconds. This is the environment file that is specified to systemd via the |
| 115 | +# EnvironmentFile key in the service unit file (or via whatever method the init |
| 116 | +# system you're using has. |
| 117 | +# |
| 118 | +# ONESHOT=yes |
| 119 | +# after starting, wait for a minute, then look at the interrupt |
| 120 | +# load and balance it once; after balancing exit and do not change |
| 121 | +# it again. |
| 122 | +#IRQBALANCE_ONESHOT= |
| 123 | +
|
| 124 | +# |
| 125 | +# IRQBALANCE_BANNED_CPUS |
| 126 | +# 64 bit bitmask which allows you to indicate which cpu's should |
| 127 | +# be skipped when reblancing irqs. Cpu numbers which have their |
| 128 | +# corresponding bits set to one in this mask will not have any |
| 129 | +# irq's assigned to them on rebalance |
| 130 | +# |
| 131 | +#IRQBALANCE_BANNED_CPUS= |
| 132 | +
|
| 133 | +# |
| 134 | +# IRQBALANCE_ARGS |
| 135 | +# append any args here to the irqbalance daemon as documented in the man page |
| 136 | +# |
| 137 | +#IRQBALANCE_ARGS= |
| 138 | +
|
| 139 | +IRQBALANCE_BANNED_CPUS= |
| 140 | +` |
0 commit comments