<div dir="ltr">Hi!<br><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jul 16, 2013 at 8:50 AM, Lennart Poettering <span dir="ltr"><<a href="mailto:lennart@poettering.net" target="_blank">lennart@poettering.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Wed, 26.06.13 19:55, Zbigniew Jędrzejewski-Szmek (<a href="mailto:zbyszek@in.waw.pl">zbyszek@in.waw.pl</a>) wrote:<br>

<br>
> A few asserts are replaced with 'return -EINVAL'. I think that<br>
> assert should not be used to check argument in public functions.<br>
><br>
> Fields in struct sd_journal are rearranged to make it less<br>
> swiss-cheesy.<br>
> ---<br>
> Does this look sound?<br>
<br>
</div>Yupp! Looks great! Please commit!<br></blockquote><div>Wouldn't this be better using pthread_atfork() to avoid all the getpid() calls?<br><br></div>I made a new patch using a global g_forked, but realized it had a race:<br>
<br></div><div class="gmail_quote">create journal<br>fork()<br></div><div class="gmail_quote">create second journal<br>log to first journal object<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">
><br>
> Zbyszek<br>
><br>
>  TODO                           |  5 +--<br>
>  man/sd_journal_open.xml        |  7 ++++<br>
>  src/journal/journal-internal.h | 18 +++++-----<br>
>  src/journal/sd-journal.c       | 80 +++++++++++++++++++++++++++++++++++++++---<br>
>  4 files changed, 93 insertions(+), 17 deletions(-)<br>
><br>
> diff --git a/TODO b/TODO<br>
> index caba4e3..2968d18 100644<br>
> --- a/TODO<br>
> +++ b/TODO<br>
> @@ -68,7 +68,7 @@ Features:<br>
><br>
>  * document systemd-journal-flush.service properly<br>
><br>
> -* chane systemd-journal-flush into a service that stays around during<br>
> +* change systemd-journal-flush into a service that stays around during<br>
>    boot, and causes the journal to be moved back to /run on shutdown,<br>
>    so that we don't keep /var busy. This needs to happen synchronously,<br>
>    hence doing this via signals is not going to work.<br>
> @@ -76,9 +76,6 @@ Features:<br>
>  * allow implementation of InaccessibleDirectories=/ plus<br>
>    ReadOnlyDirectories=... for whitelisting files for a service.<br>
><br>
> -* libsystemd-journal:<br>
> -  - return ECHILD as soon as somebody tries to reuse a journal object across a fork()<br>
> -<br>
>  * libsystemd-bus:<br>
>    - default policy (allow uid == 0 and our own uid)<br>
>    - enforce alignment of pointers passed in<br>
> diff --git a/man/sd_journal_open.xml b/man/sd_journal_open.xml<br>
> index d7ea8ff..b2f6f9e 100644<br>
> --- a/man/sd_journal_open.xml<br>
> +++ b/man/sd_journal_open.xml<br>
> @@ -131,6 +131,13 @@<br>
>                  can be rotated at any moment, and the opening of<br>
>                  specific files is inherently racy.</para><br>
><br>
> +                <para><varname>sd_journal</varname> objects cannot be<br>
> +                used in the child after a fork. Functions which take a<br>
> +                journal object as an argument<br>
> +                (<function>sd_journal_next()</function> and others)<br>
> +                will return <constant>-ECHILD</constant> after a fork.<br>
> +                </para><br>
> +<br>
>                  <para><function>sd_journal_close()</function> will<br>
>                  close the journal context allocated with<br>
>                  <function>sd_journal_open()</function> or<br>
> diff --git a/src/journal/journal-internal.h b/src/journal/journal-internal.h<br>
> index 5b717f8..5bc6535 100644<br>
> --- a/src/journal/journal-internal.h<br>
> +++ b/src/journal/journal-internal.h<br>
> @@ -97,8 +97,6 @@ struct Directory {<br>
>  };<br>
><br>
>  struct sd_journal {<br>
> -        int flags;<br>
> -<br>
>          char *path;<br>
><br>
>          Hashmap *files;<br>
> @@ -109,27 +107,29 @@ struct sd_journal {<br>
>          JournalFile *current_file;<br>
>          uint64_t current_field;<br>
><br>
> -        Hashmap *directories_by_path;<br>
> -        Hashmap *directories_by_wd;<br>
> -<br>
> -        int inotify_fd;<br>
> -<br>
>          Match *level0, *level1, *level2;<br>
><br>
> +        pid_t original_pid;<br>
> +<br>
> +        int inotify_fd;<br>
>          unsigned current_invalidate_counter, last_invalidate_counter;<br>
> +        usec_t last_process_usec;<br>
><br>
>          char *unique_field;<br>
>          JournalFile *unique_file;<br>
>          uint64_t unique_offset;<br>
><br>
> +        int flags;<br>
> +<br>
>          bool on_network;<br>
>          bool no_new_files;<br>
><br>
>          size_t data_threshold;<br>
><br>
> -        Set *errors;<br>
> +        Hashmap *directories_by_path;<br>
> +        Hashmap *directories_by_wd;<br>
><br>
> -        usec_t last_process_usec;<br>
> +        Set *errors;<br>
>  };<br>
><br>
>  char *journal_make_match_string(sd_journal *j);<br>
> diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c<br>
> index 1e70739..81b0c13 100644<br>
> --- a/src/journal/sd-journal.c<br>
> +++ b/src/journal/sd-journal.c<br>
> @@ -50,6 +50,15 @@<br>
><br>
>  #define DEFAULT_DATA_THRESHOLD (64*1024)<br>
><br>
> +static bool journal_pid_changed(sd_journal *j) {<br>
> +        assert(j);<br>
> +<br>
> +        /* We don't support people creating a journal object and<br>
> +         * keeping it around over a fork(). Let's complain. */<br>
> +<br>
> +        return j->original_pid != getpid();<br>
> +}<br>
> +<br>
>  /* We return an error here only if we didn't manage to<br>
>     memorize the real error. */<br>
>  static int set_put_error(sd_journal *j, int r) {<br>
> @@ -209,6 +218,8 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size)<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          if (!data)<br>
>                  return -EINVAL;<br>
> @@ -303,7 +314,10 @@ fail:<br>
>  }<br>
><br>
>  _public_ int sd_journal_add_conjunction(sd_journal *j) {<br>
> -        assert(j);<br>
> +        if (!j)<br>
> +                return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          if (!j->level0)<br>
>                  return 0;<br>
> @@ -321,7 +335,10 @@ _public_ int sd_journal_add_conjunction(sd_journal *j) {<br>
>  }<br>
><br>
>  _public_ int sd_journal_add_disjunction(sd_journal *j) {<br>
> -        assert(j);<br>
> +        if (!j)<br>
> +                return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          if (!j->level0)<br>
>                  return 0;<br>
> @@ -391,7 +408,6 @@ char *journal_make_match_string(sd_journal *j) {<br>
>  }<br>
><br>
>  _public_ void sd_journal_flush_matches(sd_journal *j) {<br>
> -<br>
>          if (!j)<br>
>                  return;<br>
><br>
> @@ -870,6 +886,8 @@ static int real_journal_next(sd_journal *j, direction_t direction) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          HASHMAP_FOREACH(f, j->files, i) {<br>
>                  bool found;<br>
> @@ -922,6 +940,8 @@ static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          if (skip == 0) {<br>
>                  /* If this is not a discrete skip, then at least<br>
> @@ -962,6 +982,8 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!cursor)<br>
>                  return -EINVAL;<br>
><br>
> @@ -1001,6 +1023,8 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (isempty(cursor))<br>
>                  return -EINVAL;<br>
><br>
> @@ -1100,6 +1124,8 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (isempty(cursor))<br>
>                  return -EINVAL;<br>
><br>
> @@ -1178,6 +1204,8 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) {<br>
>  _public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) {<br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          reset_location(j);<br>
>          j->current_location.type = LOCATION_SEEK;<br>
> @@ -1191,6 +1219,8 @@ _public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, u<br>
>  _public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {<br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          reset_location(j);<br>
>          j->current_location.type = LOCATION_SEEK;<br>
> @@ -1203,6 +1233,8 @@ _public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) {<br>
>  _public_ int sd_journal_seek_head(sd_journal *j) {<br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          reset_location(j);<br>
>          j->current_location.type = LOCATION_HEAD;<br>
> @@ -1213,6 +1245,8 @@ _public_ int sd_journal_seek_head(sd_journal *j) {<br>
>  _public_ int sd_journal_seek_tail(sd_journal *j) {<br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          reset_location(j);<br>
>          j->current_location.type = LOCATION_TAIL;<br>
> @@ -1651,6 +1685,7 @@ static sd_journal *journal_new(int flags, const char *path) {<br>
>          if (!j)<br>
>                  return NULL;<br>
><br>
> +        j->original_pid = getpid();<br>
>          j->inotify_fd = -1;<br>
>          j->flags = flags;<br>
>          j->data_threshold = DEFAULT_DATA_THRESHOLD;<br>
> @@ -1812,6 +1847,8 @@ _public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!ret)<br>
>                  return -EINVAL;<br>
><br>
> @@ -1838,6 +1875,8 @@ _public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id12<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          f = j->current_file;<br>
>          if (!f)<br>
> @@ -1904,6 +1943,8 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!field)<br>
>                  return -EINVAL;<br>
>          if (!data)<br>
> @@ -2030,6 +2071,8 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!data)<br>
>                  return -EINVAL;<br>
>          if (!size)<br>
> @@ -2080,6 +2123,8 @@ _public_ int sd_journal_get_fd(sd_journal *j) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          if (j->inotify_fd >= 0)<br>
>                  return j->inotify_fd;<br>
> @@ -2107,6 +2152,8 @@ _public_ int sd_journal_get_events(sd_journal *j) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          fd = sd_journal_get_fd(j);<br>
>          if (fd < 0)<br>
> @@ -2120,6 +2167,8 @@ _public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!timeout_usec)<br>
>                  return -EINVAL;<br>
><br>
> @@ -2220,6 +2269,8 @@ _public_ int sd_journal_process(sd_journal *j) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          j->last_process_usec = now(CLOCK_MONOTONIC);<br>
><br>
> @@ -2258,7 +2309,10 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {<br>
>          int r;<br>
>          uint64_t t;<br>
><br>
> -        assert(j);<br>
> +        if (!j)<br>
> +                return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          if (j->inotify_fd < 0) {<br>
><br>
> @@ -2307,6 +2361,8 @@ _public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from,<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!from && !to)<br>
>                  return -EINVAL;<br>
>          if (from == to)<br>
> @@ -2348,6 +2404,8 @@ _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!from && !to)<br>
>                  return -EINVAL;<br>
>          if (from == to)<br>
> @@ -2405,6 +2463,8 @@ _public_ int sd_journal_get_usage(sd_journal *j, uint64_t *bytes) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!bytes)<br>
>                  return -EINVAL;<br>
><br>
> @@ -2426,6 +2486,8 @@ _public_ int sd_journal_query_unique(sd_journal *j, const char *field) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (isempty(field))<br>
>                  return -EINVAL;<br>
>          if (!field_is_valid(field))<br>
> @@ -2450,6 +2512,8 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!data)<br>
>                  return -EINVAL;<br>
>          if (!l)<br>
> @@ -2562,6 +2626,8 @@ _public_ void sd_journal_restart_unique(sd_journal *j) {<br>
>  _public_ int sd_journal_reliable_fd(sd_journal *j) {<br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          return !j->on_network;<br>
>  }<br>
> @@ -2595,6 +2661,8 @@ _public_ int sd_journal_get_catalog(sd_journal *j, char **ret) {<br>
><br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!ret)<br>
>                  return -EINVAL;<br>
><br>
> @@ -2632,6 +2700,8 @@ _public_ int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret) {<br>
>  _public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) {<br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
><br>
>          j->data_threshold = sz;<br>
>          return 0;<br>
> @@ -2640,6 +2710,8 @@ _public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) {<br>
>  _public_ int sd_journal_get_data_threshold(sd_journal *j, size_t *sz) {<br>
>          if (!j)<br>
>                  return -EINVAL;<br>
> +        if (journal_pid_changed(j))<br>
> +                return -ECHILD;<br>
>          if (!sz)<br>
>                  return -EINVAL;<br>
><br>
<br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">Lennart<br>
<br>
--<br>
Lennart Poettering - Red Hat, Inc.<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
systemd-devel mailing list<br>
<a href="mailto:systemd-devel@lists.freedesktop.org">systemd-devel@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/systemd-devel" target="_blank">http://lists.freedesktop.org/mailman/listinfo/systemd-devel</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br><div dir="ltr"><br>---<br>Shawn Landden<br><div>+1 360 389 3001 (SMS preferred)</div></div>
</div></div></div>