Report about syntax errors with metadata

The information about the unit for which files are being parsed
is passed all the way down. This way messages land in the journal
with proper UNIT=... or USER_UNIT=... attribution.

'systemctl status' and 'journalctl -u' not displaying those messages
has been a source of confusion for users, since the journal entry for
a misspelt setting was often logged quite a bit earlier than the
failure to start a unit.
Based-on-a-patch-by: default avatarOleksii Shevchuk <alxchk@gmail.com>
parent c1b6628d
......@@ -123,7 +123,7 @@ static void parse_conf(void) {
if (!f)
return;
r = config_parse(BOOTCHART_CONF, f,
r = config_parse(NULL, BOOTCHART_CONF, f,
NULL, config_item_table_lookup, (void*) items, true, NULL);
if (r < 0)
log_warning("Failed to parse configuration file: %s", strerror(-r));
......
......@@ -198,7 +198,9 @@ int unit_load_dropin(Unit *u) {
return 0;
STRV_FOREACH(f, u->dropin_paths) {
r = config_parse(*f, NULL, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
r = config_parse(u->id, *f, NULL,
UNIT_VTABLE(u)->sections, config_item_perf_lookup,
(void*) load_fragment_gperf_lookup, false, u);
if (r < 0)
return r;
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -55,6 +55,7 @@
#include "env-util.h"
#include "hwclock.h"
#include "sd-daemon.h"
#include "sd-messages.h"
#include "mount-setup.h"
#include "loopback-setup.h"
......@@ -421,40 +422,47 @@ static int parse_proc_cmdline_word(const char *word) {
return 0;
}
#define DEFINE_SETTER(name, func) \
static int name( \
const char *filename, \
unsigned line, \
const char *section, \
const char *lvalue, \
int ltype, \
const char *rvalue, \
void *data, \
void *userdata) { \
\
assert(filename); \
assert(lvalue); \
assert(rvalue); \
\
func(rvalue); \
return 0; \
}
#define DEFINE_SETTER(name, func, descr) \
static int name(const char *unit, \
const char *filename, \
unsigned line, \
const char *section, \
const char *lvalue, \
int ltype, \
const char *rvalue, \
void *data, \
void *userdata) { \
\
int r; \
\
assert(filename); \
assert(lvalue); \
assert(rvalue); \
\
r = func(rvalue); \
if (r < 0) \
log_syntax(unit, LOG_ERR, filename, line, -r, \
"Invalid " descr "'%s': %s", \
rvalue, strerror(-r)); \
\
return 0; \
}
DEFINE_SETTER(config_parse_level2, log_set_max_level_from_string)
DEFINE_SETTER(config_parse_target, log_set_target_from_string)
DEFINE_SETTER(config_parse_color, log_show_color_from_string)
DEFINE_SETTER(config_parse_location, log_show_location_from_string)
DEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level")
DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target")
DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" )
DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location")
static int config_parse_cpu_affinity2(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
static int config_parse_cpu_affinity2(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char *w;
size_t l;
......@@ -482,7 +490,8 @@ static int config_parse_cpu_affinity2(
return log_oom();
if (r < 0 || cpu >= ncpus) {
log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue);
log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to parse CPU affinity '%s'", rvalue);
CPU_FREE(c);
return -EBADMSG;
}
......@@ -492,7 +501,7 @@ static int config_parse_cpu_affinity2(
if (c) {
if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
log_warning("Failed to set CPU affinity: %m");
log_warning_unit(unit, "Failed to set CPU affinity: %m");
CPU_FREE(c);
}
......@@ -520,15 +529,15 @@ static void free_join_controllers(void) {
arg_join_controllers = NULL;
}
static int config_parse_join_controllers(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
static int config_parse_join_controllers(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
unsigned n = 0;
char *state, *w;
......@@ -671,7 +680,7 @@ static int parse_config_file(void) {
return 0;
}
r = config_parse(fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, NULL);
r = config_parse(NULL, fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, NULL);
if (r < 0)
log_warning("Failed to parse configuration file: %s", strerror(-r));
......
......@@ -569,6 +569,8 @@ UnitActiveState unit_active_state_from_string(const char *s);
const char *unit_dependency_to_string(UnitDependency i);
UnitDependency unit_dependency_from_string(const char *s);
/* Macros which append UNIT= or USER_UNIT= to the message */
#define log_full_unit(level, unit, ...) log_meta_object(level, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__)
#define log_debug_unit(unit, ...) log_full_unit(LOG_DEBUG, unit, __VA_ARGS__)
#define log_info_unit(unit, ...) log_full_unit(LOG_INFO, unit, __VA_ARGS__)
......
......@@ -1309,7 +1309,7 @@ static int server_parse_config_file(Server *s) {
return -errno;
}
r = config_parse(fn, f, "Journal\0", config_item_perf_lookup,
r = config_parse(NULL, fn, f, "Journal\0", config_item_perf_lookup,
(void*) journald_gperf_lookup, false, s);
if (r < 0)
log_warning("Failed to parse configuration file: %s", strerror(-r));
......
......@@ -135,12 +135,12 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format,
/* gperf lookup function */
const struct ConfigPerfItem* journald_gperf_lookup(const char *key, unsigned length);
int config_parse_storage(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_storage(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
const char *storage_to_string(Storage s);
Storage storage_from_string(const char *s);
int config_parse_split_mode(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_split_mode(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
const char *split_mode_to_string(SplitMode s);
SplitMode split_mode_from_string(const char *s);
......
......@@ -21,6 +21,8 @@
#include <unistd.h>
#include <systemd/sd-messages.h>
#include "conf-parser.h"
#include "special.h"
#include "dbus-common.h"
......
......@@ -49,6 +49,6 @@ int manager_handle_action(
const char* handle_action_to_string(HandleAction h);
HandleAction handle_action_from_string(const char *s);
int config_parse_handle_action(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_handle_action(const char *unit, const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
#endif
......@@ -1689,7 +1689,7 @@ static int manager_parse_config_file(Manager *m) {
return -errno;
}
r = config_parse(fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
r = config_parse(NULL, fn, f, "Login\0", config_item_perf_lookup, (void*) logind_gperf_lookup, false, m);
if (r < 0)
log_warning("Failed to parse configuration file: %s", strerror(-r));
......
......@@ -36,3 +36,4 @@
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STARTING
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPED
.. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPING
.. autoattribute:: systemd.id128.SD_MESSAGE_CONFIG_ERROR
This diff is collapsed.
This diff is collapsed.
......@@ -921,15 +921,15 @@ static int install_info_add_auto(
return install_info_add(c, name_or_path, NULL);
}
static int config_parse_also(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
static int config_parse_also(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
char *w;
size_t l;
......@@ -956,15 +956,15 @@ static int config_parse_also(
return 0;
}
static int config_parse_user(
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
static int config_parse_user(const char *unit,
const char *filename,
unsigned line,
const char *section,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
InstallInfo *i = data;
char* printed;
......@@ -1016,7 +1016,8 @@ static int unit_file_load(
return -ENOMEM;
}
r = config_parse(path, f, NULL, config_item_table_lookup, (void*) items, true, info);
r = config_parse(NULL, path, f, NULL,
config_item_table_lookup, (void*) items, true, info);
if (r < 0)
return r;
......
......@@ -73,6 +73,8 @@ extern "C" {
#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72)
#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73)
#define SD_MESSAGE_CONFIG_ERROR SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01)
#ifdef __cplusplus
}
#endif
......
......@@ -85,13 +85,13 @@ static void test_config_parse_exec(void) {
ExecCommand *c = NULL, *c1;
/* basic test */
r = config_parse_exec("fake", 1, "section",
r = config_parse_exec(NULL, "fake", 1, "section",
"LValue", 0, "/RValue r1",
&c, NULL);
assert_se(r >= 0);
check_execcommand(c, "/RValue", "/RValue", "r1", false);
r = config_parse_exec("fake", 2, "section",
r = config_parse_exec(NULL, "fake", 2, "section",
"LValue", 0, "/RValue///slashes/// r1",
&c, NULL);
/* test slashes */
......@@ -101,7 +101,7 @@ static void test_config_parse_exec(void) {
"r1", false);
/* honour_argv0 */
r = config_parse_exec("fake", 3, "section",
r = config_parse_exec(NULL, "fake", 3, "section",
"LValue", 0, "@/RValue///slashes2/// argv0 r1",
&c, NULL);
assert_se(r >= 0);
......@@ -109,7 +109,7 @@ static void test_config_parse_exec(void) {
check_execcommand(c1, "/RValue/slashes2", "argv0", "r1", false);
/* ignore && honour_argv0 */
r = config_parse_exec("fake", 4, "section",
r = config_parse_exec(NULL, "fake", 4, "section",
"LValue", 0, "-@/RValue///slashes3/// argv0a r1",
&c, NULL);
assert_se(r >= 0);
......@@ -118,7 +118,7 @@ static void test_config_parse_exec(void) {
"/RValue/slashes3", "argv0a", "r1", true);
/* ignore && honour_argv0 */
r = config_parse_exec("fake", 4, "section",
r = config_parse_exec(NULL, "fake", 4, "section",
"LValue", 0, "@-/RValue///slashes4/// argv0b r1",
&c, NULL);
assert_se(r >= 0);
......@@ -127,21 +127,21 @@ static void test_config_parse_exec(void) {
"/RValue/slashes4", "argv0b", "r1", true);
/* ignore && ignore */
r = config_parse_exec("fake", 4, "section",
r = config_parse_exec(NULL, "fake", 4, "section",
"LValue", 0, "--/RValue argv0 r1",
&c, NULL);
assert_se(r == 0);
assert_se(c1->command_next == NULL);
/* ignore && ignore */
r = config_parse_exec("fake", 4, "section",
r = config_parse_exec(NULL, "fake", 4, "section",
"LValue", 0, "-@-/RValue argv0 r1",
&c, NULL);
assert_se(r == 0);
assert_se(c1->command_next == NULL);
/* semicolon */
r = config_parse_exec("fake", 5, "section",
r = config_parse_exec(NULL, "fake", 5, "section",
"LValue", 0,
"-@/RValue argv0 r1 ; "
"/goo/goo boo",
......@@ -156,7 +156,7 @@ static void test_config_parse_exec(void) {
"/goo/goo", "/goo/goo", "boo", false);
/* trailing semicolon */
r = config_parse_exec("fake", 5, "section",
r = config_parse_exec(NULL, "fake", 5, "section",
"LValue", 0,
"-@/RValue argv0 r1 ; ",
&c, NULL);
......@@ -168,7 +168,7 @@ static void test_config_parse_exec(void) {
assert_se(c1->command_next == NULL);
/* escaped semicolon */
r = config_parse_exec("fake", 5, "section",
r = config_parse_exec(NULL, "fake", 5, "section",
"LValue", 0,
"/usr/bin/find \\;",
&c, NULL);
......
......@@ -275,7 +275,7 @@ static int parse_password(const char *filename, char **wall) {
return -errno;
}
r = config_parse(filename, f, NULL, config_item_table_lookup, (void*) items, true, NULL);
r = config_parse(NULL, filename, f, NULL, config_item_table_lookup, (void*) items, true, NULL);
if (r < 0) {
log_error("Failed to parse password file %s: %s", filename, strerror(-r));
goto finish;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment