[systemd-commits] 6 commits - src/bootchart src/core src/fsck src/journal src/libsystemd-bus src/shared src/systemctl units/local-fs.target

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Mon Apr 1 20:52:21 PDT 2013


 src/bootchart/svg.c             |   19 +---
 src/core/dbus-socket.c          |   62 ++++++++++++++
 src/core/dbus-unit.c            |    1 
 src/core/dbus-unit.h            |    1 
 src/core/load-dropin.c          |   60 +++++++++----
 src/core/load-dropin.h          |    1 
 src/core/socket.c               |   22 +++++
 src/core/socket.h               |    2 
 src/core/unit.c                 |   32 +++++++
 src/core/unit.h                 |    2 
 src/fsck/fsck.c                 |   13 --
 src/journal/journal-file.c      |    2 
 src/libsystemd-bus/bus-socket.c |    2 
 src/shared/cgroup-show.c        |    9 --
 src/shared/macro.h              |   26 ++---
 src/shared/prioq.c              |    2 
 src/shared/util.c               |    2 
 src/systemctl/systemctl.c       |  176 +++++++++++++++++++++++++---------------
 units/local-fs.target           |    2 
 19 files changed, 307 insertions(+), 129 deletions(-)

New commits:
commit ae7a7182da31371555fceb2aed609e40a64b900a
Author: Oleksii Shevchuk <alxchk at gmail.com>
Date:   Mon Apr 1 13:32:35 2013 +0300

    Introspect and monitor dropin configuration

diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index dc7d1f1..f413386 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -1284,6 +1284,7 @@ const BusProperty bus_unit_properties[] = {
         { "SubState",             bus_unit_append_sub_state,          "s", 0 },
         { "FragmentPath",         bus_property_append_string,         "s", offsetof(Unit, fragment_path),                              true },
         { "SourcePath",           bus_property_append_string,         "s", offsetof(Unit, source_path),                                true },
+        { "DropinPaths",          bus_property_append_strv,          "as", offsetof(Unit, dropin_paths),                               true },
         { "UnitFileState",        bus_unit_append_file_state,         "s", 0 },
         { "InactiveExitTimestamp",bus_property_append_usec,           "t", offsetof(Unit, inactive_exit_timestamp.realtime)   },
         { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic)  },
diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h
index 34980b0..e4c5666 100644
--- a/src/core/dbus-unit.h
+++ b/src/core/dbus-unit.h
@@ -88,6 +88,7 @@
         "  <property name=\"RequiresMountsFor\" type=\"as\" access=\"read\"/>\n" \
         "  <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"SourcePath\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"DropinPaths\" type=\"as\" access=\"read\"/>\n" \
         "  <property name=\"Documentation\" type=\"as\" access=\"read\"/>\n" \
         "  <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index 95c9a38..942ad02 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -137,12 +137,44 @@ static int process_dir(Unit *u, const char *unit_path, const char *name, const c
         return 0;
 }
 
-int unit_load_dropin(Unit *u) {
+char **unit_find_dropin_paths(Unit *u) {
         Iterator i;
         char *t;
         _cleanup_strv_free_ char **strv = NULL;
+        char **configs = NULL;
         int r;
 
+        assert(u);
+
+        SET_FOREACH(t, u->names, i) {
+                char **p;
+
+                STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
+                        /* This loads the drop-in config snippets */
+                        r = process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
+                        if (r < 0)
+                                return NULL;
+                }
+        }
+
+        if (!strv_isempty(strv)) {
+                r = conf_files_list_strv(&configs, ".conf", NULL, (const char**) strv);
+                if (r < 0) {
+                        log_error("Failed to get list of configuration files: %s", strerror(-r));
+                        strv_free(configs);
+                        return NULL;
+                }
+
+        }
+
+        return configs;
+}
+
+int unit_load_dropin(Unit *u) {
+        Iterator i;
+        char *t, **f;
+        _cleanup_strv_free_ char **strv = NULL;
+        int r;
 
         assert(u);
 
@@ -159,30 +191,20 @@ int unit_load_dropin(Unit *u) {
                         r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES, NULL);
                         if (r < 0)
                                 return r;
-
-                        /* This loads the drop-in config snippets */
-                        r = process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
-                        if (r < 0)
-                                return r;
                 }
         }
 
-        if (!strv_isempty(strv)) {
-                _cleanup_strv_free_ char **files = NULL;
-                char **f;
+        u->dropin_paths = unit_find_dropin_paths(u);
+        if (! u->dropin_paths)
+                return 0;
 
-                r = conf_files_list_strv(&files, ".conf", NULL, (const char**) strv);
-                if (r < 0) {
-                        log_error("Failed to get list of configuration files: %s", strerror(-r));
+        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);
+                if (r < 0)
                         return r;
-                }
-
-                STRV_FOREACH(f, files) {
-                        r = config_parse(*f, NULL, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u);
-                        if (r < 0)
-                                return r;
-                }
         }
 
+        u->dropin_mtime = now(CLOCK_REALTIME);
+
         return 0;
 }
diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h
index 1d2fafe..fd55117 100644
--- a/src/core/load-dropin.h
+++ b/src/core/load-dropin.h
@@ -25,4 +25,5 @@
 
 /* Read service data supplementary drop-in directories */
 
+char **unit_find_dropin_paths(Unit *u);
 int unit_load_dropin(Unit *u);
diff --git a/src/core/unit.c b/src/core/unit.c
index 7111679..75a49d5 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -408,6 +408,7 @@ void unit_free(Unit *u) {
         strv_free(u->documentation);
         free(u->fragment_path);
         free(u->source_path);
+        strv_free(u->dropin_paths);
         free(u->instance);
 
         set_free_free(u->names);
@@ -696,6 +697,9 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
         if (u->source_path)
                 fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
 
+        STRV_FOREACH(j, u->dropin_paths)
+                fprintf(f, "%s\tDropin Path: %s\n", prefix, *j);
+
         if (u->job_timeout > 0)
                 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout));
 
@@ -2553,7 +2557,10 @@ void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg
 }
 
 bool unit_need_daemon_reload(Unit *u) {
+        _cleanup_strv_free_ char **t = NULL;
+        char **path;
         struct stat st;
+        unsigned loaded_cnt, current_cnt;
 
         assert(u);
 
@@ -2578,7 +2585,30 @@ bool unit_need_daemon_reload(Unit *u) {
                         return true;
         }
 
-        return false;
+        t = unit_find_dropin_paths(u);
+        loaded_cnt = strv_length(t);
+        current_cnt = strv_length(u->dropin_paths);
+
+        if (loaded_cnt == current_cnt) {
+                if (loaded_cnt == 0)
+                        return false;
+
+                if (strv_overlap(u->dropin_paths, t)) {
+                        STRV_FOREACH(path, u->dropin_paths) {
+                                zero(st);
+                                if (stat(*path, &st) < 0)
+                                        return true;
+
+                                if (u->dropin_mtime > 0 &&
+                                    timespec_load(&st.st_mtim) > u->dropin_mtime)
+                                        return true;
+                        }
+
+                        return false;
+                } else
+                        return true;
+        } else
+                return true;
 }
 
 void unit_reset_failed(Unit *u) {
diff --git a/src/core/unit.h b/src/core/unit.h
index 3da6a50..80a96e8 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -138,8 +138,10 @@ struct Unit {
 
         char *fragment_path; /* if loaded from a config file this is the primary path to it */
         char *source_path; /* if converted, the source file */
+        char **dropin_paths;
         usec_t fragment_mtime;
         usec_t source_mtime;
+        usec_t dropin_mtime;
 
         /* If there is something to do with this unit, then this is the installed job for it */
         Job *job;

commit 050fbdb8787fb9e3f4491189cbb0fd1d130fe234
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Apr 1 23:11:54 2013 -0400

    shared/cgroup-show: fix leak of "pid"

diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c
index 2f2669f..966af5e 100644
--- a/src/shared/cgroup-show.c
+++ b/src/shared/cgroup-show.c
@@ -282,7 +282,7 @@ int show_cgroup(const char *controller, const char *path, const char *prefix, un
 }
 
 static int show_extra_pids(const char *controller, const char *path, const char *prefix, unsigned n_columns, const pid_t pids[], unsigned n_pids, OutputFlags flags) {
-        pid_t *copy;
+        pid_t _cleanup_free_ *copy = NULL;
         unsigned i, j;
         int r;
 
@@ -303,13 +303,11 @@ static int show_extra_pids(const char *controller, const char *path, const char
                 return -ENOMEM;
 
         for (i = 0, j = 0; i < n_pids; i++) {
-                char *k;
+                char _cleanup_free_ *k = NULL;
 
                 r = cg_get_by_pid(controller, pids[i], &k);
-                if (r < 0) {
-                        free(copy);
+                if (r < 0)
                         return r;
-                }
 
                 if (path_startswith(k, path))
                         continue;
@@ -319,7 +317,6 @@ static int show_extra_pids(const char *controller, const char *path, const char
 
         show_pid_array(copy, j, prefix, n_columns, true, false, false, flags);
 
-        free(copy);
         return 0;
 }
 

commit 131601349515f05b50fec4821ede38f5037ec9f4
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Apr 1 23:09:35 2013 -0400

    systemctl: align all status fields to common column
    
    avahi-daemon.socket - Avahi mDNS/DNS-SD Stack Activation Socket
           Loaded: loaded (/usr/lib/systemd/system/avahi-daemon.socket; enabled)
           Active: active (listening) since Mon 2013-04-01 09:02:44 EDT; 14h ago
     ListenStream: /var/run/avahi-daemon/socket

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 4f4d334..323521a 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2255,6 +2255,7 @@ typedef struct UnitStatusInfo {
         unsigned n_connections;
         bool accept;
 
+        /* Pairs of type, path */
         char **listen;
 
         /* Device */
@@ -2282,9 +2283,20 @@ static void print_status_info(UnitStatusInfo *i) {
                 on_tty() * OUTPUT_COLOR |
                 !arg_quiet * OUTPUT_WARN_CUTOFF |
                 arg_full * OUTPUT_FULL_WIDTH;
+        int maxlen = 8; /* a value that'll suffice most of the time */
+        char **t, **t2;
 
         assert(i);
 
+        STRV_FOREACH_PAIR(t, t2, i->listen)
+                maxlen = MAX(maxlen, (int)(sizeof("Listen") - 1 + strlen(*t)));
+        if (i->accept)
+                maxlen = MAX(maxlen, (int)sizeof("Accept") - 1);
+        if (i->main_pid > 0)
+                maxlen = MAX(maxlen, (int)sizeof("Main PID") - 1);
+        else if (i->control_pid > 0)
+                maxlen = MAX(maxlen, (int)sizeof("Control") - 1);
+
         /* This shows pretty information about a unit. See
          * print_property() for a low-level property printer */
 
@@ -2296,7 +2308,7 @@ static void print_status_info(UnitStatusInfo *i) {
         printf("\n");
 
         if (i->following)
-                printf("\t  Follow: unit currently follows state of %s\n", i->following);
+                printf(" %*s: unit currently follows state of %s\n", maxlen, "Follow", i->following);
 
         if (streq_ptr(i->load_state, "error")) {
                 on = ansi_highlight_red(true);
@@ -2307,13 +2319,17 @@ static void print_status_info(UnitStatusInfo *i) {
         path = i->source_path ? i->source_path : i->fragment_path;
 
         if (i->load_error)
-                printf("\t  Loaded: %s%s%s (Reason: %s)\n", on, strna(i->load_state), off, i->load_error);
+                printf(" %*s: %s%s%s (Reason: %s)\n",
+                       maxlen, "Loaded", on, strna(i->load_state), off, i->load_error);
         else if (path && i->unit_file_state)
-                printf("\t  Loaded: %s%s%s (%s; %s)\n", on, strna(i->load_state), off, path, i->unit_file_state);
+                printf(" %*s: %s%s%s (%s; %s)\n",
+                       maxlen, "Loaded", on, strna(i->load_state), off, path, i->unit_file_state);
         else if (path)
-                printf("\t  Loaded: %s%s%s (%s)\n", on, strna(i->load_state), off, path);
+                printf(" %*s: %s%s%s (%s)\n",
+                       maxlen, "Loaded", on, strna(i->load_state), off, path);
         else
-                printf("\t  Loaded: %s%s%s\n", on, strna(i->load_state), off);
+                printf(" %*s: %s%s%s\n",
+                       maxlen, "Loaded", on, strna(i->load_state), off);
 
         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
 
@@ -2327,16 +2343,11 @@ static void print_status_info(UnitStatusInfo *i) {
                 on = off = "";
 
         if (ss)
-                printf("\t  Active: %s%s (%s)%s",
-                       on,
-                       strna(i->active_state),
-                       ss,
-                       off);
+                printf(" %*s: %s%s (%s)%s",
+                       maxlen, "Active",  on, strna(i->active_state), ss, off);
         else
-                printf("\t  Active: %s%s%s",
-                       on,
-                       strna(i->active_state),
-                       off);
+                printf(" %*s: %s%s%s",
+                       maxlen, "Active", on, strna(i->active_state), off);
 
         if (!isempty(i->result) && !streq(i->result, "success"))
                 printf(" (Result: %s)", i->result);
@@ -2363,57 +2374,37 @@ static void print_status_info(UnitStatusInfo *i) {
                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
 
                 if (s1)
-                        printf("\t          start condition failed at %s; %s\n", s2, s1);
+                        printf(" %*s start condition failed at %s; %s\n", maxlen, "", s2, s1);
                 else if (s2)
-                        printf("\t          start condition failed at %s\n", s2);
+                        printf(" %*s start condition failed at %s\n", maxlen, "", s2);
         }
 
         if (i->sysfs_path)
-                printf("\t  Device: %s\n", i->sysfs_path);
+                printf(" %*s: %s\n", maxlen, "Device", i->sysfs_path);
         if (i->where)
-                printf("\t   Where: %s\n", i->where);
+                printf(" %*s: %s\n", maxlen, "Where", i->where);
         if (i->what)
-                printf("\t    What: %s\n", i->what);
-
-        if (!strv_isempty(i->documentation)) {
-                char **t;
-                bool first = true;
+                printf(" %*s: %s\n", maxlen, "What", i->what);
 
-                STRV_FOREACH(t, i->documentation) {
-                        if (first) {
-                                printf("\t    Docs: %s\n", *t);
-                                first = false;
-                        } else
-                                printf("\t          %s\n", *t);
-                }
-        }
+        STRV_FOREACH(t, i->documentation)
+                printf(" %*s: %s\n", maxlen, t == i->documentation ? "Docs" : "", *t);
 
-        if (!strv_isempty(i->listen)) {
-                char **t;
-                bool first = true;
-
-                STRV_FOREACH(t, i->listen) {
-                        if (first) {
-                                printf("\t  Listen: %s\n", *t);
-                                first = false;
-                        } else
-                                printf("\t          %s\n", *t);
-                }
-        }
+        STRV_FOREACH_PAIR(t, t2, i->listen)
+                printf(" %*s%s: %s\n", maxlen - (int)strlen(*t), "Listen", *t, *t2);
 
         if (i->accept)
-                printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
+                printf(" %*s: %u; Connected: %u\n", maxlen, "Accepted", i->n_accepted, i->n_connections);
 
         LIST_FOREACH(exec, p, i->exec) {
-                _cleanup_free_ char *t = NULL;
+                _cleanup_free_ char *argv = NULL;
                 bool good;
 
                 /* Only show exited processes here */
                 if (p->code == 0)
                         continue;
 
-                t = strv_join(p->argv, " ");
-                printf("\t Process: %u %s=%s ", p->pid, p->name, strna(t));
+                argv = strv_join(p->argv, " ");
+                printf(" %*s: %u %s=%s ", maxlen, "Process", p->pid, p->name, strna(argv));
 
                 good = is_clean_exit_lsb(p->code, p->status, NULL);
                 if (!good) {
@@ -2449,16 +2440,14 @@ static void print_status_info(UnitStatusInfo *i) {
         }
 
         if (i->main_pid > 0 || i->control_pid > 0) {
-                printf("\t");
-
                 if (i->main_pid > 0) {
-                        printf("Main PID: %u", (unsigned) i->main_pid);
+                        printf(" %*s: %u", maxlen, "Main PID", (unsigned) i->main_pid);
 
                         if (i->running) {
-                                _cleanup_free_ char *t = NULL;
-                                get_process_comm(i->main_pid, &t);
-                                if (t)
-                                        printf(" (%s)", t);
+                                _cleanup_free_ char *comm = NULL;
+                                get_process_comm(i->main_pid, &comm);
+                                if (comm)
+                                        printf(" (%s)", comm);
                         } else if (i->exit_code > 0) {
                                 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
 
@@ -2475,32 +2464,32 @@ static void print_status_info(UnitStatusInfo *i) {
                                         printf("signal=%s", signal_to_string(i->exit_status));
                                 printf(")");
                         }
-                }
 
-                if (i->main_pid > 0 && i->control_pid > 0)
-                        printf(";");
+                        if (i->control_pid > 0)
+                                printf(";");
+                }
 
                 if (i->control_pid > 0) {
-                        _cleanup_free_ char *t = NULL;
+                        _cleanup_free_ char *c = NULL;
 
-                        printf(" Control: %u", (unsigned) i->control_pid);
+                        printf(" %*s: %u", i->main_pid ? 0 : maxlen, "Control", (unsigned) i->control_pid);
 
-                        get_process_comm(i->control_pid, &t);
-                        if (t)
-                                printf(" (%s)", t);
+                        get_process_comm(i->control_pid, &c);
+                        if (c)
+                                printf(" (%s)", c);
                 }
 
                 printf("\n");
         }
 
         if (i->status_text)
-                printf("\t  Status: \"%s\"\n", i->status_text);
+                printf(" %*s: \"%s\"\n", maxlen, "Status", i->status_text);
 
         if (i->default_control_group &&
             (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_by_spec(i->default_control_group, false) == 0)) {
                 unsigned c;
 
-                printf("\t  CGroup: %s\n", i->default_control_group);
+                printf(" %*s: %s\n", maxlen, "CGroup", i->default_control_group);
 
                 if (arg_transport != TRANSPORT_SSH) {
                         unsigned k = 0;
@@ -2763,18 +2752,14 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
 
                                 if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
                                     bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0) {
-                                        char * buf, **l;
-                                        if (asprintf(&buf, "%s: %s", type, path) < 0)
-                                                return -ENOMEM;
-
-                                        l = strv_append(i->listen, buf);
-                                        free(buf);
-
-                                        if (!l)
-                                                return -ENOMEM;
-
-                                        strv_free(i->listen);
-                                        i->listen = l;
+                                        int r;
+
+                                        r = strv_extend(&i->listen, type);
+                                        if (r < 0)
+                                                return r;
+                                        r = strv_extend(&i->listen, path);
+                                        if (r < 0)
+                                                return r;
                                 }
 
                                 dbus_message_iter_next(&sub);
@@ -2790,16 +2775,13 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
                         dbus_message_iter_recurse(iter, &sub);
                         while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
                                 const char *s;
-                                char **l;
+                                int r;
 
                                 dbus_message_iter_get_basic(&sub, &s);
 
-                                l = strv_append(i->documentation, s);
-                                if (!l)
-                                        return -ENOMEM;
-
-                                strv_free(i->documentation);
-                                i->documentation = l;
+                                r = strv_extend(&i->documentation, s);
+                                if (r < 0)
+                                        return r;
 
                                 dbus_message_iter_next(&sub);
                         }

commit 67419600875f3dae2182e3f92640bae4c8cd1f2f
Author: Oleksii Shevchuk <alxchk at gmail.com>
Date:   Mon Apr 1 23:09:45 2013 +0300

    Add Listen* to dbus properties
    
    sockets.socket - Test
    	  Loaded: loaded (/home/alxchk/.config/systemd/user/sockets.socket; static)
    	  Active: inactive (dead)
    	  Listen: Stream: /tmp/stream1
    	          Stream: @stream4
    	          Stream: [::]:9999
    	          Stream: 127.0.0.2:9996
    	          Stream: [::1]:9996
    	          Datagram: /tmp/stream2
    	          Datagram: @stream5
    	          Datagram: [::]:9998
    	          Datagram: 127.0.0.2:9995
    	          Datagram: [::1]:9995
    	          SequentialPacket: @stream6
    	          SequentialPacket: /tmp/stream3
    	          FIFO: /tmp/fifo1
    	          Special: /dev/input/event9
    	          Netlink: kobject-uevent 0
    	          MessageQueue: /msgqueue1
    
    [zj: - minor cleanups,
         - free i.listen,
         - remove sorting, because the order or sockets matters.]

diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
index 2092a63..7289581 100644
--- a/src/core/dbus-socket.c
+++ b/src/core/dbus-socket.c
@@ -63,6 +63,7 @@
         "  <property name=\"NConnections\" type=\"u\" access=\"read\"/>\n" \
         "  <property name=\"MessageQueueMaxMessages\" type=\"x\" access=\"read\"/>\n" \
         "  <property name=\"MessageQueueMessageSize\" type=\"x\" access=\"read\"/>\n" \
+        "  <property name=\"Listen\" type=\"a(ss)\" access=\"read\"/>\n"    \
         "  <property name=\"Result\" type=\"s\" access=\"read\"/>\n"    \
         "  <property name=\"SmackLabel\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"SmackLabelIPIn\" type=\"s\" access=\"read\"/>\n" \
@@ -98,6 +99,66 @@ const char bus_socket_invalidating_properties[] =
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
 static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_socket_result, socket_result, SocketResult);
 
+static int bus_socket_append_listen(DBusMessageIter *i, const char *property, void *data) {
+
+        Socket *s = SOCKET(data);
+        SocketPort *p;
+        DBusMessageIter array, stru;
+
+        assert(data);
+        assert(property);
+        assert(s);
+
+        if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(ss)", &array))
+                return log_oom();
+
+        LIST_FOREACH(port, p, s->ports) {
+                const char *type = socket_port_type_to_string(p);
+                char _cleanup_free_ *address = NULL;
+                const char *a;
+
+                if (!dbus_message_iter_open_container(&array, DBUS_TYPE_STRUCT, NULL, &stru))
+                        return log_oom();
+
+                if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &type))
+                        return log_oom();
+
+                switch (p->type) {
+                        case SOCKET_SOCKET: {
+                                int r;
+
+                                r = socket_address_print(&p->address, &address);
+                                if (r) {
+                                        log_error("socket_address_print failed: %s", strerror(-r));
+                                        return r;
+                                }
+                                a = address;
+                                break;
+                        }
+
+                        case SOCKET_SPECIAL:
+                        case SOCKET_MQUEUE:
+                        case SOCKET_FIFO:
+                                a = p->path;
+                                break;
+
+                        default:
+                                a = type;
+                }
+
+                if (!dbus_message_iter_append_basic(&stru, DBUS_TYPE_STRING, &a))
+                        return -ENOMEM;
+
+                if (!dbus_message_iter_close_container(&array, &stru))
+                        return -ENOMEM;
+        }
+
+        if (!dbus_message_iter_close_container(i, &array))
+                return -ENOMEM;
+
+        return 0;
+}
+
 static const BusProperty bus_socket_properties[] = {
         { "BindIPv6Only",   bus_socket_append_bind_ipv6_only,  "s", offsetof(Socket, bind_ipv6_only)  },
         { "Backlog",        bus_property_append_unsigned,      "u", offsetof(Socket, backlog)         },
@@ -123,6 +184,7 @@ static const BusProperty bus_socket_properties[] = {
         { "Broadcast",      bus_property_append_bool,          "b", offsetof(Socket, broadcast)       },
         { "PassCredentials",bus_property_append_bool,          "b", offsetof(Socket, pass_cred)       },
         { "PassSecurity",   bus_property_append_bool,          "b", offsetof(Socket, pass_sec)        },
+        { "Listen",         bus_socket_append_listen,      "a(ss)", 0,                                },
         { "Mark",           bus_property_append_int,           "i", offsetof(Socket, mark)            },
         { "MaxConnections", bus_property_append_unsigned,      "u", offsetof(Socket, max_connections) },
         { "NConnections",   bus_property_append_unsigned,      "u", offsetof(Socket, n_connections)   },
diff --git a/src/core/socket.c b/src/core/socket.c
index d6d531d..f3cbe08 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1969,6 +1969,28 @@ static const char *socket_sub_state_to_string(Unit *u) {
         return socket_state_to_string(SOCKET(u)->state);
 }
 
+const char* socket_port_type_to_string(SocketPort *p) {
+
+        assert(p);
+
+        switch (p->type) {
+                case SOCKET_SOCKET:
+                        switch (p->address.type) {
+                                case SOCK_STREAM: return "Stream";
+                                case SOCK_DGRAM: return "Datagram";
+                                case SOCK_SEQPACKET: return "SequentialPacket";
+                                case SOCK_RAW:
+                                        if (socket_address_family(&p->address) == AF_NETLINK)
+                                                return "Netlink";
+                                default: return "Invalid";
+                        }
+                case SOCKET_SPECIAL: return "Special";
+                case SOCKET_MQUEUE: return "MessageQueue";
+                case SOCKET_FIFO: return "FIFO";
+                default: return NULL;
+        }
+}
+
 static bool socket_check_gc(Unit *u) {
         Socket *s = SOCKET(u);
 
diff --git a/src/core/socket.h b/src/core/socket.h
index e0bae29..dbc3632 100644
--- a/src/core/socket.h
+++ b/src/core/socket.h
@@ -175,3 +175,5 @@ SocketExecCommand socket_exec_command_from_string(const char *s);
 
 const char* socket_result_to_string(SocketResult i);
 SocketResult socket_result_from_string(const char *s);
+
+const char* socket_port_type_to_string(SocketPort *p);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 6bd2e34..4f4d334 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2255,6 +2255,8 @@ typedef struct UnitStatusInfo {
         unsigned n_connections;
         bool accept;
 
+        char **listen;
+
         /* Device */
         const char *sysfs_path;
 
@@ -2386,6 +2388,19 @@ static void print_status_info(UnitStatusInfo *i) {
                 }
         }
 
+        if (!strv_isempty(i->listen)) {
+                char **t;
+                bool first = true;
+
+                STRV_FOREACH(t, i->listen) {
+                        if (first) {
+                                printf("\t  Listen: %s\n", *t);
+                                first = false;
+                        } else
+                                printf("\t          %s\n", *t);
+                }
+        }
+
         if (i->accept)
                 printf("\tAccepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
 
@@ -2736,6 +2751,37 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
 
                                 dbus_message_iter_next(&sub);
                         }
+
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Listen")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *type, *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0) {
+                                        char * buf, **l;
+                                        if (asprintf(&buf, "%s: %s", type, path) < 0)
+                                                return -ENOMEM;
+
+                                        l = strv_append(i->listen, buf);
+                                        free(buf);
+
+                                        if (!l)
+                                                return -ENOMEM;
+
+                                        strv_free(i->listen);
+                                        i->listen = l;
+                                }
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
                 } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING &&
                            streq(name, "Documentation")) {
 
@@ -2866,6 +2912,7 @@ static int print_property(const char *name, DBusMessageIter *iter) {
                         DBusMessageIter sub, sub2;
 
                         dbus_message_iter_recurse(iter, &sub);
+
                         while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
                                 const char *type, *path;
 
@@ -2880,6 +2927,24 @@ static int print_property(const char *name, DBusMessageIter *iter) {
 
                         return 0;
 
+                } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Listen")) {
+                        DBusMessageIter sub, sub2;
+
+                        dbus_message_iter_recurse(iter, &sub);
+                        while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) {
+                                const char *type, *path;
+
+                                dbus_message_iter_recurse(&sub, &sub2);
+
+                                if (bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &type, true) >= 0 &&
+                                    bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &path, false) >= 0)
+                                        printf("Listen%s=%s\n", type, path);
+
+                                dbus_message_iter_next(&sub);
+                        }
+
+                        return 0;
+
                 } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Timers")) {
                         DBusMessageIter sub, sub2;
 
@@ -3055,6 +3120,7 @@ static int show_one(const char *verb, DBusConnection *bus, const char *path, boo
         }
 
         strv_free(info.documentation);
+        strv_free(info.listen);
 
         if (!streq_ptr(info.active_state, "active") &&
             !streq_ptr(info.active_state, "reloading") &&

commit 80cfe9e163b1c92f917e0a5e053b148fca790677
Author: Dr. Tilmann Bubeck <t.bubeck at reinform.de>
Date:   Fri May 4 10:32:47 2012 +0200

    Do no isolate in case of emergency or severe problems
    
    This patch changes local-fs.target and systemd-fsck to not use
    "isolate" when going into emergency.
    This fixes https://bugzilla.redhat.com/show_bug.cgi?id=810722
    
    The motivation is, that when something wents wrong, we should
    keep everything as it is, to let the user fix the problem. When
    isolating we stop a lot of services and therefore change the
    system heavily so that it gets harder for the user to fix.
    
    An example is a crypted partition. When the fsck in a crypted
    partition fails, it previously used "emergency/start/isolate"
    which stops cryptsetup. Therefore if the user tries to fsck
    e.g. /dev/mapper/luks-356c20ae-c7a2-4f1c-ae1d-1d290a91b691
    as printed by the failing fsck, then it will not find this
    device (because it got closed).
    
    So please apply this patch to let the user see the failing
    situation.
    
    Thanks!
    
    [zj: removed dead isolate param from start_target().]
    
    https://bugs.freedesktop.org/show_bug.cgi?id=49463
    https://bugzilla.redhat.com/show_bug.cgi?id=810722

diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
index f692b3a..f298cf7 100644
--- a/src/fsck/fsck.c
+++ b/src/fsck/fsck.c
@@ -41,10 +41,10 @@ static bool arg_skip = false;
 static bool arg_force = false;
 static bool arg_show_progress = false;
 
-static void start_target(const char *target, bool isolate) {
+static void start_target(const char *target) {
         DBusMessage *m = NULL, *reply = NULL;
         DBusError error;
-        const char *mode, *basic_target = "basic.target";
+        const char *mode = "replace", *basic_target = "basic.target";
         DBusConnection *bus = NULL;
 
         assert(target);
@@ -56,11 +56,6 @@ static void start_target(const char *target, bool isolate) {
                 goto finish;
         }
 
-        if (isolate)
-                mode = "isolate";
-        else
-                mode = "replace";
-
         log_info("Running request %s/start/%s", target, mode);
 
         if (!(m = dbus_message_new_method_call("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnitReplace"))) {
@@ -389,10 +384,10 @@ int main(int argc, char *argv[]) {
 
                 if (status.si_code == CLD_EXITED && (status.si_status & 2) && root_directory)
                         /* System should be rebooted. */
-                        start_target(SPECIAL_REBOOT_TARGET, false);
+                        start_target(SPECIAL_REBOOT_TARGET);
                 else if (status.si_code == CLD_EXITED && (status.si_status & 6))
                         /* Some other problem */
-                        start_target(SPECIAL_EMERGENCY_TARGET, true);
+                        start_target(SPECIAL_EMERGENCY_TARGET);
                 else {
                         r = EXIT_SUCCESS;
                         log_warning("Ignoring error.");
diff --git a/units/local-fs.target b/units/local-fs.target
index ee02e4e..18c3d74 100644
--- a/units/local-fs.target
+++ b/units/local-fs.target
@@ -10,4 +10,4 @@ Description=Local File Systems
 Documentation=man:systemd.special(7)
 After=local-fs-pre.target
 OnFailure=emergency.target
-OnFailureIsolate=yes
+OnFailureIsolate=no

commit 9607d9470eec07df817e58f64d312ccb5ac4cfcc
Author: Cristian Rodríguez <crrodriguez at opensuse.org>
Date:   Mon Apr 1 03:08:05 2013 -0300

    Always use our own MAX/MIN definitions
    
    code in src/shared/macro.h only defined MAX/MIN in case
    they were not defined previously. however the MAX/MIN
    macros implemented in glibc are not of the "safe" kind but defined
    as:
    
    define MIN(a,b) (((a)<(b))?(a):(b))
    define MAX(a,b) (((a)>(b))?(a):(b))
    
    Avoid nasty side effects by using our own versions instead.
    
    Also fix the warnings derived from this change.
    
    [zj: - modify MAX3 macro to fix warning about _a shadowing _a,
         - do bootchart/svg.c too,
         - remove unused MIN3.]

diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c
index 0fb9fff..a4086c5 100644
--- a/src/bootchart/svg.c
+++ b/src/bootchart/svg.c
@@ -44,9 +44,6 @@
 #define kb_to_graph(m) ((m) * arg_scale_y * 0.0001)
 #define to_color(n) (192.0 - ((n) * 192.0))
 
-#define max(x, y) (((x) > (y)) ? (x) : (y))
-#define min(x, y) (((x) < (y)) ? (x) : (y))
-
 static char str[8092];
 
 #define svg(a...) do { snprintf(str, 8092, ## a); fputs(str, of); fflush(of); } while (0)
@@ -441,8 +438,8 @@ static void svg_io_bi_bar(void) {
                 int stop;
                 double tot;
 
-                start = max(i - ((range / 2) - 1), 0);
-                stop = min(i + (range / 2), samples - 1);
+                start = MAX(i - ((range / 2) - 1), 0);
+                stop = MIN(i + (range / 2), samples - 1);
 
                 tot = (double)(blockstat[stop].bi - blockstat[start].bi)
                       / (stop - start);
@@ -463,8 +460,8 @@ static void svg_io_bi_bar(void) {
                 double tot;
                 double pbi;
 
-                start = max(i - ((range / 2) - 1), 0);
-                stop = min(i + (range / 2), samples);
+                start = MAX(i - ((range / 2) - 1), 0);
+                stop = MIN(i + (range / 2), samples);
 
                 tot = (double)(blockstat[stop].bi - blockstat[start].bi)
                       / (stop - start);
@@ -517,8 +514,8 @@ static void svg_io_bo_bar(void) {
                 int stop;
                 double tot;
 
-                start = max(i - ((range / 2) - 1), 0);
-                stop = min(i + (range / 2), samples - 1);
+                start = MAX(i - ((range / 2) - 1), 0);
+                stop = MIN(i + (range / 2), samples - 1);
 
                 tot = (double)(blockstat[stop].bi - blockstat[start].bi)
                       / (stop - start);
@@ -539,8 +536,8 @@ static void svg_io_bo_bar(void) {
                 double tot;
                 double pbo;
 
-                start = max(i - ((range / 2) - 1), 0);
-                stop = min(i + (range / 2), samples);
+                start = MAX(i - ((range / 2) - 1), 0);
+                stop = MIN(i + (range / 2), samples);
 
                 tot = (double)(blockstat[stop].bo - blockstat[start].bo)
                       / (stop - start);
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 5b077be..a44e126 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1325,7 +1325,7 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
 #endif
 
         /* alloca() can't take 0, hence let's allocate at least one */
-        items = alloca(sizeof(EntryItem) * MAX(1, n_iovec));
+        items = alloca(sizeof(EntryItem) * MAX(1u, n_iovec));
 
         for (i = 0; i < n_iovec; i++) {
                 uint64_t p;
diff --git a/src/libsystemd-bus/bus-socket.c b/src/libsystemd-bus/bus-socket.c
index 5b5a731..c68c7bc 100644
--- a/src/libsystemd-bus/bus-socket.c
+++ b/src/libsystemd-bus/bus-socket.c
@@ -455,7 +455,7 @@ static int bus_socket_read_auth(sd_bus *b) {
         if (r != 0)
                 return r;
 
-        n = MAX(256, b->rbuffer_size * 2);
+        n = MAX(256u, b->rbuffer_size * 2);
 
         if (n > BUS_AUTH_SIZE_MAX)
                 n = BUS_AUTH_SIZE_MAX;
diff --git a/src/shared/macro.h b/src/shared/macro.h
index 898784a..4e5d0f4 100644
--- a/src/shared/macro.h
+++ b/src/shared/macro.h
@@ -71,29 +71,27 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
         const typeof( ((type *)0)->member ) *__mptr = (ptr); \
         (type *)( (char *)__mptr - offsetof(type,member) );})
 
-#ifndef MAX
-#define MAX(a,b)                                \
-        __extension__ ({                        \
-                        typeof(a) _a = (a);     \
-                        typeof(b) _b = (b);     \
-                        _a > _b ? _a : _b;      \
+#undef MAX
+#define MAX(a,b)                                 \
+        __extension__ ({                         \
+                        typeof(a) _a = (a);      \
+                        typeof(b) _b = (b);      \
+                        _a > _b ? _a : _b;       \
                 })
-#endif
 
-#define MAX3(a,b,c)                             \
-        MAX(MAX(a,b),c)
+#define MAX3(x,y,z)                              \
+        __extension__ ({                         \
+                        typeof(x) _c = MAX(x,y); \
+                        MAX(_c, z);              \
+                })
 
-#ifndef MIN
+#undef MIN
 #define MIN(a,b)                                \
         __extension__ ({                        \
                         typeof(a) _a = (a);     \
                         typeof(b) _b = (b);     \
                         _a < _b ? _a : _b;      \
                 })
-#endif
-
-#define MIN3(a,b,c)                             \
-        MIN(MIN(a,b),c)
 
 #ifndef CLAMP
 #define CLAMP(x, low, high)                                             \
diff --git a/src/shared/prioq.c b/src/shared/prioq.c
index 64c44ae..a220571 100644
--- a/src/shared/prioq.c
+++ b/src/shared/prioq.c
@@ -159,7 +159,7 @@ int prioq_put(Prioq *q, void *data, unsigned *idx) {
                 unsigned n;
                 struct prioq_item *j;
 
-                n = MAX((q->n_items+1) * 2, 16);
+                n = MAX((q->n_items+1) * 2, 16u);
                 j = realloc(q->items, sizeof(struct prioq_item) * n);
                 if (!j)
                         return -ENOMEM;
diff --git a/src/shared/util.c b/src/shared/util.c
index b516b9b..46c20be 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -5862,7 +5862,7 @@ void* greedy_realloc(void **p, size_t *allocated, size_t need) {
         if (*allocated >= need)
                 return *p;
 
-        a = MAX(64, need * 2);
+        a = MAX(64u, need * 2);
         q = realloc(*p, a);
         if (!q)
                 return NULL;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 328b91b..6bd2e34 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -328,7 +328,7 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
 
         if (!arg_full) {
                 unsigned basic_len;
-                id_len = MIN(max_id_len, 25);
+                id_len = MIN(max_id_len, 25u);
                 basic_len = 5 + id_len + 5 + active_len + sub_len;
                 if (job_count)
                         basic_len += job_len + 1;
@@ -337,7 +337,7 @@ static void output_units_list(const struct unit_info *unit_infos, unsigned c) {
                         extra_len = columns() - basic_len;
                         /* Either UNIT already got 25, or is fully satisfied.
                          * Grant up to 25 to DESC now. */
-                        incr = MIN(extra_len, 25);
+                        incr = MIN(extra_len, 25u);
                         desc_len += incr;
                         extra_len -= incr;
                         /* split the remaining space between UNIT and DESC,
@@ -463,7 +463,7 @@ static int get_unit_list(DBusConnection *bus, DBusMessage **reply,
                 if (*c >= n_units) {
                         struct unit_info *w;
 
-                        n_units = MAX(2 * *c, 16);
+                        n_units = MAX(2 * *c, 16u);
                         w = realloc(*unit_infos, sizeof(struct unit_info) * n_units);
                         if (!w)
                                 return log_oom();
@@ -543,7 +543,7 @@ static void output_unit_file_list(const UnitFileList *units, unsigned c) {
 
         if (!arg_full) {
                 unsigned basic_cols;
-                id_cols = MIN(max_id_len, 25);
+                id_cols = MIN(max_id_len, 25u);
                 basic_cols = 1 + id_cols + state_cols;
                 if (basic_cols < (unsigned) columns())
                         id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
@@ -657,7 +657,7 @@ static int list_unit_files(DBusConnection *bus, char **args) {
                         if (c >= n_units) {
                                 UnitFileList *w;
 
-                                n_units = MAX(2*c, 16);
+                                n_units = MAX(2*c, 16u);
                                 w = realloc(units, sizeof(struct UnitFileList) * n_units);
                                 if (!w)
                                         return log_oom();
@@ -694,7 +694,7 @@ static int list_dependencies_print(const char *name, int level, unsigned int bra
         int i;
         _cleanup_free_ char *n = NULL;
         size_t len = 0;
-        size_t max_len = MAX(columns(),20);
+        size_t max_len = MAX(columns(),20u);
 
         for (i = level - 1; i >= 0; i--) {
                 len += 2;



More information about the systemd-commits mailing list