Skip to content

Commit c6dc820

Browse files
committed
Add info command to nvidia-container-cli
1 parent 44b74ee commit c6dc820

File tree

4 files changed

+136
-0
lines changed

4 files changed

+136
-0
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ LIB_RPC_SRCS := $(SRCS_DIR)/driver_rpc.h \
7676
BIN_SRCS := $(SRCS_DIR)/cli/common.c \
7777
$(SRCS_DIR)/cli/configure.c \
7878
$(SRCS_DIR)/cli/dsl.c \
79+
$(SRCS_DIR)/cli/info.c \
7980
$(SRCS_DIR)/cli/list.c \
8081
$(SRCS_DIR)/cli/main.c \
8182
$(SRCS_DIR)/error_generic.c \

src/cli/cli.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ struct context {
2929
char *init_flags;
3030
const struct command *command;
3131

32+
/* info */
33+
bool csv_output;
34+
3235
/* configure */
3336
pid_t pid;
3437
char *rootfs;
@@ -49,9 +52,11 @@ struct context {
4952
int select_devices(struct error *, char *, const struct nvc_device *[],
5053
const struct nvc_device [], size_t);
5154

55+
extern const struct argp info_usage;
5256
extern const struct argp list_usage;
5357
extern const struct argp configure_usage;
5458

59+
int info_command(const struct context *);
5560
int list_command(const struct context *);
5661
int configure_command(const struct context *);
5762

src/cli/info.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3+
*/
4+
5+
#include <alloca.h>
6+
#include <err.h>
7+
#include <stdio.h>
8+
9+
#include "cli.h"
10+
11+
static error_t info_parser(int, char *, struct argp_state *);
12+
13+
const struct argp info_usage = {
14+
(const struct argp_option[]){
15+
{NULL, 0, NULL, 0, "Options:", -1},
16+
{"csv", 0x80, NULL, 0, "Output in CSV format", -1},
17+
{0},
18+
},
19+
info_parser,
20+
NULL,
21+
"Query the driver and report its information as well as the devices it detected.",
22+
NULL,
23+
NULL,
24+
NULL,
25+
};
26+
27+
static error_t
28+
info_parser(int key, maybe_unused char *arg, struct argp_state *state)
29+
{
30+
struct context *ctx = state->input;
31+
32+
switch (key) {
33+
case 0x80:
34+
ctx->csv_output = true;
35+
break;
36+
default:
37+
return (ARGP_ERR_UNKNOWN);
38+
}
39+
return (0);
40+
}
41+
42+
int
43+
info_command(const struct context *ctx)
44+
{
45+
bool run_as_root;
46+
struct nvc_context *nvc = NULL;
47+
struct nvc_config *nvc_cfg = NULL;
48+
struct nvc_driver_info *drv = NULL;
49+
struct nvc_device_info *dev = NULL;
50+
struct error err = {0};
51+
int rv = EXIT_FAILURE;
52+
53+
run_as_root = (geteuid() == 0);
54+
if (!run_as_root && ctx->load_kmods) {
55+
warnx("requires root privileges");
56+
return (rv);
57+
}
58+
if (run_as_root) {
59+
if (perm_set_capabilities(&err, CAP_PERMITTED, permitted_caps, nitems(permitted_caps)) < 0 ||
60+
perm_set_capabilities(&err, CAP_INHERITABLE, inherited_caps, nitems(inherited_caps)) < 0 ||
61+
perm_drop_bounds(&err) < 0) {
62+
warnx("permission error: %s", err.msg);
63+
return (rv);
64+
}
65+
} else {
66+
if (perm_set_capabilities(&err, CAP_PERMITTED, NULL, 0) < 0) {
67+
warnx("permission error: %s", err.msg);
68+
return (rv);
69+
}
70+
}
71+
72+
/* Initialize the library context. */
73+
int c = ctx->load_kmods ? CAPS_INIT_KMODS : CAPS_INIT;
74+
if (run_as_root && perm_set_capabilities(&err, CAP_EFFECTIVE, effective_caps[c], effective_caps_size(c)) < 0) {
75+
warnx("permission error: %s", err.msg);
76+
goto fail;
77+
}
78+
if ((nvc = nvc_context_new()) == NULL ||
79+
(nvc_cfg = nvc_config_new()) == NULL) {
80+
warn("memory allocation failed");
81+
goto fail;
82+
}
83+
nvc_cfg->uid = (!run_as_root && ctx->uid == (uid_t)-1) ? geteuid() : ctx->uid;
84+
nvc_cfg->gid = (!run_as_root && ctx->gid == (gid_t)-1) ? getegid() : ctx->gid;
85+
if (nvc_init(nvc, nvc_cfg, ctx->init_flags) < 0) {
86+
warnx("initialization error: %s", nvc_error(nvc));
87+
goto fail;
88+
}
89+
90+
/* Query the driver and device information. */
91+
if (run_as_root && perm_set_capabilities(&err, CAP_EFFECTIVE, effective_caps[CAPS_INFO], effective_caps_size(CAPS_INFO)) < 0) {
92+
warnx("permission error: %s", err.msg);
93+
goto fail;
94+
}
95+
if ((drv = nvc_driver_info_new(nvc, NULL)) == NULL ||
96+
(dev = nvc_device_info_new(nvc, NULL)) == NULL) {
97+
warnx("detection error: %s", nvc_error(nvc));
98+
goto fail;
99+
}
100+
101+
if (ctx->csv_output) {
102+
printf("NVRM version,CUDA version\n%s,%s\n", drv->nvrm_version, drv->cuda_version);
103+
printf("\nDevice Index,Model,GPU UUID,Bus Location,Architecture\n");
104+
for (size_t i = 0; i < dev->ngpus; ++i)
105+
printf("%zu,%s,%s,%s,%s\n", i, dev->gpus[i].model, dev->gpus[i].uuid, dev->gpus[i].busid, dev->gpus[i].arch);
106+
107+
} else {
108+
printf("%-15s %s\n%-15s %s\n", "NVRM version:", drv->nvrm_version, "CUDA version:", drv->cuda_version);
109+
for (size_t i = 0; i < dev->ngpus; ++i)
110+
printf("\n%-15s %zu\n%-15s %s\n%-15s %s\n%-15s %s\n%-15s %s\n",
111+
"Device Index:", i, "Model:", dev->gpus[i].model, "GPU UUID:", dev->gpus[i].uuid,
112+
"Bus Location:", dev->gpus[i].busid, "Architecture:", dev->gpus[i].arch);
113+
}
114+
115+
if (run_as_root && perm_set_capabilities(&err, CAP_EFFECTIVE, effective_caps[CAPS_SHUTDOWN], effective_caps_size(CAPS_SHUTDOWN)) < 0) {
116+
warnx("permission error: %s", err.msg);
117+
goto fail;
118+
}
119+
rv = EXIT_SUCCESS;
120+
fail:
121+
nvc_shutdown(nvc);
122+
nvc_device_info_free(dev);
123+
nvc_driver_info_free(drv);
124+
nvc_config_free(nvc_cfg);
125+
nvc_context_free(nvc);
126+
error_reset(&err);
127+
return (rv);
128+
}

src/cli/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static struct argp usage = {
3030
{"load-kmods", 'k', NULL, 0, "Load kernel modules", -1},
3131
{"user", 'u', "UID[:GID]", OPTION_ARG_OPTIONAL, "User and group to use for privilege separation", -1},
3232
{NULL, 0, NULL, 0, "Commands:", 0},
33+
{"info", 0, NULL, OPTION_DOC|OPTION_NO_USAGE, "Report information about the driver and devices", 0},
3334
{"list", 0, NULL, OPTION_DOC|OPTION_NO_USAGE, "List driver components", 0},
3435
{"configure", 0, NULL, OPTION_DOC|OPTION_NO_USAGE, "Configure a container with GPU support", 0},
3536
{0},
@@ -43,6 +44,7 @@ static struct argp usage = {
4344
};
4445

4546
static const struct command commands[] = {
47+
{"info", &info_usage, &info_command},
4648
{"list", &list_usage, &list_command},
4749
{"configure", &configure_usage, &configure_command},
4850
};

0 commit comments

Comments
 (0)