summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorArne Juul <arnej@yahooinc.com>2023-04-23 16:16:41 +0000
committerArne Juul <arnej@yahooinc.com>2023-04-23 16:45:51 +0000
commitaf9fb6e14901f3320919f5a3887bc00fdecc065b (patch)
treee797831f381682d0666da57aa4f76f38a17baded /client
parente2122d6ad5b018ec11dd9eb35c39a057aa0ed540 (diff)
refactor
Diffstat (limited to 'client')
-rw-r--r--client/go/internal/admin/prog/common_env.go43
-rw-r--r--client/go/internal/admin/prog/hugepages.go2
-rw-r--r--client/go/internal/admin/prog/madvise.go2
-rw-r--r--client/go/internal/admin/prog/spec_env.go10
-rw-r--r--client/go/internal/admin/prog/vespamalloc.go10
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/common_env.go73
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/numactl.go72
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/numactl_test.go89
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/progspec.go123
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/progspec_test.go38
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/startcbinary.go40
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/tuning.go2
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/valgrind.go83
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/valgrind_test.go97
-rw-r--r--client/go/internal/admin/vespa-wrapper/startcbinary/vespamalloc.go57
15 files changed, 56 insertions, 685 deletions
diff --git a/client/go/internal/admin/prog/common_env.go b/client/go/internal/admin/prog/common_env.go
deleted file mode 100644
index f743716a64e..00000000000
--- a/client/go/internal/admin/prog/common_env.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-// Author: arnej
-
-package prog
-
-import (
- "os"
- "strings"
-
- "github.com/vespa-engine/vespa/client/go/internal/admin/envvars"
- "github.com/vespa-engine/vespa/client/go/internal/vespa"
-)
-
-func (spec *Spec) configureCommonEnv() {
- os.Unsetenv(envvars.LD_PRELOAD)
- spec.Setenv(envvars.STD_THREAD_PREVENT_TRY_CATCH, "true")
- spec.Setenv(envvars.GLIBCXX_FORCE_NEW, "1")
- spec.Setenv(envvars.LD_LIBRARY_PATH, vespa.FindHome()+"/lib64:/opt/vespa-deps/lib64")
- spec.Setenv(envvars.MALLOC_ARENA_MAX, "1")
-
- // fallback from old env.vars:
- spec.considerEnvFallback(envvars.VESPA_USE_HUGEPAGES_LIST, envvars.HUGEPAGES_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_MADVISE_LIST, envvars.MADVISE_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_VESPAMALLOC, envvars.VESPAMALLOC_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_VESPAMALLOC_D, envvars.VESPAMALLOCD_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_VESPAMALLOC_DST, envvars.VESPAMALLOCDST_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_NO_VESPAMALLOC, envvars.NO_VESPAMALLOC_LIST)
- // other fallbacks:
- spec.considerFallback(envvars.ROOT, vespa.FindHome())
- spec.considerFallback(envvars.VESPA_USER, vespa.FindVespaUser())
- spec.considerFallback(envvars.VESPA_USE_HUGEPAGES_LIST, "all")
- spec.considerFallback(envvars.VESPA_USE_VESPAMALLOC, "all")
- spec.considerFallback(envvars.VESPA_USE_NO_VESPAMALLOC, strings.Join([]string{
- "vespa-rpc-invoke",
- "vespa-get-config",
- "vespa-sentinel-cmd",
- "vespa-route",
- "vespa-proton-cmd",
- "vespa-configproxy-cmd",
- "vespa-config-status",
- }, " "))
-
-}
diff --git a/client/go/internal/admin/prog/hugepages.go b/client/go/internal/admin/prog/hugepages.go
index c6f019937ff..b66d512d4c9 100644
--- a/client/go/internal/admin/prog/hugepages.go
+++ b/client/go/internal/admin/prog/hugepages.go
@@ -9,7 +9,7 @@ import (
)
func (spec *Spec) ConfigureHugePages() {
- if spec.matchesListEnv(envvars.VESPA_USE_HUGEPAGES_LIST) {
+ if spec.MatchesListEnv(envvars.VESPA_USE_HUGEPAGES_LIST) {
trace.Debug("setting", envvars.VESPA_USE_HUGEPAGES, "= 'yes'")
spec.Setenv(envvars.VESPA_USE_HUGEPAGES, "yes")
}
diff --git a/client/go/internal/admin/prog/madvise.go b/client/go/internal/admin/prog/madvise.go
index 48986a12182..967823d956b 100644
--- a/client/go/internal/admin/prog/madvise.go
+++ b/client/go/internal/admin/prog/madvise.go
@@ -9,7 +9,7 @@ import (
)
func (spec *Spec) ConfigureUseMadvise() {
- limit := spec.valueFromListEnv(envvars.VESPA_USE_MADVISE_LIST)
+ limit := spec.ValueFromListEnv(envvars.VESPA_USE_MADVISE_LIST)
if limit != "" {
trace.Trace("shall use madvise with limit", limit, "as set in", envvars.VESPA_USE_MADVISE_LIST)
spec.Setenv(envvars.VESPA_MALLOC_MADVISE_LIMIT, limit)
diff --git a/client/go/internal/admin/prog/spec_env.go b/client/go/internal/admin/prog/spec_env.go
index 4fa40695acb..c88ec963812 100644
--- a/client/go/internal/admin/prog/spec_env.go
+++ b/client/go/internal/admin/prog/spec_env.go
@@ -50,17 +50,17 @@ func (spec *Spec) EffectiveEnv() []string {
return envVec
}
-func (spec *Spec) considerFallback(varName, varValue string) {
+func (spec *Spec) ConsiderFallback(varName, varValue string) {
if spec.Getenv(varName) == "" && varValue != "" {
spec.Setenv(varName, varValue)
}
}
-func (spec *Spec) considerEnvFallback(targetVar, fallbackVar string) {
- spec.considerFallback(targetVar, spec.Getenv(fallbackVar))
+func (spec *Spec) ConsiderEnvFallback(targetVar, fallbackVar string) {
+ spec.ConsiderFallback(targetVar, spec.Getenv(fallbackVar))
}
-func (p *Spec) matchesListEnv(envVarName string) bool {
+func (p *Spec) MatchesListEnv(envVarName string) bool {
return p.matchesListString(p.Getenv(envVarName))
}
@@ -80,7 +80,7 @@ func (p *Spec) matchesListString(env string) bool {
return false
}
-func (p *Spec) valueFromListEnv(envVarName string) string {
+func (p *Spec) ValueFromListEnv(envVarName string) string {
return p.valueFromListString(p.Getenv(envVarName))
}
diff --git a/client/go/internal/admin/prog/vespamalloc.go b/client/go/internal/admin/prog/vespamalloc.go
index 439935770d7..e66c9e5d966 100644
--- a/client/go/internal/admin/prog/vespamalloc.go
+++ b/client/go/internal/admin/prog/vespamalloc.go
@@ -27,7 +27,7 @@ func vespaMallocLib(suf string) string {
func (p *Spec) ConfigureVespaMalloc() {
p.shouldUseVespaMalloc = false
- if p.matchesListEnv(envvars.VESPA_USE_NO_VESPAMALLOC) {
+ if p.MatchesListEnv(envvars.VESPA_USE_NO_VESPAMALLOC) {
trace.Trace("use no vespamalloc:", p.BaseName)
return
}
@@ -36,11 +36,11 @@ func (p *Spec) ConfigureVespaMalloc() {
return
}
var useFile string
- if p.matchesListEnv(envvars.VESPA_USE_VESPAMALLOC_DST) {
+ if p.MatchesListEnv(envvars.VESPA_USE_VESPAMALLOC_DST) {
useFile = vespaMallocLib("libvespamallocdst16.so")
- } else if p.matchesListEnv(envvars.VESPA_USE_VESPAMALLOC_D) {
+ } else if p.MatchesListEnv(envvars.VESPA_USE_VESPAMALLOC_D) {
useFile = vespaMallocLib("libvespamallocd.so")
- } else if p.matchesListEnv(envvars.VESPA_USE_VESPAMALLOC) {
+ } else if p.MatchesListEnv(envvars.VESPA_USE_VESPAMALLOC) {
useFile = vespaMallocLib("libvespamalloc.so")
}
trace.Trace("use file:", useFile)
@@ -51,7 +51,7 @@ func (p *Spec) ConfigureVespaMalloc() {
otherFile := vespaMallocLib("libvespa_load_as_huge.so")
useFile = fmt.Sprintf("%s:%s", useFile, otherFile)
}
- p.considerEnvFallback(envvars.VESPA_MALLOC_HUGEPAGES, envvars.VESPA_USE_HUGEPAGES)
+ p.ConsiderEnvFallback(envvars.VESPA_MALLOC_HUGEPAGES, envvars.VESPA_USE_HUGEPAGES)
p.vespaMallocPreload = useFile
p.shouldUseVespaMalloc = true
}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/common_env.go b/client/go/internal/admin/vespa-wrapper/startcbinary/common_env.go
index 6bc730b5119..07ec19bf7e5 100644
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/common_env.go
+++ b/client/go/internal/admin/vespa-wrapper/startcbinary/common_env.go
@@ -8,40 +8,30 @@ import (
"strings"
"github.com/vespa-engine/vespa/client/go/internal/admin/envvars"
- "github.com/vespa-engine/vespa/client/go/internal/admin/trace"
+ "github.com/vespa-engine/vespa/client/go/internal/admin/prog"
"github.com/vespa-engine/vespa/client/go/internal/vespa"
)
-func (spec *ProgSpec) considerFallback(varName, varValue string) {
- if spec.getenv(varName) == "" && varValue != "" {
- spec.setenv(varName, varValue)
- }
-}
-
-func (spec *ProgSpec) considerEnvFallback(targetVar, fallbackVar string) {
- spec.considerFallback(targetVar, spec.getenv(fallbackVar))
-}
-
-func (spec *ProgSpec) configureCommonEnv() {
+func configureCommonEnv(spec *prog.Spec) {
os.Unsetenv(envvars.LD_PRELOAD)
- spec.setenv(envvars.STD_THREAD_PREVENT_TRY_CATCH, "true")
- spec.setenv(envvars.GLIBCXX_FORCE_NEW, "1")
- spec.setenv(envvars.LD_LIBRARY_PATH, vespa.FindHome()+"/lib64:/opt/vespa-deps/lib64")
- spec.setenv(envvars.MALLOC_ARENA_MAX, "1")
+ spec.Setenv(envvars.STD_THREAD_PREVENT_TRY_CATCH, "true")
+ spec.Setenv(envvars.GLIBCXX_FORCE_NEW, "1")
+ spec.Setenv(envvars.LD_LIBRARY_PATH, vespa.FindHome()+"/lib64:/opt/vespa-deps/lib64")
+ spec.Setenv(envvars.MALLOC_ARENA_MAX, "1")
// fallback from old env.vars:
- spec.considerEnvFallback(envvars.VESPA_USE_HUGEPAGES_LIST, envvars.HUGEPAGES_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_MADVISE_LIST, envvars.MADVISE_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_VESPAMALLOC, envvars.VESPAMALLOC_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_VESPAMALLOC_D, envvars.VESPAMALLOCD_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_VESPAMALLOC_DST, envvars.VESPAMALLOCDST_LIST)
- spec.considerEnvFallback(envvars.VESPA_USE_NO_VESPAMALLOC, envvars.NO_VESPAMALLOC_LIST)
+ spec.ConsiderEnvFallback(envvars.VESPA_USE_HUGEPAGES_LIST, envvars.HUGEPAGES_LIST)
+ spec.ConsiderEnvFallback(envvars.VESPA_USE_MADVISE_LIST, envvars.MADVISE_LIST)
+ spec.ConsiderEnvFallback(envvars.VESPA_USE_VESPAMALLOC, envvars.VESPAMALLOC_LIST)
+ spec.ConsiderEnvFallback(envvars.VESPA_USE_VESPAMALLOC_D, envvars.VESPAMALLOCD_LIST)
+ spec.ConsiderEnvFallback(envvars.VESPA_USE_VESPAMALLOC_DST, envvars.VESPAMALLOCDST_LIST)
+ spec.ConsiderEnvFallback(envvars.VESPA_USE_NO_VESPAMALLOC, envvars.NO_VESPAMALLOC_LIST)
// other fallbacks:
- spec.considerFallback(envvars.ROOT, vespa.FindHome())
- spec.considerFallback(envvars.VESPA_USER, vespa.FindVespaUser())
- spec.considerFallback(envvars.VESPA_USE_HUGEPAGES_LIST, "all")
- spec.considerFallback(envvars.VESPA_USE_VESPAMALLOC, "all")
- spec.considerFallback(envvars.VESPA_USE_NO_VESPAMALLOC, strings.Join([]string{
+ spec.ConsiderFallback(envvars.ROOT, vespa.FindHome())
+ spec.ConsiderFallback(envvars.VESPA_USER, vespa.FindVespaUser())
+ spec.ConsiderFallback(envvars.VESPA_USE_HUGEPAGES_LIST, "all")
+ spec.ConsiderFallback(envvars.VESPA_USE_VESPAMALLOC, "all")
+ spec.ConsiderFallback(envvars.VESPA_USE_NO_VESPAMALLOC, strings.Join([]string{
"vespa-rpc-invoke",
"vespa-get-config",
"vespa-sentinel-cmd",
@@ -53,31 +43,16 @@ func (spec *ProgSpec) configureCommonEnv() {
}
-func (spec *ProgSpec) configureHugePages() {
- if spec.matchesListEnv(envvars.VESPA_USE_HUGEPAGES_LIST) {
- spec.setenv(envvars.VESPA_USE_HUGEPAGES, "yes")
- }
-}
-
-func (spec *ProgSpec) configureUseMadvise() {
- limit := spec.valueFromListEnv(envvars.VESPA_USE_MADVISE_LIST)
- if limit != "" {
- trace.Trace("shall use madvise with limit", limit, "as set in", envvars.VESPA_USE_MADVISE_LIST)
- spec.setenv(envvars.VESPA_MALLOC_MADVISE_LIMIT, limit)
- return
- }
-}
-
-func (spec *ProgSpec) configurePath() {
+func configurePath(spec *prog.Spec) {
// Prefer newer gdb and pstack:
- spec.prependPath("/opt/rh/gcc-toolset-12/root/usr/bin")
+ prependPath("/opt/rh/gcc-toolset-12/root/usr/bin", spec)
// Maven is needed for tester applications:
- spec.prependPath(vespa.FindHome() + "/local/maven/bin")
- spec.prependPath(vespa.FindHome() + "/bin64")
- spec.prependPath(vespa.FindHome() + "/bin")
+ prependPath(vespa.FindHome()+"/local/maven/bin", spec)
+ prependPath(vespa.FindHome()+"/bin64", spec)
+ prependPath(vespa.FindHome()+"/bin", spec)
// how to find the "java" program?
// should be available in $VESPA_HOME/bin or JAVA_HOME
- if javaHome := spec.getenv(envvars.JAVA_HOME); javaHome != "" {
- spec.prependPath(javaHome + "/bin")
+ if javaHome := spec.Getenv(envvars.JAVA_HOME); javaHome != "" {
+ prependPath(javaHome+"/bin", spec)
}
}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/numactl.go b/client/go/internal/admin/vespa-wrapper/startcbinary/numactl.go
deleted file mode 100644
index fe091dedba9..00000000000
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/numactl.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-// Author: arnej
-
-package startcbinary
-
-import (
- "fmt"
- "strconv"
- "strings"
-
- "github.com/vespa-engine/vespa/client/go/internal/admin/envvars"
- "github.com/vespa-engine/vespa/client/go/internal/admin/trace"
- "github.com/vespa-engine/vespa/client/go/internal/util"
-)
-
-func (p *ProgSpec) configureNumaCtl() {
- p.shouldUseNumaCtl = false
- p.numaSocket = -1
- if p.getenv(envvars.VESPA_NO_NUMACTL) != "" {
- return
- }
- backticks := util.BackTicksIgnoreStderr
- out, err := backticks.Run("numactl", "--hardware")
- trace.Debug("numactl --hardware says:", out)
- if err != nil {
- trace.Trace("numactl error:", err)
- return
- }
- outfoo, errfoo := backticks.Run("numactl", "--interleave", "all", "echo", "foo")
- if errfoo != nil {
- trace.Trace("cannot run with numactl:", errfoo)
- return
- }
- if outfoo != "foo\n" {
- trace.Trace("bad numactl output:", outfoo)
- return
- }
- p.shouldUseNumaCtl = true
- if affinity := p.getenv(envvars.VESPA_AFFINITY_CPU_SOCKET); affinity != "" {
- wantSocket, _ := strconv.Atoi(affinity)
- trace.Debug("want socket:", wantSocket)
- parts := strings.Fields(out)
- for idx := 0; idx+2 < len(parts); idx++ {
- if parts[idx] == "available:" && parts[idx+2] == "nodes" {
- numSockets, _ := strconv.Atoi(parts[idx+1])
- trace.Debug("numSockets:", numSockets)
- if numSockets > 1 {
- p.numaSocket = (wantSocket % numSockets)
- return
- }
- }
- }
- }
-}
-
-func (p *ProgSpec) numaCtlBinary() string {
- return "numactl"
-}
-
-func (p *ProgSpec) prependNumaCtl(args []string) []string {
- v := util.NewArrayList[string](5 + len(args))
- v.Append("numactl")
- if p.numaSocket >= 0 {
- v.Append(fmt.Sprintf("--cpunodebind=%d", p.numaSocket))
- v.Append(fmt.Sprintf("--membind=%d", p.numaSocket))
- } else {
- v.Append("--interleave")
- v.Append("all")
- }
- v.AppendAll(args...)
- return v
-}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/numactl_test.go b/client/go/internal/admin/vespa-wrapper/startcbinary/numactl_test.go
deleted file mode 100644
index 65f52be988e..00000000000
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/numactl_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package startcbinary
-
-import (
- "fmt"
- "os"
- "runtime"
- "strings"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/vespa-engine/vespa/client/go/internal/admin/trace"
-)
-
-func setup(t *testing.T, testFileName string) {
- trace.AdjustVerbosity(1)
- mockBinParent = strings.TrimSuffix(testFileName, "/numactl_test.go")
- tmpBin = t.TempDir() + "/mock.bin.numactl_test"
- err := os.MkdirAll(tmpBin, 0755)
- assert.Nil(t, err)
- t.Setenv("PATH", fmt.Sprintf("%s:%s", tmpBin, os.Getenv("PATH")))
-}
-
-func TestNumaCtlDetection(t *testing.T) {
- if runtime.GOOS == "windows" {
- return
- }
- _, tfn, _, _ := runtime.Caller(0)
- setup(t, tfn)
- orig := []string{"/bin/myprog", "-c", "cfgid"}
- spec := NewProgSpec(orig)
-
- useMock("no-numactl", "numactl")
- spec.configureNumaCtl()
- assert.Equal(t, false, spec.shouldUseNumaCtl)
-
- useMock("bad-numactl", "numactl")
- spec.configureNumaCtl()
- assert.Equal(t, false, spec.shouldUseNumaCtl)
-
- t.Setenv("VESPA_AFFINITY_CPU_SOCKET", "")
- useMock("good-numactl", "numactl")
- spec.configureNumaCtl()
- assert.Equal(t, true, spec.shouldUseNumaCtl)
- assert.Equal(t, -1, spec.numaSocket)
- argv := spec.prependNumaCtl(orig)
- trace.Trace("argv:", argv)
- assert.Equal(t, 6, len(argv))
- assert.Equal(t, "numactl", argv[0])
- assert.Equal(t, "--interleave", argv[1])
- assert.Equal(t, "all", argv[2])
- assert.Equal(t, "/bin/myprog-bin", argv[3])
- assert.Equal(t, "-c", argv[4])
- assert.Equal(t, "cfgid", argv[5])
-
- t.Setenv("VESPA_AFFINITY_CPU_SOCKET", "0")
- spec.configureNumaCtl()
- assert.Equal(t, true, spec.shouldUseNumaCtl)
- assert.Equal(t, 0, spec.numaSocket)
- argv = spec.prependNumaCtl(orig)
- trace.Trace("argv:", argv)
- assert.Equal(t, 6, len(argv))
- assert.Equal(t, "numactl", argv[0])
- assert.Equal(t, "--cpunodebind=0", argv[1])
- assert.Equal(t, "--membind=0", argv[2])
- assert.Equal(t, "/bin/myprog-bin", argv[3])
- assert.Equal(t, "-c", argv[4])
- assert.Equal(t, "cfgid", argv[5])
-
- t.Setenv("VESPA_AFFINITY_CPU_SOCKET", "1")
- spec.configureNumaCtl()
- assert.Equal(t, true, spec.shouldUseNumaCtl)
- assert.Equal(t, 1, spec.numaSocket)
- argv = spec.prependNumaCtl(orig)
- trace.Trace("argv:", argv)
- assert.Equal(t, 6, len(argv))
- assert.Equal(t, "numactl", argv[0])
- assert.Equal(t, "--cpunodebind=1", argv[1])
- assert.Equal(t, "--membind=1", argv[2])
- assert.Equal(t, "/bin/myprog-bin", argv[3])
- assert.Equal(t, "-c", argv[4])
- assert.Equal(t, "cfgid", argv[5])
-
- t.Setenv("VESPA_AFFINITY_CPU_SOCKET", "2")
- spec.configureNumaCtl()
- assert.Equal(t, true, spec.shouldUseNumaCtl)
- assert.Equal(t, 0, spec.numaSocket)
-
-}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/progspec.go b/client/go/internal/admin/vespa-wrapper/startcbinary/progspec.go
index 9975f6c3c90..b0dcc402893 100644
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/progspec.go
+++ b/client/go/internal/admin/vespa-wrapper/startcbinary/progspec.go
@@ -8,56 +8,21 @@ import (
"strings"
"github.com/vespa-engine/vespa/client/go/internal/admin/envvars"
- "github.com/vespa-engine/vespa/client/go/internal/admin/trace"
+ "github.com/vespa-engine/vespa/client/go/internal/admin/prog"
)
-type ProgSpec struct {
- Program string
- Args []string
- BaseName string
- Env map[string]string
- numaSocket int
- shouldUseCallgrind bool
- shouldUseValgrind bool
- shouldUseNumaCtl bool
- shouldUseVespaMalloc bool
- vespaMallocPreload string
-}
-
-func NewProgSpec(argv []string) *ProgSpec {
+func NewProgSpec(argv []string) *prog.Spec {
progName := argv[0]
binProg := progName + "-bin"
- p := ProgSpec{
- Program: binProg,
- Args: argv,
- BaseName: baseNameOf(progName),
- Env: make(map[string]string),
- numaSocket: -1,
- }
+ p := prog.NewSpec(argv)
+ p.Program = binProg
p.Args[0] = binProg
- return &p
-}
-
-func baseNameOf(s string) string {
- idx := strings.LastIndex(s, "/")
- idx++
- return s[idx:]
-}
-
-func (p *ProgSpec) setenv(k, v string) {
- p.Env[k] = v
-}
-
-func (p *ProgSpec) getenv(k string) string {
- if v, ok := p.Env[k]; ok {
- return v
- }
- return os.Getenv(k)
+ return p
}
-func (p *ProgSpec) prependPath(dirName string) {
+func prependPath(dirName string, p *prog.Spec) {
pathList := []string{dirName}
- oldPath := p.getenv(envvars.PATH)
+ oldPath := p.Getenv(envvars.PATH)
if oldPath == "" {
oldPath = "/usr/bin"
}
@@ -67,78 +32,6 @@ func (p *ProgSpec) prependPath(dirName string) {
}
}
newPath := strings.Join(pathList, ":")
- p.setenv(envvars.PATH, newPath)
+ p.Setenv(envvars.PATH, newPath)
os.Setenv(envvars.PATH, newPath)
}
-
-func (p *ProgSpec) matchesListEnv(envVarName string) bool {
- return p.matchesListString(p.getenv(envVarName))
-}
-
-func (p *ProgSpec) matchesListString(env string) bool {
- if env == "all" {
- trace.Debug(p.Program, "always matching in:", env)
- return true
- }
- parts := strings.Fields(env)
- for _, part := range parts {
- if p.BaseName == part {
- trace.Debug(p.Program, "has basename matching in:", env)
- return true
- }
- trace.Debug("checking matching:", p.BaseName, "!=", part)
- }
- return false
-}
-
-func (p *ProgSpec) valueFromListEnv(envVarName string) string {
- return p.valueFromListString(p.getenv(envVarName))
-}
-
-func (p *ProgSpec) valueFromListString(env string) string {
- parts := strings.Fields(env)
- for _, part := range parts {
- idx := strings.Index(part, "=")
- if idx <= 0 {
- trace.Trace("expected key=value, but got:", part)
- continue
- }
- partName := part[:idx]
- idx++
- partValue := part[idx:]
- if p.BaseName == partName || partName == "all" {
- trace.Debug(p.Program, "has basename matching in:", env)
- return partValue
- }
- trace.Debug("checking matching:", p.BaseName, "!=", part)
- }
- return ""
-}
-
-func (spec *ProgSpec) effectiveEnv() []string {
- env := make(map[string]string)
- for _, entry := range os.Environ() {
- addInMap := func(kv string) bool {
- for idx, elem := range kv {
- if elem == '=' {
- k := kv[:idx]
- env[k] = kv
- return true
- }
- }
- return false
- }
- if !addInMap(entry) {
- env[entry] = ""
- }
- }
- for k, v := range spec.Env {
- trace.Trace("add to environment:", k, "=", v)
- env[k] = k + "=" + v
- }
- envv := make([]string, 0, len(env))
- for _, v := range env {
- envv = append(envv, v)
- }
- return envv
-}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/progspec_test.go b/client/go/internal/admin/vespa-wrapper/startcbinary/progspec_test.go
deleted file mode 100644
index be113e4e350..00000000000
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/progspec_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package startcbinary
-
-import (
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestProgSpec(t *testing.T) {
- spec := NewProgSpec([]string{"/opt/vespa/bin/foobar"})
- var b bool
-
- b = spec.matchesListString("")
- assert.Equal(t, false, b)
- b = spec.matchesListString("foobar")
- assert.Equal(t, true, b)
- b = spec.matchesListString("foo bar")
- assert.Equal(t, false, b)
- b = spec.matchesListString("one foobar")
- assert.Equal(t, true, b)
- b = spec.matchesListString("foobar two")
- assert.Equal(t, true, b)
- b = spec.matchesListString("one foobar two")
- assert.Equal(t, true, b)
- b = spec.matchesListString("all")
- assert.Equal(t, true, b)
-
- var s string
- s = spec.valueFromListString("")
- assert.Equal(t, "", s)
- s = spec.valueFromListString("foobar=123")
- assert.Equal(t, "123", s)
- s = spec.valueFromListString("one=1 foobar=123 two=2")
- assert.Equal(t, "123", s)
- s = spec.valueFromListString("one=1 all=123")
- assert.Equal(t, "123", s)
-}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/startcbinary.go b/client/go/internal/admin/vespa-wrapper/startcbinary/startcbinary.go
index f5e58e59808..a062f631b2c 100644
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/startcbinary.go
+++ b/client/go/internal/admin/vespa-wrapper/startcbinary/startcbinary.go
@@ -7,20 +7,19 @@ import (
"fmt"
"os"
- "github.com/vespa-engine/vespa/client/go/internal/admin/envvars"
- "github.com/vespa-engine/vespa/client/go/internal/util"
+ "github.com/vespa-engine/vespa/client/go/internal/admin/prog"
)
-func startCbinary(spec *ProgSpec) int {
- spec.configureCommonEnv()
- spec.configurePath()
- spec.configureTuning()
- spec.configureValgrind()
- spec.configureNumaCtl()
- spec.configureHugePages()
- spec.configureUseMadvise()
- spec.configureVespaMalloc()
- err := spec.run()
+func startCbinary(spec *prog.Spec) int {
+ configureCommonEnv(spec)
+ configurePath(spec)
+ configureTuning()
+ spec.ConfigureValgrind()
+ spec.ConfigureNumaCtl()
+ spec.ConfigureHugePages()
+ spec.ConfigureUseMadvise()
+ spec.ConfigureVespaMalloc()
+ err := spec.Run()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
@@ -28,20 +27,3 @@ func startCbinary(spec *ProgSpec) int {
return 0
}
}
-
-func (spec *ProgSpec) run() error {
- prog := spec.Program
- args := spec.Args
- if spec.shouldUseValgrind {
- args = spec.prependValgrind(args)
- prog = spec.valgrindBinary()
- } else if spec.shouldUseNumaCtl {
- args = spec.prependNumaCtl(args)
- prog = spec.numaCtlBinary()
- }
- if spec.shouldUseVespaMalloc {
- spec.setenv(envvars.LD_PRELOAD, spec.vespaMallocPreload)
- }
- envv := spec.effectiveEnv()
- return util.Execvpe(prog, args, envv)
-}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/tuning.go b/client/go/internal/admin/vespa-wrapper/startcbinary/tuning.go
index 57230629d7a..f839d6a0946 100644
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/tuning.go
+++ b/client/go/internal/admin/vespa-wrapper/startcbinary/tuning.go
@@ -7,7 +7,7 @@ import (
"github.com/vespa-engine/vespa/client/go/internal/util"
)
-func (spec *ProgSpec) configureTuning() {
+func configureTuning() {
util.OptionallyReduceTimerFrequency()
util.TuneResourceLimits()
}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/valgrind.go b/client/go/internal/admin/vespa-wrapper/startcbinary/valgrind.go
deleted file mode 100644
index cccb37df8e5..00000000000
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/valgrind.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-// Author: arnej
-
-package startcbinary
-
-import (
- "fmt"
- "os"
- "strings"
-
- "github.com/vespa-engine/vespa/client/go/internal/admin/envvars"
- "github.com/vespa-engine/vespa/client/go/internal/admin/trace"
- "github.com/vespa-engine/vespa/client/go/internal/util"
- "github.com/vespa-engine/vespa/client/go/internal/vespa"
-)
-
-func (p *ProgSpec) configureValgrind() {
- p.shouldUseValgrind = false
- p.shouldUseCallgrind = false
- env := p.getenv(envvars.VESPA_USE_VALGRIND)
- allValgrind := env == "all"
- parts := strings.Split(env, " ")
- for _, part := range parts {
- if p.BaseName == part || allValgrind {
- trace.Trace("using valgrind as", p.Program, "has basename in", envvars.VESPA_USE_VALGRIND, "=>", env)
- backticks := util.BackTicksWithStderr
- out, err := backticks.Run("which", "valgrind")
- if err != nil {
- trace.Trace("no valgrind, 'which' fails:", err, "=>", out)
- return
- }
- if opts := p.getenv(envvars.VESPA_VALGRIND_OPT); strings.Contains(opts, "callgrind") {
- p.shouldUseCallgrind = true
- }
- p.shouldUseValgrind = true
- return
- }
- trace.Debug("checking", envvars.VESPA_USE_VALGRIND, ":", p.BaseName, "!=", part)
- }
-}
-
-func (p *ProgSpec) valgrindBinary() string {
- return "valgrind"
-}
-
-func (p *ProgSpec) valgrindOptions() []string {
- env := p.getenv(envvars.VESPA_VALGRIND_OPT)
- if env != "" {
- return strings.Fields(env)
- }
- result := []string{
- "--num-callers=32",
- "--run-libc-freeres=yes",
- "--track-origins=yes",
- "--freelist-vol=1000000000",
- "--leak-check=full",
- "--show-reachable=yes",
- }
- result = addValgrindSuppression(result, "etc/vespa/valgrind-suppressions.txt")
- result = addValgrindSuppression(result, "etc/vespa/suppressions.txt")
- return result
-}
-
-func addValgrindSuppression(r []string, fn string) []string {
- existsOk, fileName := vespa.HasFileUnderVespaHome(fn)
- if existsOk {
- r = append(r, fmt.Sprintf("--suppressions=%s", fileName))
- }
- return r
-}
-
-func (p *ProgSpec) valgrindLogOption() string {
- return fmt.Sprintf("--log-file=%s/tmp/valgrind.%s.log.%d", vespa.FindHome(), p.BaseName, os.Getpid())
-}
-
-func (p *ProgSpec) prependValgrind(args []string) []string {
- v := util.NewArrayList[string](15 + len(args))
- v.Append(p.valgrindBinary())
- v.AppendAll(p.valgrindOptions()...)
- v.Append(p.valgrindLogOption())
- v.AppendAll(args...)
- return v
-}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/valgrind_test.go b/client/go/internal/admin/vespa-wrapper/startcbinary/valgrind_test.go
deleted file mode 100644
index 1a105d66c4a..00000000000
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/valgrind_test.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package startcbinary
-
-import (
- "fmt"
- "os"
- "runtime"
- "strings"
- "testing"
-
- "github.com/stretchr/testify/assert"
- "github.com/vespa-engine/vespa/client/go/internal/admin/trace"
- "github.com/vespa-engine/vespa/client/go/internal/util"
-)
-
-var tmpBin string
-var mockBinParent string
-
-func useMock(prog, target string) {
- mock := fmt.Sprintf("%s/mockbin/%s", mockBinParent, prog)
- symlink := fmt.Sprintf("%s/%s", tmpBin, target)
- os.Remove(symlink)
- err := os.Symlink(mock, symlink)
- if err != nil {
- util.JustExitWith(err)
- }
-}
-
-func setupValgrind(t *testing.T, testFileName string) {
- trace.AdjustVerbosity(1)
- t.Setenv("VESPA_HOME", mockBinParent+"/mock_vespahome")
- mockBinParent = strings.TrimSuffix(testFileName, "/valgrind_test.go")
- tmpBin = t.TempDir() + "/mock.bin.valgrind_test"
- err := os.MkdirAll(tmpBin, 0755)
- assert.Nil(t, err)
- t.Setenv("PATH", fmt.Sprintf("%s:%s", tmpBin, os.Getenv("PATH")))
-}
-
-func TestValgrindDetection(t *testing.T) {
- if runtime.GOOS == "windows" {
- return
- }
- _, tfn, _, _ := runtime.Caller(0)
- setupValgrind(t, tfn)
- spec := NewProgSpec([]string{"/opt/vespa/bin/foobar"})
- var argv []string
-
- useMock("has-valgrind", "which")
-
- t.Setenv("VESPA_USE_VALGRIND", "")
- spec.configureValgrind()
- assert.Equal(t, false, spec.shouldUseValgrind)
- assert.Equal(t, false, spec.shouldUseCallgrind)
-
- t.Setenv("VESPA_USE_VALGRIND", "all")
- spec.configureValgrind()
- assert.Equal(t, true, spec.shouldUseValgrind)
- assert.Equal(t, false, spec.shouldUseCallgrind)
-
- t.Setenv("VESPA_USE_VALGRIND", "foo bar")
- spec.configureValgrind()
- assert.Equal(t, false, spec.shouldUseValgrind)
- assert.Equal(t, false, spec.shouldUseCallgrind)
-
- t.Setenv("VESPA_USE_VALGRIND", "foobar")
- spec.configureValgrind()
- assert.Equal(t, true, spec.shouldUseValgrind)
- assert.Equal(t, false, spec.shouldUseCallgrind)
-
- argv = spec.prependValgrind([]string{"/bin/myprog", "-c", "cfgid"})
- trace.Trace("argv:", argv)
- assert.Equal(t, 11, len(argv))
- assert.Equal(t, "valgrind", argv[0])
- assert.Equal(t, "/bin/myprog", argv[8])
-
- t.Setenv("VESPA_USE_VALGRIND", "another foobar yetmore")
- spec.configureValgrind()
- assert.Equal(t, true, spec.shouldUseValgrind)
- assert.Equal(t, false, spec.shouldUseCallgrind)
-
- t.Setenv("VESPA_VALGRIND_OPT", "--tool=callgrind")
- spec.configureValgrind()
- assert.Equal(t, true, spec.shouldUseValgrind)
- assert.Equal(t, true, spec.shouldUseCallgrind)
-
- argv = spec.prependValgrind([]string{"/bin/myprog", "-c", "cfgid"})
- trace.Trace("argv:", argv)
- assert.Equal(t, 6, len(argv))
- assert.Equal(t, "valgrind", argv[0])
- assert.Equal(t, "--tool=callgrind", argv[1])
- assert.Equal(t, "/bin/myprog", argv[3])
-
- useMock("no-valgrind", "which")
- spec.configureValgrind()
- assert.Equal(t, false, spec.shouldUseValgrind)
- assert.Equal(t, false, spec.shouldUseCallgrind)
-}
diff --git a/client/go/internal/admin/vespa-wrapper/startcbinary/vespamalloc.go b/client/go/internal/admin/vespa-wrapper/startcbinary/vespamalloc.go
deleted file mode 100644
index c6d53e1d03c..00000000000
--- a/client/go/internal/admin/vespa-wrapper/startcbinary/vespamalloc.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-// Author: arnej
-
-package startcbinary
-
-import (
- "fmt"
-
- "github.com/vespa-engine/vespa/client/go/internal/admin/envvars"
- "github.com/vespa-engine/vespa/client/go/internal/admin/trace"
- "github.com/vespa-engine/vespa/client/go/internal/vespa"
-)
-
-func vespaMallocLib(suf string) string {
- prefixes := []string{"lib64", "lib"}
- for _, pre := range prefixes {
- fn := fmt.Sprintf("%s/vespa/malloc/%s", pre, suf)
- existsOk, fileName := vespa.HasFileUnderVespaHome(fn)
- if existsOk {
- trace.Debug("found library:", fileName)
- return fileName
- }
- trace.Debug("bad or missing library:", fn)
- }
- return ""
-}
-
-func (p *ProgSpec) configureVespaMalloc() {
- p.shouldUseVespaMalloc = false
- if p.matchesListEnv(envvars.VESPA_USE_NO_VESPAMALLOC) {
- trace.Trace("use no vespamalloc:", p.BaseName)
- return
- }
- if p.shouldUseValgrind && !p.shouldUseCallgrind {
- trace.Trace("use valgrind, so no vespamalloc:", p.BaseName)
- return
- }
- var useFile string
- if p.matchesListEnv(envvars.VESPA_USE_VESPAMALLOC_DST) {
- useFile = vespaMallocLib("libvespamallocdst16.so")
- } else if p.matchesListEnv(envvars.VESPA_USE_VESPAMALLOC_D) {
- useFile = vespaMallocLib("libvespamallocd.so")
- } else if p.matchesListEnv(envvars.VESPA_USE_VESPAMALLOC) {
- useFile = vespaMallocLib("libvespamalloc.so")
- }
- trace.Trace("use file:", useFile)
- if useFile == "" {
- return
- }
- if loadAsHuge := p.getenv(envvars.VESPA_LOAD_CODE_AS_HUGEPAGES); loadAsHuge != "" {
- otherFile := vespaMallocLib("libvespa_load_as_huge.so")
- useFile = fmt.Sprintf("%s:%s", useFile, otherFile)
- }
- p.considerEnvFallback(envvars.VESPA_MALLOC_HUGEPAGES, envvars.VESPA_USE_HUGEPAGES)
- p.vespaMallocPreload = useFile
- p.shouldUseVespaMalloc = true
-}