3 # Copyright (c) 2017, 2018 NVIDIA CORPORATION.
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 # NVIDIA_VISIBLE_DEVICES="" *or* NVIDIA_VISIBLE_DEVICES="void"
22 # GPU support was explicitly disabled, exit early.
23 if [ -z "${NVIDIA_VISIBLE_DEVICES-x}" ] ||
[ "${NVIDIA_VISIBLE_DEVICES:-}" = "void" ]; then
27 # https://github.com/nvidia/nvidia-container-runtime#cuda_version
28 if [ -n "${CUDA_VERSION:-}" ] && [ -z "${NVIDIA_REQUIRE_CUDA:-}" ]; then
29 # Legacy CUDA image: default to all devices and all driver capabilities.
30 if [ -z "${NVIDIA_VISIBLE_DEVICES+x}" ]; then
31 NVIDIA_VISIBLE_DEVICES
="all"
33 if [ -z "${NVIDIA_DRIVER_CAPABILITIES:-}" ]; then
34 NVIDIA_DRIVER_CAPABILITIES
="all"
36 if [[ "${CUDA_VERSION}" =~ ^
[0-9]+\.
[0-9]+ ]]; then
37 NVIDIA_REQUIRE_CUDA
="cuda>=${BASH_REMATCH[0]}"
40 # NVIDIA_VISIBLE_DEVICES unset and it's not a legacy CUDA image.
41 # This is not a GPU image, exit early.
42 if [ -z "${NVIDIA_VISIBLE_DEVICES+x}" ]; then
47 export PATH
=$PATH:/usr
/sbin
:/usr
/bin
:/sbin
:/bin
48 if ! which nvidia-container-cli
>/dev
/null
; then
49 echo "ERROR: Missing tool nvidia-container-cli, see https://github.com/NVIDIA/libnvidia-container" >&2
54 [ -e /proc
/self
/uid_map
] ||
{ echo no
; return; }
56 fields
=$
(echo $line |
awk '{ print $1 " " $2 " " $3 }')
57 [ "$fields" = "0 0 4294967295" ] && { echo no
; return; } || true
58 echo $fields |
grep -q " 0 1$" && { echo userns-root
; return; } || true
59 done < /proc
/self
/uid_map
61 if [ -e /proc
/1/uid_map
]; then
62 if [ "$(cat /proc/self/uid_map)" = "$(cat /proc/1/uid_map)" ]; then
71 which "ldconfig.real" ||
which "ldconfig"
77 compute
) echo "--compute";;
78 compat32
) echo "--compat32";;
79 display
) echo "--display";;
80 graphics
) echo "--graphics";;
81 utility
) echo "--utility";;
82 video
) echo "--video";;
88 # Same behavior as strconv.ParseBool in golang
91 1|t|T|TRUE|true|True
) echo "true";;
92 0|f|F|FALSE|false|False
) echo "false";;
100 nvidia-container-cli hook for LXC
103 [ -h | --help ]: Print this help message and exit.
106 [ --no-load-kmods ]: Do not try to load the NVIDIA kernel modules.
107 [ --disable-require ]: Disable all the constraints of the form NVIDIA_REQUIRE_*.
108 [ --debug <path> ]: The path to the log file.
109 [ --ldcache <path> ]: The path to the host system's DSO cache.
110 [ --root <path> ]: The path to the driver root directory.
111 [ --ldconfig <path> ]: The path to the ldconfig binary, use a '@' prefix for a host path.
116 options
=$
(getopt
-o h
-l help,no-load-kmods
,disable-require
,debug
:,ldcache
:,root
:,ldconfig
: -- "$@")
117 if [ $?
-ne 0 ]; then
121 eval set -- "$options"
123 CLI_LOAD_KMODS
="true"
124 CLI_DISABLE_REQUIRE
="false"
132 --help) usage
&& exit 1;;
133 --no-load-kmods) CLI_LOAD_KMODS
="false"; shift 1;;
134 --disable-require) CLI_DISABLE_REQUIRE
="true"; shift 1;;
135 --debug) CLI_DEBUG
=$2; shift 2;;
136 --ldcache) CLI_LDCACHE
=$2; shift 2;;
137 --root) CLI_ROOT
=$2; shift 2;;
138 --ldconfig) CLI_LDCONFIG
=$2; shift 2;;
146 case "${LXC_HOOK_VERSION:-0}" in
147 0) HOOK_SECTION
="${2:-}"; HOOK_TYPE
="${3:-}";;
148 1) HOOK_SECTION
="${LXC_HOOK_SECTION:-}"; HOOK_TYPE
="${LXC_HOOK_TYPE:-}";;
149 *) echo "ERROR: Unsupported hook version: ${LXC_HOOK_VERSION}." >&2; exit 1;;
152 if [ "${HOOK_SECTION}" != "lxc" ]; then
153 echo "ERROR: Not running through LXC." >&2
157 if [ "${HOOK_TYPE}" != "mount" ]; then
158 echo "ERROR: This hook must be used as a \"mount\" hook." >&2
163 if [ "${USERNS}" != "yes" ]; then
164 # This is a limitation of libnvidia-container.
165 echo "FIXME: This hook currently only works in unprivileged mode." >&2
169 if [ "${USERNS}" = "yes" ]; then
170 CLI_LOAD_KMODS
="false"
171 if ! grep -q nvidia_uvm
/proc
/modules
; then
172 echo "WARN: Kernel module nvidia_uvm is not loaded, nvidia-container-cli might fail. Make sure the NVIDIA device driver is installed and loaded." >&2
176 # https://github.com/nvidia/nvidia-container-runtime#nvidia_disable_require
177 if [ -n "${NVIDIA_DISABLE_REQUIRE:-}" ]; then
178 if [ "$(parse_bool "${NVIDIA_DISABLE_REQUIRE}")" = "true" ]; then
179 CLI_DISABLE_REQUIRE
="true"
183 if [ -z "${CLI_DEBUG}" ]; then
184 if [ "${LXC_LOG_LEVEL}" = "DEBUG" ] ||
[ "${LXC_LOG_LEVEL}" = "TRACE" ]; then
185 rootfs_path
="${LXC_ROOTFS_PATH#*:}"
186 hookdir
="${rootfs_path/%rootfs/hook}"
187 if mkdir
-p "${hookdir}"; then
188 CLI_DEBUG
="${hookdir}/nvidia.log"
193 # A '@' prefix means a host path.
194 if [ -z "${CLI_LDCONFIG}" ]; then
195 if host_ldconfig
=$
(get_ldconfig
); then
196 CLI_LDCONFIG
="@${host_ldconfig}"
200 # https://github.com/nvidia/nvidia-container-runtime#nvidia_visible_devices
201 CLI_DEVICES
="${NVIDIA_VISIBLE_DEVICES}"
203 # https://github.com/nvidia/nvidia-container-runtime#nvidia_driver_capabilities
205 if [ -n "${NVIDIA_DRIVER_CAPABILITIES:-}" ]; then
206 CLI_CAPABILITIES
="${NVIDIA_DRIVER_CAPABILITIES//,/ }"
209 if [ "${CLI_CAPABILITIES}" = "all" ]; then
210 CLI_CAPABILITIES
="compute compat32 display graphics utility video"
213 if [ -z "${CLI_CAPABILITIES}" ]; then
214 CLI_CAPABILITIES
="utility"
220 if [ -n "${CLI_DEBUG}" ]; then
221 echo "INFO: Writing nvidia-container-cli log at ${CLI_DEBUG}." >&2
222 global_args
+=("--debug=${CLI_DEBUG}")
225 if [ "${CLI_LOAD_KMODS}" = "true" ]; then
226 global_args
+=(--load-kmods)
229 if [ "${USERNS}" = "yes" ]; then
230 global_args
+=(--user)
231 configure_args
+=(--no-cgroups)
234 if [ -n "${CLI_LDCACHE}" ]; then
235 global_args
+=(--ldcache="${CLI_LDCACHE}")
238 if [ -n "${CLI_ROOT}" ]; then
239 global_args
+=(--root="${CLI_ROOT}")
242 if [ -n "${CLI_LDCONFIG}" ]; then
243 configure_args
+=(--ldconfig="${CLI_LDCONFIG}")
246 if [ -n "${CLI_DEVICES}" ] && [ "${CLI_DEVICES}" != "none" ]; then
247 configure_args
+=(--device="${CLI_DEVICES}")
250 for cap
in ${CLI_CAPABILITIES}; do
251 if arg
=$
(capability_to_cli
"${cap}"); then
252 configure_args
+=("${arg}")
254 echo "ERROR: Unknown driver capability \"${cap}\"." >&2
259 # https://github.com/nvidia/nvidia-container-runtime#nvidia_require_
260 if [ "${CLI_DISABLE_REQUIRE}" = "false" ]; then
261 for req
in $
(compgen
-e "NVIDIA_REQUIRE_"); do
262 configure_args
+=("--require=${!req}")
266 if [ -d "/sys/kernel/security/apparmor" ]; then
267 # Try to transition to the unconfined AppArmor profile.
268 echo "changeprofile unconfined" > /proc
/self
/attr
/current || true
272 exec nvidia-container-cli
${global_args[@]} configure "${configure_args[@]}" "${LXC_ROOTFS_MOUNT}"