[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