[dconf: 1/9] service: Allow opening corrupt GVDB files when writing
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dconf: 1/9] service: Allow opening corrupt GVDB files when writing
- Date: Tue, 21 Aug 2018 15:42:33 +0000 (UTC)
commit 5ee749cd25f221c382fa4b9545cff62eefcb10cf
Author: Philip Withnall <withnall endlessm com>
Date: Wed Aug 1 15:14:19 2018 +0100
service: Allow opening corrupt GVDB files when writing
If a GVDB file cannot be opened due to being corrupt, move it out of the
way, warn, and open a new blank database instead.
This prevents the situation where a corrupt database stops the entire
desktop session from loading.
Note that the dconf_gvdb_utils_read_file() code path is only taken
inside DConfWriter. The DConf engine sources (such as
dconf-engine-source-system.c) open the GVDB tables separately, and
already all handle errors gracefully.
Signed-off-by: Philip Withnall <withnall endlessm com>
https://gitlab.gnome.org/GNOME/glib/issues/1454
service/dconf-gvdb-utils.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
---
diff --git a/service/dconf-gvdb-utils.c b/service/dconf-gvdb-utils.c
index 099a9f3..fdd90e2 100644
--- a/service/dconf-gvdb-utils.c
+++ b/service/dconf-gvdb-utils.c
@@ -26,6 +26,9 @@
#include "../gvdb/gvdb-builder.h"
#include "../gvdb/gvdb-reader.h"
+#include <errno.h>
+#include <glib.h>
+#include <glib/gstdio.h>
#include <string.h>
DConfChangeset *
@@ -57,7 +60,36 @@ dconf_gvdb_utils_read_file (const gchar *filename,
/* Otherwise, we should report errors to prevent ourselves from
* overwriting the database in other situations...
*/
- if (my_error)
+ if (g_error_matches (my_error, G_FILE_ERROR, G_FILE_ERROR_INVAL))
+ {
+ /* Move the database to a backup file, warn and continue with a new
+ * database. The alternative is erroring out and exiting the daemon,
+ * which leaves the user’s session essentially unusable.
+ *
+ * The code to find an unused backup filename is racy, but this is an
+ * error handling path. Who cares. */
+ g_autofree gchar *backup_filename = NULL;
+ guint i;
+
+ for (i = 0;
+ i < G_MAXUINT &&
+ (backup_filename == NULL || g_file_test (backup_filename, G_FILE_TEST_EXISTS));
+ i++)
+ {
+ g_free (backup_filename);
+ backup_filename = g_strdup_printf ("%s~%u", filename, i);
+ }
+
+ if (g_rename (filename, backup_filename) != 0)
+ g_warning ("Error renaming corrupt database from ‘%s’ to ‘%s’: %s",
+ filename, backup_filename, g_strerror (errno));
+ else
+ g_warning ("Database ‘%s’ was corrupt: moved it to ‘%s’ and created an empty replacement",
+ filename, backup_filename);
+
+ g_clear_error (&my_error);
+ }
+ else if (my_error)
{
g_propagate_prefixed_error (error, my_error, "Cannot open dconf database: ");
return NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]