Compare commits

...

23 Commits

Author SHA1 Message Date
Evan Lezar
88862eebbf Merge branch 'bump-1.12.2' into 'release-1.12'
Bump version to v1.12.2

See merge request nvidia/container-toolkit/container-toolkit!341
2023-03-14 17:14:57 +00:00
Evan Lezar
bb6aea3045 Update libnvidia-container
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2023-03-14 16:35:45 +02:00
Evan Lezar
745c8ee2e7 Bump version to v1.12.2
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2023-03-14 16:35:35 +02:00
Evan Lezar
0bedf07e7b Merge branch 'backport-install-nvidia-ctk' into 'release-1.12'
Backport changes for 1.12.1 release

See merge request nvidia/container-toolkit/container-toolkit!332
2023-03-10 11:24:34 +00:00
Evan Lezar
5c86ca17ef Update CHANGELOG.md
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2023-03-10 12:47:14 +02:00
Evan Lezar
0741252a7c Merge branch 'bump-cuda-version' into 'main'
Bump CUDA base image version to 12.1.0

See merge request nvidia/container-toolkit/container-toolkit!335
2023-03-10 12:26:09 +02:00
Evan Lezar
2d9e4cb720 Merge branch 'set-nvidia-ctk-path' into 'main'
Set nvidia-ctk.path config option based on installed path

See merge request nvidia/container-toolkit/container-toolkit!334
2023-03-09 20:18:32 +02:00
Evan Lezar
12aca454ab Also install nvidia-ctk in toolkit-container
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2023-03-09 11:49:16 +02:00
Evan Lezar
57a4072fae Merge branch 'fix-internal' into 'release-1.12'
Merge branch 'fix-internal-scans' into 'main'

See merge request nvidia/container-toolkit/container-toolkit!322
2023-03-06 12:07:02 +00:00
Evan Lezar
bac1222871 Merge branch 'fix-internal-scans' into 'main'
Fix internal scans

See merge request nvidia/container-toolkit/container-toolkit!316
2023-03-06 14:06:02 +02:00
Evan Lezar
0023db2150 Merge branch 'fix-rule-for-release' into 'release-1.12'
Run full build on release- branches

See merge request nvidia/container-toolkit/container-toolkit!319
2023-03-06 10:55:26 +00:00
Evan Lezar
3ffc8cf86d Merge branch 'cherry-pick-1.12.1' into 'release-1.12'
Bump version to 1.12.1 and cherry-pick changes

See merge request nvidia/container-toolkit/container-toolkit!311
2023-03-06 10:06:48 +00:00
Evan Lezar
a6d02feba7 Merge branch 'fix-rpm-postun-scriptlet' into 'main'
nvidia-container-toolkit.spec: fix syntax error in postun scriptlet

See merge request nvidia/container-toolkit/container-toolkit!309
2023-03-06 11:12:51 +02:00
Evan Lezar
9fc25ac641 Merge branch 'remove-outdated-platforms' into 'main'
Remove outdated platforms from CI

See merge request nvidia/container-toolkit/container-toolkit!310
2023-03-06 11:12:51 +02:00
Evan Lezar
7df553ad09 Merge branch 'CNT-3965/dont-fail-chmod-hook' into 'main'
Skip paths with errors in chmod hook

See merge request nvidia/container-toolkit/container-toolkit!303
2023-03-06 11:12:51 +02:00
Evan Lezar
d5ab1c0ba0 Merge branch 'fix-nvidia-ctk-path' into 'main'
Ensure that generate uses a consistent nvidia-ctk path

See merge request nvidia/container-toolkit/container-toolkit!301
2023-03-06 11:12:51 +02:00
Evan Lezar
bc37b97c73 Merge branch 'fix-nvidia-ctk-path' into 'main'
Fix issue with blank nvidia-ctk path

See merge request nvidia/container-toolkit/container-toolkit!297
2023-03-06 11:12:51 +02:00
Kevin Klues
2081750bea Merge branch 'support-multimple-firmware-files' into 'main'
Add globbing for mounting multiple GSP firmware files

See merge request nvidia/container-toolkit/container-toolkit!295
2023-03-06 11:12:51 +02:00
Evan Lezar
a2d1f4cfb4 Merge branch 'update-ldflags' into 'main'
Update ldflags for cgo

See merge request nvidia/container-toolkit/container-toolkit!290
2023-03-06 11:12:51 +02:00
Evan Lezar
944922a541 Remove fedora35 pipeline targets
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2023-03-06 11:12:51 +02:00
Evan Lezar
5995305554 Skip component updates on release-* branches
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2023-03-06 11:12:51 +02:00
Evan Lezar
bc81d5e68b Update libnvidia-container
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2023-03-06 11:12:42 +02:00
Evan Lezar
d50e7f1f4f Bump version to 1.12.1
Signed-off-by: Evan Lezar <elezar@nvidia.com>
2023-02-27 14:51:32 +02:00
17 changed files with 83 additions and 161 deletions

View File

@@ -71,20 +71,6 @@ stages:
DIST: debian10
PACKAGE_REPO_TYPE: debian
.dist-debian9:
rules:
- !reference [.main-or-manual, rules]
variables:
DIST: debian9
PACKAGE_REPO_TYPE: debian
.dist-fedora35:
rules:
- !reference [.main-or-manual, rules]
variables:
DIST: fedora35
PACKAGE_REPO_TYPE: rpm
.dist-opensuse-leap15.1:
rules:
- !reference [.main-or-manual, rules]
@@ -100,13 +86,6 @@ stages:
CVE_UPDATES: "cyrus-sasl-lib"
PACKAGE_REPO_TYPE: rpm
.dist-ubuntu16.04:
rules:
- !reference [.main-or-manual, rules]
variables:
DIST: ubuntu16.04
PACKAGE_REPO_TYPE: debian
.dist-ubuntu18.04:
variables:
DIST: ubuntu18.04
@@ -114,8 +93,6 @@ stages:
PACKAGE_REPO_TYPE: debian
.dist-ubuntu20.04:
rules:
- !reference [.main-or-manual, rules]
variables:
DIST: ubuntu20.04
CVE_UPDATES: "libsasl2-2 libsasl2-modules-db"
@@ -260,22 +237,15 @@ release:staging-ubi8:
needs:
- image-ubi8
release:staging-ubuntu18.04:
extends:
- .release:staging
- .dist-ubuntu18.04
needs:
- test-toolkit-ubuntu18.04
- test-containerd-ubuntu18.04
- test-crio-ubuntu18.04
- test-docker-ubuntu18.04
release:staging-ubuntu20.04:
extends:
- .release:staging
- .dist-ubuntu20.04
needs:
- image-ubuntu20.04
- test-toolkit-ubuntu20.04
- test-containerd-ubuntu20.04
- test-crio-ubuntu20.04
- test-docker-ubuntu20.04
release:staging-packaging:
extends:

View File

@@ -116,12 +116,6 @@ package-amazonlinux2-x86_64:
- .dist-amazonlinux2
- .arch-x86_64
package-centos7-ppc64le:
extends:
- .package-build
- .dist-centos7
- .arch-ppc64le
package-centos7-x86_64:
extends:
- .package-build
@@ -152,42 +146,12 @@ package-debian10-amd64:
- .dist-debian10
- .arch-amd64
package-debian9-amd64:
extends:
- .package-build
- .dist-debian9
- .arch-amd64
package-fedora35-aarch64:
extends:
- .package-build
- .dist-fedora35
- .arch-aarch64
package-fedora35-x86_64:
extends:
- .package-build
- .dist-fedora35
- .arch-x86_64
package-opensuse-leap15.1-x86_64:
extends:
- .package-build
- .dist-opensuse-leap15.1
- .arch-x86_64
package-ubuntu16.04-amd64:
extends:
- .package-build
- .dist-ubuntu16.04
- .arch-amd64
package-ubuntu16.04-ppc64le:
extends:
- .package-build
- .dist-ubuntu16.04
- .arch-ppc64le
package-ubuntu18.04-amd64:
extends:
- .package-build
@@ -240,7 +204,6 @@ image-centos7:
- .package-artifacts
- .dist-centos7
needs:
- package-centos7-ppc64le
- package-centos7-x86_64
image-ubi8:
@@ -254,17 +217,6 @@ image-ubi8:
- package-centos8-x86_64
- package-centos8-ppc64le
image-ubuntu18.04:
extends:
- .image-build
- .package-artifacts
- .dist-ubuntu18.04
needs:
- package-ubuntu18.04-amd64
- package-ubuntu18.04-arm64
- job: package-ubuntu18.04-ppc64le
optional: true
image-ubuntu20.04:
extends:
- .image-build
@@ -273,7 +225,8 @@ image-ubuntu20.04:
needs:
- package-ubuntu18.04-amd64
- package-ubuntu18.04-arm64
- package-ubuntu18.04-ppc64le
- job: package-ubuntu18.04-ppc64le
optional: true
# The DIST=packaging target creates an image containing all built packages
image-packaging:
@@ -290,26 +243,14 @@ image-packaging:
optional: true
- job: package-amazonlinux2-x86_64
optional: true
- job: package-centos7-ppc64le
optional: true
- job: package-centos7-x86_64
optional: true
- job: package-centos8-ppc64le
optional: true
- job: package-debian10-amd64
optional: true
- job: package-debian9-amd64
optional: true
- job: package-fedora35-aarch64
optional: true
- job: package-fedora35-x86_64
optional: true
- job: package-opensuse-leap15.1-x86_64
optional: true
- job: package-ubuntu16.04-amd64
optional: true
- job: package-ubuntu16.04-ppc64le
optional: true
- job: package-ubuntu18.04-ppc64le
optional: true
@@ -343,31 +284,31 @@ image-packaging:
TEST_CASES: "crio"
# Define the test targets
test-toolkit-ubuntu18.04:
test-toolkit-ubuntu20.04:
extends:
- .test:toolkit
- .dist-ubuntu18.04
- .dist-ubuntu20.04
needs:
- image-ubuntu18.04
- image-ubuntu20.04
test-containerd-ubuntu18.04:
test-containerd-ubuntu20.04:
extends:
- .test:containerd
- .dist-ubuntu18.04
- .dist-ubuntu20.04
needs:
- image-ubuntu18.04
- image-ubuntu20.04
test-crio-ubuntu18.04:
test-crio-ubuntu20.04:
extends:
- .test:crio
- .dist-ubuntu18.04
- .dist-ubuntu20.04
needs:
- image-ubuntu18.04
- image-ubuntu20.04
test-docker-ubuntu18.04:
test-docker-ubuntu20.04:
extends:
- .test:docker
- .dist-ubuntu18.04
- .dist-ubuntu20.04
needs:
- image-ubuntu18.04
- image-ubuntu20.04

View File

@@ -79,11 +79,6 @@ image-ubi8:
- .dist-ubi8
- .image-pull
image-ubuntu18.04:
extends:
- .dist-ubuntu18.04
- .image-pull
image-ubuntu20.04:
extends:
- .dist-ubuntu20.04
@@ -153,14 +148,6 @@ scan-centos7-arm64:
- image-centos7
- scan-centos7-amd64
scan-ubuntu18.04-amd64:
extends:
- .dist-ubuntu18.04
- .platform-amd64
- .scan
needs:
- image-ubuntu18.04
scan-ubuntu20.04-amd64:
extends:
- .dist-ubuntu20.04
@@ -230,12 +217,12 @@ release:packages:kitmaker:
extends:
- .release:packages
release:staging-ubuntu18.04:
release:staging-ubuntu20.04:
extends:
- .release:staging
- .dist-ubuntu18.04
- .dist-ubuntu20.04
needs:
- image-ubuntu18.04
- image-ubuntu20.04
# Define the external release targets
# Release to NGC
@@ -244,11 +231,6 @@ release:ngc-centos7:
- .dist-centos7
- .release:ngc
release:ngc-ubuntu18.04:
extends:
- .dist-ubuntu18.04
- .release:ngc
release:ngc-ubuntu20.04:
extends:
- .dist-ubuntu20.04

View File

@@ -1,5 +1,22 @@
# NVIDIA Container Toolkit Changelog
## v1.12.2
* [libnvidia-container] Fix segfault on WSL2 systems
## v1.12.1
* Don't fail chmod hook if paths are not injected
* Fix possible blank `nvidia-ctk` path in generated CDI specifications
* Fix error in postun scriplet on RPM-based systems
* Fix missing NVML symbols when running `nvidia-ctk` on some platforms [#49]
* Discover all `gsb*.bin` GSP firmware files when generating CDI specification.
* Remove `fedora35` packaging targets
* [libnvidia-container] Include all `gsp*.bin` firmware files if present
* [toolkit-container] Install `nvidia-ctk` from toolkit container
* [toolkit-container] Use installed `nvidia-ctk` path in NVIDIA Container Toolkit config
* [toolkit-container] Bump CUDA base images to 12.1.0
## v1.12.0
* Promote `v1.12.0-rc.5` to `v1.12.0`

View File

@@ -61,7 +61,7 @@ cmd-%: COMMAND_BUILD_OPTIONS = -o $(PREFIX)/$(*)
endif
cmds: $(CMD_TARGETS)
$(CMD_TARGETS): cmd-%:
GOOS=$(GOOS) go build -ldflags "-s -w -X $(CLI_VERSION_PACKAGE).gitCommit=$(GIT_COMMIT) -X $(CLI_VERSION_PACKAGE).version=$(CLI_VERSION)" $(COMMAND_BUILD_OPTIONS) $(MODULE)/cmd/$(*)
GOOS=$(GOOS) go build -ldflags "-extldflags=-Wl,-z,lazy -s -w -X $(CLI_VERSION_PACKAGE).gitCommit=$(GIT_COMMIT) -X $(CLI_VERSION_PACKAGE).version=$(CLI_VERSION)" $(COMMAND_BUILD_OPTIONS) $(MODULE)/cmd/$(*)
build:
GOOS=$(GOOS) go build ./...

View File

@@ -44,7 +44,7 @@ OUT_IMAGE = $(OUT_IMAGE_NAME):$(OUT_IMAGE_TAG)
##### Public rules #####
DEFAULT_PUSH_TARGET := ubuntu20.04
DISTRIBUTIONS := ubuntu20.04 ubuntu18.04 ubi8 centos7
DISTRIBUTIONS := ubuntu20.04 ubi8 centos7
META_TARGETS := packaging
@@ -146,10 +146,7 @@ test-packaging:
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/centos8/ppc64le" || echo "Missing centos8/ppc64le"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/centos8/x86_64" || echo "Missing centos8/x86_64"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/debian10/amd64" || echo "Missing debian10/amd64"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/debian9/amd64" || echo "Missing debian9/amd64"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/opensuse-leap15.1/x86_64" || echo "Missing opensuse-leap15.1/x86_64"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/ubuntu16.04/amd64" || echo "Missing ubuntu16.04/amd64"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/ubuntu16.04/ppc64le" || echo "Missing ubuntu16.04/ppc64le"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/ubuntu18.04/amd64" || echo "Missing ubuntu18.04/amd64"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/ubuntu18.04/arm64" || echo "Missing ubuntu18.04/arm64"
@$(DOCKER) run --rm $(IMAGE) test -d "/artifacts/packages/ubuntu18.04/ppc64le" || echo "Missing ubuntu18.04/ppc64le"

View File

@@ -87,7 +87,7 @@ func NewDriverLibraryDiscoverer(logger *logrus.Logger, driverRoot string, nvidia
// NewDriverFirmwareDiscoverer creates a discoverer for GSP firmware associated with the specified driver version.
func NewDriverFirmwareDiscoverer(logger *logrus.Logger, driverRoot string, version string) discover.Discover {
gspFirmwarePath := filepath.Join("/lib/firmware/nvidia", version, "gsp.bin")
gspFirmwarePath := filepath.Join("/lib/firmware/nvidia", version, "gsp*.bin")
return discover.NewMounts(
logger,
lookup.NewFileLocator(

View File

@@ -122,6 +122,8 @@ func (m command) validateFlags(r *cli.Context, cfg *config) error {
return err
}
cfg.nvidiaCTKPath = discover.FindNvidiaCTK(m.logger, cfg.nvidiaCTKPath)
return nil
}

View File

@@ -18,6 +18,7 @@ package chmod
import (
"fmt"
"os"
"path/filepath"
"strings"
"syscall"
@@ -133,7 +134,12 @@ func (m command) run(c *cli.Context, cfg *config) error {
func (m command) getPaths(root string, paths []string) []string {
var pathsInRoot []string
for _, f := range paths {
pathsInRoot = append(pathsInRoot, filepath.Join(root, f))
path := filepath.Join(root, f)
if _, err := os.Stat(path); err != nil {
m.logger.Debugf("Skipping path %q: %v", path, err)
continue
}
pathsInRoot = append(pathsInRoot, path)
}
return pathsInRoot

View File

@@ -47,6 +47,9 @@ func FindNvidiaCTK(logger *logrus.Logger, nvidiaCTKPath string) string {
return nvidiaCTKPath
}
if nvidiaCTKPath == "" {
nvidiaCTKPath = nvidiaCTKExecutable
}
logger.Debugf("Locating NVIDIA Container Toolkit CLI as %v", nvidiaCTKPath)
lookup := lookup.NewExecutableLocator(logger, "")
hookPath := nvidiaCTKDefaultFilePath

View File

@@ -65,7 +65,9 @@ rm -rf %{_localstatedir}/lib/rpm-state/nvidia-container-toolkit
ln -sf %{_bindir}/nvidia-container-runtime-hook %{_bindir}/nvidia-container-toolkit
%postun
if [ -L %{_bindir}/nvidia-container-toolkit ] then; rm -f %{_bindir}/nvidia-container-toolkit; fi
if [ "$1" = 0 ]; then # package is uninstalled, not upgraded
if [ -L %{_bindir}/nvidia-container-toolkit ]; then rm -f %{_bindir}/nvidia-container-toolkit; fi
fi
%files
%license LICENSE

View File

@@ -29,18 +29,12 @@ SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/../scripts && pwd )"
all=(
amazonlinux2-aarch64
amazonlinux2-x86_64
centos7-ppc64le
centos7-x86_64
centos8-aarch64
centos8-ppc64le
centos8-x86_64
debian10-amd64
debian9-amd64
fedora35-aarch64
fedora35-x86_64
opensuse-leap15.1-x86_64
ubuntu16.04-amd64
ubuntu16.04-ppc64le
ubuntu18.04-amd64
ubuntu18.04-arm64
ubuntu18.04-ppc64le
@@ -52,14 +46,6 @@ else
targets=${all[@]}
fi
echo "Updating components"
"${SCRIPTS_DIR}/update-components.sh"
if [[ -n $(git status -s third_party) && ${ALLOW_LOCAL_COMPONENT_CHANGES} != "true" ]]; then
echo "ERROR: Building with local component changes."
echo "Commit pending changes or rerun with ALLOW_LOCAL_COMPONENT_CHANGES='true'"
exit 1
fi
eval $(${SCRIPTS_DIR}/get-component-versions.sh)

View File

@@ -152,18 +152,12 @@ function sync() {
all=(
amazonlinux2-aarch64
amazonlinux2-x86_64
centos7-ppc64le
centos7-x86_64
centos8-aarch64
centos8-ppc64le
centos8-x86_64
debian10-amd64
debian9-amd64
fedora35-aarch64
fedora35-x86_64
opensuse-leap15.1-x86_64
ubuntu16.04-amd64
ubuntu16.04-ppc64le
ubuntu18.04-amd64
ubuntu18.04-arm64
ubuntu18.04-ppc64le

View File

@@ -61,6 +61,7 @@ testing::toolkit::install() {
grep -q -E "^\s*ldconfig = \"@${nvidia_run_dir}/driver/sbin/ldconfig(.real)?\"" "${shared_dir}/usr/local/nvidia/toolkit/.config/nvidia-container-runtime/config.toml"
grep -q -E "^\s*root = \"${nvidia_run_dir}/driver\"" "${shared_dir}/usr/local/nvidia/toolkit/.config/nvidia-container-runtime/config.toml"
grep -q -E "^\s*path = \"/usr/local/nvidia/toolkit/nvidia-container-cli\"" "${shared_dir}/usr/local/nvidia/toolkit/.config/nvidia-container-runtime/config.toml"
grep -q -E "^\s*path = \"/usr/local/nvidia/toolkit/nvidia-ctk\"" "${shared_dir}/usr/local/nvidia/toolkit/.config/nvidia-container-runtime/config.toml"
}
testing::toolkit::delete() {

View File

@@ -204,7 +204,12 @@ func Install(cli *cli.Context, opts *options) error {
return fmt.Errorf("error installing NVIDIA container runtime hook: %v", err)
}
err = installToolkitConfig(toolkitConfigPath, nvidiaContainerCliExecutable, opts)
nvidiaCTKPath, err := installContainerToolkitCLI(opts.toolkitRoot)
if err != nil {
return fmt.Errorf("error installing NVIDIA Container Toolkit CLI: %v", err)
}
err = installToolkitConfig(toolkitConfigPath, nvidiaContainerCliExecutable, nvidiaCTKPath, opts)
if err != nil {
return fmt.Errorf("error installing NVIDIA container toolkit config: %v", err)
}
@@ -262,7 +267,7 @@ func installLibrary(libName string, toolkitRoot string) error {
// installToolkitConfig installs the config file for the NVIDIA container toolkit ensuring
// that the settings are updated to match the desired install and nvidia driver directories.
func installToolkitConfig(toolkitConfigPath string, nvidiaContainerCliExecutablePath string, opts *options) error {
func installToolkitConfig(toolkitConfigPath string, nvidiaContainerCliExecutablePath string, nvidiaCTKPath string, opts *options) error {
log.Infof("Installing NVIDIA container toolkit config '%v'", toolkitConfigPath)
config, err := toml.LoadFile(nvidiaContainerToolkitConfigSource)
@@ -311,6 +316,9 @@ func installToolkitConfig(toolkitConfigPath string, nvidiaContainerCliExecutable
config.Set(key, value)
}
// Set nvidia-ctk options
config.Set("nvidia-ctk.path", nvidiaCTKPath)
_, err = config.WriteTo(targetConfig)
if err != nil {
return fmt.Errorf("error writing config: %v", err)
@@ -322,6 +330,19 @@ func installToolkitConfig(toolkitConfigPath string, nvidiaContainerCliExecutable
return nil
}
// installContainerToolkitCLI installs the nvidia-ctk CLI executable and wrapper.
func installContainerToolkitCLI(toolkitDir string) (string, error) {
e := executable{
source: "/usr/bin/nvidia-ctk",
target: executableTarget{
dotfileName: "nvidia-ctk.real",
wrapperName: "nvidia-ctk",
},
}
return e.install(toolkitDir)
}
// installContainerCLI sets up the NVIDIA container CLI executable, copying the executable
// and implementing the required wrapper
func installContainerCLI(toolkitRoot string) (string, error) {

View File

@@ -13,7 +13,7 @@
# limitations under the License.
LIB_NAME := nvidia-container-toolkit
LIB_VERSION := 1.12.0
LIB_VERSION := 1.12.2
# Specify the nvidia-docker2 and nvidia-container-runtime package versions.
# Note: The build tooling uses `LIB_TAG` above as the version tag.
@@ -24,7 +24,7 @@ NVIDIA_CONTAINER_RUNTIME_VERSION := 3.12.0
# Specify the expected libnvidia-container0 version for arm64-based ubuntu builds.
LIBNVIDIA_CONTAINER0_VERSION := 0.10.0+jetpack
CUDA_VERSION := 12.0.1
CUDA_VERSION := 12.1.0
GOLANG_VERSION := 1.18.8
GIT_COMMIT ?= $(shell git describe --match="" --dirty --long --always --abbrev=40 2> /dev/null || echo "")