diff --git a/src/libcrun/linux.c b/src/libcrun/linux.c index 2ed8ca2c49..885ccd3a8e 100644 --- a/src/libcrun/linux.c +++ b/src/libcrun/linux.c @@ -3442,6 +3442,17 @@ validate_sysctl (const char *original_key, const char *original_value, const cha return crun_make_error (err, 0, "the sysctl `%s` requires a new %s namespace", original_key, namespace); } +/* Best-effort attempt to give a better explanation why setting a sysctl could have failed. */ +static char * +sysctl_error_reason (const runtime_spec_schema_config_schema *def, const char *name, const char *value, int namespaces_created, int errno_) +{ + + if (strcmp (name, "net.ipv4.ping_group_range") == 0 && (errno_ == EINVAL) && (namespaces_created & CLONE_NEWUSER)) + return xstrdup ("are all the group IDs mapped in the user namespace?"); + + return NULL; +} + int libcrun_set_sysctl (libcrun_container_t *container, libcrun_error_t *err) { @@ -3491,7 +3502,12 @@ libcrun_set_sysctl (libcrun_container_t *container, libcrun_error_t *err) ret = TEMP_FAILURE_RETRY (write (fd, def->linux->sysctl->values[i], strlen (def->linux->sysctl->values[i]))); if (UNLIKELY (ret < 0)) - return crun_make_error (err, errno, "write to `/proc/sys/%s`", name); + { + cleanup_free char *reason = NULL; + + reason = sysctl_error_reason (def, def->linux->sysctl->keys[i], def->linux->sysctl->values[i], namespaces_created, errno); + return crun_make_error (err, errno, "write to `/proc/sys/%s`%s%s%s", name, reason ? " (" : "", reason ?: "", reason ? ")" : ""); + } } return 0; }