nvsandboxutils: Add script to generate bindings

This change adds a script and related files to generate the internal
bindings for Sandboxutils library with the help of c-for-go.
This can be used to update the bindings when the header file is modified
with reference to how they are generated with the Makefile in go-nvml.

Run: ./update-bindings.sh

Signed-off-by: Evan Lezar <elezar@nvidia.com>
Signed-off-by: Huy Nguyen <huyn@nvidia.com>
Signed-off-by: Sananya Majumder <sananyam@nvidia.com>
This commit is contained in:
Sananya Majumder 2024-09-24 10:04:48 -07:00
parent a5a5833c14
commit aa946f3f59
6 changed files with 944 additions and 0 deletions

View File

@ -0,0 +1,50 @@
#!/bin/bash
# Copyright 2024 NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This file generates bindings for nvsandboxutils by calling c-for-go.
set -x -e
PWD=$(pwd)
GEN_DIR="$PWD/gen"
PKG_DIR="$PWD"
GEN_BINDINGS_DIR="$GEN_DIR/nvsandboxutils"
PKG_BINDINGS_DIR="$PKG_DIR"
SOURCES=$(find "$GEN_BINDINGS_DIR" -type f)
mkdir -p "$PKG_BINDINGS_DIR"
cp "$GEN_BINDINGS_DIR/nvsandboxutils.h" "$PKG_BINDINGS_DIR/nvsandboxutils.h"
spatch --in-place --very-quiet --sp-file "$GEN_BINDINGS_DIR/anonymous_structs.cocci" "$PKG_BINDINGS_DIR/nvsandboxutils.h" > /dev/null
echo "Generating the bindings..."
c-for-go -out "$PKG_DIR/.." "$GEN_BINDINGS_DIR/nvsandboxutils.yml"
cd "$PKG_BINDINGS_DIR"
go tool cgo -godefs types.go > types_gen.go
go fmt types_gen.go
cd - > /dev/null
rm -rf "$PKG_BINDINGS_DIR/cgo_helpers.go" "$PKG_BINDINGS_DIR/types.go" "$PKG_BINDINGS_DIR/_obj"
go run "$GEN_BINDINGS_DIR/generateapi.go" --sourceDir "$PKG_BINDINGS_DIR" --output "$PKG_BINDINGS_DIR/zz_generated.api.go"
# go fmt "$PKG_BINDINGS_DIR"
SED_SEARCH_STRING='// WARNING: This file has automatically been generated on'
SED_REPLACE_STRING='// WARNING: THIS FILE WAS AUTOMATICALLY GENERATED.'
grep -l -R "$SED_SEARCH_STRING" "$PKG_DIR" | grep -v "/gen/" | xargs sed -i -E "s#$SED_SEARCH_STRING.*\$#$SED_REPLACE_STRING#g"
SED_SEARCH_STRING='// (.*) nvsandboxutils/nvsandboxutils.h:[0-9]+'
SED_REPLACE_STRING='// \1 nvsandboxutils/nvsandboxutils.h'
grep -l -RE "$SED_SEARCH_STRING" "$PKG_DIR" | grep -v "/gen/" | xargs sed -i -E "s#$SED_SEARCH_STRING\$#$SED_REPLACE_STRING#g"

View File

@ -0,0 +1,100 @@
@patch@
type WRAPPER_TYPE;
field list FIELDS;
identifier V;
expression E;
fresh identifier ST = "nvSandboxUtilsGenerated_struct___";
fresh identifier TEMP_VAR = "nvSandboxUtilsGenerated_variable___" ## V;
@@
++ struct ST {
++ WRAPPER_TYPE TEMP_VAR;
++ FIELDS
++ };
+
WRAPPER_TYPE
{
...
(
- struct {
- FIELDS
- } V[E];
+ struct ST V[E];
|
- struct {
- FIELDS
- } V;
+ struct ST V;
)
...
};
@capture@
type WRAPPER_TYPE;
identifier TEMP_VAR;
identifier ST =~ "^nvSandboxUtilsGenerated_struct___";
@@
struct ST {
WRAPPER_TYPE TEMP_VAR;
...
};
@script:python concat@
WRAPPER_TYPE << capture.WRAPPER_TYPE;
TEMP_VAR << capture.TEMP_VAR;
ST << capture.ST;
T;
@@
def removePrefix(string, prefix):
if string.startswith(prefix):
return string[len(prefix):]
return string
def removeSuffix(string, suffix):
if string.endswith(suffix):
return string[:-len(suffix)]
return string
WRAPPER_TYPE = removeSuffix(WRAPPER_TYPE, "_t")
TEMP_VAR = removePrefix(TEMP_VAR, "nvSandboxUtilsGenerated_variable___")
coccinelle.T = cocci.make_type(WRAPPER_TYPE + TEMP_VAR[0].upper() + TEMP_VAR[1:] + "_t")
@add_typedef@
identifier capture.ST;
type concat.T;
type WRAPPER_TYPE;
identifier TEMP_VAR;
@@
- struct ST {
+ typedef struct {
- WRAPPER_TYPE TEMP_VAR;
...
- };
+ } T;
@update@
identifier capture.ST;
type concat.T;
identifier V;
expression E;
type WRAPPER_TYPE;
@@
WRAPPER_TYPE
{
...
(
- struct ST V[E];
+ T V[E];
|
- struct ST V;
+ T V;
)
...
};

View File

@ -0,0 +1,389 @@
/**
# Copyright 2024 NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
**/
package main
import (
"flag"
"fmt"
"go/ast"
"go/parser"
"go/token"
"io"
"io/fs"
"os"
"path/filepath"
"slices"
"sort"
"strings"
"unicode"
)
type GeneratableInterfacePoperties struct {
Type string
Interface string
Exclude []string
PackageMethodsAliasedFrom string
}
var GeneratableInterfaces = []GeneratableInterfacePoperties{
{
Type: "library",
Interface: "Interface",
PackageMethodsAliasedFrom: "libnvsandboxutils",
},
}
func main() {
sourceDir := flag.String("sourceDir", "", "Path to the source directory for all go files")
output := flag.String("output", "", "Path to the output file (default: stdout)")
flag.Parse()
// Check if required flags are provided
if *sourceDir == "" {
flag.Usage()
return
}
writer, closer, err := getWriter(*output)
if err != nil {
fmt.Printf("Error: %v", err)
return
}
defer func() {
_ = closer()
}()
header, err := generateHeader()
if err != nil {
fmt.Printf("Error: %v", err)
return
}
fmt.Fprint(writer, header)
for i, p := range GeneratableInterfaces {
if p.PackageMethodsAliasedFrom != "" {
comment, err := generatePackageMethodsComment(p)
if err != nil {
fmt.Printf("Error: %v", err)
return
}
fmt.Fprint(writer, comment)
output, err := generatePackageMethods(*sourceDir, p)
if err != nil {
fmt.Printf("Error: %v", err)
return
}
fmt.Fprintf(writer, "%s\n", output)
}
comment, err := generateInterfaceComment(p)
if err != nil {
fmt.Printf("Error: %v", err)
return
}
fmt.Fprint(writer, comment)
output, err := generateInterface(*sourceDir, p)
if err != nil {
fmt.Printf("Error: %v", err)
return
}
fmt.Fprint(writer, output)
if i < (len(GeneratableInterfaces) - 1) {
fmt.Fprint(writer, "\n")
}
}
}
func getWriter(outputFile string) (io.Writer, func() error, error) {
if outputFile == "" {
return os.Stdout, func() error { return nil }, nil
}
file, err := os.Create(outputFile)
if err != nil {
return nil, nil, err
}
return file, file.Close, nil
}
func generateHeader() (string, error) {
lines := []string{
"/**",
"# Copyright 2024 NVIDIA CORPORATION",
"#",
"# Licensed under the Apache License, Version 2.0 (the \"License\");",
"# you may not use this file except in compliance with the License.",
"# You may obtain a copy of the License at",
"#",
"# http://www.apache.org/licenses/LICENSE-2.0",
"#",
"# Unless required by applicable law or agreed to in writing, software",
"# distributed under the License is distributed on an \"AS IS\" BASIS,",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.",
"# See the License for the specific language governing permissions and",
"# limitations under the License.",
"**/",
"",
"// Generated Code; DO NOT EDIT.",
"",
"package nvsandboxutils",
"",
"",
}
return strings.Join(lines, "\n"), nil
}
func generatePackageMethodsComment(input GeneratableInterfacePoperties) (string, error) {
commentFmt := []string{
"// The variables below represent package level methods from the %s type.",
}
var signature strings.Builder
comment := strings.Join(commentFmt, "\n")
comment = fmt.Sprintf(comment, input.Type)
signature.WriteString(fmt.Sprintf("%s\n", comment))
return signature.String(), nil
}
func generateInterfaceComment(input GeneratableInterfacePoperties) (string, error) {
commentFmt := []string{
"// %s represents the interface for the %s type.",
"//",
"//go:generate moq -out mock/%s.go -pkg mock . %s:%s",
}
var signature strings.Builder
comment := strings.Join(commentFmt, "\n")
comment = fmt.Sprintf(comment, input.Interface, input.Type, strings.ToLower(input.Interface), input.Interface, input.Interface)
signature.WriteString(fmt.Sprintf("%s\n", comment))
return signature.String(), nil
}
func generatePackageMethods(sourceDir string, input GeneratableInterfacePoperties) (string, error) {
var signature strings.Builder
signature.WriteString("var (\n")
methods, err := extractMethodsFromPackage(sourceDir, input)
if err != nil {
return "", err
}
for _, method := range methods {
name := method.Name.Name
formatted := fmt.Sprintf("\t%s = %s.%s\n", name, input.PackageMethodsAliasedFrom, name)
signature.WriteString(formatted)
}
signature.WriteString(")\n")
return signature.String(), nil
}
func generateInterface(sourceDir string, input GeneratableInterfacePoperties) (string, error) {
var signature strings.Builder
signature.WriteString(fmt.Sprintf("type %s interface {\n", input.Interface))
methods, err := extractMethodsFromPackage(sourceDir, input)
if err != nil {
return "", err
}
for _, method := range methods {
formatted := fmt.Sprintf("\t%s\n", formatMethodSignature(method))
signature.WriteString(formatted)
}
signature.WriteString("}\n")
return signature.String(), nil
}
func getGoFiles(sourceDir string) (map[string][]byte, error) {
gofiles := make(map[string][]byte)
err := filepath.WalkDir(sourceDir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() || filepath.Ext(path) != ".go" {
return nil
}
content, err := os.ReadFile(path)
if err != nil {
return err
}
gofiles[path] = content
return nil
})
if err != nil {
return nil, fmt.Errorf("walking %s: %w", sourceDir, err)
}
return gofiles, nil
}
func extractMethodsFromPackage(sourceDir string, input GeneratableInterfacePoperties) ([]*ast.FuncDecl, error) {
gofiles, err := getGoFiles(sourceDir)
if err != nil {
return nil, err
}
var methods []*ast.FuncDecl
for file, content := range gofiles {
m, err := extractMethods(file, content, input)
if err != nil {
return nil, err
}
methods = append(methods, m...)
}
sort.Slice(methods, func(i, j int) bool {
return methods[i].Name.Name < methods[j].Name.Name
})
return methods, nil
}
func extractMethods(sourceFile string, sourceContent []byte, input GeneratableInterfacePoperties) ([]*ast.FuncDecl, error) {
// Parse source file
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, sourceFile, sourceContent, parser.ParseComments)
if err != nil {
return nil, err
}
// Traverse AST to find type declarations and associated methods
var methods []*ast.FuncDecl
for _, decl := range node.Decls {
funcDecl, ok := decl.(*ast.FuncDecl)
if !ok {
continue
}
// Check if the function is a method associated with the specified type
if receiverType := funcDecl.Recv; receiverType != nil {
var ident *ast.Ident
for _, field := range receiverType.List {
switch fieldType := field.Type.(type) {
case *ast.Ident:
ident = fieldType
case *ast.StarExpr:
// Update ident if it's a *ast.StarExpr
if newIdent, ok := fieldType.X.(*ast.Ident); ok {
// If the inner type is an *ast.Ident, update ident
ident = newIdent
}
}
// No identifier found
if ident == nil {
continue
}
// Identifier is not the one we are looking for
if ident.Name != input.Type {
continue
}
// Ignore non-public methods
if !isPublic(funcDecl.Name.Name) {
continue
}
// Ignore method in the exclude list
if slices.Contains(input.Exclude, funcDecl.Name.Name) {
continue
}
methods = append(methods, funcDecl)
}
}
}
return methods, nil
}
func formatMethodSignature(decl *ast.FuncDecl) string {
var signature strings.Builder
// Write method name
signature.WriteString(decl.Name.Name)
signature.WriteString("(")
// Write parameters
if decl.Type.Params != nil {
for i, param := range decl.Type.Params.List {
if i > 0 {
signature.WriteString(", ")
}
signature.WriteString(formatFieldList(param))
}
}
signature.WriteString(")")
// Write return types
if decl.Type.Results != nil {
signature.WriteString(" ")
if len(decl.Type.Results.List) > 1 {
signature.WriteString("(")
}
for i, result := range decl.Type.Results.List {
if i > 0 {
signature.WriteString(", ")
}
signature.WriteString(formatFieldList(result))
}
if len(decl.Type.Results.List) > 1 {
signature.WriteString(")")
}
}
return signature.String()
}
func formatFieldList(field *ast.Field) string {
var builder strings.Builder
switch fieldType := field.Type.(type) {
case *ast.Ident:
builder.WriteString(fieldType.Name)
case *ast.ArrayType:
builder.WriteString("[]")
builder.WriteString(formatFieldList(&ast.Field{Type: fieldType.Elt}))
case *ast.StarExpr:
builder.WriteString("*")
builder.WriteString(formatFieldList(&ast.Field{Type: fieldType.X}))
}
return builder.String()
}
func isPublic(name string) bool {
if len(name) == 0 {
return false
}
return unicode.IsUpper([]rune(name)[0])
}

View File

@ -0,0 +1,298 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NVSANDBOXUTILS_H__
#define __NVSANDBOXUTILS_H__
#ifdef __cplusplus
extern "C" {
#endif
#define INPUT_LENGTH 256
#define MAX_FILE_PATH 256
#define MAX_NAME_LENGTH 256
/***************************************************************************************************/
/** @defgroup enums Enumerations
* @{
*/
/***************************************************************************************************/
/**
* Return types
*/
typedef enum
{
NVSANDBOXUTILS_SUCCESS = 0, //!< The operation was successful
NVSANDBOXUTILS_ERROR_UNINITIALIZED = 1, //!< The library wasn't successfully initialized
NVSANDBOXUTILS_ERROR_NOT_SUPPORTED = 2, //!< The requested operation is not supported on target device
NVSANDBOXUTILS_ERROR_INVALID_ARG = 3, //!< A supplied argument is invalid
NVSANDBOXUTILS_ERROR_INSUFFICIENT_SIZE = 4, //!< A supplied argument is not large enough
NVSANDBOXUTILS_ERROR_VERSION_NOT_SUPPORTED = 5, //!< Requested library version is not supported
NVSANDBOXUTILS_ERROR_LIBRARY_LOAD = 6, //!< The library load failed
NVSANDBOXUTILS_ERROR_FUNCTION_NOT_FOUND = 7, //!< Called function was not found
NVSANDBOXUTILS_ERROR_DEVICE_NOT_FOUND = 8, //!< Target device was not found
NVSANDBOXUTILS_ERROR_NVML_LIB_CALL = 9, //!< NVML library call failed
NVSANDBOXUTILS_ERROR_OUT_OF_MEMORY = 10, //!< There is insufficient memory
NVSANDBOXUTILS_ERROR_FILEPATH_NOT_FOUND = 11, //!< A supplied file path was not found
NVSANDBOXUTILS_ERROR_UNKNOWN = 0xFFFF, //!< Unknown error occurred
} nvSandboxUtilsRet_t;
/**
* Return if there is an error
*/
#define RETURN_ON_SANDBOX_ERROR(result) \
if ((result) != NVSANDBOXUTILS_SUCCESS) { \
NVSANDBOXUTILS_ERROR_MSG("%s %d result=%d", __func__, __LINE__, result); \
return result; \
}
/**
* Log levels
*/
typedef enum
{
NVSANDBOXUTILS_LOG_LEVEL_FATAL = 0, //!< Log fatal errors
NVSANDBOXUTILS_LOG_LEVEL_ERROR = 1, //!< Log all errors
NVSANDBOXUTILS_LOG_LEVEL_WARN = 2, //!< Log all warnings
NVSANDBOXUTILS_LOG_LEVEL_DEBUG = 3, //!< Log all debug messages
NVSANDBOXUTILS_LOG_LEVEL_INFO = 4, //!< Log all info messages
NVSANDBOXUTILS_LOG_LEVEL_NONE = 0xFFFF, //!< Log none
} nvSandboxUtilsLogLevel_t;
/**
* Input rootfs to help access files inside the driver container
*/
typedef enum
{
NV_ROOTFS_DEFAULT, //!< Default no rootfs
NV_ROOTFS_PATH, //!< /run/nvidia/driver
NV_ROOTFS_PID, //!< /proc/PID/mountinfo
} nvSandboxUtilsRootfsInputType_t;
/**
* File type
*/
typedef enum
{
NV_DEV, //!< /dev file system
NV_PROC, //!< /proc file system
NV_SYS, //!< /sys file system
} nvSandboxUtilsFileType_t;
/**
* File subtype
*/
typedef enum
{
NV_DEV_NVIDIA, //!< /dev/nvidia0
NV_DEV_DRI_CARD, //!< /dev/dri/card1
NV_DEV_DRI_RENDERD, //!< /dev/dri/renderD128
NV_DEV_DRI_CARD_SYMLINK, //!< /dev/dri/by-path/pci-0000:41:00.0-card
NV_DEV_DRI_RENDERD_SYMLINK, //!< /dev/dri/by-path/pci-0000:41:00.0-render
NV_DEV_NVIDIA_UVM, //!< /dev/nvidia-uvm
NV_DEV_NVIDIA_UVM_TOOLS, //!< /dev/nvidia-uvm-tools
NV_DEV_NVIDIA_MODESET, //!< /dev/nvidia-uvm-modeset
NV_DEV_NVIDIA_CTL, //!< /dev/nvidiactl
NV_DEV_GDRDRV, //!< /dev/gdrdrv
NV_DEV_NVIDIA_CAPS_NVIDIA_CAP, //!< /dev/nvidia-caps/nvidia-cap22
NV_PROC_DRIVER_NVIDIA_GPUS_PCIBUSID, //!< /proc/driver/nvidia/gpus/0000:2d:00.0
NV_PROC_DRIVER_NVIDIA_GPUS, //!< /proc/driver/nvidia/gpus (for mask out)
NV_PROC_NVIDIA_PARAMS, //!< /proc/driver/nvidia/params
NV_PROC_NVIDIA_CAPS_MIG_MINORS, //!< /proc/driver/nvidia-caps/mig-minors
NV_PROC_DRIVER_NVIDIA_CAPABILITIES_GPU, //!< /proc/driver/nvidia/capabilities/gpu0
NV_PROC_DRIVER_NVIDIA_CAPABILITIES, //!< /proc/driver/nvidia/capabilities (for mask out)
NV_PROC_DRIVER_NVIDIA_CAPABILITIIES_GPU_MIG_CI_ACCESS, //!< proc/driver/nvidia/capabilities/gpu0/mig/gi2/ci0/access
NV_SYS_MODULE_NVIDIA_DRIVER_PCIBUSID, //!< /sys/module/nvidia/drivers/pci:nvidia/0000:2d:00.0
NV_SYS_MODULE_NVIDIA_DRIVER, //!< /sys/module/nvidia/drivers/pci:nvidia (for mask out)
NV_NUM_SUBTYPE, // always at the end.
} nvSandboxUtilsFileSystemSubType_t;
/**
* File module
*/
typedef enum
{
NV_GPU, //!< Target device
NV_MIG, //!< Target device- MIG
NV_DRIVER_NVIDIA, //!< NVIDIA kernel driver
NV_DRIVER_NVIDIA_UVM, //!< NVIDIA kernel driver-UVM
NV_DRIVER_NVIDIA_MODESET, //!< NVIDIA kernel driver-modeset
NV_DRIVER_GDRDRV, //!< GDRDRV driver
NV_SYSTEM, //!< System module
} nvSandboxUtilsFileModule_t;
/**
* Flag to provide additional details about the file
*/
typedef enum
{
NV_FILE_FLAG_HINT = (1 << 0), //!< Default no hint
NV_FILE_FLAG_MASKOUT = (1 << 1), //!< For /proc/driver/nvidia/gpus
NV_FILE_FLAG_CONTENT = (1 << 2), //!< For /proc/driver/nvidia/params
//!< For SYMLINK
//!< Use \p nvSandboxUtilsGetFileContent to get name of the linked file
NV_FILE_FLAG_DEPRECTATED = (1 << 3), //!< For all the FIRMWARE GSP file
NV_FILE_FLAG_CANDIDATES = (1 << 4), //!< For libcuda.so
} nvSandboxUtilsFileFlag_t;
/**
* Input type of the target device
*/
typedef enum
{
NV_GPU_INPUT_GPU_UUID, //!< GPU UUID
NV_GPU_INPUT_MIG_UUID, //!< MIG UUID
NV_GPU_INPUT_PCI_ID, //!< PCIe DBDF ID
NV_GPU_INPUT_PCI_INDEX, //!< PCIe bus order (0 points to the GPU that has lowest PCIe BDF)
} nvSandboxUtilsGpuInputType_t;
/** @} */
/***************************************************************************************************/
/** @defgroup dataTypes Structures and Unions
* @{
*/
/***************************************************************************************************/
/**
* Initalization input v1
*/
typedef struct
{
unsigned int version; //!< Version for the structure
nvSandboxUtilsRootfsInputType_t type; //!< One of \p nvSandboxUtilsRootfsInputType_t
char value[INPUT_LENGTH]; //!< String representation of input
} nvSandboxUtilsInitInput_v1_t;
typedef nvSandboxUtilsInitInput_v1_t nvSandboxUtilsInitInput_t;
/**
* File system information
*/
typedef struct nvSandboxUtilsGpuFileInfo_v1_t
{
struct nvSandboxUtilsGpuFileInfo_v1_t *next; //!< Pointer to the next node in the linked list
nvSandboxUtilsFileType_t fileType; //!< One of \p nvSandboxUtilsFileType_t
nvSandboxUtilsFileSystemSubType_t fileSubType; //!< One of \p nvSandboxUtilsFileSystemSubType_t
nvSandboxUtilsFileModule_t module; //!< One of \p nvSandboxUtilsFileModule_t
nvSandboxUtilsFileFlag_t flags; //!< One of \p nvSandboxUtilsFileFlag_t
char *filePath; //!< Relative file path to rootfs
}nvSandboxUtilsGpuFileInfo_v1_t;
/**
* GPU resource request v1
*/
typedef struct
{
unsigned int version; //!< Version for the structure
nvSandboxUtilsGpuInputType_t inputType; //!< One of \p nvSandboxUtilsGpuInputType_t
char input[INPUT_LENGTH]; //!< String representation of input
nvSandboxUtilsGpuFileInfo_v1_t *files; //!< Linked list of \ref nvSandboxUtilsGpuFileInfo_v1_t
} nvSandboxUtilsGpuRes_v1_t;
typedef nvSandboxUtilsGpuRes_v1_t nvSandboxUtilsGpuRes_t;
/** @} */
/***************************************************************************************************/
/** @defgroup funcs Functions
* @{
*/
/***************************************************************************************************/
/* *************************************************
* Initialize library
* *************************************************
*/
/**
* Prepare library resources before library API can be used.
* This initialization will not fail if one of the initialization prerequisites fails.
* @param input Reference to the called-supplied input struct that has initialization fields
*
* @returns @ref NVSANDBOXUTILS_SUCCESS on success
* @returns @ref NVSANDBOXUTILS_ERROR_INVALID_ARG if \p input->value isn't a valid rootfs path
* @returns @ref NVSANDBOXUTILS_ERROR_VERSION_NOT_SUPPORTED if \p input->version isn't supported by the library
* @returns @ref NVSANDBOXUTILS_ERROR_FILEPATH_NOT_FOUND if any of the required file paths are not found during initialization
* @returns @ref NVSANDBOXUTILS_ERROR_OUT_OF_MEMORY if there is insufficient system memory during initialization
* @returns @ref NVSANDBOXUTILS_ERROR_LIBRARY_LOAD on any error during loading the library
*/
nvSandboxUtilsRet_t nvSandboxUtilsInit(nvSandboxUtilsInitInput_t *input);
/* *************************************************
* Shutdown library
* *************************************************
*/
/**
* Clean up library resources created by init call
*
* @returns @ref NVSANDBOXUTILS_SUCCESS on success
*/
nvSandboxUtilsRet_t nvSandboxUtilsShutdown(void);
/* *************************************************
* Get NVIDIA RM driver version
* *************************************************
*/
/**
* Get NVIDIA RM driver version
* @param version Reference to caller-supplied buffer to return driver version string
* @param length The maximum allowed length of the string returned in \p version
*
* @returns @ref NVSANDBOXUTILS_SUCCESS on success
* @returns @ref NVSANDBOXUTILS_ERROR_INVALID_ARG if \p version is NULL
* @returns @ref NVSANDBOXUTILS_ERROR_NVML_LIB_CALL on any error during driver version query from NVML
*/
nvSandboxUtilsRet_t nvSandboxUtilsGetDriverVersion(char *version, unsigned int length);
/* *************************************************
* Get /dev, /proc, /sys file system information
* *************************************************
*/
/**
* Get /dev, /proc, /sys file system information
* @param request Reference to caller-supplied request struct to return the file system information
*
* @returns @ref NVSANDBOXUTILS_SUCCESS on success
* @returns @ref NVSANDBOXUTILS_ERROR_INVALID_ARG if \p request->input doesn't match any device
* @returns @ref NVSANDBOXUTILS_ERROR_VERSION_NOT_SUPPORTED if \p request->version isn't supported by the library
*/
nvSandboxUtilsRet_t nvSandboxUtilsGetGpuResource(nvSandboxUtilsGpuRes_t *request);
/* *************************************************
* Get content of given file path
* *************************************************
*/
/**
* Get file content of input file path
* @param filePath Reference to the file path
* @param content Reference to the caller-supplied buffer to return the file content
* @param contentSize Reference to the maximum allowed size of content. It is updated to the actual size of the content on return
*
* @returns @ref NVSANDBOXUTILS_SUCCESS on success
* @returns @ref NVSANDBOXUTILS_ERROR_INVALID_ARG if \p filePath or \p content is NULL
* @returns @ref NVSANDBOXUTILS_ERROR_INSUFFICIENT_SIZE if \p contentSize is too small
* @returns @ref NVSANDBOXUTILS_ERROR_FILEPATH_NOT_FOUND on an error while obtaining the content for the file path
*/
nvSandboxUtilsRet_t nvSandboxUtilsGetFileContent(char *filePath, char *content, unsigned int *contentSize);
/** @} */
#ifdef __cplusplus
}
#endif
#endif // __NVSANDBOXUTILS_H__

View File

@ -0,0 +1,66 @@
# Copyright (c) 2024, NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
---
GENERATOR:
PackageName: nvsandboxutils
PackageDescription: "Package NVSANDBOXUTILS bindings"
PackageLicense: |-
Copyright (c) 2024, NVIDIA CORPORATION
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Includes: ["nvsandboxutils.h"]
FlagGroups:
- {name: "LDFLAGS", traits: ["linux"], flags: ["-Wl,--export-dynamic","-Wl,--unresolved-symbols=ignore-in-object-files"]}
- {name: "LDFLAGS", traits: ["darwin"], flags: ["-Wl,-undefined,dynamic_lookup"]}
PARSER:
SourcesPaths: ["nvsandboxutils.h"]
TRANSLATOR:
ConstRules:
defines: eval
enum: eval
PtrTips:
function:
- {target: "^nvSandboxUtils", default: "sref"}
MemTips:
- {target: "^nvSandboxUtils", default: "raw"}
Rules:
const:
- {action: accept, from: "^NVSANDBOXUTILS_"}
- {action: accept, from: "^nvSandboxUtils"}
- {action: replace, from: "^NVSANDBOXUTILS_"}
- {action: replace, from: "^nvSandboxUtils"}
- {action: accept, from: "^NV"}
- {action: accept, from: "^MAX"}
- {action: accept, from: "^INPUT"}
- {action: replace, from: "_t$"}
- {transform: export}
type:
- {action: accept, from: "^nvSandboxUtils"}
- {action: replace, from: "^nvSandboxUtils"}
- {action: replace, from: "_t$"}
- {transform: export}
function:
- {action: accept, from: "^nvSandboxUtils"}
- {transform: unexport}

View File

@ -0,0 +1,41 @@
#!/bin/bash
# Copyright 2024 NVIDIA CORPORATION
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# This file allows for the nvsandboxutils bindings to be updated using the tooling
# implemented in https://github.com/NVIDIA/go-nvml.
# To run this:
# cd internal/nvsandboxutils
# ./update-bindings.sh
set -e
BUILDIMAGE=bindings
docker build \
--build-arg GOLANG_VERSION=1.22.1 \
--build-arg C_FOR_GO_TAG=8eeee8c3b71f9c3c90c4a73db54ed08b0bba971d \
-t ${BUILDIMAGE} \
-f docker/Dockerfile.devel \
https://github.com/NVIDIA/go-nvml.git
docker run --rm -ti \
-e GOCACHE=/tmp/.cache/go \
-e GOMODCACHE=/tmp/.cache/gomod \
-v $(pwd):/nvsandboxutils \
-w /nvsandboxutils \
-u $(id -u):$(id -g) \
${BUILDIMAGE} \
./gen/generate-bindings.sh