From: Lennart Poettering Date: Tue, 7 Jan 2025 13:24:33 +0000 (+0100) Subject: json-util: fine tune json_dispatch_log_level() X-Git-Tag: v258-rc1~1559^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa3137f9d05a9574d795bd0db7ba3abc595f06c4;p=thirdparty%2Fsystemd.git json-util: fine tune json_dispatch_log_level() Let's give the user control on how to handle JSON "null" assignments of the log level. As one of three cases: as failure, as LOG_NULL (i.e. to turn off logging) or as LOG_INFO (as our usual default log level). Let's then use that in the generic SetLogLevel() call, so that callers can use it to explicitly turn off logging in a service. Note that this was (probably accidentally) already implemented, except that the introspection enforcement blocked it. Let's clean this up and make this officially a thing, since it's generally useful to turn off logging I think. --- diff --git a/src/basic/log.h b/src/basic/log.h index 3859a6c41de..02f3f509d18 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -34,6 +34,7 @@ typedef enum LogTarget{ /* This log level disables logging completely. It can only be passed to log_set_max_level() and cannot be * used as a regular log level. */ #define LOG_NULL (LOG_EMERG - 1) +assert_cc(LOG_NULL == -1); #define SYNTHETIC_ERRNO(num) (abs(num) | (1 << 30)) #define IS_SYNTHETIC_ERRNO(val) (((val) >> 30) == 1) diff --git a/src/libsystemd/sd-json/json-util.c b/src/libsystemd/sd-json/json-util.c index ea64205c14e..b7990411ea8 100644 --- a/src/libsystemd/sd-json/json-util.c +++ b/src/libsystemd/sd-json/json-util.c @@ -344,8 +344,15 @@ int json_dispatch_ifindex(const char *name, sd_json_variant *variant, sd_json_di int json_dispatch_log_level(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) { int *log_level = ASSERT_PTR(userdata), r, t; + /* If SD_JSON_STRICT is set, we'll refuse attempts to set the log level to null. If SD_JSON_RELAX is + * set we'll turn null (and any negative log level) into LOG_NULL (which when used as max log level + * means: no logging). Otherwise we turn null into LOG_INFO (which is typically our default). */ + if (sd_json_variant_is_null(variant)) { - *log_level = -1; + if (FLAGS_SET(flags, SD_JSON_STRICT)) + return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' may not be null.", strna(name)); + + *log_level = FLAGS_SET(flags, SD_JSON_RELAX) ? LOG_NULL : LOG_INFO; return 0; } @@ -353,8 +360,9 @@ int json_dispatch_log_level(const char *name, sd_json_variant *variant, sd_json_ if (r < 0) return r; - /* If SD_JSON_RELAX is set allow a zero interface index, otherwise refuse. */ - if (LOG_PRI(t) != t) + if (FLAGS_SET(flags, SD_JSON_RELAX) && t < 0) + t = LOG_NULL; + else if (LOG_PRI(t) != t) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid log level.", strna(name)); *log_level = t; diff --git a/src/shared/varlink-io.systemd.service.c b/src/shared/varlink-io.systemd.service.c index f34d5cfead6..d029fda41ba 100644 --- a/src/shared/varlink-io.systemd.service.c +++ b/src/shared/varlink-io.systemd.service.c @@ -11,8 +11,8 @@ static SD_VARLINK_DEFINE_METHOD(Reload); static SD_VARLINK_DEFINE_METHOD( SetLogLevel, - SD_VARLINK_FIELD_COMMENT("The maximum log level."), - SD_VARLINK_DEFINE_INPUT(level, SD_VARLINK_INT, 0)); + SD_VARLINK_FIELD_COMMENT("The maximum log level, using BSD syslog log level integers."), + SD_VARLINK_DEFINE_INPUT(level, SD_VARLINK_INT, SD_VARLINK_NULLABLE)); SD_VARLINK_DEFINE_INTERFACE( io_systemd_service,