GUADEC cancelled due to beer shortage
- From: Mark McLoughlin <markmc redhat com>
- To: Desktop Devel <desktop-devel-list gnome org>
- Subject: GUADEC cancelled due to beer shortage
- Date: Mon, 21 Jun 2004 18:25:36 +0100
Hey,
Well, no. I lie. But I got your attention :-)
If you care about GConf preferences being shareable between pre-2.6 and
2.8 (or later) logins - or if you think someone might shout at you if it
doesn't work - you need to read this email.
In GNOME 2.6 we introduced a feature into GConf's default backend
whereby you could tell it to save a part of the GConf tree to a single
file (%gconf-tree.xml) rather than to a file (%gconf.xml) in every
directory of that part of the tree. See:
http://mail.gnome.org/archives/gconf-list/2003-July/msg00001.html
And we had a huge thread on this list which was related, but I didn't
really understand what was going on there:
http://mail.gnome.org/archives/desktop-devel-list/2003-October/thread.html#00084
Anyway, the plan now is that we're going to switch this feature on very
soon. See:
http://bugzilla.gnome.org/show_bug.cgi?id=138498
The way its going to work is that, we have a hardcoded list of
directories and we will coalesce the contents of each of those
directories *sub-directories* when we next go to save a change. e.g. the
list contains "/apps", so the next time you change
/apps/metacity/general/theme you'll find a %gconf-tree.xml file in
~/.gconf/apps/metacity.
Effectively, this means that changes made to your preferences using
GNOME 2.8 will not be visible if you log back into GNOME 2.4 or earlier.
To disable this behaviour you can pass a "nomerge" flag to the backend
e.g. change
xml:readwrite:$(HOME)/.gconf
to
xml:readwrite,nomerge:$(HOME)/.gconf
I'll be committing the patch below as soon as I've given it a decent
hammering. Initial testing suggests its okay, however.
Rational for the change is twofold:
1) Lessen the pain of sharing a homedir between simultaneous logins by
saving apps configuration as atomic units. This then gives us the
same hypothetically-broken-but-usually-OK behaviour as regular dotfiles.
2) Performance improvements
Cheers,
Mark.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gconf/ChangeLog,v
retrieving revision 1.527
diff -u -p -r1.527 ChangeLog
--- ChangeLog 21 Jun 2004 10:22:39 -0000 1.527
+++ ChangeLog 21 Jun 2004 16:15:42 -0000
@@ -1,0 +1,39 @@
+2004-06-21 Mark McLoughlin <mark skynet ie>
+
+ Fix for bug #138498 - turn on "subtree-in-a-file" for the
+ subdirectories of the following directories:
+
+ /apps/evolution",
+ /apps/panel/profiles",
+ /apps
+ /desktop/gnome
+ /system
+ /schemas/apps
+ /schemas/desktop/gnome
+ /schemas/system
+ /schemas
+ /
+
+ You can turn this of by passing the "nomerge" flag to the
+ backend - e.g. xml:readwrite,nomerge:$(HOME)/.gconf
+
+ * backends/markup-tree.[ch]:
+ (markup_tree_get): pass in the nomerge path.
+ (markup_dir_build_file_path),
+ (markup_dir_build_dir_path): simple wrappers for build_path().
+ (load_subtree), (load_entries), (load_subdirs),
+ (delete_useless_subdirs): upd. for above change.
+ (recursively_load_subtree): impl. recursively loading the tree
+ below a given dir.
+ (should_save_as_subtree): logic to figure out which dirs should
+ be saved as merged files.
+ (markup_dir_sync): save the dir in a merged file if neccessary.
+ (markup_dir_build_path): allow building a non-filesystem path.
+ (parse_tree), (save_tree): upd.
+ (write_dir): set the "not_in_filesystem" flag.
+
+ * backends/markup-backend.c:
+ (resolve_address), (ms_new): parse and use the "nomerge" flag.
+
+ * backends/gconf-merge-tree.c: (merge_tree): upd.
+
Index: backends/gconf-merge-tree.c
===================================================================
RCS file: /cvs/gnome/gconf/backends/gconf-merge-tree.c,v
retrieving revision 1.2
diff -u -p -r1.2 gconf-merge-tree.c
--- backends/gconf-merge-tree.c 28 Oct 2003 14:15:47 -0000 1.2
+++ backends/gconf-merge-tree.c 21 Jun 2004 16:15:42 -0000
@@ -39,25 +39,6 @@ _gconf_mode_t_to_mode (mode_t orig)
return mode;
}
-static void
-recursively_load_entire_tree (MarkupDir *dir)
-{
- GSList *tmp;
-
- load_entries (dir);
- load_subdirs (dir);
-
- tmp = dir->subdirs;
- while (tmp != NULL)
- {
- MarkupDir *subdir = tmp->data;
-
- recursively_load_entire_tree (subdir);
-
- tmp = tmp->next;
- }
-}
-
static gboolean
merge_tree (const char *root_dir)
{
@@ -80,9 +61,9 @@ merge_tree (const char *root_dir)
}
- tree = markup_tree_get (root_dir, dir_mode, file_mode);
+ tree = markup_tree_get (root_dir, dir_mode, file_mode, FALSE);
- recursively_load_entire_tree (tree->root);
+ recursively_load_subtree (tree->root);
error = NULL;
save_tree (tree->root, TRUE, file_mode, &error);
@@ -90,7 +71,7 @@ merge_tree (const char *root_dir)
{
char *markup_file;
- markup_file = markup_dir_build_path (tree->root, TRUE, TRUE);
+ markup_file = markup_dir_build_file_path (tree->root, TRUE);
fprintf (stderr, _("Error saving GConf tree to '%s': %s\n"),
markup_file,
error->message);
Index: backends/markup-backend.c
===================================================================
RCS file: /cvs/gnome/gconf/backends/markup-backend.c,v
retrieving revision 1.11
diff -u -p -r1.11 markup-backend.c
--- backends/markup-backend.c 19 Apr 2004 10:05:47 -0000 1.11
+++ backends/markup-backend.c 21 Jun 2004 16:15:42 -0000
@@ -65,11 +65,13 @@ typedef struct
MarkupTree *tree;
guint dir_mode;
guint file_mode;
+ guint try_merge : 1;
} MarkupSource;
static MarkupSource* ms_new (const char *root_dir,
guint dir_mode,
guint file_mode,
+ gboolean try_merge,
GConfLock *lock);
static void ms_destroy (MarkupSource *source);
@@ -262,6 +264,7 @@ resolve_address (const char *address,
char** address_flags;
char** iter;
gboolean force_readonly;
+ gboolean try_merge;
root_dir = get_dir_from_address (address, err);
if (root_dir == NULL)
@@ -286,6 +289,7 @@ resolve_address (const char *address,
}
force_readonly = FALSE;
+ try_merge = TRUE;
address_flags = gconf_address_flags (address);
if (address_flags)
@@ -296,7 +300,10 @@ resolve_address (const char *address,
if (strcmp (*iter, "readonly") == 0)
{
force_readonly = TRUE;
- break;
+ }
+ else if (strcmp (*iter, "nomerge") == 0)
+ {
+ try_merge = FALSE;
}
++iter;
@@ -386,9 +393,12 @@ resolve_address (const char *address,
return NULL;
}
+ if (try_merge && !(flags & GCONF_SOURCE_ALL_WRITEABLE))
+ try_merge = FALSE;
+
/* Create the new source */
- xsource = ms_new (root_dir, dir_mode, file_mode, lock);
+ xsource = ms_new (root_dir, dir_mode, file_mode, try_merge, lock);
gconf_log (GCL_DEBUG,
_("Directory/file permissions for XML source at root %s are: %o/%o"),
@@ -891,6 +901,7 @@ static MarkupSource*
ms_new (const char* root_dir,
guint dir_mode,
guint file_mode,
+ gboolean try_merge,
GConfLock *lock)
{
MarkupSource* ms;
@@ -909,8 +920,12 @@ ms_new (const char* root_dir,
ms->dir_mode = dir_mode;
ms->file_mode = file_mode;
+ ms->try_merge = try_merge;
- ms->tree = markup_tree_get (ms->root_dir, ms->dir_mode, ms->file_mode);
+ ms->tree = markup_tree_get (ms->root_dir,
+ ms->dir_mode,
+ ms->file_mode,
+ ms->try_merge);
return ms;
}
Index: backends/markup-tree.c
===================================================================
RCS file: /cvs/gnome/gconf/backends/markup-tree.c,v
retrieving revision 1.8
diff -u -p -r1.8 markup-tree.c
--- backends/markup-tree.c 12 Jun 2004 07:39:15 -0000 1.8
+++ backends/markup-tree.c 21 Jun 2004 16:15:42 -0000
@@ -63,8 +63,9 @@ static void markup_dir_free
static gboolean markup_dir_needs_sync (MarkupDir *dir);
static gboolean markup_dir_sync (MarkupDir *dir);
static char* markup_dir_build_path (MarkupDir *dir,
- gboolean with_data_file,
- gboolean subtree_data_file);
+ gboolean filesystem_path,
+ gboolean with_data_file,
+ gboolean subtree_data_file);
static void markup_dir_set_entries_need_save (MarkupDir *dir);
static MarkupEntry* markup_entry_new (MarkupDir *dir,
@@ -89,14 +90,34 @@ struct _MarkupTree
MarkupDir *root;
guint refcount;
+
+ guint try_merge : 1;
};
static GHashTable *trees_by_root_dir = NULL;
+/* List of dirs whose subdirs should be saved as a
+ * subtree-in-a-file. The order is important.
+ */
+static const char *save_as_subtree_dirs[] =
+{
+ "/apps/evolution",
+ "/apps/panel/profiles",
+ "/apps",
+ "/desktop/gnome",
+ "/system"
+ "/schemas/apps",
+ "/schemas/desktop/gnome",
+ "/schemas/system",
+ "/schemas",
+ "/"
+};
+
MarkupTree*
markup_tree_get (const char *root_dir,
guint dir_mode,
- guint file_mode)
+ guint file_mode,
+ gboolean try_merge)
{
MarkupTree *tree = NULL;
@@ -116,6 +137,7 @@ markup_tree_get (const char *root_dir,
tree->dirname = g_strdup (root_dir);
tree->dir_mode = dir_mode;
tree->file_mode = file_mode;
+ tree->try_merge = try_merge != FALSE;
tree->root = markup_dir_new (tree, NULL, "/");
@@ -258,6 +280,20 @@ markup_dir_queue_sync (MarkupDir *dir)
}
}
+static inline char *
+markup_dir_build_file_path (MarkupDir *dir,
+ gboolean subtree_data_file)
+{
+ return markup_dir_build_path (dir, TRUE, TRUE, subtree_data_file);
+}
+
+static inline char *
+markup_dir_build_dir_path (MarkupDir *dir,
+ gboolean filesystem_path)
+{
+ return markup_dir_build_path (dir, filesystem_path, FALSE, FALSE);
+}
+
static MarkupDir*
markup_tree_get_dir_internal (MarkupTree *tree,
const char *full_key,
@@ -361,7 +397,7 @@ load_subtree (MarkupDir *dir)
GError *tmp_err = NULL;
char *markup_file;
- markup_file = markup_dir_build_path (dir, TRUE, TRUE);
+ markup_file = markup_dir_build_file_path (dir, TRUE);
if (!gconf_file_exists (markup_file))
{
g_free (markup_file);
@@ -427,7 +463,7 @@ load_entries (MarkupDir *dir)
/* this message is debug-only because it usually happens
* when creating a new directory
*/
- markup_file = markup_dir_build_path (dir, TRUE, FALSE);
+ markup_file = markup_dir_build_file_path (dir, FALSE);
gconf_log (GCL_DEBUG,
"Failed to load file \"%s\": %s",
markup_file, tmp_err->message);
@@ -467,7 +503,7 @@ load_subdirs (MarkupDir *dir)
if (load_subtree (dir))
return TRUE;
- markup_dir = markup_dir_build_path (dir, FALSE, FALSE);
+ markup_dir = markup_dir_build_dir_path (dir, TRUE);
dp = opendir (markup_dir);
@@ -786,8 +822,8 @@ delete_useless_subdirs (MarkupDir *dir)
char *fs_dirname;
char *fs_filename;
- fs_dirname = markup_dir_build_path (subdir, FALSE, FALSE);
- fs_filename = markup_dir_build_path (subdir, TRUE, dir->save_as_subtree);
+ fs_dirname = markup_dir_build_dir_path (subdir, TRUE);
+ fs_filename = markup_dir_build_file_path (subdir, dir->save_as_subtree);
if (unlink (fs_filename) < 0)
{
@@ -887,6 +923,80 @@ delete_useless_entries (MarkupDir *dir)
return some_deleted;
}
+static void
+recursively_load_subtree (MarkupDir *dir)
+{
+ GSList *tmp;
+
+ load_entries (dir);
+ load_subdirs (dir);
+
+ tmp = dir->subdirs;
+ while (tmp != NULL)
+ {
+ MarkupDir *subdir = tmp->data;
+
+ recursively_load_subtree (subdir);
+
+ tmp = tmp->next;
+ }
+}
+
+static gboolean
+should_save_as_subtree (MarkupDir *dir)
+{
+ gboolean save_as_subtree = FALSE;
+ char *dir_path;
+ char *parent_path;
+ int pathlen;
+ int i;
+
+ if (!dir->tree->try_merge)
+ return FALSE;
+
+ /* never merge root */
+ if (!dir->parent)
+ return FALSE;
+
+ dir_path = markup_dir_build_dir_path (dir, FALSE);
+ pathlen = strlen (dir_path);
+
+ parent_path = markup_dir_build_dir_path (dir->parent, FALSE);
+
+ i = 0;
+ while (i < G_N_ELEMENTS (save_as_subtree_dirs))
+ {
+ const char *match = save_as_subtree_dirs [i];
+
+ /* 2 rules:
+ * 1) If @match is an ancestor of this dir, don't
+ * consider merging this dir
+ * 2) If @match is this dir's parent, then merge
+ * this dir
+ *
+ * (1) is so that we don't e.g., with "/apps" and
+ * "/apps/panel/profiles", merge /apps/panel when
+ * we really want to merge /apps/panel/profiles/default
+ */
+
+ if (strncmp (match, dir_path, pathlen) == 0)
+ break;
+
+ if (strcmp (match, parent_path) == 0)
+ {
+ save_as_subtree = TRUE;
+ break;
+ }
+
+ ++i;
+ }
+
+ g_free (dir_path);
+ g_free (parent_path);
+
+ return save_as_subtree;
+}
+
static gboolean
markup_dir_sync (MarkupDir *dir)
{
@@ -918,10 +1028,16 @@ markup_dir_sync (MarkupDir *dir)
tmp = tmp->next;
}
+
+ if (!dir->save_as_subtree && should_save_as_subtree (dir))
+ {
+ dir->save_as_subtree = TRUE;
+ recursively_load_subtree (dir);
+ }
- fs_dirname = markup_dir_build_path (dir, FALSE, FALSE);
- fs_filename = markup_dir_build_path (dir, TRUE, FALSE);
- fs_subtree = markup_dir_build_path (dir, TRUE, TRUE);
+ fs_dirname = markup_dir_build_dir_path (dir, TRUE);
+ fs_filename = markup_dir_build_file_path (dir, FALSE);
+ fs_subtree = markup_dir_build_file_path (dir, TRUE);
/* For a dir to be loaded as a subdir, it must have a
* %gconf.xml file, even if it has no entries in that
@@ -1051,6 +1167,7 @@ markup_dir_sync (MarkupDir *dir)
static char*
markup_dir_build_path (MarkupDir *dir,
+ gboolean filesystem_path,
gboolean with_data_file,
gboolean subtree_data_file)
{
@@ -1059,6 +1176,8 @@ markup_dir_build_path (MarkupDir *dir,
GSList *tmp;
MarkupDir *iter;
+ g_assert (filesystem_path || !with_data_file);
+
components = NULL;
iter = dir;
while (iter->parent != NULL) /* exclude root dir */
@@ -1067,7 +1186,11 @@ markup_dir_build_path (MarkupDir *dir,
iter = iter->parent;
}
- name = g_string_new (dir->tree->dirname);
+ if (filesystem_path)
+ name = g_string_new (dir->tree->dirname);
+ else
+ name = g_string_new (components ? NULL : "/");
+
tmp = components;
while (tmp != NULL)
{
@@ -3072,7 +3195,7 @@ parse_tree (MarkupDir *root,
char *text;
gsize length;
- filename = markup_dir_build_path (root, TRUE, parse_subtree);
+ filename = markup_dir_build_file_path (root, parse_subtree);
parse_info_init (&info, root, parse_subtree);
@@ -3570,6 +3693,8 @@ write_dir (MarkupDir *dir,
gboolean retval = FALSE;
char *whitespace;
+ dir->not_in_filesystem = TRUE;
+
/* This dir will be deleted from the
* MarkupTree after syncing anyway ...
*/
@@ -3639,7 +3764,7 @@ save_tree (MarkupDir *dir,
new_fd = -1;
f = NULL;
- filename = markup_dir_build_path (dir, TRUE, save_as_subtree);
+ filename = markup_dir_build_file_path (dir, save_as_subtree);
new_filename = g_strconcat (filename, ".new", NULL);
new_fd = open (new_filename, O_WRONLY | O_CREAT, file_mode);
Index: backends/markup-tree.h
===================================================================
RCS file: /cvs/gnome/gconf/backends/markup-tree.h,v
retrieving revision 1.4
diff -u -p -r1.4 markup-tree.h
--- backends/markup-tree.h 13 Mar 2003 20:24:57 -0000 1.4
+++ backends/markup-tree.h 21 Jun 2004 16:15:42 -0000
@@ -31,7 +31,8 @@ typedef struct _MarkupEntry MarkupEntry;
MarkupTree* markup_tree_get (const char *root_dir,
guint dir_mode,
- guint file_mode);
+ guint file_mode,
+ gboolean try_merge);
void markup_tree_unref (MarkupTree *tree);
void markup_tree_rebuild (MarkupTree *tree);
MarkupDir* markup_tree_lookup_dir (MarkupTree *tree,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]