[systemd-commits] 5 commits - src/core

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Sun Jan 26 22:24:35 PST 2014


 src/core/job.c     |   36 +++++++++++++++++++++++++++++++++++-
 src/core/job.h     |    2 ++
 src/core/manager.c |   40 +++++++++++++++++++++++++++++++---------
 src/core/mount.c   |   16 ++++++++++++++++
 src/core/scope.c   |   16 ++++++++++++++++
 src/core/service.c |   16 ++++++++++++++++
 src/core/socket.c  |   16 ++++++++++++++++
 src/core/swap.c    |   16 ++++++++++++++++
 src/core/unit.c    |   20 +++++++++++++++-----
 src/core/unit.h    |    2 ++
 10 files changed, 165 insertions(+), 15 deletions(-)

New commits:
commit 36be24c8f82141fda995841d177e9e4113e1ef06
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Jan 27 01:23:20 2014 -0500

    core: require mounts for the root and working directories
    
    We know that launching a unit will fail if some required directories
    haven't been mounted yet. There's no point in starting it just to
    have it fail even before it gets a chance to run.

diff --git a/src/core/unit.c b/src/core/unit.c
index fc14658..e5ea994 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -671,6 +671,18 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
         assert(u);
         assert(c);
 
+        if (c->working_directory) {
+                r = unit_require_mounts_for(u, c->working_directory);
+                if (r < 0)
+                        return r;
+        }
+
+        if (c->root_directory) {
+                r = unit_require_mounts_for(u, c->root_directory);
+                if (r < 0)
+                        return r;
+        }
+
         if (c->std_output != EXEC_OUTPUT_KMSG &&
             c->std_output != EXEC_OUTPUT_SYSLOG &&
             c->std_output != EXEC_OUTPUT_JOURNAL &&

commit 70b64bd3561c2bbe6cad2e590d4e3e25426f75b5
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Jan 27 01:23:16 2014 -0500

    core: simplify check for path absoluteness
    
    Just a microopt.

diff --git a/src/core/unit.c b/src/core/unit.c
index e3b6206..fc14658 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2997,17 +2997,15 @@ int unit_require_mounts_for(Unit *u, const char *path) {
          * units can easily determine which units to make themselves a
          * dependency of. */
 
+        if (!path_is_absolute(path))
+                return -EINVAL;
+
         p = strdup(path);
         if (!p)
                 return -ENOMEM;
 
         path_kill_slashes(p);
 
-        if (!path_is_absolute(p)) {
-                free(p);
-                return -EINVAL;
-        }
-
         if (!path_is_safe(p)) {
                 free(p);
                 return -EPERM;

commit fd08a8403f8c4075db95a0a4aec92689897c1e63
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Jan 27 01:15:27 2014 -0500

    manager: rearm jobs timer
    
    It would fire just once.
    
    Also fix units from sec to usec as appropriate.
    
    Decrease the switching interval to 1/3 s, so that when the time
    remaining is displayed with 1s precision, it doesn't jump by 2s every
    once in a while. Also, the system is feels noticably faster when the
    status changes couple of times per second instead of every few
    seconds.

diff --git a/src/core/manager.c b/src/core/manager.c
index 76c8dac..9d43a1c 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -80,8 +80,8 @@
 #define GC_QUEUE_USEC_MAX (10*USEC_PER_SEC)
 
 /* Initial delay and the interval for printing status messages about running jobs */
-#define JOBS_IN_PROGRESS_WAIT_SEC 5
-#define JOBS_IN_PROGRESS_PERIOD_SEC 1
+#define JOBS_IN_PROGRESS_WAIT_USEC (5*USEC_PER_SEC)
+#define JOBS_IN_PROGRESS_PERIOD_USEC (USEC_PER_SEC / 3)
 #define JOBS_IN_PROGRESS_PERIOD_DIVISOR 3
 
 /* Where clients shall send notification messages to */
@@ -102,7 +102,7 @@ static int manager_watch_jobs_in_progress(Manager *m) {
         if (m->jobs_in_progress_event_source)
                 return 0;
 
-        return sd_event_add_monotonic(m->event, JOBS_IN_PROGRESS_WAIT_SEC, 0, manager_dispatch_jobs_in_progress, m, &m->jobs_in_progress_event_source);
+        return sd_event_add_monotonic(m->event, JOBS_IN_PROGRESS_WAIT_USEC, 0, manager_dispatch_jobs_in_progress, m, &m->jobs_in_progress_event_source);
 }
 
 #define CYLON_BUFFER_EXTRA (2*(sizeof(ANSI_RED_ON)-1) + sizeof(ANSI_HIGHLIGHT_RED_ON)-1 + 2*(sizeof(ANSI_HIGHLIGHT_OFF)-1))
@@ -1741,11 +1741,20 @@ static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32
 
 static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata) {
         Manager *m = userdata;
+        int r;
+        uint64_t next;
 
         assert(m);
+        assert(source);
 
         manager_print_jobs_in_progress(m);
-        return 0;
+
+        next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
+        r = sd_event_source_set_time(source, next);
+        if (r < 0)
+                return r;
+
+        return sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
 }
 
 int manager_loop(Manager *m) {
@@ -2451,8 +2460,10 @@ void manager_check_finished(Manager *m) {
                 m->jobs_in_progress_event_source = sd_event_source_unref(m->jobs_in_progress_event_source);
 
         if (hashmap_size(m->jobs) > 0) {
-                if (m->jobs_in_progress_event_source)
-                        sd_event_source_set_time(m->jobs_in_progress_event_source, JOBS_IN_PROGRESS_PERIOD_SEC);
+                if (m->jobs_in_progress_event_source) {
+                        uint64_t next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
+                        sd_event_source_set_time(m->jobs_in_progress_event_source, next);
+                }
                 return;
         }
 

commit 2cba2e03524ec0922ddc70f933e8a89b7d23b4ec
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Jan 27 00:59:08 2014 -0500

    manager: print ephemeral information about running jobs' timeouts
    
    Produces output like:
    [  *** ] (1 of 2) A start job is running for slow.service (33s / 1min 30s)
    
    The first nubmer is the time since job start, the second is the job timeout.

diff --git a/src/core/job.c b/src/core/job.c
index e6529b6..fb6709e 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -860,11 +860,14 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user
 int job_start_timer(Job *j) {
         int r;
 
-        if (j->unit->job_timeout <= 0 || j->timer_event_source)
+        if (j->timer_event_source)
                 return 0;
 
         j->begin_usec = now(CLOCK_MONOTONIC);
 
+        if (j->unit->job_timeout <= 0)
+                return 0;
+
         r = sd_event_add_monotonic(j->manager->event, j->begin_usec + j->unit->job_timeout, 0, job_dispatch_timer, j, &j->timer_event_source);
         if (r < 0)
                 return r;
diff --git a/src/core/manager.c b/src/core/manager.c
index 95fc7e6..76c8dac 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -143,6 +143,8 @@ static void manager_print_jobs_in_progress(Manager *m) {
         unsigned counter = 0, print_nr;
         char cylon[6 + CYLON_BUFFER_EXTRA + 1];
         unsigned cylon_pos;
+        char time[FORMAT_TIMESPAN_MAX], limit[FORMAT_TIMESPAN_MAX] = "no limit";
+        uint64_t x;
 
         assert(m);
 
@@ -162,14 +164,23 @@ static void manager_print_jobs_in_progress(Manager *m) {
                 cylon_pos = 14 - cylon_pos;
         draw_cylon(cylon, sizeof(cylon), 6, cylon_pos);
 
+        m->jobs_in_progress_iteration++;
+
         if (m->n_running_jobs > 1)
                 if (asprintf(&job_of_n, "(%u of %u) ", counter, m->n_running_jobs) < 0)
                         job_of_n = NULL;
 
-        manager_status_printf(m, true, cylon, "%sA %s job is running for %s",
-                              strempty(job_of_n), job_type_to_string(j->type), unit_description(j->unit));
+        format_timespan(time, sizeof(time), now(CLOCK_MONOTONIC) - j->begin_usec, 1*USEC_PER_SEC);
+        if (job_get_timeout(j, &x) > 0)
+                format_timespan(limit, sizeof(limit), x - j->begin_usec, 1*USEC_PER_SEC);
+
+        manager_status_printf(m, true, cylon,
+                              "%sA %s job is running for %s (%s / %s)",
+                              strempty(job_of_n),
+                              job_type_to_string(j->type),
+                              unit_description(j->unit),
+                              time, limit);
 
-        m->jobs_in_progress_iteration++;
 }
 
 static int manager_watch_idle_pipe(Manager *m) {

commit 68db7a3bd9b2f8640c7297382b6d20eb995f7e1e
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Jan 27 00:57:34 2014 -0500

    core: add function to tell when job will time out
    
    Things will continue when either the job timeout
    or the unit timeout is reached. Add functionality to
    access that info.

diff --git a/src/core/job.c b/src/core/job.c
index 7faa8da..e6529b6 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -1086,6 +1086,37 @@ void job_shutdown_magic(Job *j) {
         asynchronous_sync();
 }
 
+int job_get_timeout(Job *j, uint64_t *timeout) {
+        Unit *u = j->unit;
+        uint64_t x = -1, y = -1;
+        int r = 0, q = 0;
+
+        assert(u);
+
+        if (j->timer_event_source) {
+                r = sd_event_source_get_time(j->timer_event_source, &x);
+                if (r < 0)
+                        return r;
+                r = 1;
+        }
+
+        if (UNIT_VTABLE(u)->get_timeout) {
+                q = UNIT_VTABLE(u)->get_timeout(u, &y);
+                if (q < 0)
+                        return q;
+        }
+
+        if (r == 0 && q == 0)
+                return 0;
+
+        *timeout = MIN(x, y);
+
+        log_info("job_get_timeout %s %d/%"PRIu64" %d/%"PRIu64" -> 1/%"PRIu64,
+                 j->unit->id, r, x, q, y, *timeout);
+
+        return 1;
+}
+
 static const char* const job_state_table[_JOB_STATE_MAX] = {
         [JOB_WAITING] = "waiting",
         [JOB_RUNNING] = "running"
diff --git a/src/core/job.h b/src/core/job.h
index 0500e12..8cc3a02 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -222,3 +222,5 @@ JobMode job_mode_from_string(const char *s) _pure_;
 
 const char* job_result_to_string(JobResult t) _const_;
 JobResult job_result_from_string(const char *s) _pure_;
+
+int job_get_timeout(Job *j, uint64_t *timeout) _pure_;
diff --git a/src/core/mount.c b/src/core/mount.c
index bce5054..90da883 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1583,6 +1583,20 @@ static void mount_shutdown(Manager *m) {
         }
 }
 
+static int mount_get_timeout(Unit *u, uint64_t *timeout) {
+        Mount *m = MOUNT(u);
+        int r;
+
+        if (!m->timer_event_source)
+                return 0;
+
+        r = sd_event_source_get_time(m->timer_event_source, timeout);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 static int mount_enumerate(Manager *m) {
         int r;
         assert(m);
@@ -1796,6 +1810,8 @@ const UnitVTable mount_vtable = {
         .bus_set_property = bus_mount_set_property,
         .bus_commit_properties = bus_mount_commit_properties,
 
+        .get_timeout = mount_get_timeout,
+
         .enumerate = mount_enumerate,
         .shutdown = mount_shutdown,
 
diff --git a/src/core/scope.c b/src/core/scope.c
index 56c3746..87983f6 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -318,6 +318,20 @@ static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
         return unit_kill_common(u, who, signo, -1, -1, error);
 }
 
+static int scope_get_timeout(Unit *u, uint64_t *timeout) {
+        Scope *s = SCOPE(u);
+        int r;
+
+        if (!s->timer_event_source)
+                return 0;
+
+        r = sd_event_source_get_time(s->timer_event_source, timeout);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
         Scope *s = SCOPE(u);
 
@@ -478,6 +492,8 @@ const UnitVTable scope_vtable = {
 
         .kill = scope_kill,
 
+        .get_timeout = scope_get_timeout,
+
         .serialize = scope_serialize,
         .deserialize_item = scope_deserialize_item,
 
diff --git a/src/core/service.c b/src/core/service.c
index a2f0e35..d949f7a 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -3401,6 +3401,20 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
                 unit_add_to_dbus_queue(u);
 }
 
+static int service_get_timeout(Unit *u, uint64_t *timeout) {
+        Service *s = SERVICE(u);
+        int r;
+
+        if (!s->timer_event_source)
+                return 0;
+
+        r = sd_event_source_get_time(s->timer_event_source, timeout);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 #ifdef HAVE_SYSV_COMPAT
 
 static int service_enumerate(Manager *m) {
@@ -3832,6 +3846,8 @@ const UnitVTable service_vtable = {
         .bus_set_property = bus_service_set_property,
         .bus_commit_properties = bus_service_commit_properties,
 
+        .get_timeout = service_get_timeout,
+
 #ifdef HAVE_SYSV_COMPAT
         .enumerate = service_enumerate,
 #endif
diff --git a/src/core/socket.c b/src/core/socket.c
index 1f2a2c0..7eac0eb 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2344,6 +2344,20 @@ static int socket_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
         return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
 }
 
+static int socket_get_timeout(Unit *u, uint64_t *timeout) {
+        Socket *s = SOCKET(u);
+        int r;
+
+        if (!s->timer_event_source)
+                return 0;
+
+        r = sd_event_source_get_time(s->timer_event_source, timeout);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
         [SOCKET_DEAD] = "dead",
         [SOCKET_START_PRE] = "start-pre",
@@ -2408,6 +2422,8 @@ const UnitVTable socket_vtable = {
 
         .kill = socket_kill,
 
+        .get_timeout = socket_get_timeout,
+
         .serialize = socket_serialize,
         .deserialize_item = socket_deserialize_item,
         .distribute_fds = socket_distribute_fds,
diff --git a/src/core/swap.c b/src/core/swap.c
index 6b204df..26141e6 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -1367,6 +1367,20 @@ static int swap_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
         return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
 }
 
+static int swap_get_timeout(Unit *u, uint64_t *timeout) {
+        Swap *s = SWAP(u);
+        int r;
+
+        if (!s->timer_event_source)
+                return 0;
+
+        r = sd_event_source_get_time(s->timer_event_source, timeout);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 static const char* const swap_state_table[_SWAP_STATE_MAX] = {
         [SWAP_DEAD] = "dead",
         [SWAP_ACTIVATING] = "activating",
@@ -1429,6 +1443,8 @@ const UnitVTable swap_vtable = {
 
         .kill = swap_kill,
 
+        .get_timeout = swap_get_timeout,
+
         .serialize = swap_serialize,
         .deserialize_item = swap_deserialize_item,
 
diff --git a/src/core/unit.h b/src/core/unit.h
index 45816ea..c686aec 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -410,6 +410,8 @@ struct UnitVTable {
         /* Called whenever CLOCK_REALTIME made a jump */
         void (*time_change)(Unit *u);
 
+        int (*get_timeout)(Unit *u, uint64_t *timeout);
+
         /* This is called for each unit type and should be used to
          * enumerate existing devices and load them. However,
          * everything that is loaded here should still stay in



More information about the systemd-commits mailing list