Skip to content

Commit 735014f

Browse files
authored
Merge pull request containers#1754 from tylerfanelli/krun-vm-config-flavor
krun: Parse libkrun flavor indicated in `KRUN_VM_FILE`
2 parents c3c51ba + 379524f commit 735014f

File tree

1 file changed

+93
-36
lines changed

1 file changed

+93
-36
lines changed

src/libcrun/handlers/krun.c

Lines changed: 93 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
*/
6060
#define KRUN_VM_FILE "/.krun_vm.json"
6161

62+
#define KRUN_FLAVOR_SEV "sev"
63+
6264
struct krun_config
6365
{
6466
void *handle;
@@ -138,17 +140,11 @@ libkrun_configure_kernel (uint32_t ctx_id, void *handle, yajl_val *config_tree,
138140
}
139141

140142
static int
141-
libkrun_configure_vm (uint32_t ctx_id, void *handle, bool *configured, libcrun_error_t *err)
143+
libkrun_read_vm_config (yajl_val *config_tree, libcrun_error_t *err)
142144
{
143-
int32_t (*krun_set_vm_config) (uint32_t ctx_id, uint8_t num_vcpus, uint32_t ram_mib);
144-
struct parser_context ctx = { 0, stderr };
145-
cleanup_free char *config = NULL;
146-
yajl_val config_tree = NULL;
147-
yajl_val cpus = NULL;
148-
yajl_val ram_mib = NULL;
149-
const char *path_cpus[] = { "cpus", (const char *) 0 };
150-
const char *path_ram_mib[] = { "ram_mib", (const char *) 0 };
151145
int ret;
146+
cleanup_free char *config = NULL;
147+
struct parser_context ctx = { 0, stderr };
152148

153149
if (access (KRUN_VM_FILE, F_OK) != 0)
154150
return 0;
@@ -157,20 +153,36 @@ libkrun_configure_vm (uint32_t ctx_id, void *handle, bool *configured, libcrun_e
157153
if (UNLIKELY (ret < 0))
158154
return ret;
159155

160-
ret = parse_json_file (&config_tree, config, &ctx, err);
156+
ret = parse_json_file (config_tree, config, &ctx, err);
161157
if (UNLIKELY (ret < 0))
162158
return ret;
163159

160+
return 0;
161+
}
162+
163+
static int
164+
libkrun_configure_vm (uint32_t ctx_id, void *handle, bool *configured, yajl_val *config_tree, libcrun_error_t *err)
165+
{
166+
int32_t (*krun_set_vm_config) (uint32_t ctx_id, uint8_t num_vcpus, uint32_t ram_mib);
167+
yajl_val cpus = NULL;
168+
yajl_val ram_mib = NULL;
169+
const char *path_cpus[] = { "cpus", (const char *) 0 };
170+
const char *path_ram_mib[] = { "ram_mib", (const char *) 0 };
171+
int ret;
172+
173+
if (*config_tree == NULL)
174+
return 0;
175+
164176
/* Try to configure an external kernel. If the configuration file doesn't
165177
* specify a kernel, libkrun automatically fall back to using libkrunfw,
166178
* if the library is present and was loaded while creating the context.
167179
*/
168-
ret = libkrun_configure_kernel (ctx_id, handle, &config_tree, err);
180+
ret = libkrun_configure_kernel (ctx_id, handle, config_tree, err);
169181
if (UNLIKELY (ret))
170182
return ret;
171183

172-
cpus = yajl_tree_get (config_tree, path_cpus, yajl_t_number);
173-
ram_mib = yajl_tree_get (config_tree, path_ram_mib, yajl_t_number);
184+
cpus = yajl_tree_get (*config_tree, path_cpus, yajl_t_number);
185+
ram_mib = yajl_tree_get (*config_tree, path_ram_mib, yajl_t_number);
174186
/* Both cpus and ram_mib must be present at the same time */
175187
if (cpus == NULL || ram_mib == NULL || ! YAJL_IS_INTEGER (cpus) || ! YAJL_IS_INTEGER (ram_mib))
176188
return 0;
@@ -189,6 +201,60 @@ libkrun_configure_vm (uint32_t ctx_id, void *handle, bool *configured, libcrun_e
189201
return 0;
190202
}
191203

204+
static int
205+
libkrun_configure_flavor (void *cookie, yajl_val *config_tree, libcrun_error_t *err)
206+
{
207+
int ret, sev_indicated = 0;
208+
const char *path_flavor[] = { "flavor", (const char *) 0 };
209+
struct krun_config *kconf = (struct krun_config *) cookie;
210+
yajl_val val_flavor = NULL;
211+
char *flavor = NULL;
212+
213+
// Read if the SEV flavor was indicated in the krun VM config.
214+
val_flavor = yajl_tree_get (*config_tree, path_flavor, yajl_t_string);
215+
if (val_flavor != NULL && YAJL_IS_STRING (val_flavor))
216+
{
217+
flavor = YAJL_GET_STRING (val_flavor);
218+
219+
// The SEV flavor will be used if the krun VM config indicates to use SEV
220+
// within the "flavor" field.
221+
sev_indicated |= strcmp (flavor, KRUN_FLAVOR_SEV) == 0;
222+
}
223+
224+
// To maintain backward compatibility, also use the SEV flavor if the
225+
// KRUN_SEV_FILE was found.
226+
sev_indicated |= access (KRUN_SEV_FILE, F_OK) == 0;
227+
228+
if (sev_indicated)
229+
{
230+
if (kconf->handle_sev == NULL)
231+
error (EXIT_FAILURE, 0, "the container requires libkrun-sev but it's not available");
232+
233+
// We no longer need the libkrun handle.
234+
ret = dlclose (kconf->handle);
235+
if (UNLIKELY (ret != 0))
236+
return crun_make_error (err, 0, "could not unload handle: `%s`", dlerror ());
237+
238+
kconf->handle = kconf->handle_sev;
239+
kconf->ctx_id = kconf->ctx_id_sev;
240+
kconf->sev = true;
241+
}
242+
else
243+
{
244+
if (kconf->handle == NULL)
245+
error (EXIT_FAILURE, 0, "the container requires libkrun but it's not available");
246+
247+
// We no longer need the libkrun-sev handle.
248+
ret = dlclose (kconf->handle_sev);
249+
if (UNLIKELY (ret != 0))
250+
return crun_make_error (err, 0, "could not unload handle: `%s`", dlerror ());
251+
252+
kconf->sev = false;
253+
}
254+
255+
return 0;
256+
}
257+
192258
static int
193259
libkrun_exec (void *cookie, libcrun_container_t *container, const char *pathname, char *const argv[])
194260
{
@@ -206,23 +272,18 @@ libkrun_exec (void *cookie, libcrun_container_t *container, const char *pathname
206272
cpu_set_t set;
207273
libcrun_error_t err;
208274
bool configured = false;
275+
yajl_val config_tree = NULL;
209276

210-
if (access (KRUN_SEV_FILE, F_OK) == 0)
211-
{
212-
if (kconf->handle_sev == NULL)
213-
error (EXIT_FAILURE, 0, "the container requires libkrun-sev but it's not available");
214-
handle = kconf->handle_sev;
215-
ctx_id = kconf->ctx_id_sev;
216-
kconf->sev = true;
217-
}
218-
else
219-
{
220-
if (kconf->handle == NULL)
221-
error (EXIT_FAILURE, 0, "the container requires libkrun but it's not available");
222-
handle = kconf->handle;
223-
ctx_id = kconf->ctx_id;
224-
kconf->sev = false;
225-
}
277+
ret = libkrun_read_vm_config (&config_tree, &err);
278+
if (UNLIKELY (ret < 0))
279+
error (EXIT_FAILURE, -ret, "libkrun VM config exists, but unable to parse");
280+
281+
ret = libkrun_configure_flavor (cookie, &config_tree, &err);
282+
if (UNLIKELY (ret < 0))
283+
error (EXIT_FAILURE, -ret, "unable to configure libkrun flavor");
284+
285+
handle = kconf->handle;
286+
ctx_id = kconf->ctx_id;
226287

227288
krun_set_log_level = dlsym (handle, "krun_set_log_level");
228289
krun_start_enter = dlsym (handle, "krun_start_enter");
@@ -259,7 +320,7 @@ libkrun_exec (void *cookie, libcrun_container_t *container, const char *pathname
259320
error (EXIT_FAILURE, -ret, "could not set krun root");
260321
}
261322

262-
ret = libkrun_configure_vm (ctx_id, handle, &configured, &err);
323+
ret = libkrun_configure_vm (ctx_id, handle, &configured, &config_tree, &err);
263324
if (UNLIKELY (ret))
264325
{
265326
libcrun_error_t *tmp_err = &err;
@@ -295,6 +356,8 @@ libkrun_exec (void *cookie, libcrun_container_t *container, const char *pathname
295356
error (EXIT_FAILURE, -ret, "could not set krun vm configuration");
296357
}
297358

359+
yajl_tree_free (config_tree);
360+
298361
ret = krun_start_enter (ctx_id);
299362
return -ret;
300363
}
@@ -467,12 +530,6 @@ libkrun_unload (void *cookie, libcrun_error_t *err)
467530
if (UNLIKELY (r != 0))
468531
return crun_make_error (err, 0, "could not unload handle: `%s`", dlerror ());
469532
}
470-
if (kconf->handle_sev != NULL)
471-
{
472-
r = dlclose (kconf->handle_sev);
473-
if (UNLIKELY (r != 0))
474-
return crun_make_error (err, 0, "could not unload handle_sev: `%s`", dlerror ());
475-
}
476533
}
477534
return 0;
478535
}

0 commit comments

Comments
 (0)