persistent property store - first try
Kay Sievers
kay.sievers at vrfy.org
Thu Jun 10 17:21:22 PDT 2004
On Thu, Jun 10, 2004 at 06:29:55PM -0400, Joe Shaw wrote:
> On Fri, 2004-06-11 at 00:06 +0200, Kay Sievers wrote:
> > +hal_pstore_close (HalPStore *pstore)
> > +{
> > + g_free (pstore->path);
> > + g_free (pstore->uuid);
> > + g_free (pstore);
> > +}
>
> Are you sure you want to free pstore->uuid here? If you do, pstore_uuid
> will be garbage if you try to call hal_pstore_open() without first
> calling hal_pstore_init(). You probably want to either g_strdup() it in
> hal_store_open() or not free it at all (and declare it const in the
> struct definition).
Excellent eyes! :) Yeah, it was a leftover from the first version
without the global uuid.
> On a related note, you might want to check in hal_pstore_open() that
> hal_pstore_init() is called first. Or just make hal_pstore_init()
> static and have hal_pstore_open() lazily call it.
Hmm, with the explicit init we can read the stored uuid from any location,
but I don't know if we ever need this?
thanks,
Kay
-------------- next part --------------
--- hal/hal/hald/Makefile.am 2004-06-05 02:58:50.000000000 +0200
+++ hal.kay/hal/hald/Makefile.am 2004-06-10 14:23:39.087721792 +0200
@@ -25,6 +25,7 @@
logger.h logger.c \
osspec.h \
property.h property.c \
+ pstore.h pstore.c \
hald_conf.h hald_conf.c
hald_SOURCES += \
--- hal/hal/hald/hald.h 2004-04-03 09:46:33.000000000 +0200
+++ hal.kay/hal/hald/hald.h 2004-06-10 14:23:39.089721488 +0200
@@ -31,6 +31,7 @@
#include <dbus/dbus.h>
#include "device_store.h"
+#include "pstore.h"
/**
* @addtogroup HalDaemon
@@ -40,6 +41,7 @@
HalDeviceStore *hald_get_gdl (void);
HalDeviceStore *hald_get_tdl (void);
+HalPStore *hald_get_pstore_sys (void);
void property_atomic_update_begin ();
void property_atomic_update_end ();
--- hal/hal/hald/hald.c 2004-06-05 02:58:50.000000000 +0200
+++ hal.kay/hal/hald/hald.c 2004-06-11 01:51:51.894261024 +0200
@@ -46,6 +46,7 @@
#include "logger.h"
#include "hald.h"
#include "device_store.h"
+#include "pstore.h"
#include "device_info.h"
#include "osspec.h"
#include "hald_dbus.h"
@@ -61,6 +62,8 @@
static HalDeviceStore *temporary_device_list = NULL;
+static HalPStore *pstore_sys = NULL;
+
static void
gdl_store_changed (HalDeviceStore *store, HalDevice *device,
gboolean is_added, gpointer user_data)
@@ -131,6 +134,15 @@
return temporary_device_list;
}
+HalPStore *
+hald_get_pstore_sys (void)
+{
+ if (pstore_sys == NULL)
+ pstore_sys = hal_pstore_open (HAL_PSTORE_SYSTEM_PATH);
+
+ return pstore_sys;
+}
+
/**
* @defgroup MainDaemon Basic functions
* @ingroup HalDaemon
@@ -273,6 +285,9 @@
loop = g_main_loop_new (NULL, FALSE);
+ /* initialize persitent property store, read uuid from path */
+ hal_pstore_init (HAL_PSTORE_SYSTEM_PATH "/uuid");
+
/* initialize operating system specific parts */
osspec_init (dbus_connection);
/* and detect devices */
--- hal/hal/hald/device.h 2004-04-26 22:08:58.000000000 +0200
+++ hal.kay/hal/hald/device.h 2004-06-10 20:57:47.734581008 +0200
@@ -150,4 +150,8 @@
void hal_device_callouts_finished (HalDevice *device);
+gboolean hal_device_property_set_persistence (HalDevice *device,
+ const char *key,
+ gboolean persistence);
+
#endif /* DEVICE_H */
--- hal/hal/hald/device.c 2004-04-26 22:08:58.000000000 +0200
+++ hal.kay/hal/hald/device.c 2004-06-10 22:38:15.740184864 +0200
@@ -31,7 +31,9 @@
#include <stdio.h>
#include <string.h>
+#include "hald.h"
#include "device.h"
+#include "pstore.h"
#include "hald_marshal.h"
#include "logger.h"
@@ -603,6 +605,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, FALSE);
+ if (hal_property_get_persistence (prop))
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -613,6 +618,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, TRUE);
+ if (hal_property_get_persistence (prop))
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -638,6 +646,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, FALSE);
+ if (hal_property_get_persistence (prop))
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -648,6 +659,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, TRUE);
+ if (hal_property_get_persistence (prop))
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -673,6 +687,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, FALSE);
+ if (hal_property_get_persistence (prop))
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -683,6 +700,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, TRUE);
+ if (hal_property_get_persistence (prop))
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -708,6 +728,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, FALSE);
+ if (hal_property_get_persistence (prop))
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -718,6 +741,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, TRUE);
+ if (hal_property_get_persistence (prop))
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -731,6 +757,9 @@
if (prop == NULL)
return FALSE;
+ if (hal_property_get_persistence (prop))
+ hal_pstore_delete_property (hald_get_pstore_sys (), device, prop);
+
device->properties = g_slist_remove (device->properties, prop);
hal_property_free (prop);
@@ -741,6 +770,29 @@
return TRUE;
}
+gboolean
+hal_device_property_set_persistence (HalDevice *device,
+ const char *key,
+ gboolean persistence)
+{
+ HalProperty *prop;
+
+ prop = hal_device_property_find (device, key);
+
+ if (prop == NULL)
+ return FALSE;
+
+ hal_property_set_persistence (prop, persistence);
+
+ /* Write it to disk, or delete it */
+ if (hal_property_get_persistence (prop) == TRUE)
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+ else
+ hal_pstore_delete_property (hald_get_pstore_sys (), device, prop);
+
+ return TRUE;
+}
+
void
hal_device_print (HalDevice *device)
{
--- hal/hal/hald/property.h 2004-04-20 22:54:15.000000000 +0200
+++ hal.kay/hal/hald/property.h 2004-06-10 20:51:24.043910856 +0200
@@ -59,5 +59,8 @@
dbus_bool_t value);
void hal_property_set_double (HalProperty *prop,
double value);
+void hal_property_set_persistence (HalProperty *prop,
+ gboolean persistence);
+gboolean hal_property_get_persistence (HalProperty *prop);
#endif /* PROPERTY_H */
--- hal/hal/hald/property.c 2004-04-20 22:54:15.000000000 +0200
+++ hal.kay/hal/hald/property.c 2004-06-10 22:28:08.578487472 +0200
@@ -42,13 +42,14 @@
dbus_bool_t bool_value;
double double_value;
};
+ gboolean persistence;
};
void
hal_property_free (HalProperty *prop)
{
g_free (prop->key);
-
+
if (prop->type == DBUS_TYPE_STRING)
g_free (prop->str_value);
@@ -226,3 +227,20 @@
prop->type = DBUS_TYPE_DOUBLE;
prop->double_value = value;
}
+
+void
+hal_property_set_persistence (HalProperty *prop, gboolean persistence)
+{
+ g_return_if_fail (prop != NULL);
+
+ prop->persistence = persistence;
+}
+
+gboolean
+hal_property_get_persistence (HalProperty *prop)
+{
+ g_return_val_if_fail (prop != NULL, -1);
+
+ return prop->persistence;
+}
+
--- hal/hal/hald/hald_dbus.c 2004-05-04 18:05:35.000000000 +0200
+++ hal.kay/hal/hald/hald_dbus.c 2004-06-10 22:55:36.500965176 +0200
@@ -872,6 +872,7 @@
type = dbus_message_iter_get_arg_type (&iter);
rc = FALSE;
+
switch (type) {
case DBUS_TYPE_STRING:
rc = hal_device_property_set_string (device, key,
@@ -899,6 +900,10 @@
break;
}
+ /* FIXME: temporary hack to test pstore; makes all D-BUS properties persistent */
+ hal_device_property_set_persistence (device, key, TRUE);
+ HAL_WARNING (("FIXME: persistence set for all D-BUS props; udi=%s, key=%s", udi, key));
+
if (!rc) {
raise_property_type_error (connection, message, udi, key);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
--- hal/hal/hald/linux/common.c 2004-04-26 22:42:13.000000000 +0200
+++ hal.kay/hal/hald/linux/common.c 2004-06-10 14:23:39.091721184 +0200
@@ -44,6 +44,7 @@
#include "../logger.h"
#include "../device_store.h"
+#include "../pstore.h"
#include "../device_info.h"
#include "../hald.h"
#include "common.h"
@@ -512,6 +513,8 @@
HAL_INFO (("Found a .fdi file for %s", d->udi));
}
+ /* add possible saved properties for this udi from disk*/
+ hal_pstore_load_device (hald_get_pstore_sys (), d);
}
return computed_udi;
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ hal.kay/hal/hald/pstore.h 2004-06-10 14:23:39.091721184 +0200
@@ -0,0 +1,58 @@
+/***************************************************************************
+ * CVSID: $Id: $
+ *
+ * pstore.h : persistent property store on disk
+ *
+ * Copyright (C) 2004 Kay Sievers, <kay.sievers at vrfy.org>
+ *
+ * Licensed under the Academic Free License version 2.0
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#ifndef PSTORE_H
+#define PSTORE_H
+
+#define HAL_PSTORE_SYSTEM_PATH "/var/lib/hal"
+
+#include "device.h"
+#include "property.h"
+
+typedef struct _HalPStore HalPStore;
+
+void hal_pstore_init (const char *path);
+
+HalPStore *hal_pstore_open (const char *path);
+
+void hal_pstore_close (HalPStore *pstore);
+
+void hal_pstore_save_property (HalPStore *pstore,
+ HalDevice *device,
+ HalProperty *prop);
+
+void hal_pstore_load_property (HalPStore *pstore,
+ HalDevice *device,
+ const char *key);
+
+void hal_pstore_delete_property (HalPStore *pstore,
+ HalDevice *device,
+ HalProperty *prop);
+
+void hal_pstore_load_device (HalPStore *pstore,
+ HalDevice *device);
+
+
+#endif /* PSTORE_H */
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ hal.kay/hal/hald/pstore.c 2004-06-11 01:59:58.257322600 +0200
@@ -0,0 +1,363 @@
+/***************************************************************************
+ * CVSID: $Id: $
+ *
+ * pstore.c : persistent property store on disk
+ *
+ * Copyright (C) 2004 Kay Sievers, <kay.sievers at vrfy.org>
+ *
+ * Licensed under the Academic Free License version 2.0
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <glib.h>
+
+#include "logger.h"
+#include "pstore.h"
+
+#define PSTR "String:"
+#define PINT32 "Int32:"
+#define PBOOL "Bool:"
+#define PDOUBLE "Double:"
+#define UDI_STRIP "/org/freedesktop/Hal"
+
+static char *pstore_uuid = NULL;
+
+struct _HalPStore {
+ char *path;
+ const char *uuid;
+};
+
+/** Create relative or absolute path.
+ *
+ */
+static int
+create_path(const char *path)
+{
+ char *p;
+ char *pos;
+ struct stat stats;
+
+ if (stat (path, &stats) == 0)
+ return 0;
+
+ p = g_strdup (path);
+ pos = strrchr (p, '/');
+ if (pos != NULL && pos != p) {
+ pos[0] = '\0';
+ create_path (p);
+ }
+ g_free (p);
+
+ return mkdir(path, 0755);
+}
+
+/** Return absolute filename with simplified udi string.
+ *
+ */
+static char
+*build_path (HalPStore *pstore,
+ const char *udi, const char *file)
+{
+ char *path;
+ const char *udi_s;
+
+ udi_s = udi;
+ /* strip namespace part of udi string */
+ if (udi != NULL &&
+ g_ascii_strncasecmp(udi, UDI_STRIP, sizeof(UDI_STRIP)-1) == 0)
+ udi_s = &udi[sizeof(UDI_STRIP)-1];
+
+ path = g_build_filename (G_DIR_SEPARATOR_S,
+ pstore->path, pstore->uuid,
+ udi_s, file, NULL);
+
+ return path;
+}
+
+/** Init pstore system by reading or generating our uuid.
+ *
+ */
+void
+hal_pstore_init (const char *uuid_file)
+{
+ char *uuid;
+ char hostname[HOST_NAME_MAX];
+ char *p;
+ GIOChannel *io;
+ GError *error = NULL;
+ int written;
+
+ g_file_get_contents (uuid_file, &uuid, NULL, NULL);
+
+ if (uuid == NULL) {
+ /* create new uuid and save it to disk */
+ gethostname (hostname, HOST_NAME_MAX);
+ uuid = g_strdup_printf ("%s-%lx", hostname, time(NULL));
+
+ p = g_path_get_dirname (uuid_file);
+ create_path(p);
+ g_free(p);
+
+ io = g_io_channel_new_file (uuid_file, "w", &error);
+ if (error != NULL) {
+ HAL_WARNING (("error creating file %s", error->message));
+ g_error_free (error);
+ return;
+ }
+ g_io_channel_write_chars (io, uuid, -1, &written, &error);
+ g_io_channel_shutdown (io, TRUE, NULL);
+ if (error != NULL) {
+ HAL_WARNING (("error writing to file %s", error->message));
+ g_error_free (error);
+ return;
+ }
+ }
+
+ HAL_DEBUG (("uuid is %s", uuid));
+ pstore_uuid = uuid;
+}
+
+
+/** Open pstore on the given location.
+ *
+ */
+HalPStore
+*hal_pstore_open (const char *path)
+{
+ HalPStore *pstore;
+ char *p;
+
+ if (pstore_uuid == NULL)
+ return NULL;
+
+ pstore = g_new0 (HalPStore, 1);
+
+ pstore->path = g_strdup (path);
+
+ pstore->uuid = pstore_uuid;
+
+ p = g_build_path (G_DIR_SEPARATOR_S,
+ pstore->path, pstore->uuid, NULL);
+ create_path(p);
+ g_free(p);
+
+ HAL_DEBUG (("opened pstore at %s/%s/", pstore->path, pstore->uuid));
+
+ return pstore;
+}
+
+/** Turn around the OPEN sign, in the store's entrance :)
+ *
+ */
+void
+hal_pstore_close (HalPStore *pstore)
+{
+ g_free (pstore->path);
+ g_free (pstore);
+}
+
+/** Save a property value to the disk.
+ *
+ */
+void
+hal_pstore_save_property (HalPStore *pstore,
+ HalDevice *device, HalProperty *prop)
+{
+ char *path;
+ char *file;
+ GIOChannel *io;
+ GError *error = NULL;
+ char *id;
+ char *value;
+ char *buf;
+ int written;
+
+ switch (hal_property_get_type (prop)) {
+ case DBUS_TYPE_STRING:
+ id = PSTR;
+ break;
+ case DBUS_TYPE_INT32:
+ id = PINT32;
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ id = PBOOL;
+ break;
+ case DBUS_TYPE_DOUBLE:
+ id = PDOUBLE;
+ break;
+ default:
+ HAL_WARNING (("unknown property type %s",
+ hal_property_get_key (prop)));
+ return;
+ }
+
+ path = build_path (pstore, hal_device_get_udi (device), NULL);
+ create_path(path);
+ g_free(path);
+
+ file = build_path (pstore,
+ hal_device_get_udi (device),
+ hal_property_get_key (prop));
+
+ io = g_io_channel_new_file (file, "w", &error);
+ if (error != NULL) {
+ HAL_WARNING (("error creating file %s (%s)", file, error->message));
+ g_error_free (error);
+ g_free (file);
+ return;
+ }
+
+ value = hal_property_to_string (prop);
+
+ buf = g_strconcat (id, value, NULL);
+ g_free (value);
+
+ HAL_DEBUG (("write %s to disk", hal_property_get_key (prop)));
+
+ g_io_channel_write_chars (io, buf, -1, &written, &error);
+ if (error != NULL) {
+ HAL_WARNING (("error writing to file %s (%s)", file, error->message));
+ g_error_free (error);
+ }
+
+ g_io_channel_shutdown (io, TRUE, NULL);
+ g_free (buf);
+ g_free (file);
+}
+
+/** Load a stored property value from the disk.
+ *
+ */
+void
+hal_pstore_load_property (HalPStore *pstore,
+ HalDevice *device, const char *key)
+{
+ char *file;
+ char *buf;
+ char *str;
+ int i;
+ double d;
+
+ file = build_path (pstore, hal_device_get_udi (device), key);
+
+ g_file_get_contents (file, &buf, NULL, NULL);
+ g_free (file);
+ if (buf == NULL) {
+ HAL_DEBUG (("error reading file %s", file));
+ return;
+ }
+
+ if (g_ascii_strncasecmp (buf, PSTR, sizeof (PSTR)-1) == 0) {
+ str = &buf[sizeof (PSTR)-1];
+ hal_device_property_set_string (device, key, str);
+ HAL_INFO (("STRING %s read for %s", str, key));
+ goto exit;
+ }
+
+ if (g_ascii_strncasecmp (buf, PINT32, sizeof (PINT32)-1) == 0) {
+ str = &buf[sizeof (PINT32)-1];
+ i = strtol (str, NULL, 10);
+ hal_device_property_set_int (device, key, i);
+ goto exit;
+ }
+
+ if (g_ascii_strncasecmp (buf, PBOOL, sizeof (PBOOL)-1) == 0) {
+ str = &buf[sizeof (PBOOL)-1];
+ if (g_ascii_strcasecmp (str, "true") == 0)
+ i = TRUE;
+ else
+ i = FALSE;
+ hal_device_property_set_bool (device, key, i);
+ goto exit;
+ }
+
+ if (g_ascii_strncasecmp (buf, PDOUBLE, sizeof (PDOUBLE)-1) == 0) {
+ str = &buf[sizeof (PDOUBLE)-1];
+ d = atof (str);
+ hal_device_property_set_double (device, key, d);
+ goto exit;
+ }
+
+ HAL_WARNING (("error determining pstore property type %s", key));
+
+exit:
+ g_free (buf);
+}
+
+/** Delete a stored property from the disk.
+ *
+ */
+void
+hal_pstore_delete_property (HalPStore *pstore,
+ HalDevice *device, HalProperty *prop)
+{
+ char *file;
+
+ file = build_path (pstore,
+ hal_device_get_udi (device),
+ hal_property_get_key (prop));
+
+ HAL_DEBUG (("unlinking %s", file));
+
+ unlink(file);
+ g_free(file);
+}
+
+/** Load all stored properties of a device from the disk.
+ *
+ */
+void
+hal_pstore_load_device (HalPStore *pstore,
+ HalDevice *device)
+{
+ GDir *dir;
+ GError *error = NULL;
+ const char *dirname;
+ char *path;
+
+ path = build_path (pstore,
+ hal_device_get_udi (device),
+ NULL);
+
+ HAL_DEBUG (("reading directory %s", path));
+
+ dir = g_dir_open (path, 0, &error);
+ if (error)
+ goto exit;
+
+ while (1) {
+ dirname = g_dir_read_name (dir);
+ if (dirname == NULL)
+ break;
+
+ hal_pstore_load_property (pstore, device, dirname);
+ }
+
+ g_dir_close (dir);
+
+exit:
+ g_free (path);
+}
-------------- next part --------------
_______________________________________________
hal mailing list
hal at freedesktop.org
http://freedesktop.org/mailman/listinfo/hal
More information about the Hal
mailing list