mirror of
https://github.com/systemd/systemd
synced 2024-10-07 16:51:02 +00:00
Merge pull request #2650 from vcaputo/async_fsync
Perform journal offlines asynchronously when possible
This commit is contained in:
commit
1f210bdbe6
|
@ -54,7 +54,7 @@ void iovw_rebase(struct iovec_wrapper *iovw, char *old, char *new) {
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
static int do_rotate(JournalFile **f, bool compress, bool seal) {
|
static int do_rotate(JournalFile **f, bool compress, bool seal) {
|
||||||
int r = journal_file_rotate(f, compress, seal);
|
int r = journal_file_rotate(f, compress, seal, NULL);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (*f)
|
if (*f)
|
||||||
log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
|
log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
|
||||||
|
|
|
@ -203,7 +203,7 @@ static int open_output(Writer *w, const char* host) {
|
||||||
O_RDWR|O_CREAT, 0640,
|
O_RDWR|O_CREAT, 0640,
|
||||||
arg_compress, arg_seal,
|
arg_compress, arg_seal,
|
||||||
&w->metrics,
|
&w->metrics,
|
||||||
w->mmap,
|
w->mmap, NULL,
|
||||||
NULL, &w->journal);
|
NULL, &w->journal);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_error_errno(r, "Failed to open output journal %s: %m",
|
log_error_errno(r, "Failed to open output journal %s: %m",
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
@ -38,6 +39,7 @@
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "random-util.h"
|
#include "random-util.h"
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
|
#include "set.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "xattr-util.h"
|
#include "xattr-util.h"
|
||||||
|
|
||||||
|
@ -86,33 +88,127 @@
|
||||||
/* The mmap context to use for the header we pick as one above the last defined typed */
|
/* The mmap context to use for the header we pick as one above the last defined typed */
|
||||||
#define CONTEXT_HEADER _OBJECT_TYPE_MAX
|
#define CONTEXT_HEADER _OBJECT_TYPE_MAX
|
||||||
|
|
||||||
static int journal_file_set_online(JournalFile *f) {
|
/* This may be called from a separate thread to prevent blocking the caller for the duration of fsync().
|
||||||
|
* As a result we use atomic operations on f->offline_state for inter-thread communications with
|
||||||
|
* journal_file_set_offline() and journal_file_set_online(). */
|
||||||
|
static void journal_file_set_offline_internal(JournalFile *f) {
|
||||||
|
assert(f);
|
||||||
|
assert(f->fd >= 0);
|
||||||
|
assert(f->header);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
switch (f->offline_state) {
|
||||||
|
case OFFLINE_CANCEL:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_CANCEL, OFFLINE_DONE))
|
||||||
|
continue;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case OFFLINE_AGAIN_FROM_SYNCING:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_SYNCING, OFFLINE_SYNCING))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OFFLINE_AGAIN_FROM_OFFLINING:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_OFFLINING, OFFLINE_SYNCING))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OFFLINE_SYNCING:
|
||||||
|
(void) fsync(f->fd);
|
||||||
|
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_SYNCING, OFFLINE_OFFLINING))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
f->header->state = STATE_OFFLINE;
|
||||||
|
(void) fsync(f->fd);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OFFLINE_OFFLINING:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_OFFLINING, OFFLINE_DONE))
|
||||||
|
continue;
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
|
case OFFLINE_DONE:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case OFFLINE_JOINED:
|
||||||
|
log_debug("OFFLINE_JOINED unexpected offline state for journal_file_set_offline_internal()");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void * journal_file_set_offline_thread(void *arg) {
|
||||||
|
JournalFile *f = arg;
|
||||||
|
|
||||||
|
journal_file_set_offline_internal(f);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int journal_file_set_offline_thread_join(JournalFile *f) {
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->writable)
|
if (f->offline_state == OFFLINE_JOINED)
|
||||||
return -EPERM;
|
return 0;
|
||||||
|
|
||||||
if (!(f->fd >= 0 && f->header))
|
r = pthread_join(f->offline_thread, NULL);
|
||||||
return -EINVAL;
|
if (r)
|
||||||
|
return -r;
|
||||||
|
|
||||||
|
f->offline_state = OFFLINE_JOINED;
|
||||||
|
|
||||||
if (mmap_cache_got_sigbus(f->mmap, f->fd))
|
if (mmap_cache_got_sigbus(f->mmap, f->fd))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
switch (f->header->state) {
|
return 0;
|
||||||
case STATE_ONLINE:
|
}
|
||||||
return 0;
|
|
||||||
|
|
||||||
case STATE_OFFLINE:
|
/* Trigger a restart if the offline thread is mid-flight in a restartable state. */
|
||||||
f->header->state = STATE_ONLINE;
|
static bool journal_file_set_offline_try_restart(JournalFile *f) {
|
||||||
fsync(f->fd);
|
for (;;) {
|
||||||
return 0;
|
switch (f->offline_state) {
|
||||||
|
case OFFLINE_AGAIN_FROM_SYNCING:
|
||||||
|
case OFFLINE_AGAIN_FROM_OFFLINING:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case OFFLINE_CANCEL:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_CANCEL, OFFLINE_AGAIN_FROM_SYNCING))
|
||||||
|
continue;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case OFFLINE_SYNCING:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_SYNCING, OFFLINE_AGAIN_FROM_SYNCING))
|
||||||
|
continue;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case OFFLINE_OFFLINING:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_OFFLINING, OFFLINE_AGAIN_FROM_OFFLINING))
|
||||||
|
continue;
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int journal_file_set_offline(JournalFile *f) {
|
/* Sets a journal offline.
|
||||||
|
*
|
||||||
|
* If wait is false then an offline is dispatched in a separate thread for a
|
||||||
|
* subsequent journal_file_set_offline() or journal_file_set_online() of the
|
||||||
|
* same journal to synchronize with.
|
||||||
|
*
|
||||||
|
* If wait is true, then either an existing offline thread will be restarted
|
||||||
|
* and joined, or if none exists the offline is simply performed in this
|
||||||
|
* context without involving another thread.
|
||||||
|
*/
|
||||||
|
int journal_file_set_offline(JournalFile *f, bool wait) {
|
||||||
|
bool restarted;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
if (!f->writable)
|
if (!f->writable)
|
||||||
|
@ -124,21 +220,109 @@ int journal_file_set_offline(JournalFile *f) {
|
||||||
if (f->header->state != STATE_ONLINE)
|
if (f->header->state != STATE_ONLINE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fsync(f->fd);
|
/* Restart an in-flight offline thread and wait if needed, or join a lingering done one. */
|
||||||
|
restarted = journal_file_set_offline_try_restart(f);
|
||||||
|
if ((restarted && wait) || !restarted) {
|
||||||
|
r = journal_file_set_offline_thread_join(f);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
if (mmap_cache_got_sigbus(f->mmap, f->fd))
|
if (restarted)
|
||||||
return -EIO;
|
return 0;
|
||||||
|
|
||||||
f->header->state = STATE_OFFLINE;
|
/* Initiate a new offline. */
|
||||||
|
f->offline_state = OFFLINE_SYNCING;
|
||||||
|
|
||||||
if (mmap_cache_got_sigbus(f->mmap, f->fd))
|
if (wait) /* Without using a thread if waiting. */
|
||||||
return -EIO;
|
journal_file_set_offline_internal(f);
|
||||||
|
else {
|
||||||
fsync(f->fd);
|
r = pthread_create(&f->offline_thread, NULL, journal_file_set_offline_thread, f);
|
||||||
|
if (r > 0)
|
||||||
|
return -r;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int journal_file_set_online(JournalFile *f) {
|
||||||
|
bool joined = false;
|
||||||
|
|
||||||
|
assert(f);
|
||||||
|
|
||||||
|
if (!f->writable)
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (!(f->fd >= 0 && f->header))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
while (!joined) {
|
||||||
|
switch (f->offline_state) {
|
||||||
|
case OFFLINE_JOINED:
|
||||||
|
/* No offline thread, no need to wait. */
|
||||||
|
joined = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OFFLINE_SYNCING:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_SYNCING, OFFLINE_CANCEL))
|
||||||
|
continue;
|
||||||
|
/* Canceled syncing prior to offlining, no need to wait. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OFFLINE_AGAIN_FROM_SYNCING:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_SYNCING, OFFLINE_CANCEL))
|
||||||
|
continue;
|
||||||
|
/* Canceled restart from syncing, no need to wait. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OFFLINE_AGAIN_FROM_OFFLINING:
|
||||||
|
if (!__sync_bool_compare_and_swap(&f->offline_state, OFFLINE_AGAIN_FROM_OFFLINING, OFFLINE_CANCEL))
|
||||||
|
continue;
|
||||||
|
/* Canceled restart from offlining, must wait for offlining to complete however. */
|
||||||
|
|
||||||
|
/* fall through to wait */
|
||||||
|
default: {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = journal_file_set_offline_thread_join(f);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
joined = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmap_cache_got_sigbus(f->mmap, f->fd))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
switch (f->header->state) {
|
||||||
|
case STATE_ONLINE:
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case STATE_OFFLINE:
|
||||||
|
f->header->state = STATE_ONLINE;
|
||||||
|
(void) fsync(f->fd);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool journal_file_is_offlining(JournalFile *f) {
|
||||||
|
assert(f);
|
||||||
|
|
||||||
|
__sync_synchronize();
|
||||||
|
|
||||||
|
if (f->offline_state == OFFLINE_DONE ||
|
||||||
|
f->offline_state == OFFLINE_JOINED)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
JournalFile* journal_file_close(JournalFile *f) {
|
JournalFile* journal_file_close(JournalFile *f) {
|
||||||
assert(f);
|
assert(f);
|
||||||
|
|
||||||
|
@ -159,7 +343,7 @@ JournalFile* journal_file_close(JournalFile *f) {
|
||||||
sd_event_source_unref(f->post_change_timer);
|
sd_event_source_unref(f->post_change_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
journal_file_set_offline(f);
|
journal_file_set_offline(f, true);
|
||||||
|
|
||||||
if (f->mmap && f->fd >= 0)
|
if (f->mmap && f->fd >= 0)
|
||||||
mmap_cache_close_fd(f->mmap, f->fd);
|
mmap_cache_close_fd(f->mmap, f->fd);
|
||||||
|
@ -203,6 +387,15 @@ JournalFile* journal_file_close(JournalFile *f) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void journal_file_close_set(Set *s) {
|
||||||
|
JournalFile *f;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
while ((f = set_steal_first(s)))
|
||||||
|
(void) journal_file_close(f);
|
||||||
|
}
|
||||||
|
|
||||||
static int journal_file_init_header(JournalFile *f, JournalFile *template) {
|
static int journal_file_init_header(JournalFile *f, JournalFile *template) {
|
||||||
Header h = {};
|
Header h = {};
|
||||||
ssize_t k;
|
ssize_t k;
|
||||||
|
@ -263,7 +456,7 @@ static int journal_file_refresh_header(JournalFile *f) {
|
||||||
r = journal_file_set_online(f);
|
r = journal_file_set_online(f);
|
||||||
|
|
||||||
/* Sync the online state to disk */
|
/* Sync the online state to disk */
|
||||||
fsync(f->fd);
|
(void) fsync(f->fd);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -2710,6 +2903,7 @@ int journal_file_open(
|
||||||
bool seal,
|
bool seal,
|
||||||
JournalMetrics *metrics,
|
JournalMetrics *metrics,
|
||||||
MMapCache *mmap_cache,
|
MMapCache *mmap_cache,
|
||||||
|
Set *deferred_closes,
|
||||||
JournalFile *template,
|
JournalFile *template,
|
||||||
JournalFile **ret) {
|
JournalFile **ret) {
|
||||||
|
|
||||||
|
@ -2829,6 +3023,9 @@ int journal_file_open(
|
||||||
f->header = h;
|
f->header = h;
|
||||||
|
|
||||||
if (!newly_created) {
|
if (!newly_created) {
|
||||||
|
if (deferred_closes)
|
||||||
|
journal_file_close_set(deferred_closes);
|
||||||
|
|
||||||
r = journal_file_verify_header(f);
|
r = journal_file_verify_header(f);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -2898,12 +3095,12 @@ fail:
|
||||||
if (f->fd >= 0 && mmap_cache_got_sigbus(f->mmap, f->fd))
|
if (f->fd >= 0 && mmap_cache_got_sigbus(f->mmap, f->fd))
|
||||||
r = -EIO;
|
r = -EIO;
|
||||||
|
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
|
int journal_file_rotate(JournalFile **f, bool compress, bool seal, Set *deferred_closes) {
|
||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL;
|
||||||
size_t l;
|
size_t l;
|
||||||
JournalFile *old_file, *new_file = NULL;
|
JournalFile *old_file, *new_file = NULL;
|
||||||
|
@ -2943,8 +3140,13 @@ int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
|
||||||
* we archive them */
|
* we archive them */
|
||||||
old_file->defrag_on_close = true;
|
old_file->defrag_on_close = true;
|
||||||
|
|
||||||
r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, old_file, &new_file);
|
r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, deferred_closes, old_file, &new_file);
|
||||||
journal_file_close(old_file);
|
|
||||||
|
if (deferred_closes &&
|
||||||
|
set_put(deferred_closes, old_file) >= 0)
|
||||||
|
(void) journal_file_set_offline(old_file, false);
|
||||||
|
else
|
||||||
|
(void) journal_file_close(old_file);
|
||||||
|
|
||||||
*f = new_file;
|
*f = new_file;
|
||||||
return r;
|
return r;
|
||||||
|
@ -2958,6 +3160,7 @@ int journal_file_open_reliably(
|
||||||
bool seal,
|
bool seal,
|
||||||
JournalMetrics *metrics,
|
JournalMetrics *metrics,
|
||||||
MMapCache *mmap_cache,
|
MMapCache *mmap_cache,
|
||||||
|
Set *deferred_closes,
|
||||||
JournalFile *template,
|
JournalFile *template,
|
||||||
JournalFile **ret) {
|
JournalFile **ret) {
|
||||||
|
|
||||||
|
@ -2965,7 +3168,7 @@ int journal_file_open_reliably(
|
||||||
size_t l;
|
size_t l;
|
||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL;
|
||||||
|
|
||||||
r = journal_file_open(fname, flags, mode, compress, seal, metrics, mmap_cache, template, ret);
|
r = journal_file_open(fname, flags, mode, compress, seal, metrics, mmap_cache, deferred_closes, template, ret);
|
||||||
if (!IN_SET(r,
|
if (!IN_SET(r,
|
||||||
-EBADMSG, /* corrupted */
|
-EBADMSG, /* corrupted */
|
||||||
-ENODATA, /* truncated */
|
-ENODATA, /* truncated */
|
||||||
|
@ -3006,7 +3209,7 @@ int journal_file_open_reliably(
|
||||||
|
|
||||||
log_warning_errno(r, "File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
|
log_warning_errno(r, "File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
|
||||||
|
|
||||||
return journal_file_open(fname, flags, mode, compress, seal, metrics, mmap_cache, template, ret);
|
return journal_file_open(fname, flags, mode, compress, seal, metrics, mmap_cache, deferred_closes, template, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset) {
|
int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset) {
|
||||||
|
|
|
@ -63,6 +63,16 @@ typedef enum LocationType {
|
||||||
LOCATION_SEEK
|
LOCATION_SEEK
|
||||||
} LocationType;
|
} LocationType;
|
||||||
|
|
||||||
|
typedef enum OfflineState {
|
||||||
|
OFFLINE_JOINED,
|
||||||
|
OFFLINE_SYNCING,
|
||||||
|
OFFLINE_OFFLINING,
|
||||||
|
OFFLINE_CANCEL,
|
||||||
|
OFFLINE_AGAIN_FROM_SYNCING,
|
||||||
|
OFFLINE_AGAIN_FROM_OFFLINING,
|
||||||
|
OFFLINE_DONE
|
||||||
|
} OfflineState;
|
||||||
|
|
||||||
typedef struct JournalFile {
|
typedef struct JournalFile {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
@ -105,6 +115,9 @@ typedef struct JournalFile {
|
||||||
|
|
||||||
OrderedHashmap *chain_cache;
|
OrderedHashmap *chain_cache;
|
||||||
|
|
||||||
|
pthread_t offline_thread;
|
||||||
|
volatile OfflineState offline_state;
|
||||||
|
|
||||||
#if defined(HAVE_XZ) || defined(HAVE_LZ4)
|
#if defined(HAVE_XZ) || defined(HAVE_LZ4)
|
||||||
void *compress_buffer;
|
void *compress_buffer;
|
||||||
size_t compress_buffer_size;
|
size_t compress_buffer_size;
|
||||||
|
@ -136,11 +149,14 @@ int journal_file_open(
|
||||||
bool seal,
|
bool seal,
|
||||||
JournalMetrics *metrics,
|
JournalMetrics *metrics,
|
||||||
MMapCache *mmap_cache,
|
MMapCache *mmap_cache,
|
||||||
|
Set *deferred_closes,
|
||||||
JournalFile *template,
|
JournalFile *template,
|
||||||
JournalFile **ret);
|
JournalFile **ret);
|
||||||
|
|
||||||
int journal_file_set_offline(JournalFile *f);
|
int journal_file_set_offline(JournalFile *f, bool wait);
|
||||||
|
bool journal_file_is_offlining(JournalFile *f);
|
||||||
JournalFile* journal_file_close(JournalFile *j);
|
JournalFile* journal_file_close(JournalFile *j);
|
||||||
|
void journal_file_close_set(Set *s);
|
||||||
|
|
||||||
int journal_file_open_reliably(
|
int journal_file_open_reliably(
|
||||||
const char *fname,
|
const char *fname,
|
||||||
|
@ -150,6 +166,7 @@ int journal_file_open_reliably(
|
||||||
bool seal,
|
bool seal,
|
||||||
JournalMetrics *metrics,
|
JournalMetrics *metrics,
|
||||||
MMapCache *mmap_cache,
|
MMapCache *mmap_cache,
|
||||||
|
Set *deferred_closes,
|
||||||
JournalFile *template,
|
JournalFile *template,
|
||||||
JournalFile **ret);
|
JournalFile **ret);
|
||||||
|
|
||||||
|
@ -223,7 +240,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
|
||||||
void journal_file_dump(JournalFile *f);
|
void journal_file_dump(JournalFile *f);
|
||||||
void journal_file_print_header(JournalFile *f);
|
void journal_file_print_header(JournalFile *f);
|
||||||
|
|
||||||
int journal_file_rotate(JournalFile **f, bool compress, bool seal);
|
int journal_file_rotate(JournalFile **f, bool compress, bool seal, Set *deferred_closes);
|
||||||
|
|
||||||
void journal_file_post_change(JournalFile *f);
|
void journal_file_post_change(JournalFile *f);
|
||||||
int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t);
|
int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t);
|
||||||
|
|
|
@ -251,15 +251,15 @@ static int open_journal(
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
if (reliably)
|
if (reliably)
|
||||||
r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
|
r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, s->deferred_closes, NULL, &f);
|
||||||
else
|
else
|
||||||
r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
|
r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, s->deferred_closes, NULL, &f);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = journal_file_enable_post_change_timer(f, s->event, POST_CHANGE_TIMER_INTERVAL_USEC);
|
r = journal_file_enable_post_change_timer(f, s->event, POST_CHANGE_TIMER_INTERVAL_USEC);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
|
||||||
/* Too many open? Then let's close one */
|
/* Too many open? Then let's close one */
|
||||||
f = ordered_hashmap_steal_first(s->user_journals);
|
f = ordered_hashmap_steal_first(s->user_journals);
|
||||||
assert(f);
|
assert(f);
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &f);
|
r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &f);
|
||||||
|
@ -313,7 +313,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
|
||||||
|
|
||||||
r = ordered_hashmap_put(s->user_journals, UID_TO_PTR(uid), f);
|
r = ordered_hashmap_put(s->user_journals, UID_TO_PTR(uid), f);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
return s->system_journal;
|
return s->system_journal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ static int do_rotate(
|
||||||
if (!*f)
|
if (!*f)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
r = journal_file_rotate(f, s->compress, seal);
|
r = journal_file_rotate(f, s->compress, seal, s->deferred_closes);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
if (*f)
|
if (*f)
|
||||||
log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
|
log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
|
||||||
|
@ -364,6 +364,13 @@ void server_rotate(Server *s) {
|
||||||
/* Old file has been closed and deallocated */
|
/* Old file has been closed and deallocated */
|
||||||
ordered_hashmap_remove(s->user_journals, k);
|
ordered_hashmap_remove(s->user_journals, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Perform any deferred closes which aren't still offlining. */
|
||||||
|
SET_FOREACH(f, s->deferred_closes, i)
|
||||||
|
if (!journal_file_is_offlining(f)) {
|
||||||
|
(void) set_remove(s->deferred_closes, f);
|
||||||
|
(void) journal_file_close(f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void server_sync(Server *s) {
|
void server_sync(Server *s) {
|
||||||
|
@ -372,13 +379,13 @@ void server_sync(Server *s) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (s->system_journal) {
|
if (s->system_journal) {
|
||||||
r = journal_file_set_offline(s->system_journal);
|
r = journal_file_set_offline(s->system_journal, false);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to sync system journal, ignoring: %m");
|
log_warning_errno(r, "Failed to sync system journal, ignoring: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
ORDERED_HASHMAP_FOREACH(f, s->user_journals, i) {
|
ORDERED_HASHMAP_FOREACH(f, s->user_journals, i) {
|
||||||
r = journal_file_set_offline(f);
|
r = journal_file_set_offline(f, false);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to sync user journal, ignoring: %m");
|
log_warning_errno(r, "Failed to sync user journal, ignoring: %m");
|
||||||
}
|
}
|
||||||
|
@ -1765,6 +1772,10 @@ int server_init(Server *s) {
|
||||||
if (!s->mmap)
|
if (!s->mmap)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
s->deferred_closes = set_new(NULL);
|
||||||
|
if (!s->deferred_closes)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
r = sd_event_default(&s->event);
|
r = sd_event_default(&s->event);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to create event loop: %m");
|
return log_error_errno(r, "Failed to create event loop: %m");
|
||||||
|
@ -1918,17 +1929,22 @@ void server_done(Server *s) {
|
||||||
JournalFile *f;
|
JournalFile *f;
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
if (s->deferred_closes) {
|
||||||
|
journal_file_close_set(s->deferred_closes);
|
||||||
|
set_free(s->deferred_closes);
|
||||||
|
}
|
||||||
|
|
||||||
while (s->stdout_streams)
|
while (s->stdout_streams)
|
||||||
stdout_stream_free(s->stdout_streams);
|
stdout_stream_free(s->stdout_streams);
|
||||||
|
|
||||||
if (s->system_journal)
|
if (s->system_journal)
|
||||||
journal_file_close(s->system_journal);
|
(void) journal_file_close(s->system_journal);
|
||||||
|
|
||||||
if (s->runtime_journal)
|
if (s->runtime_journal)
|
||||||
journal_file_close(s->runtime_journal);
|
(void) journal_file_close(s->runtime_journal);
|
||||||
|
|
||||||
while ((f = ordered_hashmap_steal_first(s->user_journals)))
|
while ((f = ordered_hashmap_steal_first(s->user_journals)))
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
|
|
||||||
ordered_hashmap_free(s->user_journals);
|
ordered_hashmap_free(s->user_journals);
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,8 @@ struct Server {
|
||||||
|
|
||||||
MMapCache *mmap;
|
MMapCache *mmap;
|
||||||
|
|
||||||
|
Set *deferred_closes;
|
||||||
|
|
||||||
struct udev *udev;
|
struct udev *udev;
|
||||||
|
|
||||||
uint64_t *kernel_seqnum;
|
uint64_t *kernel_seqnum;
|
||||||
|
|
|
@ -1248,7 +1248,7 @@ static int add_any_file(sd_journal *j, const char *path) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f);
|
r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, NULL, &f);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_debug_errno(r, "Failed to open journal file %s: %m", path);
|
log_debug_errno(r, "Failed to open journal file %s: %m", path);
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1258,7 +1258,7 @@ static int add_any_file(sd_journal *j, const char *path) {
|
||||||
|
|
||||||
r = ordered_hashmap_put(j->files, f->path, f);
|
r = ordered_hashmap_put(j->files, f->path, f);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1343,7 +1343,7 @@ static void remove_file_real(sd_journal *j, JournalFile *f) {
|
||||||
j->fields_file_lost = true;
|
j->fields_file_lost = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
|
|
||||||
j->current_invalidate_counter ++;
|
j->current_invalidate_counter ++;
|
||||||
}
|
}
|
||||||
|
@ -1784,7 +1784,7 @@ _public_ void sd_journal_close(sd_journal *j) {
|
||||||
sd_journal_flush_matches(j);
|
sd_journal_flush_matches(j);
|
||||||
|
|
||||||
while ((f = ordered_hashmap_steal_first(j->files)))
|
while ((f = ordered_hashmap_steal_first(j->files)))
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
|
|
||||||
ordered_hashmap_free(j->files);
|
ordered_hashmap_free(j->files);
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ int main(int argc, char *argv[]) {
|
||||||
assert_se(mkdtemp(dn));
|
assert_se(mkdtemp(dn));
|
||||||
fn = strappend(dn, "/test.journal");
|
fn = strappend(dn, "/test.journal");
|
||||||
|
|
||||||
r = journal_file_open(fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, &new_journal);
|
r = journal_file_open(fn, O_CREAT|O_RDWR, 0644, false, false, NULL, NULL, NULL, NULL, &new_journal);
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
|
|
||||||
r = sd_journal_open(&j, 0);
|
r = sd_journal_open(&j, 0);
|
||||||
|
@ -66,7 +66,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
sd_journal_close(j);
|
sd_journal_close(j);
|
||||||
|
|
||||||
journal_file_close(new_journal);
|
(void) journal_file_close(new_journal);
|
||||||
|
|
||||||
unlink(fn);
|
unlink(fn);
|
||||||
assert_se(rmdir(dn) == 0);
|
assert_se(rmdir(dn) == 0);
|
||||||
|
|
|
@ -52,12 +52,12 @@ noreturn static void log_assert_errno(const char *text, int eno, const char *fil
|
||||||
|
|
||||||
static JournalFile *test_open(const char *name) {
|
static JournalFile *test_open(const char *name) {
|
||||||
JournalFile *f;
|
JournalFile *f;
|
||||||
assert_ret(journal_file_open(name, O_RDWR|O_CREAT, 0644, true, false, NULL, NULL, NULL, &f));
|
assert_ret(journal_file_open(name, O_RDWR|O_CREAT, 0644, true, false, NULL, NULL, NULL, NULL, &f));
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_close(JournalFile *f) {
|
static void test_close(JournalFile *f) {
|
||||||
journal_file_close (f);
|
(void) journal_file_close (f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void append_number(JournalFile *f, int n, uint64_t *seqnum) {
|
static void append_number(JournalFile *f, int n, uint64_t *seqnum) {
|
||||||
|
@ -217,7 +217,7 @@ static void test_sequence_numbers(void) {
|
||||||
assert_se(chdir(t) >= 0);
|
assert_se(chdir(t) >= 0);
|
||||||
|
|
||||||
assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0644,
|
assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0644,
|
||||||
true, false, NULL, NULL, NULL, &one) == 0);
|
true, false, NULL, NULL, NULL, NULL, &one) == 0);
|
||||||
|
|
||||||
append_number(one, 1, &seqnum);
|
append_number(one, 1, &seqnum);
|
||||||
printf("seqnum=%"PRIu64"\n", seqnum);
|
printf("seqnum=%"PRIu64"\n", seqnum);
|
||||||
|
@ -234,7 +234,7 @@ static void test_sequence_numbers(void) {
|
||||||
memcpy(&seqnum_id, &one->header->seqnum_id, sizeof(sd_id128_t));
|
memcpy(&seqnum_id, &one->header->seqnum_id, sizeof(sd_id128_t));
|
||||||
|
|
||||||
assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0644,
|
assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0644,
|
||||||
true, false, NULL, NULL, one, &two) == 0);
|
true, false, NULL, NULL, NULL, one, &two) == 0);
|
||||||
|
|
||||||
assert_se(two->header->state == STATE_ONLINE);
|
assert_se(two->header->state == STATE_ONLINE);
|
||||||
assert_se(!sd_id128_equal(two->header->file_id, one->header->file_id));
|
assert_se(!sd_id128_equal(two->header->file_id, one->header->file_id));
|
||||||
|
@ -265,7 +265,7 @@ static void test_sequence_numbers(void) {
|
||||||
seqnum = 0;
|
seqnum = 0;
|
||||||
|
|
||||||
assert_se(journal_file_open("two.journal", O_RDWR, 0,
|
assert_se(journal_file_open("two.journal", O_RDWR, 0,
|
||||||
true, false, NULL, NULL, NULL, &two) == 0);
|
true, false, NULL, NULL, NULL, NULL, &two) == 0);
|
||||||
|
|
||||||
assert_se(sd_id128_equal(two->header->seqnum_id, seqnum_id));
|
assert_se(sd_id128_equal(two->header->seqnum_id, seqnum_id));
|
||||||
|
|
||||||
|
|
|
@ -92,9 +92,9 @@ int main(int argc, char *argv[]) {
|
||||||
assert_se(mkdtemp(t));
|
assert_se(mkdtemp(t));
|
||||||
assert_se(chdir(t) >= 0);
|
assert_se(chdir(t) >= 0);
|
||||||
|
|
||||||
assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &one) == 0);
|
assert_se(journal_file_open("one.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, NULL, &one) == 0);
|
||||||
assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &two) == 0);
|
assert_se(journal_file_open("two.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, NULL, &two) == 0);
|
||||||
assert_se(journal_file_open("three.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &three) == 0);
|
assert_se(journal_file_open("three.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, NULL, &three) == 0);
|
||||||
|
|
||||||
for (i = 0; i < N_ENTRIES; i++) {
|
for (i = 0; i < N_ENTRIES; i++) {
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
|
@ -133,9 +133,9 @@ int main(int argc, char *argv[]) {
|
||||||
free(q);
|
free(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
journal_file_close(one);
|
(void) journal_file_close(one);
|
||||||
journal_file_close(two);
|
(void) journal_file_close(two);
|
||||||
journal_file_close(three);
|
(void) journal_file_close(three);
|
||||||
|
|
||||||
assert_se(sd_journal_open_directory(&j, t, 0) >= 0);
|
assert_se(sd_journal_open_directory(&j, t, 0) >= 0);
|
||||||
|
|
||||||
|
|
|
@ -55,12 +55,12 @@ static int raw_verify(const char *fn, const char *verification_key) {
|
||||||
JournalFile *f;
|
JournalFile *f;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f);
|
r = journal_file_open(fn, O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, NULL, &f);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
|
r = journal_file_verify(f, verification_key, NULL, NULL, NULL, false);
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
log_info("Generating...");
|
log_info("Generating...");
|
||||||
|
|
||||||
assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
|
assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, !!verification_key, NULL, NULL, NULL, NULL, &f) == 0);
|
||||||
|
|
||||||
for (n = 0; n < N_ENTRIES; n++) {
|
for (n = 0; n < N_ENTRIES; n++) {
|
||||||
struct iovec iovec;
|
struct iovec iovec;
|
||||||
|
@ -107,11 +107,11 @@ int main(int argc, char *argv[]) {
|
||||||
free(test);
|
free(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
|
|
||||||
log_info("Verifying...");
|
log_info("Verifying...");
|
||||||
|
|
||||||
assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, &f) == 0);
|
assert_se(journal_file_open("test.journal", O_RDONLY, 0666, true, !!verification_key, NULL, NULL, NULL, NULL, &f) == 0);
|
||||||
/* journal_file_print_header(f); */
|
/* journal_file_print_header(f); */
|
||||||
journal_file_dump(f);
|
journal_file_dump(f);
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ int main(int argc, char *argv[]) {
|
||||||
format_timestamp(b, sizeof(b), to),
|
format_timestamp(b, sizeof(b), to),
|
||||||
format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
|
format_timespan(c, sizeof(c), total > to ? total - to : 0, 0));
|
||||||
|
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
|
|
||||||
if (verification_key) {
|
if (verification_key) {
|
||||||
log_info("Toggling bits...");
|
log_info("Toggling bits...");
|
||||||
|
|
|
@ -42,7 +42,7 @@ static void test_non_empty(void) {
|
||||||
assert_se(mkdtemp(t));
|
assert_se(mkdtemp(t));
|
||||||
assert_se(chdir(t) >= 0);
|
assert_se(chdir(t) >= 0);
|
||||||
|
|
||||||
assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, &f) == 0);
|
assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, NULL, &f) == 0);
|
||||||
|
|
||||||
dual_timestamp_get(&ts);
|
dual_timestamp_get(&ts);
|
||||||
|
|
||||||
|
@ -104,10 +104,10 @@ static void test_non_empty(void) {
|
||||||
|
|
||||||
assert_se(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0);
|
assert_se(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0);
|
||||||
|
|
||||||
journal_file_rotate(&f, true, true);
|
journal_file_rotate(&f, true, true, NULL);
|
||||||
journal_file_rotate(&f, true, true);
|
journal_file_rotate(&f, true, true, NULL);
|
||||||
|
|
||||||
journal_file_close(f);
|
(void) journal_file_close(f);
|
||||||
|
|
||||||
log_info("Done...");
|
log_info("Done...");
|
||||||
|
|
||||||
|
@ -131,13 +131,13 @@ static void test_empty(void) {
|
||||||
assert_se(mkdtemp(t));
|
assert_se(mkdtemp(t));
|
||||||
assert_se(chdir(t) >= 0);
|
assert_se(chdir(t) >= 0);
|
||||||
|
|
||||||
assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, false, false, NULL, NULL, NULL, &f1) == 0);
|
assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, false, false, NULL, NULL, NULL, NULL, &f1) == 0);
|
||||||
|
|
||||||
assert_se(journal_file_open("test-compress.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, &f2) == 0);
|
assert_se(journal_file_open("test-compress.journal", O_RDWR|O_CREAT, 0666, true, false, NULL, NULL, NULL, NULL, &f2) == 0);
|
||||||
|
|
||||||
assert_se(journal_file_open("test-seal.journal", O_RDWR|O_CREAT, 0666, false, true, NULL, NULL, NULL, &f3) == 0);
|
assert_se(journal_file_open("test-seal.journal", O_RDWR|O_CREAT, 0666, false, true, NULL, NULL, NULL, NULL, &f3) == 0);
|
||||||
|
|
||||||
assert_se(journal_file_open("test-seal-compress.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, &f4) == 0);
|
assert_se(journal_file_open("test-seal-compress.journal", O_RDWR|O_CREAT, 0666, true, true, NULL, NULL, NULL, NULL, &f4) == 0);
|
||||||
|
|
||||||
journal_file_print_header(f1);
|
journal_file_print_header(f1);
|
||||||
puts("");
|
puts("");
|
||||||
|
@ -158,10 +158,10 @@ static void test_empty(void) {
|
||||||
assert_se(rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
|
assert_se(rm_rf(t, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
journal_file_close(f1);
|
(void) journal_file_close(f1);
|
||||||
journal_file_close(f2);
|
(void) journal_file_close(f2);
|
||||||
journal_file_close(f3);
|
(void) journal_file_close(f3);
|
||||||
journal_file_close(f4);
|
(void) journal_file_close(f4);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
Loading…
Reference in a new issue