diff options
Diffstat (limited to 'engine')
-rw-r--r-- | engine/Makefile.am | 1 | ||||
-rw-r--r-- | engine/dconf-engine-source-private.h | 1 | ||||
-rw-r--r-- | engine/dconf-engine-source-user-nfs.c | 93 | ||||
-rw-r--r-- | engine/dconf-engine-source.c | 17 |
4 files changed, 109 insertions, 3 deletions
diff --git a/engine/Makefile.am b/engine/Makefile.am index b69c70c..8eda5f1 100644 --- a/engine/Makefile.am +++ b/engine/Makefile.am @@ -9,6 +9,7 @@ libdconf_engine_a_SOURCES = \ dconf-engine-source-private.h \ dconf-engine-source.h \ dconf-engine-source-user.c \ + dconf-engine-source-user-nfs.c \ dconf-engine-source-system.c \ dconf-engine-source.c \ dconf-engine.h \ diff --git a/engine/dconf-engine-source-private.h b/engine/dconf-engine-source-private.h index 822354a..57840dc 100644 --- a/engine/dconf-engine-source-private.h +++ b/engine/dconf-engine-source-private.h @@ -26,6 +26,7 @@ #include "dconf-engine-source.h" G_GNUC_INTERNAL extern const DConfEngineSourceVTable dconf_engine_source_user_vtable; +G_GNUC_INTERNAL extern const DConfEngineSourceVTable dconf_engine_source_user_nfs_vtable; G_GNUC_INTERNAL extern const DConfEngineSourceVTable dconf_engine_source_system_vtable; #endif /* __dconf_engine_source_private_h__ */ diff --git a/engine/dconf-engine-source-user-nfs.c b/engine/dconf-engine-source-user-nfs.c new file mode 100644 index 0000000..336fa04 --- /dev/null +++ b/engine/dconf-engine-source-user-nfs.c @@ -0,0 +1,93 @@ +/* + * Copyright © 2010 Codethink Limited + * Copyright © 2012 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie <desrt@desrt.ca> + */ + +#include "dconf-engine-source-private.h" + +#include "../shm/dconf-shm.h" +#include "dconf-engine.h" +#include <sys/mman.h> +#include <fcntl.h> +#include <errno.h> + +static void +dconf_engine_source_user_nfs_init (DConfEngineSource *source) +{ + GError *error = NULL; + GVariant *reply; + + source->bus_type = G_BUS_TYPE_SESSION; + source->bus_name = g_strdup ("ca.desrt.dconf"); + source->object_path = g_strdup_printf ("/ca/desrt/dconf/Writer/%s", source->name); + source->writable = TRUE; + + /* We need to get the dconf-service to come online and notice that + * we're on an NFS home directory. In that case it will copy the + * given database into the XDG_RUNTIME_DIR which is where we will + * access it. + * + * This prevents us from doing mmap() on a file on NFS (which often + * results in us seeing SIGBUS). + */ + reply = dconf_engine_dbus_call_sync_func (G_BUS_TYPE_SESSION, source->bus_name, source->object_path, + "ca.desrt.dconf.Writer", "Init", NULL, G_VARIANT_TYPE_UNIT, &error); + + if (reply) + g_variant_unref (reply); + else + { + g_warning ("Trying to start the dconf service failed: %s. Expect problems.", error->message); + g_error_free (error); + } +} + +static gboolean +dconf_engine_source_user_nfs_needs_reopen (DConfEngineSource *source) +{ + return !source->values || !gvdb_table_is_valid (source->values); +} + +static GvdbTable * +dconf_engine_source_user_nfs_reopen (DConfEngineSource *source) +{ + GvdbTable *table; + gchar *filename; + + filename = g_build_filename (dconf_shm_get_shmdir (), source->name, NULL); + table = gvdb_table_new (filename, FALSE, NULL); + g_free (filename); + + return table; +} + +static void +dconf_engine_source_user_nfs_finalize (DConfEngineSource *source) +{ +} + +G_GNUC_INTERNAL +const DConfEngineSourceVTable dconf_engine_source_user_nfs_vtable = { + .instance_size = sizeof (DConfEngineSource), + .init = dconf_engine_source_user_nfs_init, + .finalize = dconf_engine_source_user_nfs_finalize, + .needs_reopen = dconf_engine_source_user_nfs_needs_reopen, + .reopen = dconf_engine_source_user_nfs_reopen +}; diff --git a/engine/dconf-engine-source.c b/engine/dconf-engine-source.c index 4eb7faa..68b10de 100644 --- a/engine/dconf-engine-source.c +++ b/engine/dconf-engine-source.c @@ -71,6 +71,15 @@ dconf_engine_source_refresh (DConfEngineSource *source) return FALSE; } +static const DConfEngineSourceVTable * +dconf_engine_source_get_user_vtable (void) +{ + if (dconf_shm_homedir_is_native ()) + return &dconf_engine_source_user_vtable; + else + return &dconf_engine_source_user_nfs_vtable; +} + DConfEngineSource * dconf_engine_source_new (const gchar *description) { @@ -94,7 +103,7 @@ dconf_engine_source_new (const gchar *description) /* Check if the part before the colon is "user-db"... */ if ((colon == description + 7) && memcmp (description, "user-db", 7) == 0) - vtable = &dconf_engine_source_user_vtable; + vtable = dconf_engine_source_get_user_vtable (); /* ...or "system-db" */ else if ((colon == description + 9) && memcmp (description, "system-db", 9) == 0) @@ -122,10 +131,12 @@ dconf_engine_source_new (const gchar *description) DConfEngineSource * dconf_engine_source_new_default (void) { + const DConfEngineSourceVTable *vtable; DConfEngineSource *source; - source = g_malloc0 (dconf_engine_source_user_vtable.instance_size); - source->vtable = &dconf_engine_source_user_vtable; + vtable = dconf_engine_source_get_user_vtable (); + source = g_malloc0 (vtable->instance_size); + source->vtable = vtable; source->name = g_strdup ("user"); source->vtable->init (source); |