Skip to content

Commit 3134607

Browse files
giuseppeanonymous0719
authored andcommitted
linux: honor execCPUAffinity from main configuration file
Closes: https://issues.redhat.com/browse/OCPBUGS-65579 Signed-off-by: Giuseppe Scrivano <[email protected]>
1 parent 91df434 commit 3134607

File tree

2 files changed

+73
-9
lines changed

2 files changed

+73
-9
lines changed

src/libcrun/linux.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4969,12 +4969,9 @@ handle_pidfd_receiver (pid_t pid, libcrun_container_t *container, libcrun_error_
49694969
}
49704970

49714971
static bool
4972-
has_exec_cpu_affinity (runtime_spec_schema_config_schema_process *process)
4972+
has_exec_cpu_affinity (runtime_spec_schema_config_schema_process_exec_cpu_affinity *affinity)
49734973
{
4974-
if (process == NULL || process->exec_cpu_affinity == NULL)
4975-
return false;
4976-
return (! is_empty_string (process->exec_cpu_affinity->initial))
4977-
|| (! is_empty_string (process->exec_cpu_affinity->final));
4974+
return affinity && ((! is_empty_string (affinity->initial)) || (! is_empty_string (affinity->final)));
49784975
}
49794976

49804977
pid_t
@@ -5274,6 +5271,7 @@ join_process_parent_helper (libcrun_context_t *context,
52745271
char res;
52755272
pid_t pid;
52765273
cleanup_close int sync_fd = sync_socket_fd;
5274+
runtime_spec_schema_config_schema_process_exec_cpu_affinity *cpu_affinity = NULL;
52775275

52785276
if (terminal_fd)
52795277
*terminal_fd = -1;
@@ -5296,13 +5294,18 @@ join_process_parent_helper (libcrun_context_t *context,
52965294
return crun_make_error (err, errno, "waitpid for exec child pid");
52975295

52985296
if (process && process->exec_cpu_affinity)
5297+
cpu_affinity = process->exec_cpu_affinity;
5298+
else if (container && container->container_def && container->container_def->process && container->container_def->process->exec_cpu_affinity)
5299+
cpu_affinity = container->container_def->process->exec_cpu_affinity;
5300+
5301+
if (cpu_affinity)
52995302
{
5300-
ret = libcrun_set_cpu_affinity_from_string (pid, process->exec_cpu_affinity->initial, err);
5303+
ret = libcrun_set_cpu_affinity_from_string (pid, cpu_affinity->initial, err);
53015304
if (UNLIKELY (ret < 0))
53025305
return ret;
53035306
}
53045307

5305-
if (! has_exec_cpu_affinity (process))
5308+
if (! has_exec_cpu_affinity (cpu_affinity))
53065309
{
53075310
ret = libcrun_reset_cpu_affinity_mask (pid, err);
53085311
if (UNLIKELY (ret < 0))
@@ -5336,9 +5339,9 @@ join_process_parent_helper (libcrun_context_t *context,
53365339
return ret;
53375340
}
53385341

5339-
if (process && process->exec_cpu_affinity)
5342+
if (cpu_affinity)
53405343
{
5341-
ret = libcrun_set_cpu_affinity_from_string (pid, process->exec_cpu_affinity->final, err);
5344+
ret = libcrun_set_cpu_affinity_from_string (pid, cpu_affinity->final, err);
53425345
if (UNLIKELY (ret < 0))
53435346
return ret;
53445347
}

tests/test_exec.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,66 @@ def exec_and_get_affinity_mask(cid, exec_cpu_affinity=None):
477477
shutil.rmtree(tempdir)
478478
return 0
479479

480+
def test_exec_cpu_affinity_config_file():
481+
"""Test that exec honors execCPUAffinity from container configuration when not specified in exec process"""
482+
if len(os.sched_getaffinity(0)) < 4:
483+
return 77
484+
485+
conf = base_config()
486+
conf['process']['args'] = ['/init', 'pause']
487+
# Set execCPUAffinity in the container's main process configuration
488+
conf['process']['execCPUAffinity'] = {"initial": "0-1", "final": "0-2"}
489+
add_all_namespaces(conf)
490+
cid = None
491+
tempdir = tempfile.mkdtemp()
492+
493+
def cpu_mask_from_proc_status(status):
494+
for l in status.split("\n"):
495+
parts = l.split(":")
496+
if parts[0] == "Cpus_allowed_list":
497+
return parts[1].strip()
498+
return ""
499+
500+
def exec_without_cpu_affinity_and_get_mask(cid):
501+
"""Execute a process without specifying execCPUAffinity and get its CPU mask"""
502+
process_file = os.path.join(tempdir, "process.json")
503+
with open(process_file, "w") as f:
504+
process = {
505+
"user": {
506+
"uid": 0,
507+
"gid": 0
508+
},
509+
"terminal": False,
510+
"cwd": "/",
511+
"args": [
512+
"/init",
513+
"cat",
514+
"/proc/self/status"
515+
]
516+
# Note: No execCPUAffinity specified here - should fall back to container config
517+
}
518+
json.dump(process, f)
519+
520+
out = run_crun_command(["exec", "--process", process_file, cid])
521+
return cpu_mask_from_proc_status(out)
522+
523+
try:
524+
_, cid = run_and_get_output(conf, command='run', detach=True)
525+
526+
# Execute without specifying execCPUAffinity - should use container's config final value
527+
mask = exec_without_cpu_affinity_and_get_mask(cid)
528+
if mask != "0-2":
529+
sys.stderr.write("# execCPUAffinity fallback test failed: cpu mask %s != 0-2\n" % mask)
530+
sys.stderr.write("# expected to use container's execCPUAffinity.final value\n")
531+
return -1
532+
533+
return 0
534+
finally:
535+
if cid is not None:
536+
run_crun_command(["delete", "-f", cid])
537+
shutil.rmtree(tempdir)
538+
return 0
539+
480540
def test_exec_getpgrp():
481541
conf = base_config()
482542
add_all_namespaces(conf)
@@ -695,6 +755,7 @@ def test_exec_exit_code():
695755
"exec_populate_home_env_from_process_uid" : test_exec_populate_home_env_from_process_uid,
696756
"exec-test-uid-tty": test_uid_tty,
697757
"exec-cpu-affinity": test_exec_cpu_affinity,
758+
"exec-cpu-affinity-config-file": test_exec_cpu_affinity_config_file,
698759
"exec-getpgrp": test_exec_getpgrp,
699760
"exec-help" : test_exec_help,
700761
"exec-error-propagation" : test_exec_error_propagation,

0 commit comments

Comments
 (0)