summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@redhat.com>2013-05-13 17:40:40 +0200
committerTomas Bzatek <tbzatek@redhat.com>2013-05-13 17:40:40 +0200
commit3381859ba7a92f4824ff09a7aa951407bf4e1c72 (patch)
treed0169ffc24434c3e02afba19826ed85ba3f3df24
parent21811b3ae17ec705327484c1ce0be75fec95bb0e (diff)
metadata: Create new journal if it doesn't exist
With concurrent access of multiple daemons there may be a moment when tree file exists but not the journal file. The daemon can't write anything without journal and is doomed until next rotation. Missing journal file can also happen on system crash etc. This patch tries to create new journal file only when it doesn't exist, other errors still lead to inability to store anything. This will also allow us to have journal file somewhere else, e.g. on a non-persistent storage. https://bugzilla.gnome.org/show_bug.cgi?id=637095
-rw-r--r--metadata/metabuilder.c6
-rw-r--r--metadata/metabuilder.h2
-rw-r--r--metadata/metatree.c16
3 files changed, 18 insertions, 6 deletions
diff --git a/metadata/metabuilder.c b/metadata/metabuilder.c
index 58bb57bd..c7e69fac 100644
--- a/metadata/metabuilder.c
+++ b/metadata/metabuilder.c
@@ -843,8 +843,8 @@ get_journal_filename (const char *filename, guint32 random_tag)
return g_strconcat (filename, "-", tag, ".log", NULL);
}
-static gboolean
-create_new_journal (const char *filename, guint32 random_tag)
+gboolean
+meta_builder_create_new_journal (const char *filename, guint32 random_tag)
{
char *journal_name;
guint32 size_offset;
@@ -1016,7 +1016,7 @@ meta_builder_write (MetaBuilder *builder,
if (!write_all_data_and_close (fd, out->str, out->len))
goto out;
- if (!create_new_journal (filename, random_tag))
+ if (!meta_builder_create_new_journal (filename, random_tag))
goto out;
/* Open old file so we can set it rotated */
diff --git a/metadata/metabuilder.h b/metadata/metabuilder.h
index 364c0d84..ad3876ff 100644
--- a/metadata/metabuilder.h
+++ b/metadata/metabuilder.h
@@ -68,6 +68,8 @@ void meta_builder_copy (MetaBuilder *builder,
guint64 mtime);
gboolean meta_builder_write (MetaBuilder *builder,
const char *filename);
+gboolean meta_builder_create_new_journal (const char *filename,
+ guint32 random_tag);
MetaFile * metafile_new (const char *name,
MetaFile *parent);
void metafile_free (MetaFile *file);
diff --git a/metadata/metatree.c b/metadata/metatree.c
index 20b78627..8e2ab46c 100644
--- a/metadata/metatree.c
+++ b/metadata/metatree.c
@@ -1146,20 +1146,30 @@ meta_journal_open (MetaTree *tree, const char *filename, gboolean for_write, gui
char *data;
char *journal_filename;
int open_flags, mmap_prot;
+ gboolean retried;
g_assert (sizeof (MetaJournalHeader) == 20);
-
- journal_filename = get_journal_filename (filename, tag);
+ retried = FALSE;
if (for_write)
open_flags = O_RDWR;
else
open_flags = O_RDONLY;
+ retry:
+ journal_filename = get_journal_filename (filename, tag);
fd = safe_open (tree, journal_filename, open_flags);
g_free (journal_filename);
if (fd == -1)
- return NULL;
+ {
+ if (errno == ENOENT && tree->for_write && !retried)
+ {
+ retried = TRUE;
+ if (meta_builder_create_new_journal (filename, tag))
+ goto retry;
+ }
+ return NULL;
+ }
if (fstat (fd, &statbuf) != 0 ||
statbuf.st_size < sizeof (MetaJournalHeader))