- journal: add a setgid "systemd-journal" utility to invoke from libsystemd-journal, which passes fds via STDOUT and does PK access
- journactl: support negative filtering, i.e. FOOBAR!="waldo",
and !FOOBAR for events without FOOBAR.
- - journal: store timestamp of journal_file_set_offline() int he header,
+ - journal: store timestamp of journal_file_set_offline() in the header,
so it is possible to display when the file was last synced.
- journal-send.c, log.c: when the log socket is clogged, and we drop, count this and write a message about this when it gets unclogged again.
- journal: find a way to allow dropping history early, based on priority, other rules
them via machined, and also watch containers coming and going.
Benefit: nspawn --ephemeral would start working nicely with the journal.
- assign MESSAGE_ID to log messages about failed services
+ - check if loop in decompress_blob_xz() is necessary
* add a test if all entries in the catalog are properly formatted.
(Adding dashes in a catalog entry currently results in the catalog entry
<refnamediv>
<refname>sd_journal_get_data</refname>
<refname>sd_journal_enumerate_data</refname>
+ <refname>sd_journal_enumerate_available_data</refname>
<refname>sd_journal_restart_data</refname>
<refname>SD_JOURNAL_FOREACH_DATA</refname>
<refname>sd_journal_set_data_threshold</refname>
<paramdef>size_t *<parameter>length</parameter></paramdef>
</funcprototype>
+ <funcprototype>
+ <funcdef>int <function>sd_journal_enumerate_available_data</function></funcdef>
+ <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+ <paramdef>const void **<parameter>data</parameter></paramdef>
+ <paramdef>size_t *<parameter>length</parameter></paramdef>
+ </funcprototype>
+
<funcprototype>
<funcdef>void <function>sd_journal_restart_data</function></funcdef>
<paramdef>sd_journal *<parameter>j</parameter></paramdef>
<refsect1>
<title>Description</title>
- <para><function>sd_journal_get_data()</function> gets the data
- object associated with a specific field from the current journal
- entry. It takes four arguments: the journal context object, a
- string with the field name to request, plus a pair of pointers to
- pointer/size variables where the data object and its size shall be
- stored in. The field name should be an entry field name.
- Well-known field names are listed in
- <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
- The returned data is in a read-only memory map and is only valid
- until the next invocation of
- <function>sd_journal_get_data()</function> or
- <function>sd_journal_enumerate_data()</function>, or the read
- pointer is altered. Note that the data returned will be prefixed
- with the field name and '='. Also note that, by default, data fields
- larger than 64K might get truncated to 64K. This threshold may be
- changed and turned off with
- <function>sd_journal_set_data_threshold()</function> (see
- below).</para>
+ <para><function>sd_journal_get_data()</function> gets the data object associated with a specific field
+ from the current journal entry. It takes four arguments: the journal context object, a string with the
+ field name to request, plus a pair of pointers to pointer/size variables where the data object and its
+ size shall be stored in. The field name should be an entry field name. Well-known field names are listed in
+ <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ but any field can be specified. The returned data is in a read-only memory map and is only valid until
+ the next invocation of <function>sd_journal_get_data()</function>,
+ <function>sd_journal_enumerate_data()</function>,
+ <function>sd_journal_enumerate_available_data()</function>, or when the read pointer is altered. Note
+ that the data returned will be prefixed with the field name and <literal>=</literal>. Also note that, by
+ default, data fields larger than 64K might get truncated to 64K. This threshold may be changed and turned
+ off with <function>sd_journal_set_data_threshold()</function> (see below).</para>
<para><function>sd_journal_enumerate_data()</function> may be used
to iterate through all fields of the current entry. On each
format as with <function>sd_journal_get_data()</function> and also
follows the same life-time semantics.</para>
+ <para><function>sd_journal_enumerate_available_data()</function> is similar to
+ <function>sd_journal_enumerate_data()</function>, but silently skips any fields which may be valid, but
+ are too large or not supported by current implementation.</para>
+
<para><function>sd_journal_restart_data()</function> resets the
data enumeration index to the beginning of the entry. The next
invocation of <function>sd_journal_enumerate_data()</function>
will return the first field of the entry again.</para>
- <para>Note that the <function>SD_JOURNAL_FOREACH_DATA()</function>
- macro may be used as a handy wrapper around
- <function>sd_journal_restart_data()</function> and
- <function>sd_journal_enumerate_data()</function>.</para>
+ <para>Note that the <function>SD_JOURNAL_FOREACH_DATA()</function> macro may be used as a handy wrapper
+ around <function>sd_journal_restart_data()</function> and
+ <function>sd_journal_enumerate_available_data()</function>.</para>
<para>Note that these functions will not work before
<citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<refsect1>
<title>Return Value</title>
- <para><function>sd_journal_get_data()</function> returns 0 on
- success or a negative errno-style error code. If the current entry
- does not include the specified field, -ENOENT is returned. If
- <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
- has not been called at least once, -EADDRNOTAVAIL is returned.
- <function>sd_journal_enumerate_data()</function> returns a
- positive integer if the next field has been read, 0 when no more
- fields are known, or a negative errno-style error code.
- <function>sd_journal_restart_data()</function> returns nothing.
- <function>sd_journal_set_data_threshold()</function> and
- <function>sd_journal_get_threshold()</function> return 0 on
- success or a negative errno-style error code.</para>
+ <para><function>sd_journal_get_data()</function> returns 0 on success or a negative errno-style error
+ code. <function>sd_journal_enumerate_data()</function> and
+ <function>sd_journal_enumerate_available_data()</function> return a positive integer if the next field
+ has been read, 0 when no more fields remain, or a negative errno-style error code.
+ <function>sd_journal_restart_data()</function> doesn't return anything.
+ <function>sd_journal_set_data_threshold()</function> and <function>sd_journal_get_threshold()</function>
+ return 0 on success or a negative errno-style error code.</para>
+
+ <refsect2>
+ <title>Errors</title>
+
+ <para>Returned errors may indicate the following problems:</para>
+
+ <variablelist>
+ <varlistentry id='EINVAL'>
+ <term><constant>-EINVAL</constant></term>
+
+ <listitem><para>One of the required parameters is <constant>NULL</constant> or invalid.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry id='ECHILD'>
+ <term><constant>-ECHILD</constant></term>
+
+ <listitem><para>The journal object was created in a different process.</para></listitem>
+ </varlistentry>
+
+ <varlistentry id='EADDRNOTAVAIL'>
+ <term><constant>-EADDRNOTAVAIL</constant></term>
+
+ <listitem><para>The read pointer is not positioned at a valid entry;
+ <citerefentry><refentrytitle>sd_journal_next</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ or a related call has not been called at least once.</para></listitem>
+ </varlistentry>
+
+ <varlistentry id='ENOENT'>
+ <term><constant>-ENOENT</constant></term>
+
+ <listitem><para>The current entry does not include the specified field.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id='ENOMEM'>
+ <term><constant>-ENOMEM</constant></term>
+
+ <listitem><para>Memory allocation failed.</para></listitem>
+ </varlistentry>
+
+ <varlistentry id='ENOBUFS'>
+ <term><constant>-ENOBUFS</constant></term>
+
+ <listitem><para>A compressed entry is too large.</para></listitem>
+ </varlistentry>
+
+ <varlistentry id='E2BIG'>
+ <term><constant>-E2BIG</constant></term>
+
+ <listitem><para>The data field is too large for this computer architecture (e.g. above 4 GB on a
+ 32-bit architecture).</para></listitem>
+ </varlistentry>
+
+ <varlistentry id='EPROTONOSUPPORT'>
+ <term><constant>-EPROTONOSUPPORT</constant></term>
+
+ <listitem><para>The journal is compressed with an unsupported method or the journal uses an
+ unsupported feature.</para></listitem>
+ </varlistentry>
+
+ <varlistentry id='EBADMSG'>
+ <term><constant>-EBADMSG</constant></term>
+
+ <listitem><para>The journal is corrupted (possibly just the entry being iterated over).
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry id='EIO'>
+ <term><constant>-EIO</constant></term>
+
+ <listitem><para>An I/O error was reported by the kernel.</para></listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
</refsect1>
<refsect1>
<refnamediv>
<refname>sd_journal_query_unique</refname>
<refname>sd_journal_enumerate_unique</refname>
+ <refname>sd_journal_enumerate_available_unique</refname>
<refname>sd_journal_restart_unique</refname>
<refname>SD_JOURNAL_FOREACH_UNIQUE</refname>
<refpurpose>Read unique data fields from the journal</refpurpose>
<paramdef>const char *<parameter>field</parameter></paramdef>
</funcprototype>
+ <funcprototype>
+ <funcdef>int <function>sd_journal_enumerate_available_unique</function></funcdef>
+ <paramdef>sd_journal *<parameter>j</parameter></paramdef>
+ <paramdef>const void **<parameter>data</parameter></paramdef>
+ <paramdef>size_t *<parameter>length</parameter></paramdef>
+ </funcprototype>
+
<funcprototype>
<funcdef>int <function>sd_journal_enumerate_unique</function></funcdef>
<paramdef>sd_journal *<parameter>j</parameter></paramdef>
<refsect1>
<title>Description</title>
- <para><function>sd_journal_query_unique()</function> queries the
- journal for all unique values the specified field can take. It
- takes two arguments: the journal to query and the field name to
- look for. Well-known field names are listed on
- <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
- Field names must be specified without a trailing '='. After this
- function has been executed successfully the field values may be
- queried using <function>sd_journal_enumerate_unique()</function>.
- Invoking this call a second time will change the field name being
- queried and reset the enumeration index to the first field value
- that matches.</para>
-
- <para><function>sd_journal_enumerate_unique()</function> may be
- used to iterate through all data fields which match the previously
- selected field name as set with
- <function>sd_journal_query_unique()</function>. On each invocation
- the next field data matching the field name is returned. The order
- of the returned data fields is not defined. It takes three
- arguments: the journal context object, plus a pair of pointers to
- pointer/size variables where the data object and its size shall be
- stored in. The returned data is in a read-only memory map and is
- only valid until the next invocation of
- <function>sd_journal_enumerate_unique()</function>. Note that the
- data returned will be prefixed with the field name and '='. Note
- that this call is subject to the data field size threshold as
- controlled by
- <function>sd_journal_set_data_threshold()</function>.</para>
+ <para><function>sd_journal_query_unique()</function> queries the journal for all unique values the
+ specified field can take. It takes two arguments: the journal to query and the field name to look
+ for. Well-known field names are listed on
+ <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ but any field can be specified. Field names must be specified without a trailing
+ <literal>=</literal>. After this function has been executed successfully the field values may be queried
+ using <function>sd_journal_enumerate_unique()</function> and
+ <function>sd_journal_enumerate_available_unique()</function>. Invoking one of those calls will change the
+ field name being queried and reset the enumeration index to the first field value that matches.</para>
+
+ <para><function>sd_journal_enumerate_unique()</function> may be used to iterate through all data fields
+ which match the previously selected field name as set with
+ <function>sd_journal_query_unique()</function>. On each invocation the next field data matching the field
+ name is returned. The order of the returned data fields is not defined. It takes three arguments: the
+ journal object, plus a pair of pointers to pointer/size variables where the data object and its size
+ shall be stored. The returned data is in a read-only memory map and is only valid until the next
+ invocation of <function>sd_journal_enumerate_unique()</function>. Note that the data returned will be
+ prefixed with the field name and <literal>=</literal>. Note that this call is subject to the data field
+ size threshold as controlled by <function>sd_journal_set_data_threshold()</function> and only the initial
+ part of the field up to the threshold is returned. An error is returned for fields which cannot be
+ retrieved. See the error list below for details.</para>
+
+ <para><function>sd_journal_enumerate_available_unique()</function> is similar to
+ <function>sd_journal_enumerate_unique()</function>, but silently skips any fields which may be valid, but
+ are too large or not supported by current implementation.</para>
<para><function>sd_journal_restart_unique()</function> resets the
data enumeration index to the beginning of the list. The next
will return the first field data matching the field name
again.</para>
- <para>Note that the
- <function>SD_JOURNAL_FOREACH_UNIQUE()</function> macro may be used
- as a handy wrapper around
- <function>sd_journal_restart_unique()</function> and
- <function>sd_journal_enumerate_unique()</function>.</para>
+ <para>Note that the <function>SD_JOURNAL_FOREACH_UNIQUE()</function> macro may be used as a handy wrapper
+ around <function>sd_journal_restart_unique()</function> and
+ <function>sd_journal_enumerate_available_unique()</function>.</para>
<para>Note that these functions currently are not influenced by
matches set with <function>sd_journal_add_match()</function> but
<refsect1>
<title>Return Value</title>
- <para><function>sd_journal_query_unique()</function> returns 0 on
- success or a negative errno-style error code.
- <function>sd_journal_enumerate_unique()</function> returns a
- positive integer if the next field data has been read, 0 when no
- more fields are known, or a negative errno-style error code.
- <function>sd_journal_restart_unique()</function> returns
- nothing.</para>
+ <para><function>sd_journal_query_unique()</function> returns 0 on success or a negative errno-style error
+ code. <function>sd_journal_enumerate_unique()</function> and and
+ <function>sd_journal_query_available_unique()</function> return a positive integer if the next field data
+ has been read, 0 when no more fields remain, or a negative errno-style error code.
+ <function>sd_journal_restart_unique()</function> doesn't return anything.</para>
+
+ <refsect2>
+ <title>Errors</title>
+
+ <para>Returned errors may indicate the following problems:</para>
+
+ <variablelist>
+ <xi:include href="sd_journal_get_data.xml" xpointer="EINVAL"/>
+ <xi:include href="sd_journal_get_data.xml" xpointer="ECHILD"/>
+ <xi:include href="sd_journal_get_data.xml" xpointer="EADDRNOTAVAIL"/>
+ <xi:include href="sd_journal_get_data.xml" xpointer="ENOENT"/>
+ <xi:include href="sd_journal_get_data.xml" xpointer="ENOBUFS"/>
+ <xi:include href="sd_journal_get_data.xml" xpointer="E2BIG"/>
+ <xi:include href="sd_journal_get_data.xml" xpointer="EPROTONOSUPPORT"/>
+ <xi:include href="sd_journal_get_data.xml" xpointer="EBADMSG"/>
+ <xi:include href="sd_journal_get_data.xml" xpointer="EIO"/>
+ </variablelist>
+ </refsect2>
</refsect1>
<refsect1>
<refsect1>
<title>Examples</title>
- <para>Use the <function>SD_JOURNAL_FOREACH_UNIQUE</function> macro
- to iterate through all values a field of the journal can take. The
- following example lists all unit names referenced in the
- journal:</para>
+ <para>Use the <function>SD_JOURNAL_FOREACH_UNIQUE</function> macro to iterate through all values a field
+ of the journal can take (and which can be accessed on the given architecture and are not compressed with
+ an unsupported mechanism). The following example lists all unit names referenced in the journal:</para>
<programlisting><xi:include href="journal-iterate-unique.c" parse="text" /></programlisting>
</refsect1>
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
details about named file descriptors and their ordering.</para>
- <para>This setting defaults to <option>null</option>.</para>
-
- <para>Note that services which specify <option>DefaultDependencies=no</option> and use
- <varname>StandardInput=</varname> or <varname>StandardOutput=</varname> with
- <option>tty</option>/<option>tty-force</option>/<option>tty-fail</option>, should specify
- <option>After=systemd-vconsole-setup.service</option>, to make sure that the tty initialization is
- finished before they start.</para></listitem>
+ <para>This setting defaults to <option>null</option>.</para></listitem>
</varlistentry>
<varlistentry>
static int fix_acl(int fd, uid_t uid) {
#if HAVE_ACL
- _cleanup_(acl_freep) acl_t acl = NULL;
- acl_entry_t entry;
- acl_permset_t permset;
int r;
assert(fd >= 0);
+ assert(uid_is_valid(uid));
if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY)
return 0;
- /* Make sure normal users can read (but not write or delete)
- * their own coredumps */
-
- acl = acl_get_fd(fd);
- if (!acl)
- return log_error_errno(errno, "Failed to get ACL: %m");
-
- if (acl_create_entry(&acl, &entry) < 0 ||
- acl_set_tag_type(entry, ACL_USER) < 0 ||
- acl_set_qualifier(entry, &uid) < 0)
- return log_error_errno(errno, "Failed to patch ACL: %m");
-
- if (acl_get_permset(entry, &permset) < 0 ||
- acl_add_perm(permset, ACL_READ) < 0)
- return log_warning_errno(errno, "Failed to patch ACL: %m");
-
- r = calc_acl_mask_if_needed(&acl);
+ /* Make sure normal users can read (but not write or delete) their own coredumps */
+ r = add_acls_for_user(fd, uid);
if (r < 0)
- return log_warning_errno(r, "Failed to patch ACL: %m");
-
- if (acl_set_fd(fd, acl) < 0)
- return log_error_errno(errno, "Failed to apply ACL: %m");
+ return log_error_errno(r, "Failed to adjust ACL of coredump: %m");
#endif
return 0;
X509 *cert;
};
+#if HAVE_P11KIT
static void pkcs11_callback_data_release(struct pkcs11_callback_data *data) {
erase_and_free(data->pin_used);
X509_free(data->cert);
}
-#if HAVE_P11KIT
static int pkcs11_callback(
CK_FUNCTION_LIST *m,
CK_SESSION_HANDLE session,
int decompress_blob_zstd(
const void *src, uint64_t src_size,
- void **dst, size_t *dst_alloc_size, size_t* dst_size, size_t dst_max) {
+ void **dst, size_t *dst_alloc_size, size_t *dst_size, size_t dst_max) {
#if HAVE_ZSTD
- size_t space;
+ uint64_t size;
assert(src);
assert(src_size > 0);
assert(dst_size);
assert(*dst_alloc_size == 0 || *dst);
- if (src_size > SIZE_MAX/2) /* Overflow? */
- return -ENOBUFS;
- space = src_size * 2;
- if (dst_max > 0 && space > dst_max)
- space = dst_max;
-
- if (!greedy_realloc(dst, dst_alloc_size, space, 1))
- return -ENOMEM;
+ size = ZSTD_getFrameContentSize(src, src_size);
+ if (IN_SET(size, ZSTD_CONTENTSIZE_ERROR, ZSTD_CONTENTSIZE_UNKNOWN))
+ return -EBADMSG;
- for (;;) {
- size_t k;
+ if (dst_max > 0 && size > dst_max)
+ size = dst_max;
+ if (size > SIZE_MAX)
+ return -E2BIG;
- k = ZSTD_decompress(*dst, *dst_alloc_size, src, src_size);
- if (!ZSTD_isError(k)) {
- *dst_size = k;
- return 0;
- }
- if (ZSTD_getErrorCode(k) != ZSTD_error_dstSize_tooSmall)
- return zstd_ret_to_errno(k);
+ if (!(greedy_realloc(dst, dst_alloc_size, MAX(ZSTD_DStreamOutSize(), size), 1)))
+ return -ENOMEM;
- if (dst_max > 0 && space >= dst_max) /* Already at max? */
- return -ENOBUFS;
- if (space > SIZE_MAX / 2) /* Overflow? */
- return -ENOBUFS;
+ _cleanup_(ZSTD_freeDCtxp) ZSTD_DCtx *dctx = ZSTD_createDCtx();
+ if (!dctx)
+ return -ENOMEM;
- space *= 2;
- if (dst_max > 0 && space > dst_max)
- space = dst_max;
+ ZSTD_inBuffer input = {
+ .src = src,
+ .size = src_size,
+ };
+ ZSTD_outBuffer output = {
+ .dst = *dst,
+ .size = *dst_alloc_size,
+ };
- if (!greedy_realloc(dst, dst_alloc_size, space, 1))
- return -ENOMEM;
+ size_t k = ZSTD_decompressStream(dctx, &output, &input);
+ if (ZSTD_isError(k)) {
+ log_debug("ZSTD decoder failed: %s", ZSTD_getErrorName(k));
+ return zstd_ret_to_errno(k);
}
+ assert(output.pos >= size);
+
+ *dst_size = size;
+ return 0;
#else
return -EPROTONOSUPPORT;
#endif
src, src_size,
dst, dst_alloc_size, dst_size, dst_max);
else
- return -EBADMSG;
+ return -EPROTONOSUPPORT;
}
int decompress_startswith_xz(const void *src, uint64_t src_size,
const void *prefix, size_t prefix_len,
uint8_t extra) {
#if HAVE_ZSTD
- _cleanup_(ZSTD_freeDCtxp) ZSTD_DCtx *dctx = NULL;
- size_t k;
-
assert(src);
assert(src_size > 0);
assert(buffer);
assert(prefix);
assert(*buffer_size == 0 || *buffer);
- dctx = ZSTD_createDCtx();
+ uint64_t size = ZSTD_getFrameContentSize(src, src_size);
+ if (IN_SET(size, ZSTD_CONTENTSIZE_ERROR, ZSTD_CONTENTSIZE_UNKNOWN))
+ return -EBADMSG;
+
+ if (size < prefix_len + 1)
+ return 0; /* Decompressed text too short to match the prefix and extra */
+
+ _cleanup_(ZSTD_freeDCtxp) ZSTD_DCtx *dctx = ZSTD_createDCtx();
if (!dctx)
return -ENOMEM;
.dst = *buffer,
.size = *buffer_size,
};
+ size_t k;
- for (;;) {
- k = ZSTD_decompressStream(dctx, &output, &input);
- if (ZSTD_isError(k)) {
- log_debug("ZSTD decoder failed: %s", ZSTD_getErrorName(k));
- return zstd_ret_to_errno(k);
- }
-
- if (output.pos >= prefix_len + 1)
- return memcmp(*buffer, prefix, prefix_len) == 0 &&
- ((const uint8_t*) *buffer)[prefix_len] == extra;
-
- if (input.pos >= input.size)
- return 0;
-
- if (*buffer_size > SIZE_MAX/2)
- return -ENOBUFS;
-
- if (!(greedy_realloc(buffer, buffer_size, *buffer_size * 2, 1)))
- return -ENOMEM;
-
- output.dst = *buffer;
- output.size = *buffer_size;
+ k = ZSTD_decompressStream(dctx, &output, &input);
+ if (ZSTD_isError(k)) {
+ log_debug("ZSTD decoder failed: %s", ZSTD_getErrorName(k));
+ return zstd_ret_to_errno(k);
}
+ assert(output.pos >= prefix_len + 1);
+
+ return memcmp(*buffer, prefix, prefix_len) == 0 &&
+ ((const uint8_t*) *buffer)[prefix_len] == extra;
#else
return -EPROTONOSUPPORT;
#endif
#define JOURNAL_FOREACH_DATA_RETVAL(j, data, l, retval) \
for (sd_journal_restart_data(j); ((retval) = sd_journal_enumerate_data((j), &(data), &(l))) > 0; )
+
+/* All errors that we might encounter while extracting a field that are not real errors,
+ * but only mean that the field is too large or we don't support the compression. */
+static inline bool JOURNAL_ERRNO_IS_UNAVAILABLE_FIELD(int r) {
+ return IN_SET(abs(r),
+ ENOBUFS, /* Field or decompressed field too large */
+ E2BIG, /* Field too large for pointer width */
+ EPROTONOSUPPORT); /* Unsupported compression */
+}
return 1;
}
+_public_ int sd_journal_enumerate_available_data(sd_journal *j, const void **data, size_t *size) {
+ for (;;) {
+ int r;
+
+ r = sd_journal_enumerate_data(j, data, size);
+ if (r >= 0)
+ return r;
+ if (!JOURNAL_ERRNO_IS_UNAVAILABLE_FIELD(r))
+ return r;
+ j->current_field++; /* Try with the next field */
+ }
+}
+
_public_ void sd_journal_restart_data(sd_journal *j) {
if (!j)
return;
}
}
+_public_ int sd_journal_enumerate_available_unique(sd_journal *j, const void **data, size_t *size) {
+ for (;;) {
+ int r;
+
+ r = sd_journal_enumerate_unique(j, data, size);
+ if (r >= 0)
+ return r;
+ if (!JOURNAL_ERRNO_IS_UNAVAILABLE_FIELD(r))
+ return r;
+ /* Try with the next field. sd_journal_enumerate_unique() modifies state, so on the next try
+ * we will access the next field. */
+ }
+}
+
_public_ void sd_journal_restart_unique(sd_journal *j) {
if (!j)
return;
int r;
_cleanup_free_ char *huge = NULL;
+ log_debug("/* %s */", __func__);
+
assert_se(huge = malloc(HUGE_SIZE));
memcpy(huge, "HUGE=", STRLEN("HUGE="));
memset(&huge[STRLEN("HUGE=")], 'x', HUGE_SIZE - STRLEN("HUGE=") - 1);
sd_path_lookup_strv;
sd_notify_barrier;
+
+ sd_journal_enumerate_available_data;
+ sd_journal_enumerate_available_unique;
} LIBSYSTEMD_245;
int add_acls_for_user(int fd, uid_t uid) {
_cleanup_(acl_freep) acl_t acl = NULL;
- acl_entry_t entry;
acl_permset_t permset;
+ acl_entry_t entry;
int r;
+ assert(fd >= 0);
+ assert(uid_is_valid(uid));
+
acl = acl_get_fd(fd);
if (!acl)
return -errno;
return -errno;
}
- /* We do not recalculate the mask unconditionally here,
- * so that the fchmod() mask above stays intact. */
+ /* We do not recalculate the mask unconditionally here, so that the fchmod() mask above stays
+ * intact. */
if (acl_get_permset(entry, &permset) < 0 ||
acl_add_perm(permset, ACL_READ) < 0)
return -errno;
if (r < 0)
return r;
- return acl_set_fd(fd, acl);
+ if (acl_set_fd(fd, acl) < 0)
+ return -errno;
+
+ return 0;
}
int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *l);
int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *l);
+int sd_journal_enumerate_available_data(sd_journal *j, const void **data, size_t *l);
void sd_journal_restart_data(sd_journal *j);
int sd_journal_add_match(sd_journal *j, const void *data, size_t size);
int sd_journal_query_unique(sd_journal *j, const char *field);
int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l);
+int sd_journal_enumerate_available_unique(sd_journal *j, const void **data, size_t *l);
void sd_journal_restart_unique(sd_journal *j);
int sd_journal_enumerate_fields(sd_journal *j, const char **field);
if (sd_journal_seek_tail(j) < 0) { } \
else while (sd_journal_previous(j) > 0)
-/* Iterate through the data fields of the current journal entry */
+/* Iterate through all available data fields of the current journal entry */
#define SD_JOURNAL_FOREACH_DATA(j, data, l) \
- for (sd_journal_restart_data(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; )
+ for (sd_journal_restart_data(j); sd_journal_enumerate_available_data((j), &(data), &(l)) > 0; )
-/* Iterate through the all known values of a specific field */
+/* Iterate through all available values of a specific field */
#define SD_JOURNAL_FOREACH_UNIQUE(j, data, l) \
- for (sd_journal_restart_unique(j); sd_journal_enumerate_unique((j), &(data), &(l)) > 0; )
+ for (sd_journal_restart_unique(j); sd_journal_enumerate_available_unique((j), &(data), &(l)) > 0; )
/* Iterate through all known field names */
#define SD_JOURNAL_FOREACH_FIELD(j, field) \
else
inst_rules 10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
fi
+ if [[ "$LOOKS_LIKE_SUSE" ]]; then
+ inst_rules 60-persistent-storage.rules 61-persistent-storage-compat.rules 99-systemd.rules
+ fi
}
install_systemd() {
inst /etc/sysconfig/init || :
inst /etc/passwd
inst /etc/shadow
- inst /etc/login.defs
+ inst_any /etc/login.defs /usr/etc/login.defs
inst /etc/group
inst /etc/shells
inst_any /etc/nsswitch.conf /usr/etc/nsswitch.conf
ln -fs ../usr/bin/systemctl $initdir/bin/
ln -fs ../usr/lib/systemd $initdir/lib/
inst_simple "/usr/lib/systemd/system/haveged.service"
+ instmods ext4
}
_umount_dir() {