chiark / gitweb /
log: add an "error" parameter to all low-level logging calls and intrdouce log_error_...
authorLennart Poettering <lennart@poettering.net>
Thu, 27 Nov 2014 18:48:02 +0000 (19:48 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 27 Nov 2014 21:05:23 +0000 (22:05 +0100)
This change has two benefits:

- The format string %m will now resolve to the specified error (or to
  errno if the specified error is 0. This allows getting rid of a ton of
  strerror() invocations, a function that is not thread-safe.

- The specified error can be passed to the journal in the ERRNO= field.

Now of course, we just need somebody to convert all cases of this:

        log_error("Something happened: %s", strerror(-r));

into thus:

        log_error_errno(-r, "Something happened: %m");

21 files changed:
src/core/kmod-setup.c
src/core/selinux-access.c
src/core/unit.h
src/journal-remote/microhttpd-util.c
src/libsystemd-network/dhcp-internal.h
src/libsystemd-network/dhcp-server-internal.h
src/libsystemd-network/dhcp6-internal.h
src/libsystemd-network/ipv4ll-internal.h
src/libsystemd-network/sd-icmp6-nd.c
src/modules-load/modules-load.c
src/network/networkd-ipv4ll.c
src/network/networkd-link.h
src/network/networkd-netdev.c
src/network/networkd-netdev.h
src/network/networkd.h
src/shared/conf-parser.c
src/shared/conf-parser.h
src/shared/log.c
src/shared/log.h
src/test/test-hostname.c
src/udev/udev-builtin-kmod.c

index 4795a47..50af793 100644 (file)
@@ -44,7 +44,7 @@ static void systemd_kmod_log(
 
         /* library logging is enabled at debug only */
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        log_metav(LOG_DEBUG, file, line, fn, format, args);
+        log_metav(LOG_DEBUG, 0, file, line, fn, format, args);
         REENABLE_WARNING;
 }
 
index a50dec3..b3835d5 100644 (file)
@@ -112,7 +112,7 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
 #endif
 
         va_start(ap, fmt);
-        log_metav(LOG_USER | LOG_INFO, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
+        log_metav(LOG_USER | LOG_INFO, 0, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
         va_end(ap);
 
         return 0;
index 8b24272..54ba11a 100644 (file)
@@ -596,7 +596,9 @@ UnitActiveState unit_active_state_from_string(const char *s) _pure_;
 
 /* 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_full_unit(level, unit, ...) log_meta_object(level, 0, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__)
+#define log_full_unit_errno(level, error, unit, ...) log_meta_object(level, error, __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__)
 #define log_notice_unit(unit, ...)      log_full_unit(LOG_NOTICE, unit, __VA_ARGS__)
index 55c45f4..bec4134 100644 (file)
@@ -41,7 +41,7 @@ void microhttpd_logger(void *arg, const char *fmt, va_list ap) {
         f = strappenda("microhttpd: ", fmt);
 
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        log_metav(LOG_INFO, NULL, 0, NULL, f, ap);
+        log_metav(LOG_INFO, 0, NULL, 0, NULL, f, ap);
         REENABLE_WARNING;
 }
 
@@ -126,11 +126,10 @@ void log_func_gnutls(int level, const char *message) {
 
         if (0 <= level && level < (int) ELEMENTSOF(gnutls_log_map)) {
                 if (gnutls_log_map[level].enabled)
-                        log_meta(gnutls_log_map[level].level, NULL, 0, NULL,
-                                 "gnutls %d/%s: %s", level, gnutls_log_map[level].names[1], message);
+                        log_meta(gnutls_log_map[level].level, 0, NULL, 0, NULL, "gnutls %d/%s: %s", level, gnutls_log_map[level].names[1], message);
         } else {
                 log_debug("Received GNUTLS message with unknown level %d.", level);
-                log_meta(LOG_DEBUG, NULL, 0, NULL, "gnutls: %s", message);
+                log_meta(LOG_DEBUG, 0, NULL, 0, NULL, "gnutls: %s", message);
         }
 }
 
index d358a49..d76d0c2 100644 (file)
@@ -71,4 +71,4 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_unref);
 #define DHCP_CLIENT_DONT_DESTROY(client) \
         _cleanup_dhcp_client_unref_ _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
 
-#define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
+#define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)
index 480da22..6c2c248 100644 (file)
@@ -79,7 +79,7 @@ typedef struct DHCPRequest {
 DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_server*, sd_dhcp_server_unref);
 #define _cleanup_dhcp_server_unref_ _cleanup_(sd_dhcp_server_unrefp)
 
-#define log_dhcp_server(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
+#define log_dhcp_server(client, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCP SERVER: " fmt, ##__VA_ARGS__)
 
 int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message,
                                size_t length);
index 6cc0aa8..3737d49 100644 (file)
@@ -56,7 +56,7 @@ struct DHCP6IA {
 
 typedef struct DHCP6IA DHCP6IA;
 
-#define log_dhcp6_client(p, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
+#define log_dhcp6_client(p, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "DHCPv6 CLIENT: " fmt, ##__VA_ARGS__)
 
 int dhcp_network_icmp6_bind_router_solicitation(int index);
 int dhcp_network_icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
index fe5ef8e..7b5d372 100644 (file)
@@ -35,4 +35,4 @@ void arp_packet_probe(struct ether_arp *arp, be32_t pa, const struct ether_addr
 void arp_packet_announcement(struct ether_arp *arp, be32_t pa, const struct ether_addr *ha);
 int arp_packet_verify_headers(struct ether_arp *arp);
 
-#define log_ipv4ll(ll, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "IPv4LL: " fmt, ##__VA_ARGS__)
+#define log_ipv4ll(ll, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "IPv4LL: " fmt, ##__VA_ARGS__)
index 2473fbb..23f5682 100644 (file)
@@ -54,7 +54,7 @@ struct sd_icmp6_nd {
         void *userdata;
 };
 
-#define log_icmp6_nd(p, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__)
+#define log_icmp6_nd(p, fmt, ...) log_meta(LOG_DEBUG, 0, __FILE__, __LINE__, __func__, "ICMPv6 CLIENT: " fmt, ##__VA_ARGS__)
 
 static void icmp6_nd_notify(sd_icmp6_nd *nd, int event)
 {
index c676fd1..da67247 100644 (file)
@@ -44,7 +44,7 @@ static void systemd_kmod_log(void *data, int priority, const char *file, int lin
                              const char *fn, const char *format, va_list args) {
 
         DISABLE_WARNING_FORMAT_NONLITERAL;
-        log_metav(priority, file, line, fn, format, args);
+        log_metav(priority, 0, file, line, fn, format, args);
         REENABLE_WARNING;
 }
 
index 5467bc3..fd55f79 100644 (file)
@@ -40,8 +40,7 @@ static int ipv4ll_address_lost(Link *link) {
         if (r < 0)
                 return 0;
 
-        log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u",
-                       ADDRESS_FMT_VAL(addr));
+        log_debug_link(link, "IPv4 link-local release %u.%u.%u.%u", ADDRESS_FMT_VAL(addr));
 
         r = address_new_dynamic(&address);
         if (r < 0) {
index 7acf404..5eb4b88 100644 (file)
@@ -132,7 +132,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref);
 
 /* Macros which append INTERFACE= to the message */
 
-#define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
+#define log_full_link(level, link, fmt, ...) log_meta_object(level, 0, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
 #define log_debug_link(link, ...)       log_full_link(LOG_DEBUG, link, ##__VA_ARGS__)
 #define log_info_link(link, ...)        log_full_link(LOG_INFO, link, ##__VA_ARGS__)
 #define log_notice_link(link, ...)      log_full_link(LOG_NOTICE, link, ##__VA_ARGS__)
index fd1f51e..bdb0b88 100644 (file)
@@ -65,7 +65,6 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
 DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
 
-
 static void netdev_cancel_callbacks(NetDev *netdev) {
         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
         netdev_join_callback *callback;
index a6fad2d..54339ae 100644 (file)
@@ -192,7 +192,7 @@ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsign
 
 /* Macros which append INTERFACE= to the message */
 
-#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__)
+#define log_full_netdev(level, netdev, fmt, ...) log_meta_object(level, 0, __FILE__, __LINE__, __func__, "INTERFACE=", netdev->ifname, "%-*s: " fmt, IFNAMSIZ, netdev->ifname, ##__VA_ARGS__)
 #define log_debug_netdev(netdev, ...)       log_full_netdev(LOG_DEBUG, netdev, ##__VA_ARGS__)
 #define log_info_netdev(netdev, ...)        log_full_netdev(LOG_INFO, netdev, ##__VA_ARGS__)
 #define log_notice_netdev(netdev, ...)      log_full_netdev(LOG_NOTICE, netdev, ##__VA_ARGS__)
index 19a661e..9acf31c 100644 (file)
@@ -336,7 +336,7 @@ int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union
 
 /* Macros which append INTERFACE= to the message */
 
-#define log_full_link(level, link, fmt, ...) log_meta_object(level, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
+#define log_full_link(level, link, fmt, ...) log_meta_object(level, 0, __FILE__, __LINE__, __func__, "INTERFACE=", link->ifname, "%-*s: " fmt, IFNAMSIZ, link->ifname, ##__VA_ARGS__)
 #define log_debug_link(link, ...)       log_full_link(LOG_DEBUG, link, ##__VA_ARGS__)
 #define log_info_link(link, ...)        log_full_link(LOG_INFO, link, ##__VA_ARGS__)
 #define log_notice_link(link, ...)      log_full_link(LOG_NOTICE, link, ##__VA_ARGS__)
index 027c49c..6bd9d9e 100644 (file)
 #include "exit-status.h"
 #include "sd-messages.h"
 
-int log_syntax_internal(const char *unit, int level,
-                        const char *file, unsigned line, const char *func,
-                        const char *config_file, unsigned config_line,
-                        int error, const char *format, ...) {
+int log_syntax_internal(
+                const char *unit,
+                int level,
+                const char *file,
+                int line,
+                const char *func,
+                const char *config_file,
+                unsigned config_line,
+                int error,
+                const char *format, ...) {
 
         _cleanup_free_ char *msg = NULL;
         int r;
@@ -55,21 +61,21 @@ int log_syntax_internal(const char *unit, int level,
 
         if (unit)
                 r = log_struct_internal(level,
+                                        error > 0 ? error : EINVAL,
                                         file, line, func,
                                         getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit,
                                         MESSAGE_ID(SD_MESSAGE_CONFIG_ERROR),
                                         "CONFIG_FILE=%s", config_file,
                                         "CONFIG_LINE=%u", config_line,
-                                        "ERRNO=%d", error > 0 ? error : EINVAL,
                                         "MESSAGE=[%s:%u] %s", config_file, config_line, msg,
                                         NULL);
         else
                 r = log_struct_internal(level,
+                                        error > 0 ? error : EINVAL,
                                         file, line, func,
                                         MESSAGE_ID(SD_MESSAGE_CONFIG_ERROR),
                                         "CONFIG_FILE=%s", config_file,
                                         "CONFIG_LINE=%u", config_line,
-                                        "ERRNO=%d", error > 0 ? error : EINVAL,
                                         "MESSAGE=[%s:%u] %s", config_file, config_line, msg,
                                         NULL);
 
index 69d3271..2507a44 100644 (file)
@@ -119,10 +119,16 @@ int config_parse_mode(const char *unit, const char *filename, unsigned line, con
 int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 
-int log_syntax_internal(const char *unit, int level,
-                        const char *file, unsigned line, const char *func,
-                        const char *config_file, unsigned config_line,
-                        int error, const char *format, ...) _printf_(9, 10);
+int log_syntax_internal(
+                const char *unit,
+                int level,
+                const char *file,
+                int line,
+                const char *func,
+                const char *config_file,
+                unsigned config_line,
+                int error,
+                const char *format, ...) _printf_(9, 10);
 
 #define log_syntax(unit, level, config_file, config_line, error, ...)   \
         log_syntax_internal(unit, level,                                \
index d465311..ba959b9 100644 (file)
@@ -122,7 +122,7 @@ static int create_log_socket(int type) {
                 timeval_store(&tv, 10 * USEC_PER_MSEC);
         else
                 timeval_store(&tv, 10 * USEC_PER_SEC);
-        (void)setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+        (void) setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
 
         return fd;
 }
@@ -302,10 +302,11 @@ void log_set_facility(int facility) {
 
 static int write_to_console(
                 int level,
+                int error,
                 const char*file,
                 int line,
                 const char *func,
-                const char *object_name,
+                const char *object_field,
                 const char *object,
                 const char *buffer) {
 
@@ -356,13 +357,14 @@ static int write_to_console(
 }
 
 static int write_to_syslog(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *object_name,
-        const char *object,
-        const char *buffer) {
+                int level,
+                int error,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_field,
+                const char *object,
+                const char *buffer) {
 
         char header_priority[16], header_time[64], header_pid[16];
         struct iovec iovec[5] = {};
@@ -418,13 +420,14 @@ static int write_to_syslog(
 }
 
 static int write_to_kmsg(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *object_name,
-        const char *object,
-        const char *buffer) {
+                int level,
+                int error,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_field,
+                const char *object,
+                const char *buffer) {
 
         char header_priority[16], header_pid[16];
         struct iovec iovec[5] = {};
@@ -450,45 +453,55 @@ static int write_to_kmsg(
         return 1;
 }
 
-static int log_do_header(char *header, size_t size,
-                         int level,
-                         const char *file, int line, const char *func,
-                         const char *object_name, const char *object) {
+static int log_do_header(
+                char *header,
+                size_t size,
+                int level,
+                int error,
+                const char *file, int line, const char *func,
+                const char *object_field, const char *object) {
+
         snprintf(header, size,
                  "PRIORITY=%i\n"
                  "SYSLOG_FACILITY=%i\n"
-                 "%s%.*s%s"
+                 "%s%s%s"
                  "%s%.*i%s"
-                 "%s%.*s%s"
-                 "%s%.*s%s"
+                 "%s%s%s"
+                 "%s%.*i%s"
+                 "%s%s%s"
                  "SYSLOG_IDENTIFIER=%s\n",
                  LOG_PRI(level),
                  LOG_FAC(level),
-                 file ? "CODE_FILE=" : "",
-                 file ? LINE_MAX : 0, file, /* %.0s means no output */
-                 file ? "\n" : "",
+                 isempty(file) ? "" : "CODE_FILE=",
+                 isempty(file) ? "" : file,
+                 isempty(file) ? "" : "\n",
                  line ? "CODE_LINE=" : "",
                  line ? 1 : 0, line, /* %.0d means no output too, special case for 0 */
                  line ? "\n" : "",
-                 func ? "CODE_FUNCTION=" : "",
-                 func ? LINE_MAX : 0, func,
-                 func ? "\n" : "",
-                 object ? object_name : "",
-                 object ? LINE_MAX : 0, object, /* %.0s means no output */
-                 object ? "\n" : "",
+                 isempty(func) ? "" : "CODE_FUNCTION=",
+                 isempty(func) ? "" : func,
+                 isempty(func) ? "" : "\n",
+                 error ? "ERRNO=" : "",
+                 error ? 1 : 0, error,
+                 error ? "\n" : "",
+                 isempty(object) ? "" : object_field,
+                 isempty(object) ? "" : object,
+                 isempty(object) ? "" : "\n",
                  program_invocation_short_name);
         header[size - 1] = '\0';
+
         return 0;
 }
 
 static int write_to_journal(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *object_name,
-        const char *object,
-        const char *buffer) {
+                int level,
+                int error,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_field,
+                const char *object,
+                const char *buffer) {
 
         char header[LINE_MAX];
         struct iovec iovec[4] = {};
@@ -497,8 +510,7 @@ static int write_to_journal(
         if (journal_fd < 0)
                 return 0;
 
-        log_do_header(header, sizeof(header), level,
-                      file, line, func, object_name, object);
+        log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object);
 
         IOVEC_SET_STRING(iovec[0], header);
         IOVEC_SET_STRING(iovec[1], "MESSAGE=");
@@ -515,13 +527,14 @@ static int write_to_journal(
 }
 
 static int log_dispatch(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *object_name,
-        const char *object,
-        char *buffer) {
+                int level,
+                int error,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_field,
+                const char *object,
+                char *buffer) {
 
         int r = 0;
 
@@ -548,8 +561,7 @@ static int log_dispatch(
                     log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
                     log_target == LOG_TARGET_JOURNAL) {
 
-                        k = write_to_journal(level, file, line, func,
-                                             object_name, object, buffer);
+                        k = write_to_journal(level, error, file, line, func, object_field, object, buffer);
                         if (k < 0) {
                                 if (k != -EAGAIN)
                                         log_close_journal();
@@ -561,8 +573,7 @@ static int log_dispatch(
                 if (log_target == LOG_TARGET_SYSLOG_OR_KMSG ||
                     log_target == LOG_TARGET_SYSLOG) {
 
-                        k = write_to_syslog(level, file, line, func,
-                                            object_name, object, buffer);
+                        k = write_to_syslog(level, error, file, line, func, object_field, object, buffer);
                         if (k < 0) {
                                 if (k != -EAGAIN)
                                         log_close_syslog();
@@ -578,8 +589,7 @@ static int log_dispatch(
                      log_target == LOG_TARGET_JOURNAL_OR_KMSG ||
                      log_target == LOG_TARGET_KMSG)) {
 
-                        k = write_to_kmsg(level, file, line, func,
-                                          object_name, object, buffer);
+                        k = write_to_kmsg(level, error, file, line, func, object_field, object, buffer);
                         if (k < 0) {
                                 log_close_kmsg();
                                 log_open_console();
@@ -588,8 +598,7 @@ static int log_dispatch(
                 }
 
                 if (k <= 0) {
-                        k = write_to_console(level, file, line, func,
-                                             object_name, object, buffer);
+                        k = write_to_console(level, error, file, line, func, object_field, object, buffer);
                         if (k < 0)
                                 return k;
                 }
@@ -602,6 +611,7 @@ static int log_dispatch(
 
 int log_dump_internal(
         int level,
+        int error,
         const char*file,
         int line,
         const char *func,
@@ -614,16 +624,17 @@ int log_dump_internal(
         if (_likely_(LOG_PRI(level) > log_max_level))
                 return 0;
 
-        return log_dispatch(level, file, line, func, NULL, NULL, buffer);
+        return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
 }
 
 int log_metav(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *format,
-        va_list ap) {
+                int level,
+                int error,
+                const char*file,
+                int line,
+                const char *func,
+                const char *format,
+                va_list ap) {
 
         PROTECT_ERRNO;
         char buffer[LINE_MAX];
@@ -631,38 +642,44 @@ int log_metav(
         if (_likely_(LOG_PRI(level) > log_max_level))
                 return 0;
 
+        /* Make sure that %m maps to the specified error */
+        if (error != 0)
+                errno = error;
+
         vsnprintf(buffer, sizeof(buffer), format, ap);
         char_array_0(buffer);
 
-        return log_dispatch(level, file, line, func, NULL, NULL, buffer);
+        return log_dispatch(level, error, file, line, func, NULL, NULL, buffer);
 }
 
 int log_meta(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *format, ...) {
+                int level,
+                int error,
+                const char*file,
+                int line,
+                const char *func,
+                const char *format, ...) {
 
         int r;
         va_list ap;
 
         va_start(ap, format);
-        r = log_metav(level, file, line, func, format, ap);
+        r = log_metav(level, error, file, line, func, format, ap);
         va_end(ap);
 
         return r;
 }
 
 int log_metav_object(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *object_name,
-        const char *object,
-        const char *format,
-        va_list ap) {
+                int level,
+                int error,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_field,
+                const char *object,
+                const char *format,
+                va_list ap) {
 
         PROTECT_ERRNO;
         char buffer[LINE_MAX];
@@ -670,34 +687,44 @@ int log_metav_object(
         if (_likely_(LOG_PRI(level) > log_max_level))
                 return 0;
 
+        /* Make sure that %m maps to the specified error */
+        if (error != 0)
+                errno = error;
+
         vsnprintf(buffer, sizeof(buffer), format, ap);
         char_array_0(buffer);
 
-        return log_dispatch(level, file, line, func,
-                            object_name, object, buffer);
+        return log_dispatch(level, error, file, line, func, object_field, object, buffer);
 }
 
 int log_meta_object(
-        int level,
-        const char*file,
-        int line,
-        const char *func,
-        const char *object_name,
-        const char *object,
-        const char *format, ...) {
+                int level,
+                int error,
+                const char*file,
+                int line,
+                const char *func,
+                const char *object_field,
+                const char *object,
+                const char *format, ...) {
 
         int r;
         va_list ap;
 
         va_start(ap, format);
-        r = log_metav_object(level, file, line, func,
-                             object_name, object, format, ap);
+        r = log_metav_object(level, error, file, line, func, object_field, object, format, ap);
         va_end(ap);
 
         return r;
 }
 
-static void log_assert(int level, const char *text, const char *file, int line, const char *func, const char *format) {
+static void log_assert(
+                int level,
+                const char *text,
+                const char *file,
+                int line,
+                const char *func,
+                const char *format) {
+
         static char buffer[LINE_MAX];
 
         if (_likely_(LOG_PRI(level) > log_max_level))
@@ -710,7 +737,7 @@ static void log_assert(int level, const char *text, const char *file, int line,
         char_array_0(buffer);
         log_abort_msg = buffer;
 
-        log_dispatch(level, file, line, func, NULL, NULL, buffer);
+        log_dispatch(level, 0, file, line, func, NULL, NULL, buffer);
 }
 
 noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) {
@@ -729,12 +756,13 @@ void log_assert_failed_return(const char *text, const char *file, int line, cons
 }
 
 int log_oom_internal(const char *file, int line, const char *func) {
-        log_meta(LOG_ERR, file, line, func, "Out of memory.");
+        log_meta(LOG_ERR, ENOMEM, file, line, func, "Out of memory.");
         return -ENOMEM;
 }
 
 int log_struct_internal(
                 int level,
+                int error,
                 const char *file,
                 int line,
                 const char *func,
@@ -767,8 +795,7 @@ int log_struct_internal(
                 static const char nl = '\n';
 
                 /* If the journal is available do structured logging */
-                log_do_header(header, sizeof(header), level,
-                              file, line, func, NULL, NULL);
+                log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL);
                 IOVEC_SET_STRING(iovec[n++], header);
 
                 va_start(ap, format);
@@ -840,8 +867,7 @@ int log_struct_internal(
                 va_end(ap);
 
                 if (found)
-                        r = log_dispatch(level, file, line, func,
-                                         NULL, NULL, buf + 8);
+                        r = log_dispatch(level, error, file, line, func, NULL, NULL, buf + 8);
                 else
                         r = -EINVAL;
         }
index 8141e9d..9dd68df 100644 (file)
@@ -77,44 +77,49 @@ void log_parse_environment(void);
 
 int log_meta(
                 int level,
+                int error,
                 const char*file,
                 int line,
                 const char *func,
-                const char *format, ...) _printf_(5,6);
+                const char *format, ...) _printf_(6,7);
 
 int log_metav(
                 int level,
+                int error,
                 const char*file,
                 int line,
                 const char *func,
                 const char *format,
-                va_list ap) _printf_(5,0);
+                va_list ap) _printf_(6,0);
 
 int log_meta_object(
                 int level,
+                int error,
                 const char*file,
                 int line,
                 const char *func,
                 const char *object_name,
                 const char *object,
-                const char *format, ...) _printf_(7,8);
+                const char *format, ...) _printf_(8,9);
 
 int log_metav_object(
                 int level,
+                int error,
                 const char*file,
                 int line,
                 const char *func,
                 const char *object_name,
                 const char *object,
                 const char *format,
-                va_list ap) _printf_(7,0);
+                va_list ap) _printf_(8,0);
 
 int log_struct_internal(
                 int level,
+                int error,
                 const char *file,
                 int line,
                 const char *func,
-                const char *format, ...) _printf_(5,0) _sentinel_;
+                const char *format, ...) _printf_(6,0) _sentinel_;
 
 int log_oom_internal(
                 const char *file,
@@ -124,11 +129,13 @@ int log_oom_internal(
 /* This modifies the buffer passed! */
 int log_dump_internal(
                 int level,
+                int error,
                 const char*file,
                 int line,
                 const char *func,
                 char *buffer);
 
+/* Logging for various assertions */
 noreturn void log_assert_failed(
                 const char *text,
                 const char *file,
@@ -147,12 +154,16 @@ void log_assert_failed_return(
                 int line,
                 const char *func);
 
-#define log_full(level, ...) \
-do { \
-        if (log_get_max_level() >= (level)) \
-                log_meta((level), __FILE__, __LINE__, __func__, __VA_ARGS__); \
-} while (0)
+/* Logging with level */
+#define log_full_errno(level, error, ...)                               \
+        do {                                                            \
+                if (log_get_max_level() >= (level))                     \
+                        log_meta((level), error, __FILE__, __LINE__, __func__, __VA_ARGS__); \
+        } while (false)
 
+#define log_full(level, ...) log_full_errno(level, 0, __VA_ARGS__)
+
+/* Normal logging */
 #define log_debug(...)     log_full(LOG_DEBUG,   __VA_ARGS__)
 #define log_info(...)      log_full(LOG_INFO,    __VA_ARGS__)
 #define log_notice(...)    log_full(LOG_NOTICE,  __VA_ARGS__)
@@ -160,18 +171,28 @@ do { \
 #define log_error(...)     log_full(LOG_ERR,     __VA_ARGS__)
 #define log_emergency(...) log_full(getpid() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
 
+/* Logging triggered by an errno-like error */
+#define log_debug_errno(error, ...)     log_full_errno(LOG_DEBUG,   error, __VA_ARGS__)
+#define log_info_errno(error, ...)      log_full_errno(LOG_INFO,    error, __VA_ARGS__)
+#define log_notice_errno(error, ...)    log_full_errno(LOG_NOTICE,  error, __VA_ARGS__)
+#define log_warning_errno(error, ...)   log_full_errno(LOG_WARNING, error, __VA_ARGS__)
+#define log_error_errno(error, ...)     log_full_errno(LOG_ERR,     error, __VA_ARGS__)
+#define log_emergency_errno(error, ...) log_full_errno(getpid() == 1 ? LOG_EMERG : LOG_ERR, __VA_ARGS__)
+
 #ifdef LOG_TRACE
 #  define log_trace(...) log_debug(__VA_ARGS__)
 #else
 #  define log_trace(...) do {} while(0)
 #endif
 
-#define log_struct(level, ...) log_struct_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__)
-
-#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
+/* Structured logging */
+#define log_struct(level, ...) log_struct_internal(level, 0, __FILE__, __LINE__, __func__, __VA_ARGS__)
+#define log_struct_errno(level, error, ...) log_struct_internal(level, error, __FILE__, __LINE__, __func__, __VA_ARGS__)
 
 /* This modifies the buffer passed! */
-#define log_dump(level, buffer) log_dump_internal(level, __FILE__, __LINE__, __func__, buffer)
+#define log_dump(level, buffer) log_dump_internal(level, 0, __FILE__, __LINE__, __func__, buffer)
+
+#define log_oom() log_oom_internal(__FILE__, __LINE__, __func__)
 
 bool log_on_console(void) _pure_;
 
index ad4f285..1bc4126 100644 (file)
@@ -32,7 +32,7 @@ int main(int argc, char* argv[]) {
 
         r = hostname_setup();
         if (r < 0)
-                fprintf(stderr, "hostname: %s\n", strerror(-r));
+                log_error_errno(-r, "hostname: %m");
 
         return 0;
 }
index 66807b3..f3d1647 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "udev.h"
 
-static struct kmod_ctx *ctx;
+static struct kmod_ctx *ctx = NULL;
 
 static int load_module(struct udev *udev, const char *alias) {
         struct kmod_list *list = NULL;
@@ -43,18 +43,18 @@ static int load_module(struct udev *udev, const char *alias) {
                 return err;
 
         if (list == NULL)
-                log_debug("no module matches '%s'", alias);
+                log_debug("No module matches '%s'", alias);
 
         kmod_list_foreach(l, list) {
                 struct kmod_module *mod = kmod_module_get_module(l);
 
                 err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
                 if (err == KMOD_PROBE_APPLY_BLACKLIST)
-                        log_debug("module '%s' is blacklisted", kmod_module_get_name(mod));
+                        log_debug("Module '%s' is blacklisted", kmod_module_get_name(mod));
                 else if (err == 0)
-                        log_debug("inserted '%s'", kmod_module_get_name(mod));
+                        log_debug("Inserted '%s'", kmod_module_get_name(mod));
                 else
-                        log_debug("failed to insert '%s'", kmod_module_get_name(mod));
+                        log_debug("Failed to insert '%s'", kmod_module_get_name(mod));
 
                 kmod_module_unref(mod);
         }
@@ -63,10 +63,8 @@ static int load_module(struct udev *udev, const char *alias) {
         return err;
 }
 
-_printf_(6,0)
-static void udev_kmod_log(void *data, int priority, const char *file, int line,
-                          const char *fn, const char *format, va_list args) {
-        log_metav(priority, file, line, fn, format, args);
+_printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *file, int line, const char *fn, const char *format, va_list args) {
+        log_metav(priority, 0, file, line, fn, format, args);
 }
 
 static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) {
@@ -82,7 +80,7 @@ static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool te
         }
 
         for (i = 2; argv[i]; i++) {
-                log_debug("execute '%s' '%s'", argv[1], argv[i]);
+                log_debug("Execute '%s' '%s'", argv[1], argv[i]);
                 load_module(udev, argv[i]);
         }
 
@@ -98,7 +96,7 @@ static int builtin_kmod_init(struct udev *udev) {
         if (!ctx)
                 return -ENOMEM;
 
-        log_debug("load module index");
+        log_debug("Load module index");
         kmod_set_log_fn(ctx, udev_kmod_log, udev);
         kmod_load_resources(ctx);
         return 0;
@@ -106,13 +104,13 @@ static int builtin_kmod_init(struct udev *udev) {
 
 /* called on udev shutdown and reload request */
 static void builtin_kmod_exit(struct udev *udev) {
-        log_debug("unload module index");
+        log_debug("Unload module index");
         ctx = kmod_unref(ctx);
 }
 
 /* called every couple of seconds during event activity; 'true' if config has changed */
 static bool builtin_kmod_validate(struct udev *udev) {
-        log_debug("validate module index");
+        log_debug("Validate module index");
         if (!ctx)
                 return false;
         return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK);