persistent property store - first try
Kay Sievers
kay.sievers at vrfy.org
Tue Jun 8 18:57:58 PDT 2004
Hi,
here is a first try to store properties on disk. Please have a look, if
we can do it this way. The properties are stored in a directory
with the udi as the name. HAL creates a uuid starting with the hostname
to be able to store user properies in a .hal/ directory home, so every box
can have its own data in the users $HOME.
[kay at pim kay]$ tree /var/lib/hal/
/var/lib/hal/
`-- pim-95a478b32fa0
`-- org
`-- freedesktop
`-- Hal
`-- devices
|-- pci_8086_3340
| `-- save.key
`-- usb_46d_c00e_1100_-1_noserial
|-- flag
|-- flag.true
|-- number
|-- save.key
|-- save.key2
`-- save.key3
[kay at pim usb_46d_c00e_1100_-1_noserial]$ cat save.key
String:yeah
Just open a store with:
hal_pstore_open("/var/lib/hal");
and save a property with:
hal_pstore_save_property(store, device, property);
(A directory will be created and the value is saved to the file)
to read one attribute back, call:
hal_pstore_load_property(store, device, "info.test")
to read all saved attributed for a device, call:
hal_pstore_load_device(store, device);
I've hooked it into the current code:
The saved properties are loaded after the device's fdi parsing.
The property are only saved if the key starts with "save". This is
just to be able to play around with it. We need to decide, which
properties we want to live on disk and when the save should be triggered.
To play around, just set a property, starting with "save*" and look at "/var/lib/hal/":
hal-set-property --udi /org/freedesktop/Hal/devices/pci_8086_3340 --string yeah --key save.test
The uuid must be saved on disk and loaded on the store's init, it's just
a static string for now. Only the system_store is active now.
Please share your thoughts.
thanks,
Kay
-------------- next part --------------
Index: hald/Makefile.am
===================================================================
RCS file: /cvs/hal/hal/hald/Makefile.am,v
retrieving revision 1.26
diff -u -r1.26 Makefile.am
--- a/hald/Makefile.am 1 Jun 2004 21:10:02 -0000 1.26
+++ b/hald/Makefile.am 9 Jun 2004 01:11:26 -0000
@@ -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 += \
Index: hald/device.c
===================================================================
RCS file: /cvs/hal/hal/hald/device.c,v
retrieving revision 1.6
diff -u -r1.6 device.c
--- a/hald/device.c 26 Apr 2004 20:08:58 -0000 1.6
+++ b/hald/device.c 9 Jun 2004 01:11:26 -0000
@@ -32,6 +32,7 @@
#include <string.h>
#include "device.h"
+#include "pstore.h"
#include "hald_marshal.h"
#include "logger.h"
@@ -603,6 +604,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, FALSE);
+ if (strncmp (key, "save", 4) == 0 )
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
@@ -613,6 +617,9 @@
g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
key, FALSE, TRUE);
+ if (strncmp (key, "save", 4) == 0 )
+ hal_pstore_save_property (hald_get_pstore_sys (), device, prop);
+
return TRUE;
}
Index: hald/hald.c
===================================================================
RCS file: /cvs/hal/hal/hald/hald.c,v
retrieving revision 1.8
diff -u -r1.8 hald.c
--- a/hald/hald.c 1 Jun 2004 21:10:02 -0000 1.8
+++ b/hald/hald.c 9 Jun 2004 01:11:26 -0000
@@ -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,17 @@
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
Index: hald/hald.h
===================================================================
RCS file: /cvs/hal/hal/hald/hald.h,v
retrieving revision 1.4
diff -u -r1.4 hald.h
--- a/hald/hald.h 3 Apr 2004 07:46:33 -0000 1.4
+++ b/hald/hald.h 9 Jun 2004 01:11:26 -0000
@@ -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 ();
Index: hald/linux/common.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux/common.c,v
retrieving revision 1.7
diff -u -r1.7 common.c
--- a/hald/linux/common.c 26 Apr 2004 20:42:13 -0000 1.7
+++ b/hald/linux/common.c 9 Jun 2004 01:11:27 -0000
@@ -44,6 +44,7 @@
#include "../logger.h"
#include "../device_store.h"
+#include "../pstore.h"
#include "../device_info.h"
#include "../hald.h"
#include "common.h"
@@ -511,7 +512,9 @@
if (di_search_and_merge (d)) {
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
+++ b/hald/pstore.c 2004-06-09 03:01:12.991488760 +0200
@@ -0,0 +1,305 @@
+/***************************************************************************
+ * 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 <sys/stat.h>
+#include <glib.h>
+
+#include "logger.h"
+#include "pstore.h"
+
+#define PSTR "String:"
+#define PINT32 "Int32:"
+#define PBOOL "Bool:"
+#define PDOUBLE "Double:"
+
+struct _HalPStore {
+ char *path;
+ char *uuid;
+};
+
+static int create_abs_path(const char *path)
+{
+ char *p;
+ char *pos;
+ struct stat stats;
+
+ p = g_strconcat (path, "/", NULL);
+ pos = p;
+ while (1) {
+ pos = strchr(&pos[1], '/');
+ if (pos == NULL)
+ break;
+
+ pos[0] = '\0';
+
+ if (stat (p, &stats) != 0) {
+ if (mkdir(p, 0755) != 0) {
+ HAL_DEBUG (("mkdir failed for %s", p));
+ return -1;
+ }
+ }
+ pos[0] = '/';
+ }
+ return 0;
+}
+
+/** Initializes the persistent store by reading/generating
+ * our uuid to store properties in a directoy named after it.
+ *
+ */
+HalPStore
+*hal_pstore_open (const char *path)
+{
+ HalPStore *pstore;
+ char hostname[HOST_NAME_MAX];
+ char *p;
+
+ pstore = g_new0 (HalPStore, 1);
+
+ pstore->path = g_strdup (path);
+
+ /* FIXME: read already computed uuid from store, or
+ * if it's the first open, compute one and save it
+ */
+
+ gethostname (hostname, HOST_NAME_MAX);
+ pstore->uuid = g_strjoin ("-", hostname, "95a478b32fa0", NULL);
+ HAL_DEBUG (("uuid is %s", pstore->uuid));
+
+ p = g_build_path (G_DIR_SEPARATOR_S,
+ path, pstore->uuid, NULL);
+ create_abs_path(p);
+ HAL_DEBUG (("opened pstore at %s", p));
+ g_free(p);
+
+ 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->uuid);
+ 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 *str;
+ int written;
+
+ path = g_build_path (G_DIR_SEPARATOR_S,
+ pstore->path, pstore->uuid,
+ hal_device_get_udi (device), NULL);
+ create_abs_path(path);
+ g_free(path);
+
+ file = g_build_filename (G_DIR_SEPARATOR_S,
+ pstore->path, pstore->uuid,
+ hal_device_get_udi (device),
+ hal_property_get_key (prop), NULL);
+
+ io = g_io_channel_new_file (file, "w", &error);
+ if (error) {
+ HAL_INFO (("Couldn't open %s for writing", file));
+ g_free (file);
+ return;
+ }
+
+ HAL_INFO (("write %s to disk", hal_property_get_key (prop)));
+
+ switch (hal_property_get_type (prop)) {
+ case DBUS_TYPE_STRING:
+ g_io_channel_write_chars (io, PSTR, -1, &written, &error);
+ break;
+ case DBUS_TYPE_INT32:
+ g_io_channel_write_chars (io, PINT32, -1, &written, &error);
+ break;
+ case DBUS_TYPE_BOOLEAN:
+ g_io_channel_write_chars (io, PBOOL, -1, &written, &error);
+ break;
+ case DBUS_TYPE_DOUBLE:
+ g_io_channel_write_chars (io, PDOUBLE, -1, &written, &error);
+ break;
+ default:
+ HAL_INFO (("unknown property type %s",
+ hal_property_get_key (prop)));
+ }
+
+ str = hal_property_to_string (prop);
+ g_io_channel_write_chars (io, str, -1, &written, &error);
+
+ g_free (file);
+ g_free (str);
+ g_io_channel_shutdown (io, TRUE, &error);
+}
+
+/** Load a stored property value from the disk.
+ *
+ */
+void
+hal_pstore_load_property (HalPStore *pstore,
+ HalDevice *device, const char *key)
+{
+ char *file;
+ GIOChannel *io;
+ GError *error = NULL;
+ char *buf;
+ int buf_len;
+ char *str;
+ int i;
+ double d;
+
+ file = g_build_filename (G_DIR_SEPARATOR_S,
+ pstore->path, pstore->uuid,
+ hal_device_get_udi (device),
+ key, NULL);
+
+ HAL_DEBUG (("reading %s", file));
+ io = g_io_channel_new_file (file, "r", &error);
+ g_free (file);
+ if (error) {
+ HAL_INFO (("Couldn't open %s", file));
+ return;
+ }
+
+ g_io_channel_read_to_end (io, &buf, &buf_len, &error);
+ g_io_channel_shutdown (io, TRUE, &error);
+ if (error)
+ goto exit;
+
+ 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 = 1;
+ else
+ i = 0;
+ 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_INFO (("error reading pstore property %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 = g_build_filename (G_DIR_SEPARATOR_S,
+ pstore->path, pstore->uuid,
+ hal_device_get_udi (device),
+ hal_property_get_key (prop),
+ NULL);
+
+ 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 = g_build_path (G_DIR_SEPARATOR_S,
+ pstore->path, pstore->uuid,
+ 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);
+}
--- /dev/null 2004-02-23 22:02:56.000000000 +0100
+++ b/hald/pstore.h 2004-06-08 23:58:35.826231072 +0200
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * 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;
+
+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 */
-------------- next part --------------
_______________________________________________
hal mailing list
hal at freedesktop.org
http://freedesktop.org/mailman/listinfo/hal
More information about the Hal
mailing list