diff --git a/src/core/varlink-unit.c b/src/core/varlink-unit.c index 964efa3534..c90ff987e8 100644 --- a/src/core/varlink-unit.c +++ b/src/core/varlink-unit.c @@ -753,7 +753,8 @@ typedef struct StartTransientContextParameters { const char *description; TransientExecContextParameters exec; TransientServiceParameters service; - const char *bad_exec_field; /* Set by inner Exec dispatcher to the unknown sub-property name */ + const char *bad_exec_field; /* Set by inner Exec dispatcher to the unknown sub-property name */ + const char *bad_service_field; } StartTransientContextParameters; static void start_transient_context_parameters_done(StartTransientContextParameters *p) { @@ -885,7 +886,7 @@ static int dispatch_transient_service(const char *name, sd_json_variant *variant StartTransientContextParameters *p = ASSERT_PTR(userdata); p->service.present = true; - return sd_json_dispatch(variant, service_dispatch, /* flags= */ 0, &p->service); + return sd_json_dispatch_full(variant, service_dispatch, /* bad= */ NULL, /* flags= */ 0, &p->service, &p->bad_service_field); } static int dispatch_transient_context(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) { @@ -911,6 +912,8 @@ static int dispatch_transient_context(const char *name, sd_json_variant *variant * actual sub-property. */ if (streq(bad_field, "Exec") && !isempty(p->context.bad_exec_field)) p->unsupported_property = strjoin("Exec.", p->context.bad_exec_field); + else if (streq(bad_field, "Service") && !isempty(p->context.bad_service_field)) + p->unsupported_property = strjoin("Service.", p->context.bad_service_field); else p->unsupported_property = strdup(bad_field); if (!p->unsupported_property) diff --git a/test/units/TEST-26-SYSTEMCTL.sh b/test/units/TEST-26-SYSTEMCTL.sh index a98ef7646d..d489cc3ec8 100755 --- a/test/units/TEST-26-SYSTEMCTL.sh +++ b/test/units/TEST-26-SYSTEMCTL.sh @@ -690,8 +690,17 @@ varlinkctl call "$MANAGER_SOCKET" io.systemd.Unit.StartTransient \ '{"context":{"ID":"varlink-transient-exec.slice","Exec":{"WorkingDirectory":{"path":"/tmp","missingOK":false}}}}' |& grep "io.systemd.Unit.UnitTypeNotSupported" # Unknown field in Exec is rejected as PropertyNotSupported defer_transient_cleanup varlink-transient-unknown-exec.service -varlinkctl call "$MANAGER_SOCKET" io.systemd.Unit.StartTransient \ - '{"context":{"ID":"varlink-transient-unknown-exec.service","Exec":{"RootDirectory":"/tmp"},"Service":{"Type":"oneshot","ExecStart":[{"path":"/bin/true"}]}}}' |& grep "io.systemd.Unit.PropertyNotSupported" +unsupported_exec=$(varlinkctl call "$MANAGER_SOCKET" io.systemd.Unit.StartTransient \ + '{"context":{"ID":"varlink-transient-unknown-exec.service","Exec":{"RootDirectory":"/tmp"},"Service":{"Type":"oneshot","ExecStart":[{"path":"/bin/true"}]}}}' 2>&1 || true) +echo "$unsupported_exec" | grep "io.systemd.Unit.PropertyNotSupported" +echo "$unsupported_exec" | grep "Exec.RootDirectory" +# Service field declared in the IDL but not yet settable at creation is rejected as PropertyNotSupported, +# and the offending sub-property is identified +defer_transient_cleanup varlink-transient-unknown-service.service +unsupported_service=$(varlinkctl call "$MANAGER_SOCKET" io.systemd.Unit.StartTransient \ + '{"context":{"ID":"varlink-transient-unknown-service.service","Service":{"Type":"oneshot","Restart":"always","ExecStart":[{"path":"/bin/true"}]}}}' 2>&1 || true) +echo "$unsupported_service" | grep "io.systemd.Unit.PropertyNotSupported" +echo "$unsupported_service" | grep "Service.Restart" set -o pipefail transient_cleanup