[systemd-commits] 7 commits - .gitignore Makefile.am TODO src/journal src/login
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Nov 26 17:40:18 PST 2013
.gitignore | 1
Makefile.am | 7 +
TODO | 5 -
src/journal/journal-file.c | 157 ++++++++++++++++++++++++++-------------
src/journal/journald-server.c | 11 ++
src/journal/test-journal-flush.c | 71 +++++++++++++++++
src/login/logind-action.c | 20 +++-
src/login/logind-core.c | 2
src/login/logind-dbus.c | 17 ++--
src/login/logind-inhibit.c | 6 +
src/login/logind-inhibit.h | 2
11 files changed, 231 insertions(+), 68 deletions(-)
New commits:
commit 85a428c69465b047731b6abb5005f01824f1444e
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Nov 27 02:38:06 2013 +0100
logind: log which process is delaying suspend and not closing locks
diff --git a/src/login/logind-action.c b/src/login/logind-action.c
index cb64df0..7744add 100644
--- a/src/login/logind-action.c
+++ b/src/login/logind-action.c
@@ -58,6 +58,7 @@ int manager_handle_action(
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
InhibitWhat inhibit_operation;
+ Inhibitor *offending = NULL;
bool supported;
int r;
@@ -71,7 +72,7 @@ int manager_handle_action(
/* If the key handling is inhibited, don't do anything */
if (inhibit_key > 0) {
- if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0)) {
+ if (manager_is_inhibited(m, inhibit_key, INHIBIT_BLOCK, NULL, true, false, 0, NULL)) {
log_debug("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_key));
return 0;
}
@@ -109,15 +110,26 @@ int manager_handle_action(
/* If the actual operation is inhibited, warn and fail */
if (!ignore_inhibited &&
- manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0)) {
+ manager_is_inhibited(m, inhibit_operation, INHIBIT_BLOCK, NULL, false, false, 0, &offending)) {
+ _cleanup_free_ char *comm = NULL, *u = NULL;
+
+ get_process_comm(offending->pid, &comm);
+ u = uid_to_name(offending->uid);
/* If this is just a recheck of the lid switch then don't warn about anything */
if (!is_edge) {
- log_debug("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation));
+ log_debug("Refusing operation, %s is inhibited by UID %lu/%s, PID %lu/%s.",
+ inhibit_what_to_string(inhibit_operation),
+ (unsigned long) offending->uid, strna(u),
+ (unsigned long) offending->pid, strna(comm));
return 0;
}
- log_error("Refusing operation, %s is inhibited.", inhibit_what_to_string(inhibit_operation));
+ log_error("Refusing operation, %s is inhibited by UID %lu/%s, PID %lu/%s.",
+ inhibit_what_to_string(inhibit_operation),
+ (unsigned long) offending->uid, strna(u),
+ (unsigned long) offending->pid, strna(comm));
+
warn_melody();
return -EPERM;
}
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 9c31bf8..72ee9fe 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -389,7 +389,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t) {
assert(m);
- idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0);
+ idle_hint = !manager_is_inhibited(m, INHIBIT_IDLE, INHIBIT_BLOCK, t, false, false, 0, NULL);
HASHMAP_FOREACH(s, m->sessions, i) {
dual_timestamp k;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index a972d93..e0333cd 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -1399,7 +1399,7 @@ int bus_manager_shutdown_or_sleep_now_or_later(
delayed =
m->inhibit_delay_max > 0 &&
- manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0);
+ manager_is_inhibited(m, w, INHIBIT_DELAY, NULL, false, false, 0, NULL);
if (delayed)
/* Shutdown is delayed, keep in mind what we
@@ -1465,7 +1465,7 @@ static int method_do_shutdown_or_sleep(
return r;
multiple_sessions = r > 0;
- blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid);
+ blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
if (multiple_sessions) {
r = bus_verify_polkit_async(m->bus, &m->polkit_registry, message,
@@ -1610,7 +1610,7 @@ static int method_can_shutdown_or_sleep(
return r;
multiple_sessions = r > 0;
- blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid);
+ blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
if (multiple_sessions) {
r = bus_verify_polkit(m->bus, message, action_multiple_sessions, false, &challenge, error);
@@ -2105,6 +2105,7 @@ int manager_send_changed(Manager *manager, const char *property, ...) {
int manager_dispatch_delayed(Manager *manager) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+ Inhibitor *offending = NULL;
int r;
assert(manager);
@@ -2113,12 +2114,18 @@ int manager_dispatch_delayed(Manager *manager) {
return 0;
/* Continue delay? */
- if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0)) {
+ if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) {
+ _cleanup_free_ char *comm = NULL, *u = NULL;
+
+ get_process_comm(offending->pid, &comm);
+ u = uid_to_name(offending->uid);
if (manager->action_timestamp + manager->inhibit_delay_max > now(CLOCK_MONOTONIC))
return 0;
- log_info("Delay lock is active but inhibitor timeout is reached.");
+ log_info("Delay lock is active (UID %lu/%s, PID %lu/%s) but inhibitor timeout is reached.",
+ (unsigned long) offending->uid, strna(u),
+ (unsigned long) offending->pid, strna(comm));
}
/* Actually do the operation */
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
index 1b6f136..35e1abd 100644
--- a/src/login/logind-inhibit.c
+++ b/src/login/logind-inhibit.c
@@ -372,7 +372,8 @@ bool manager_is_inhibited(
dual_timestamp *since,
bool ignore_inactive,
bool ignore_uid,
- uid_t uid) {
+ uid_t uid,
+ Inhibitor **offending) {
Inhibitor *i;
Iterator j;
@@ -400,6 +401,9 @@ bool manager_is_inhibited(
ts = i->since;
inhibited = true;
+
+ if (offending)
+ *offending = i;
}
if (since)
diff --git a/src/login/logind-inhibit.h b/src/login/logind-inhibit.h
index da3d7e7..f767876 100644
--- a/src/login/logind-inhibit.h
+++ b/src/login/logind-inhibit.h
@@ -85,7 +85,7 @@ int inhibitor_create_fifo(Inhibitor *i);
void inhibitor_remove_fifo(Inhibitor *i);
InhibitWhat manager_inhibit_what(Manager *m, InhibitMode mm);
-bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid);
+bool manager_is_inhibited(Manager *m, InhibitWhat w, InhibitMode mm, dual_timestamp *since, bool ignore_inactive, bool ignore_uid, uid_t uid, Inhibitor **offending);
const char *inhibit_what_to_string(InhibitWhat k);
InhibitWhat inhibit_what_from_string(const char *s);
commit fbb634117d0b0ebd5b105e65b141e75ae9af7f8f
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Nov 27 01:54:25 2013 +0100
journald: mention how long we needed to flush to /var in the logs
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index ce419d4..01e75b6 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -970,9 +970,12 @@ static int system_journal_open(Server *s) {
}
int server_flush_to_var(Server *s) {
- int r;
sd_id128_t machine;
sd_journal *j = NULL;
+ char ts[FORMAT_TIMESPAN_MAX];
+ usec_t start;
+ unsigned n = 0;
+ int r;
assert(s);
@@ -990,6 +993,8 @@ int server_flush_to_var(Server *s) {
log_debug("Flushing to /var...");
+ start = now(CLOCK_MONOTONIC);
+
r = sd_id128_get_machine(&machine);
if (r < 0)
return r;
@@ -1009,6 +1014,8 @@ int server_flush_to_var(Server *s) {
f = j->current_file;
assert(f && f->current_offset > 0);
+ n++;
+
r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
if (r < 0) {
log_error("Can't read entry: %s", strerror(-r));
@@ -1052,6 +1059,8 @@ finish:
sd_journal_close(j);
+ server_driver_message(s, SD_ID128_NULL, "Time spent on flushing to /var is %s for %u entries.", format_timespan(ts, sizeof(ts), now(CLOCK_MONOTONIC) - start, 0), n);
+
return r;
}
commit eda4b58b50509dc8ad0428a46e20f6c5cf516d58
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Nov 27 01:44:52 2013 +0100
journal: simplify pre-allocation logic
let's just do a single fallocate() as far as possible, and don't
distuingish between allocated space and file size.
This way we can save a syscall for each append, which makes quite some
benefits.
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 14eae8f..4009b29 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -315,7 +315,7 @@ static int journal_file_verify_header(JournalFile *f) {
}
static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) {
- uint64_t old_size, new_size, file_size;
+ uint64_t old_size, new_size;
int r;
assert(f);
@@ -356,6 +356,11 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
}
}
+ /* Increase by larger blocks at once */
+ new_size = ((new_size+FILE_SIZE_INCREASE-1) / FILE_SIZE_INCREASE) * FILE_SIZE_INCREASE;
+ if (f->metrics.max_size > 0 && new_size > f->metrics.max_size)
+ new_size = f->metrics.max_size;
+
/* Note that the glibc fallocate() fallback is very
inefficient, hence we try to minimize the allocation area
as we can. */
@@ -363,16 +368,8 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
if (r != 0)
return -r;
- /* Increase the file size a bit further than this, so that we
- * we can create larger memory maps to cache */
- file_size = ((new_size+FILE_SIZE_INCREASE-1) / FILE_SIZE_INCREASE) * FILE_SIZE_INCREASE;
- if (file_size > (uint64_t) f->last_stat.st_size) {
- if (file_size > new_size)
- ftruncate(f->fd, file_size);
-
- if (fstat(f->fd, &f->last_stat) < 0)
- return -errno;
- }
+ if (fstat(f->fd, &f->last_stat) < 0)
+ return -errno;
f->header->arena_size = htole64(new_size - le64toh(f->header->header_size));
commit d0767ffd08bbb5c069e266710eb0462315e47e6d
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Nov 27 01:01:53 2013 +0100
journal: add a test case for flushing messages out of a series of journal files into a single new one
diff --git a/.gitignore b/.gitignore
index 8d0d770..f8f6c8a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -123,6 +123,7 @@
/test-job-type
/test-journal
/test-journal-enum
+/test-journal-flush
/test-journal-interleaving
/test-journal-match
/test-journal-send
diff --git a/Makefile.am b/Makefile.am
index 47c269d..0119751 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2961,6 +2961,12 @@ test_journal_stream_SOURCES = \
test_journal_stream_LDADD = \
libsystemd-journal-core.la
+test_journal_flush_SOURCES = \
+ src/journal/test-journal-flush.c
+
+test_journal_flush_LDADD = \
+ libsystemd-journal-core.la
+
test_journal_init_SOURCES = \
src/journal/test-journal-init.c
@@ -3167,6 +3173,7 @@ tests += \
test-journal-init \
test-journal-verify \
test-journal-interleaving \
+ test-journal-flush \
test-mmap-cache \
test-catalog
diff --git a/TODO b/TODO
index 653258a..3383f35 100644
--- a/TODO
+++ b/TODO
@@ -85,8 +85,6 @@ Features:
* be more careful what we export on the bus as (usec_t) 0 and (usec_t) -1
-* increase journal files by a few MB each time, instead of piecemeal
-
* add field to transient units that indicate whether systemd or somebody else saves/restores its settings, for integration with libvirt
* systemctl: rework wait filter to not require match callback
@@ -392,9 +390,6 @@ Features:
* service: watchdog logic: for testing purposes allow ping, but do not require pong
* journal:
- - do not use magic msync() in src/journal/journal-file.c, just call fsync()
- <alxchk> poettering: looks like msync just calls vfs_fsync
- http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/mm/msync.c#n18
- import and delete pstore filesystem content at startup
- journald: also get thread ID from client, plus thread name
- journal: when waiting for journal additions in the client always sleep at least 1s or so, in order to minimize wakeups
diff --git a/src/journal/test-journal-flush.c b/src/journal/test-journal-flush.c
new file mode 100644
index 0000000..e61e87a
--- /dev/null
+++ b/src/journal/test-journal-flush.c
@@ -0,0 +1,71 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2013 Lennart Poettering
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+
+#include "sd-journal.h"
+#include "journal-file.h"
+#include "journal-internal.h"
+
+int main(int argc, char *argv[]) {
+
+ char fn[sizeof("/var/tmp/test-journal-flush-")-1 + DECIMAL_STR_MAX(pid_t) + sizeof(".journal")];
+ JournalFile *new_journal = NULL;
+ sd_journal *j = NULL;
+ unsigned n = 0;
+ int r;
+
+ sprintf(fn, "/var/tmp/test-journal-flush-%lu.journal", (unsigned long) getpid());
+
+ r = journal_file_open(fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, &new_journal);
+ assert_se(r >= 0);
+
+ unlink(fn);
+
+ r = sd_journal_open(&j, 0);
+ assert_se(r >= 0);
+
+ sd_journal_set_data_threshold(j, 0);
+
+ SD_JOURNAL_FOREACH(j) {
+ Object *o;
+ JournalFile *f;
+
+ f = j->current_file;
+ assert(f && f->current_offset > 0);
+
+ r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
+ assert(r >= 0);
+
+ r = journal_file_copy_entry(f, new_journal, o, f->current_offset, NULL, NULL, NULL);
+ assert(r >= 0);
+
+ n++;
+ if (n > 10000)
+ break;
+ }
+
+ sd_journal_close(j);
+
+ journal_file_close(new_journal);
+
+ return 0;
+}
commit 248c78c79c5cca9b981800d816a77591e504066a
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Nov 27 00:59:07 2013 +0100
journal: allow journal_file_copy_entry() to work on non-local files
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 409be76..14eae8f 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -2732,10 +2732,6 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
ts.monotonic = le64toh(o->entry.monotonic);
ts.realtime = le64toh(o->entry.realtime);
- if (to->tail_entry_monotonic_valid &&
- ts.monotonic < le64toh(to->header->tail_entry_monotonic))
- return -EINVAL;
-
n = journal_file_entry_n_items(o);
items = alloca(sizeof(EntryItem) * n);
commit e5462cd80e5328a769137c261c93931ea0c27bab
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Nov 27 00:58:39 2013 +0100
journal: fix iteration when we go backwards from the beginning of an array chain element
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 27cd16f..409be76 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1687,7 +1687,7 @@ found:
return 0;
/* Let's cache this item for the next invocation */
- chain_cache_put(f->chain_cache, ci, first, a, array->entry_array.items[0], t, i + (subtract_one ? -1 : 0));
+ chain_cache_put(f->chain_cache, ci, first, a, array->entry_array.items[0], t, subtract_one ? (i > 0 ? i-1 : (uint64_t) -1) : i);
if (subtract_one && i == 0)
p = last_p;
commit f268980d2cee694fa4118a71402a47c316af0425
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Nov 26 20:37:53 2013 +0100
journal: optimize bisection logic a bit by caching the last position
This way we can do a quick restart limiting a bit how wildly we need to
jump around during the bisection process.
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 481c242..27cd16f 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -1366,6 +1366,7 @@ typedef struct ChainCacheItem {
uint64_t array; /* the cached array */
uint64_t begin; /* the first item in the cached array */
uint64_t total; /* the total number of items in all arrays before this one in the chain */
+ uint64_t last_index; /* the last index we looked at, to optimize locality when bisecting */
} ChainCacheItem;
static void chain_cache_put(
@@ -1374,7 +1375,8 @@ static void chain_cache_put(
uint64_t first,
uint64_t array,
uint64_t begin,
- uint64_t total) {
+ uint64_t total,
+ uint64_t last_index) {
if (!ci) {
/* If the chain item to cache for this chain is the
@@ -1402,12 +1404,14 @@ static void chain_cache_put(
ci->array = array;
ci->begin = begin;
ci->total = total;
+ ci->last_index = last_index;
}
-static int generic_array_get(JournalFile *f,
- uint64_t first,
- uint64_t i,
- Object **ret, uint64_t *offset) {
+static int generic_array_get(
+ JournalFile *f,
+ uint64_t first,
+ uint64_t i,
+ Object **ret, uint64_t *offset) {
Object *o;
uint64_t p = 0, a, t = 0;
@@ -1448,7 +1452,7 @@ static int generic_array_get(JournalFile *f,
found:
/* Let's cache this item for the next invocation */
- chain_cache_put(f->chain_cache, ci, first, a, o->entry_array.items[0], t);
+ chain_cache_put(f->chain_cache, ci, first, a, o->entry_array.items[0], t, i);
r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
if (r < 0)
@@ -1463,11 +1467,12 @@ found:
return 1;
}
-static int generic_array_get_plus_one(JournalFile *f,
- uint64_t extra,
- uint64_t first,
- uint64_t i,
- Object **ret, uint64_t *offset) {
+static int generic_array_get_plus_one(
+ JournalFile *f,
+ uint64_t extra,
+ uint64_t first,
+ uint64_t i,
+ Object **ret, uint64_t *offset) {
Object *o;
@@ -1498,17 +1503,18 @@ enum {
TEST_RIGHT
};
-static int generic_array_bisect(JournalFile *f,
- uint64_t first,
- uint64_t n,
- uint64_t needle,
- int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
- direction_t direction,
- Object **ret,
- uint64_t *offset,
- uint64_t *idx) {
-
- uint64_t a, p, t = 0, i = 0, last_p = 0;
+static int generic_array_bisect(
+ JournalFile *f,
+ uint64_t first,
+ uint64_t n,
+ uint64_t needle,
+ int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
+ direction_t direction,
+ Object **ret,
+ uint64_t *offset,
+ uint64_t *idx) {
+
+ uint64_t a, p, t = 0, i = 0, last_p = 0, last_index = (uint64_t) -1;
bool subtract_one = false;
Object *o, *array = NULL;
int r;
@@ -1533,7 +1539,7 @@ static int generic_array_bisect(JournalFile *f,
return r;
if (r == TEST_LEFT) {
- /* OK, what we are looking for is right of th
+ /* OK, what we are looking for is right of the
* begin of this EntryArray, so let's jump
* straight to previously cached array in the
* chain */
@@ -1541,6 +1547,7 @@ static int generic_array_bisect(JournalFile *f,
a = ci->array;
n -= ci->total;
t = ci->total;
+ last_index = ci->last_index;
}
}
@@ -1571,6 +1578,60 @@ static int generic_array_bisect(JournalFile *f,
if (r == TEST_RIGHT) {
left = 0;
right -= 1;
+
+ if (last_index != (uint64_t) -1) {
+ assert(last_index <= right);
+
+ /* If we cached the last index we
+ * looked at, let's try to not to jump
+ * too wildly around and see if we can
+ * limit the range to look at early to
+ * the immediate neighbors of the last
+ * index we looked at. */
+
+ if (last_index > 0) {
+ uint64_t x = last_index - 1;
+
+ p = le64toh(array->entry_array.items[x]);
+ if (p <= 0)
+ return -EBADMSG;
+
+ r = test_object(f, p, needle);
+ if (r < 0)
+ return r;
+
+ if (r == TEST_FOUND)
+ r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;
+
+ if (r == TEST_RIGHT)
+ right = x;
+ else
+ left = x + 1;
+ }
+
+ if (last_index < right) {
+ uint64_t y = last_index + 1;
+
+ p = le64toh(array->entry_array.items[y]);
+ if (p <= 0)
+ return -EBADMSG;
+
+ r = test_object(f, p, needle);
+ if (r < 0)
+ return r;
+
+ if (r == TEST_FOUND)
+ r = direction == DIRECTION_DOWN ? TEST_RIGHT : TEST_LEFT;
+
+ if (r == TEST_RIGHT)
+ right = y;
+ else
+ left = y + 1;
+ }
+
+ last_index = (uint64_t) -1;
+ }
+
for (;;) {
if (left == right) {
if (direction == DIRECTION_UP)
@@ -1581,8 +1642,8 @@ static int generic_array_bisect(JournalFile *f,
}
assert(left < right);
-
i = (left + right) / 2;
+
p = le64toh(array->entry_array.items[i]);
if (p <= 0)
return -EBADMSG;
@@ -1615,6 +1676,7 @@ static int generic_array_bisect(JournalFile *f,
n -= k;
t += k;
+ last_index = (uint64_t) -1;
a = le64toh(array->entry_array.next_entry_array_offset);
}
@@ -1625,7 +1687,7 @@ found:
return 0;
/* Let's cache this item for the next invocation */
- chain_cache_put(f->chain_cache, ci, first, a, array->entry_array.items[0], t);
+ chain_cache_put(f->chain_cache, ci, first, a, array->entry_array.items[0], t, i + (subtract_one ? -1 : 0));
if (subtract_one && i == 0)
p = last_p;
@@ -1650,16 +1712,18 @@ found:
return 1;
}
-static int generic_array_bisect_plus_one(JournalFile *f,
- uint64_t extra,
- uint64_t first,
- uint64_t n,
- uint64_t needle,
- int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
- direction_t direction,
- Object **ret,
- uint64_t *offset,
- uint64_t *idx) {
+
+static int generic_array_bisect_plus_one(
+ JournalFile *f,
+ uint64_t extra,
+ uint64_t first,
+ uint64_t n,
+ uint64_t needle,
+ int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
+ direction_t direction,
+ Object **ret,
+ uint64_t *offset,
+ uint64_t *idx) {
int r;
bool step_back = false;
More information about the systemd-commits
mailing list