From 04c1849878b16c260bdddb8d80b5b48871b93f68 Mon Sep 17 00:00:00 2001 From: Daniel Hiltgen Date: Mon, 6 Oct 2025 14:36:44 -0700 Subject: [PATCH] discovery: prevent dup OLLAMA_LIBRARY_PATH (#12514) This variable isn't currently documented or intended as something the user can override, but if the user happens to set OLLAMA_LIBRARY_PATH we were doubling this in the subprocess environment which will cause problems with the new bootstrap discovery logic. --- discover/runner.go | 8 +++++++- llm/server.go | 9 +++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/discover/runner.go b/discover/runner.go index f69680715..6aabbb874 100644 --- a/discover/runner.go +++ b/discover/runner.go @@ -442,15 +442,18 @@ func bootstrapDevices(ctx context.Context, ollamaLibDirs []string, extraEnvs []s cmd.Stderr = os.Stderr } // cmd.SysProcAttr = llm.LlamaServerSysProcAttr // circular dependency - bring back once refactored - cmd.Env = append(cmd.Env, "OLLAMA_LIBRARY_PATH="+strings.Join(ollamaLibDirs, string(filepath.ListSeparator))) pathEnvVal := strings.Join(libraryPaths, string(filepath.ListSeparator)) pathNeeded := true + ollamaPathNeeded := true extraDone := make([]bool, len(extraEnvs)) for i := range cmd.Env { cmp := strings.SplitN(cmd.Env[i], "=", 2) if strings.EqualFold(cmp[0], pathEnv) { cmd.Env[i] = pathEnv + "=" + pathEnvVal pathNeeded = false + } else if strings.EqualFold(cmp[0], "OLLAMA_LIBRARY_PATH") { + cmd.Env[i] = "OLLAMA_LIBRARY_PATH=" + strings.Join(ollamaLibDirs, string(filepath.ListSeparator)) + ollamaPathNeeded = false } else { for j := range extraEnvs { if extraDone[j] { @@ -467,6 +470,9 @@ func bootstrapDevices(ctx context.Context, ollamaLibDirs []string, extraEnvs []s if pathNeeded { cmd.Env = append(cmd.Env, pathEnv+"="+pathEnvVal) } + if ollamaPathNeeded { + cmd.Env = append(cmd.Env, "OLLAMA_LIBRARY_PATH="+strings.Join(ollamaLibDirs, string(filepath.ListSeparator))) + } for i := range extraDone { if !extraDone[i] { cmd.Env = append(cmd.Env, extraEnvs[i]) diff --git a/llm/server.go b/llm/server.go index a7e8049b7..e7c1029e8 100644 --- a/llm/server.go +++ b/llm/server.go @@ -359,20 +359,22 @@ func NewLlamaServer(gpus discover.GpuInfoList, modelPath string, f *ggml.GGML, a s.cmd.Stderr = s.status s.cmd.SysProcAttr = LlamaServerSysProcAttr - s.cmd.Env = append(s.cmd.Env, "OLLAMA_LIBRARY_PATH="+strings.Join(ggmlPaths, string(filepath.ListSeparator))) - // Always filter down the set of GPUs in case there are any unsupported devices that might crash envWorkarounds := gpus.GetVisibleDevicesEnv() pathEnvVal := strings.Join(libraryPaths, string(filepath.ListSeparator)) // Update or add the path variable with our adjusted version pathNeeded := true + ollamaPathNeeded := true envWorkaroundDone := make([]bool, len(envWorkarounds)) for i := range s.cmd.Env { cmp := strings.SplitN(s.cmd.Env[i], "=", 2) if strings.EqualFold(cmp[0], pathEnv) { s.cmd.Env[i] = pathEnv + "=" + pathEnvVal pathNeeded = false + } else if strings.EqualFold(cmp[0], "OLLAMA_LIBRARY_PATH") { + s.cmd.Env[i] = "OLLAMA_LIBRARY_PATH=" + strings.Join(ggmlPaths, string(filepath.ListSeparator)) + ollamaPathNeeded = false } else if len(envWorkarounds) != 0 { for j, kv := range envWorkarounds { tmp := strings.SplitN(kv, "=", 2) @@ -386,6 +388,9 @@ func NewLlamaServer(gpus discover.GpuInfoList, modelPath string, f *ggml.GGML, a if pathNeeded { s.cmd.Env = append(s.cmd.Env, pathEnv+"="+pathEnvVal) } + if ollamaPathNeeded { + s.cmd.Env = append(s.cmd.Env, "OLLAMA_LIBRARY_PATH="+strings.Join(ggmlPaths, string(filepath.ListSeparator))) + } for i, done := range envWorkaroundDone { if !done { s.cmd.Env = append(s.cmd.Env, envWorkarounds[i])