[systemd-commits] 4 commits - TODO man/journalctl.xml src/journal
Lennart Poettering
lennart at kemper.freedesktop.org
Mon Nov 3 14:12:43 PST 2014
TODO | 3 -
man/journalctl.xml | 33 +++++++++++++++++-
src/journal/journal-vacuum.c | 45 +++++++++++++++---------
src/journal/journal-vacuum.h | 2 -
src/journal/journalctl.c | 58 +++++++++++++++++++++++++++++---
src/journal/journald-server.c | 2 -
src/journal/test-journal-interleaving.c | 4 +-
src/journal/test-journal.c | 4 +-
8 files changed, 120 insertions(+), 31 deletions(-)
New commits:
commit 29a6c2d02088ff0b5da51b4d9ffe714b106de2f1
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 23:10:47 2014 +0100
update TODO
diff --git a/TODO b/TODO
index 5d2a634..b54aa61 100644
--- a/TODO
+++ b/TODO
@@ -405,6 +405,7 @@ Features:
* service: watchdog logic: for testing purposes allow ping, but do not require pong
* journal:
+ - consider introducing implicit _TTY= field
- 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
@@ -426,7 +427,6 @@ Features:
- 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
- journal: When used on NFS, check payload hashes
- - journald: check whether it is OK if the client can still modify delivered journal entries
- journal live copy, based on libneon (client) and libmicrohttpd (server)
- journald: add kernel cmdline option to disable ratelimiting for debug purposes
- refuse taking lower-case variable names in sd_journal_send() and friends.
@@ -436,7 +436,6 @@ Features:
- journal: sanely deal with entries which are larger than the individual file size, but where the components would fit
- Replace utmp, wtmp, btmp, and lastlog completely with journal
- journalctl: instead --after-cursor= maybe have a --cursor=XYZ+1 syntax?
- - tmpfiles: when applying ownership to /run/log/journal, also do this for the journal fails contained in it
- when a kernel driver logs in a tight loop, we should ratelimit that too.
- journald: optionally, log debug messages to /run but everything else to /var
- journald: when we drop syslog messages because the syslog socket is
commit 26d8ff04914a5208d029e899682cd314b7714bf0
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 23:10:34 2014 +0100
journald: fix memory leak on error path
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index d141fe0..80723c4 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -283,7 +283,11 @@ int journal_directory_vacuum(
patch_realtime(directory, p, &st, &realtime);
- GREEDY_REALLOC(list, n_allocated, n_list + 1);
+ if (!GREEDY_REALLOC(list, n_allocated, n_list + 1)) {
+ free(p);
+ r = -ENOMEM;
+ goto finish;
+ }
list[n_list].filename = p;
list[n_list].usage = 512UL * (uint64_t) st.st_blocks;
commit 332076b45b8a78f018ade2dfdc7e4279a56d49cc
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 23:10:21 2014 +0100
journald: also check journal file size to deduce if it is empty
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index dbf5d22..d141fe0 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -121,22 +121,30 @@ static void patch_realtime(
}
static int journal_file_empty(int dir_fd, const char *name) {
- int r;
- le64_t n_entries;
_cleanup_close_ int fd;
+ struct stat st;
+ le64_t n_entries;
+ ssize_t n;
fd = openat(dir_fd, name, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
if (fd < 0)
return -errno;
- if (lseek(fd, offsetof(Header, n_entries), SEEK_SET) < 0)
+ if (fstat(fd, &st) < 0)
return -errno;
- r = read(fd, &n_entries, sizeof(n_entries));
- if (r != sizeof(n_entries))
- return r == 0 ? -EINVAL : -errno;
+ /* If an offline file doesn't even have a header we consider it empty */
+ if (st.st_size < (off_t) sizeof(Header))
+ return 1;
+
+ /* If the number of entries is empty, we consider it empty, too */
+ n = pread(fd, &n_entries, sizeof(n_entries), offsetof(Header, n_entries));
+ if (n < 0)
+ return -errno;
+ if (n != sizeof(n_entries))
+ return -EIO;
- return le64toh(n_entries) == 0;
+ return le64toh(n_entries) <= 0;
}
int journal_directory_vacuum(
commit dbd2a83fbf051fc51bdca3aa7536c78479488c5b
Author: Lennart Poettering <lennart at poettering.net>
Date: Mon Nov 3 23:08:33 2014 +0100
journalctl: add new --vacuum-size= and --vacuum-time= commands to clean up journal files based on a size/time limit
This is equivalent to the effect of SystemMaxUse= and RetentionSec=,
however can be invoked directly instead of implicitly.
diff --git a/man/journalctl.xml b/man/journalctl.xml
index 0ed3ca3..0703bf9 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -761,8 +761,37 @@
<term><option>--disk-usage</option></term>
<listitem><para>Shows the current disk
- usage of all
- journal files.</para></listitem>
+ usage of all journal files. This shows
+ the sum of the disk usage of all
+ archived and active journal
+ files.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--vacuum-size=</option></term>
+ <term><option>--vacuum-time=</option></term>
+
+ <listitem><para>Removes archived
+ journal files until the disk space
+ they use falls below the specified
+ size (specified with the usual K, M,
+ G, T suffixes), or all journal files
+ contain no data older than the
+ specified timespan (specified with the
+ usual s, min, h, days, months, weeks,
+ years suffixes). Note that running
+ <option>--vacuum-size=</option> has
+ only indirect effect on the output
+ shown by <option>--disk-usage</option>
+ as the latter includes active journal
+ files, while the former only operates
+ on archived journal
+ files. <option>--vacuum-size=</option>
+ and <option>--vacuum-time=</option>
+ may be combined in a single invocation
+ to enforce both a size and time limit
+ on the archived journal
+ files.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c
index 7699482..dbf5d22 100644
--- a/src/journal/journal-vacuum.c
+++ b/src/journal/journal-vacuum.c
@@ -143,7 +143,8 @@ int journal_directory_vacuum(
const char *directory,
uint64_t max_use,
usec_t max_retention_usec,
- usec_t *oldest_usec) {
+ usec_t *oldest_usec,
+ bool verbose) {
_cleanup_closedir_ DIR *d = NULL;
int r = 0;
@@ -152,6 +153,7 @@ int journal_directory_vacuum(
size_t n_allocated = 0;
uint64_t sum = 0, freed = 0;
usec_t retention_limit = 0;
+ char sbytes[FORMAT_BYTES_MAX];
assert(directory);
@@ -262,14 +264,12 @@ int journal_directory_vacuum(
uint64_t size = 512UL * (uint64_t) st.st_blocks;
if (unlinkat(dirfd(d), p, 0) >= 0) {
- log_info("Deleted empty journal %s/%s (%"PRIu64" bytes).",
- directory, p, size);
+ log_full(verbose ? LOG_INFO : LOG_DEBUG, "Deleted empty archived journal %s/%s (%s).", directory, p, format_bytes(sbytes, sizeof(sbytes), size));
freed += size;
} else if (errno != ENOENT)
- log_warning("Failed to delete %s/%s: %m", directory, p);
+ log_warning("Failed to delete empty archived journal %s/%s: %m", directory, p);
free(p);
-
continue;
}
@@ -297,8 +297,7 @@ int journal_directory_vacuum(
break;
if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) {
- log_debug("Deleted archived journal %s/%s (%"PRIu64" bytes).",
- directory, list[i].filename, list[i].usage);
+ log_full(verbose ? LOG_INFO : LOG_DEBUG, "Deleted archived journal %s/%s (%s).", directory, list[i].filename, format_bytes(sbytes, sizeof(sbytes), list[i].usage));
freed += list[i].usage;
if (list[i].usage < sum)
@@ -307,7 +306,7 @@ int journal_directory_vacuum(
sum = 0;
} else if (errno != ENOENT)
- log_warning("Failed to delete %s/%s: %m", directory, list[i].filename);
+ log_warning("Failed to delete archived journal %s/%s: %m", directory, list[i].filename);
}
if (oldest_usec && i < n_list && (*oldest_usec == 0 || list[i].realtime < *oldest_usec))
@@ -318,7 +317,7 @@ finish:
free(list[i].filename);
free(list);
- log_debug("Vacuuming done, freed %"PRIu64" bytes", freed);
+ log_full(verbose ? LOG_INFO : LOG_DEBUG, "Vacuuming done, freed %s of archived journals on disk.", format_bytes(sbytes, sizeof(sbytes), freed));
return r;
}
diff --git a/src/journal/journal-vacuum.h b/src/journal/journal-vacuum.h
index bc30c3a..a7fb6f0 100644
--- a/src/journal/journal-vacuum.h
+++ b/src/journal/journal-vacuum.h
@@ -23,4 +23,4 @@
#include <inttypes.h>
-int journal_directory_vacuum(const char *directory, uint64_t max_use, usec_t max_retention_usec, usec_t *oldest_usec);
+int journal_directory_vacuum(const char *directory, uint64_t max_use, usec_t max_retention_usec, usec_t *oldest_usec, bool vacuum);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index f50faf4..b168d1e 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -59,6 +59,7 @@
#include "journal-verify.h"
#include "journal-authenticate.h"
#include "journal-qrcode.h"
+#include "journal-vacuum.h"
#include "fsprg.h"
#include "unit-name.h"
#include "catalog.h"
@@ -111,6 +112,8 @@ static bool arg_reverse = false;
static int arg_journal_type = 0;
static const char *arg_root = NULL;
static const char *arg_machine = NULL;
+static off_t arg_vacuum_size = (off_t) -1;
+static usec_t arg_vacuum_time = USEC_INFINITY;
static enum {
ACTION_SHOW,
@@ -124,6 +127,7 @@ static enum {
ACTION_UPDATE_CATALOG,
ACTION_LIST_BOOTS,
ACTION_FLUSH,
+ ACTION_VACUUM,
} arg_action = ACTION_SHOW;
typedef struct boot_id_t {
@@ -231,14 +235,16 @@ static void help(void) {
"\nCommands:\n"
" -h --help Show this help text\n"
" --version Show package version\n"
+ " -F --field=FIELD List all values that a specified field takes\n"
" --new-id128 Generate a new 128-bit ID\n"
- " --header Show journal header information\n"
" --disk-usage Show total disk usage of all journal files\n"
- " -F --field=FIELD List all values that a specified field takes\n"
+ " --vacuum-size=BYTES Remove old journals until disk space drops below size\n"
+ " --vacuum-time=TIME Remove old journals until none left older than\n"
+ " --flush Flush all journal data from /run into /var\n"
+ " --header Show journal header information\n"
" --list-catalog Show message IDs of all entries in the message catalog\n"
" --dump-catalog Show entries in the message catalog\n"
" --update-catalog Update the message catalog database\n"
- " --flush Flush all journal data from /run into /var\n"
#ifdef HAVE_GCRYPT
" --setup-keys Generate a new FSS key pair\n"
" --verify Verify journal file consistency\n"
@@ -276,6 +282,8 @@ static int parse_argv(int argc, char *argv[]) {
ARG_FORCE,
ARG_UTC,
ARG_FLUSH,
+ ARG_VACUUM_SIZE,
+ ARG_VACUUM_TIME,
};
static const struct option options[] = {
@@ -327,6 +335,8 @@ static int parse_argv(int argc, char *argv[]) {
{ "machine", required_argument, NULL, 'M' },
{ "utc", no_argument, NULL, ARG_UTC },
{ "flush", no_argument, NULL, ARG_FLUSH },
+ { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE },
+ { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME },
{}
};
@@ -525,6 +535,26 @@ static int parse_argv(int argc, char *argv[]) {
arg_action = ACTION_DISK_USAGE;
break;
+ case ARG_VACUUM_SIZE:
+ r = parse_size(optarg, 1024, &arg_vacuum_size);
+ if (r < 0) {
+ log_error("Failed to parse vacuum size: %s", optarg);
+ return r;
+ }
+
+ arg_action = ACTION_VACUUM;
+ break;
+
+ case ARG_VACUUM_TIME:
+ r = parse_sec(optarg, &arg_vacuum_time);
+ if (r < 0) {
+ log_error("Failed to parse vacuum time: %s", optarg);
+ return r;
+ }
+
+ arg_action = ACTION_VACUUM;
+ break;
+
#ifdef HAVE_GCRYPT
case ARG_FORCE:
arg_force = true;
@@ -1812,11 +1842,31 @@ int main(int argc, char *argv[]) {
if (r < 0)
return EXIT_FAILURE;
- printf("Journals take up %s on disk.\n",
+ printf("Archived and active journals take up %s on disk.\n",
format_bytes(sbytes, sizeof(sbytes), bytes));
return EXIT_SUCCESS;
}
+ if (arg_action == ACTION_VACUUM) {
+ Directory *d;
+ Iterator i;
+
+ HASHMAP_FOREACH(d, j->directories_by_path, i) {
+ int q;
+
+ if (d->is_root)
+ continue;
+
+ q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_time, NULL, true);
+ if (q < 0) {
+ log_error("Failed to vacuum: %s", strerror(-q));
+ r = q;
+ }
+ }
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ }
+
if (arg_action == ACTION_LIST_BOOTS) {
r = list_boots(j);
goto finish;
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index cf6bbcc..19cd6fe 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -375,7 +375,7 @@ static void do_vacuum(Server *s, char *ids, JournalFile *f, const char* path,
return;
p = strappenda(path, ids);
- r = journal_directory_vacuum(p, metrics->max_use, s->max_retention_usec, &s->oldest_file_usec);
+ r = journal_directory_vacuum(p, metrics->max_use, s->max_retention_usec, &s->oldest_file_usec, false);
if (r < 0 && r != -ENOENT)
log_error("Failed to vacuum %s: %s", p, strerror(-r));
}
diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c
index 6c5995e..8067cd3 100644
--- a/src/journal/test-journal-interleaving.c
+++ b/src/journal/test-journal-interleaving.c
@@ -189,7 +189,7 @@ static void test_skip(void (*setup)(void)) {
if (arg_keep)
log_info("Not removing %s", t);
else {
- journal_directory_vacuum(".", 3000000, 0, NULL);
+ journal_directory_vacuum(".", 3000000, 0, NULL, true);
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
}
@@ -274,7 +274,7 @@ static void test_sequence_numbers(void) {
if (arg_keep)
log_info("Not removing %s", t);
else {
- journal_directory_vacuum(".", 3000000, 0, NULL);
+ journal_directory_vacuum(".", 3000000, 0, NULL, true);
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
}
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
index 6025d04..74168b9 100644
--- a/src/journal/test-journal.c
+++ b/src/journal/test-journal.c
@@ -126,7 +126,7 @@ static void test_non_empty(void) {
if (arg_keep)
log_info("Not removing %s", t);
else {
- journal_directory_vacuum(".", 3000000, 0, NULL);
+ journal_directory_vacuum(".", 3000000, 0, NULL, true);
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
}
@@ -165,7 +165,7 @@ static void test_empty(void) {
if (arg_keep)
log_info("Not removing %s", t);
else {
- journal_directory_vacuum(".", 3000000, 0, NULL);
+ journal_directory_vacuum(".", 3000000, 0, NULL, true);
assert_se(rm_rf_dangerous(t, false, true, false) >= 0);
}
More information about the systemd-commits
mailing list