[systemd-commits] 4 commits - src/core src/journal src/shared src/test

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Tue Jan 28 16:07:32 PST 2014


 src/core/job.c             |    7 ++++-
 src/core/manager.c         |   27 ++++++++++++++++++----
 src/journal/journal-send.c |    2 -
 src/shared/missing.h       |    4 ---
 src/shared/util.c          |   53 +++++----------------------------------------
 src/test/test-util.c       |   12 +++++-----
 6 files changed, 40 insertions(+), 65 deletions(-)

New commits:
commit e5723c894db1ead8a10ffb1800e53e9064656d7e
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Tue Jan 28 18:26:06 2014 -0500

    manager: requeue the cylon eye for 5s later when a job finishes
    
    We'd reqeue the next status update very soon after. Change it so that we wait
    for full 5s without any job status changes until we print anything.

diff --git a/src/core/manager.c b/src/core/manager.c
index edde109..5f50fee 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -97,12 +97,16 @@ static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t use
 static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
 
 static int manager_watch_jobs_in_progress(Manager *m) {
+        usec_t next;
+
         assert(m);
 
         if (m->jobs_in_progress_event_source)
                 return 0;
 
-        return sd_event_add_monotonic(m->event, now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC, 0, manager_dispatch_jobs_in_progress, m, &m->jobs_in_progress_event_source);
+        next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
+        log_debug("queuing for "USEC_FMT, next);
+        return sd_event_add_monotonic(m->event, next, 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))
@@ -186,7 +190,7 @@ static void manager_print_jobs_in_progress(Manager *m) {
         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,
+        manager_status_printf(m, false, cylon,
                               "%sA %s job is running for %s (%s / %s)",
                               strempty(job_of_n),
                               job_type_to_string(j->type),
@@ -1762,6 +1766,7 @@ static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t use
         manager_print_jobs_in_progress(m);
 
         next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
+        log_debug("requeuing for "USEC_FMT, next);
         r = sd_event_source_set_time(source, next);
         if (r < 0)
                 return r;
@@ -2462,7 +2467,8 @@ void manager_check_finished(Manager *m) {
 
         if (hashmap_size(m->jobs) > 0) {
                 if (m->jobs_in_progress_event_source) {
-                        uint64_t next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_PERIOD_USEC;
+                        uint64_t next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
+                        log_debug("requeuing for "USEC_FMT, next);
                         sd_event_source_set_time(m->jobs_in_progress_event_source, next);
                 }
                 return;

commit 8bb310c3c6f5a52f2d483fd8dfb16ca66ecf7a5f
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Tue Jan 28 18:25:39 2014 -0500

    manager: print ephemeral information about running jobs' timeouts (v2)
    
    This reverts commit 28c758de94bc8ba97b89d9dab3f517cf466978d0
    but makes job_coldplug smarter.
    
    In (v1) I changed the job start timestamp to be always set, so the
    start time can be reported in the cylon eye message.  The bug was that
    when deserializing jobs, they would be ignored if their start
    timestamp was unset which was synonymous with no timeout. But after
    the change, jobs would have a start timestamp set despite having no
    timeout. After deserialization they would be considered immediately
    expired. Fix this by checking if the timeout is not zero when
    considering jobs for expiration.

diff --git a/src/core/job.c b/src/core/job.c
index 1bcf496..941f956 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -864,11 +864,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;
@@ -1048,7 +1051,7 @@ int job_coldplug(Job *j) {
 
         assert(j);
 
-        if (j->begin_usec <= 0)
+        if (j->begin_usec == 0 || j->unit->job_timeout == 0)
                 return 0;
 
         if (j->timer_event_source)
diff --git a/src/core/manager.c b/src/core/manager.c
index f7f8fa6..edde109 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -153,6 +153,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);
 
@@ -174,14 +176,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 0f010ef2130e887347212d4a3f81abafc78985a0
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Tue Jan 28 18:25:31 2014 -0500

    Base mkostemp_safe on mkostemp
    
    It is nice to wrap umask handling and return convention,
    but glibc's mkostemp is async-signal-safe already.

diff --git a/src/shared/missing.h b/src/shared/missing.h
index 939f81d..ac6f5bf 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -324,10 +324,6 @@ static inline int name_to_handle_at(int fd, const char *name, struct file_handle
 #  define DRM_IOCTL_DROP_MASTER _IO('d', 0x1f)
 #endif
 
-#ifndef TMP_MAX
-# define TMP_MAX 238328
-#endif
-
 #if defined(__i386__) || defined(__x86_64__)
 
 /* The precise definition of __O_TMPFILE is arch specific, so let's
diff --git a/src/shared/util.c b/src/shared/util.c
index 30512d1..4c5b048 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6093,43 +6093,20 @@ int getpeersec(int fd, char **ret) {
         return 0;
 }
 
+/* This is much like like mkostemp() but is subject to umask(). */
 int mkostemp_safe(char *pattern, int flags) {
-        unsigned long tries = TMP_MAX;
-        char *s;
-        int r;
         _cleanup_umask_ mode_t u;
+        int fd;
 
         assert(pattern);
 
         u = umask(077);
 
-        /* This is much like like mkostemp() but avoids using any
-         * static variables, thus is async signal safe. Also, it's not
-         * subject to umask(). */
-
-        s = endswith(pattern, "XXXXXX");
-        if (!s)
-                return -EINVAL;
-
-        while (tries--) {
-                unsigned i;
-                int fd;
-
-                r = dev_urandom(s, 6);
-                if (r < 0)
-                        return r;
-
-                for (i = 0; i < 6; i++)
-                        s[i] = ALPHANUMERICAL[(unsigned) s[i] % (sizeof(ALPHANUMERICAL)-1)];
-
-                fd = open(pattern, flags|O_EXCL|O_CREAT|O_NOCTTY|O_NOFOLLOW, S_IRUSR|S_IWUSR);
-                if (fd >= 0)
-                        return fd;
-                if (!IN_SET(errno, EEXIST, EINTR))
-                        return -errno;
-        }
+        fd = mkostemp(pattern, flags);
+        if (fd < 0)
+                return -errno;
 
-        return -EEXIST;
+        return fd;
 }
 
 int open_tmpfile(const char *path, int flags) {

commit 87b0284327e34a4b96c22085fa2cdb3219294991
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Tue Jan 28 18:23:38 2014 -0500

    Get rid of write_safe
    
    Current glibc implementation is safe. Kernel does this atomically,
    and write is actually implemented through writev. So if write is
    async-signal-safe, than writev pretty much must be too.

diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index 960c577..ca9199f 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -314,7 +314,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
         if (buffer_fd < 0)
                 return buffer_fd;
 
-        n = writev_safe(buffer_fd, w, j);
+        n = writev(buffer_fd, w, j);
         if (n < 0) {
                 close_nointr_nofail(buffer_fd);
                 return -errno;
diff --git a/src/shared/util.c b/src/shared/util.c
index 2b91ef8..30512d1 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6093,24 +6093,6 @@ int getpeersec(int fd, char **ret) {
         return 0;
 }
 
-int writev_safe(int fd, const struct iovec *w, int j) {
-        for (int i = 0; i < j; i++) {
-                size_t written = 0;
-
-                while (written < w[i].iov_len) {
-                        ssize_t r;
-
-                        r = write(fd, (char*) w[i].iov_base + written, w[i].iov_len - written);
-                        if (r < 0 && errno != -EINTR)
-                                return -errno;
-
-                        written += r;
-                }
-        }
-
-        return 0;
-}
-
 int mkostemp_safe(char *pattern, int flags) {
         unsigned long tries = TMP_MAX;
         char *s;
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 43bb024..9d6f4be 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -580,8 +580,8 @@ static void test_in_set(void) {
         assert_se(!IN_SET(0, 1, 2, 3, 4));
 }
 
-static void test_writev_safe(void) {
-        char name[] = "/tmp/test-writev_safe.XXXXXX";
+static void test_writing_tmpfile(void) {
+        char name[] = "/tmp/test-systemd_writing_tmpfile.XXXXXX";
         _cleanup_free_ char *contents;
         size_t size;
         int fd, r;
@@ -592,10 +592,10 @@ static void test_writev_safe(void) {
         IOVEC_SET_STRING(iov[2], "");
 
         fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
-        printf("test_writev_safe: %s", name);
+        printf("tmpfile: %s", name);
 
-        r = writev_safe(fd, iov, 3);
-        assert(r == 0);
+        r = writev(fd, iov, 3);
+        assert(r >= 0);
 
         r = read_full_file(name, &contents, &size);
         assert(r == 0);
@@ -640,7 +640,7 @@ int main(int argc, char *argv[]) {
         test_fstab_node_to_udev_node();
         test_get_files_in_directory();
         test_in_set();
-        test_writev_safe();
+        test_writing_tmpfile();
 
         return 0;
 }



More information about the systemd-commits mailing list