Skip to content

Commit

Permalink
Merge pull request #755 from elezar/fix-libcuda-so
Browse files Browse the repository at this point in the history
Fix bug where libcuda.so is not found in ldcache
  • Loading branch information
elezar authored Oct 24, 2024
2 parents 771ac6b + fa5a4ac commit 8860878
Show file tree
Hide file tree
Showing 23 changed files with 307 additions and 363 deletions.
102 changes: 0 additions & 102 deletions cmd/nvidia-ctk/system/print-ldcache/print-ldcache.go

This file was deleted.

2 changes: 0 additions & 2 deletions cmd/nvidia-ctk/system/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (

devchar "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk/system/create-dev-char-symlinks"
devicenodes "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk/system/create-device-nodes"
ldcache "github.com/NVIDIA/nvidia-container-toolkit/cmd/nvidia-ctk/system/print-ldcache"
"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
)

Expand All @@ -47,7 +46,6 @@ func (m command) build() *cli.Command {
system.Subcommands = []*cli.Command{
devchar.NewCommand(m.logger),
devicenodes.NewCommand(m.logger),
ldcache.NewCommand(m.logger),
}

return &system
Expand Down
79 changes: 5 additions & 74 deletions internal/ldcache/ldcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,12 @@ import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"syscall"
"unsafe"

"github.com/NVIDIA/nvidia-container-toolkit/internal/logger"
"github.com/NVIDIA/nvidia-container-toolkit/internal/lookup/symlinks"
)

const ldcachePath = "/etc/ld.so.cache"
Expand Down Expand Up @@ -82,10 +79,9 @@ type entry2 struct {

// LDCache represents the interface for performing lookups into the LDCache
//
//go:generate moq -out ldcache_mock.go . LDCache
//go:generate moq -rm -out ldcache_mock.go . LDCache
type LDCache interface {
List() ([]string, []string)
Lookup(...string) ([]string, []string)
}

type ldcache struct {
Expand All @@ -105,14 +101,7 @@ func New(logger logger.Interface, root string) (LDCache, error) {

logger.Debugf("Opening ld.conf at %v", path)
f, err := os.Open(path)
if os.IsNotExist(err) {
logger.Warningf("Could not find ld.so.cache at %v; creating empty cache", path)
e := &empty{
logger: logger,
path: path,
}
return e, nil
} else if err != nil {
if err != nil {
return nil, err
}
defer f.Close()
Expand Down Expand Up @@ -196,7 +185,7 @@ type entry struct {
}

// getEntries returns the entires of the ldcache in a go-friendly struct.
func (c *ldcache) getEntries(selected func(string) bool) []entry {
func (c *ldcache) getEntries() []entry {
var entries []entry
for _, e := range c.entries {
bits := 0
Expand All @@ -223,9 +212,6 @@ func (c *ldcache) getEntries(selected func(string) bool) []entry {
c.logger.Debugf("Skipping invalid lib")
continue
}
if !selected(lib) {
continue
}
value := bytesToString(c.libs[e.Value:])
if value == "" {
c.logger.Debugf("Skipping invalid value for lib %v", lib)
Expand All @@ -236,51 +222,19 @@ func (c *ldcache) getEntries(selected func(string) bool) []entry {
bits: bits,
value: value,
}

entries = append(entries, e)
}

return entries
}

// List creates a list of libraries in the ldcache.
// The 32-bit and 64-bit libraries are returned separately.
func (c *ldcache) List() ([]string, []string) {
all := func(s string) bool { return true }

return c.resolveSelected(all)
}

// Lookup searches the ldcache for the specified prefixes.
// The 32-bit and 64-bit libraries matching the prefixes are returned.
func (c *ldcache) Lookup(libPrefixes ...string) ([]string, []string) {
c.logger.Debugf("Looking up %v in cache", libPrefixes)

// We define a functor to check whether a given library name matches any of the prefixes
matchesAnyPrefix := func(s string) bool {
for _, p := range libPrefixes {
if strings.HasPrefix(s, p) {
return true
}
}
return false
}

return c.resolveSelected(matchesAnyPrefix)
}

// resolveSelected process the entries in the LDCach based on the supplied filter and returns the resolved paths.
// The paths are separated by bittage.
func (c *ldcache) resolveSelected(selected func(string) bool) ([]string, []string) {
paths := make(map[int][]string)
processed := make(map[string]bool)

for _, e := range c.getEntries(selected) {
path, err := c.resolve(e.value)
if err != nil {
c.logger.Debugf("Could not resolve entry: %v", err)
continue
}
for _, e := range c.getEntries() {
path := filepath.Join(c.root, e.value)
if processed[path] {
continue
}
Expand All @@ -291,29 +245,6 @@ func (c *ldcache) resolveSelected(selected func(string) bool) ([]string, []strin
return paths[32], paths[64]
}

// resolve resolves the specified ldcache entry based on the value being processed.
// The input is the name of the entry in the cache.
func (c *ldcache) resolve(target string) (string, error) {
name := filepath.Join(c.root, target)

c.logger.Debugf("checking %v", name)

link, err := symlinks.Resolve(name)
if err != nil {
return "", fmt.Errorf("failed to resolve symlink: %v", err)
}
if link == name {
return name, nil
}

// We return absolute paths for all targets
if !filepath.IsAbs(link) || strings.HasPrefix(link, ".") {
link = filepath.Join(filepath.Dir(target), link)
}

return c.resolve(link)
}

// bytesToString converts a byte slice to a string.
// This assumes that the byte slice is null-terminated
func bytesToString(value []byte) string {
Expand Down
46 changes: 1 addition & 45 deletions internal/ldcache/ldcache_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8860878

Please sign in to comment.