hal/hald/linux2 blockdev.c, 1.4, 1.5 blockdev.h, 1.2, 1.3 osspec.c,
1.15, 1.16
David Zeuthen
david at freedesktop.org
Tue Feb 22 19:03:14 PST 2005
Update of /cvs/hal/hal/hald/linux2
In directory gabe:/tmp/cvs-serv15911/hald/linux2
Modified Files:
blockdev.c blockdev.h osspec.c
Log Message:
2005-02-22 David Zeuthen <davidz at redhat.com>
* hald/linux2/osspec.c: Use kernel events layer instead of D_NOTIFY
on /etc/mtab. Yay!
* hald/linux2/blockdev.c (update_mount_point): Use /proc/mounts as
we're now using the kernel events layer to get mount/umount signals
rather than waiting for /etc/mtab to be changed. Otherwise we've
would have a race with mount(1). Add some usable debug information.
(blockdev_mount_status_changed): Renamed from blockdev_mtab_changed.
* hald/hald_dbus.c (device_send_signal_property_modified): Yikes,
append to the right iterator; fixes segfault
Index: blockdev.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/blockdev.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- blockdev.c 11 Feb 2005 22:01:08 -0000 1.4
+++ blockdev.c 23 Feb 2005 03:03:12 -0000 1.5
@@ -161,21 +161,26 @@
struct mntent *mnte;
const char *device_file;
char buf[512];
-
+
if ((device_file = hal_device_property_get_string (d, "block.device")) == NULL)
goto out;
-
- if ((f = setmntent ("/etc/mtab", "r")) == NULL) {
- HAL_ERROR (("Could not open /etc/mtab"));
+
+ HAL_INFO (("Update mount point for %s (device_file %s)", d->udi, device_file));
+
+ snprintf (buf, sizeof (buf), "%s/mounts", get_hal_proc_path ());
+ if ((f = setmntent (buf, "r")) == NULL) {
+ HAL_ERROR (("Could not open /proc/mounts"));
goto out;
}
-
+
+ /* TODO: should use major:minor numbers to catch /dev/root */
while ((mnte = getmntent_r (f, &mnt, buf, sizeof(buf))) != NULL) {
if (strcmp (mnt.mnt_fsname, device_file) == 0) {
device_property_atomic_update_begin ();
hal_device_property_set_bool (d, "volume.is_mounted", TRUE);
hal_device_property_set_string (d, "volume.mount_point", mnt.mnt_dir);
device_property_atomic_update_end ();
+ HAL_INFO (("Setting mount point %s for %s", mnt.mnt_dir, device_file));
goto found;
}
}
@@ -185,6 +190,8 @@
hal_device_property_set_string (d, "volume.mount_point", "");
device_property_atomic_update_end ();
+ HAL_INFO (("Clearing mount point for %s", device_file));
+
found:
endmntent (f);
out:
@@ -192,20 +199,31 @@
}
void
-blockdev_mtab_changed (void)
+blockdev_mount_status_changed (const gchar *sysfs_path, gboolean is_mounted)
{
- GSList *i;
- GSList *volumes;
+ HalDevice *d;
+ HAL_INFO (("mount_status_changed for '%s', is_mounted=%d", sysfs_path, is_mounted));
- volumes = hal_device_store_match_multiple_key_value_string (hald_get_gdl (),
- "volume.fsusage",
- "filesystem");
- for (i = volumes; i != NULL; i = g_slist_next (i)) {
- HalDevice *d;
+ if ((d = hal_device_store_match_key_value_string (hald_get_gdl (), "linux.sysfs_path", sysfs_path)) == NULL)
+ goto error;
- d = HAL_DEVICE (i->data);
- update_mount_point (d);
+ if (!hal_device_has_capability (d, "volume")) {
+ /* may have a fakevolume */
+ d = hal_device_store_match_key_value_string (hald_get_gdl (),
+ "info.parent",
+ d->udi);
+ if (d == NULL || !hal_device_has_capability (d, "volume"))
+ goto error;
}
+
+ HAL_INFO (("Applies to %s", d->udi));
+
+ update_mount_point (d);
+ return;
+
+error:
+ HAL_INFO (("Couldn't find hal volume for %s", d->udi));
+ ;
}
static void
Index: blockdev.h
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/blockdev.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- blockdev.h 10 Feb 2005 17:03:57 -0000 1.2
+++ blockdev.h 23 Feb 2005 03:03:12 -0000 1.3
@@ -38,6 +38,6 @@
HotplugEvent *blockdev_generate_remove_hotplug_event (HalDevice *d);
-void blockdev_mtab_changed (void);
+void blockdev_mount_status_changed (const gchar *sysfs_path, gboolean is_mounted);
#endif /* BLOCKDEV_H */
Index: osspec.c
===================================================================
RCS file: /cvs/hal/hal/hald/linux2/osspec.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- osspec.c 22 Feb 2005 18:46:56 -0000 1.15
+++ osspec.c 23 Feb 2005 03:03:12 -0000 1.16
@@ -194,46 +194,6 @@
return TRUE;
}
-static int sigio_unix_signal_pipe_fds[2];
-static GIOChannel *sigio_iochn;
-
-static void
-sigio_handler (int sig)
-{
- static char marker[1] = {'S'};
-
- /* write a 'S' character to the other end to tell about
- * the signal. Note that 'the other end' is a GIOChannel thingy
- * that is only called from the mainloop - thus this is how we
- * defer this since UNIX signal handlers are evil
- *
- * Oh, and write(2) is indeed reentrant */
- write (sigio_unix_signal_pipe_fds[1], marker, 1);
-}
-
-static gboolean
-sigio_iochn_data (GIOChannel *source, GIOCondition condition, gpointer user_data)
-{
- GError *err = NULL;
- gchar data[1];
- gsize bytes_read;
-
- /* Empty the pipe */
- if (G_IO_STATUS_NORMAL != g_io_channel_read_chars (source, data, 1, &bytes_read, &err)) {
- HAL_ERROR (("Error emptying callout notify pipe: %s", err->message));
- g_error_free (err);
- goto out;
- }
-
- /* TODO: check mtime on /etc/mtab file */
- HAL_INFO (("/etc/mtab changed"));
- blockdev_mtab_changed ();
-
-out:
- return TRUE;
-}
-
-
#define VALID_NLMSG(h, s) ((NLMSG_OK (h, s) && \
s >= sizeof (struct nlmsghdr) && \
s >= h->nlmsg_len))
@@ -249,8 +209,6 @@
socklen_t nladdrlen = sizeof(nladdr);
char buf[1024];
- HAL_INFO (("data!", buf));
-
if (cond & ~(G_IO_IN | G_IO_PRI)) {
HAL_ERROR (("Error occurred on netlink socket"));
return TRUE;
@@ -286,19 +244,33 @@
HAL_INFO (("total_read=%d buf='%s'", total_read, buf));
}
+ /* Handle event: "mount@/block/hde" */
+ if (g_str_has_prefix (buf, "mount")) {
+ gchar sysfs_path[HAL_PATH_MAX];
+ g_strlcpy (sysfs_path, get_hal_sysfs_path (), sizeof (sysfs_path));
+ g_strlcat (sysfs_path, ((char *) buf) + sizeof ("mount"), sizeof (sysfs_path));
+ blockdev_mount_status_changed (sysfs_path, TRUE);
+ }
+
+ /* Handle event: "umount@/block/hde" */
+ if (g_str_has_prefix (buf, "umount")) {
+ gchar sysfs_path[HAL_PATH_MAX];
+ g_strlcpy (sysfs_path, get_hal_sysfs_path (), sizeof (sysfs_path));
+ g_strlcat (sysfs_path, ((char *) buf) + sizeof ("umount"), sizeof (sysfs_path));
+ blockdev_mount_status_changed (sysfs_path, FALSE);
+ }
+
return TRUE;
}
void
osspec_init (void)
{
- int etcfd;
int socketfd;
struct sockaddr_un saddr;
socklen_t addrlen;
GIOChannel *channel;
const int on = 1;
- guint sigio_iochn_listener_source_id;
static int netlink_fd = -1;
struct sockaddr_nl netlink_addr;
GIOChannel *netlink_channel;
@@ -326,7 +298,6 @@
g_io_add_watch (channel, G_IO_IN, hald_helper_data, NULL);
g_io_channel_unref (channel);
-
/* Get mount points for /proc and /sys */
if (!hal_util_get_fs_mnt_path ("sysfs", hal_sysfs_path, sizeof (hal_sysfs_path))) {
HAL_ERROR (("Could not get sysfs mount point"));
@@ -339,22 +310,9 @@
}
HAL_INFO (("proc mount point is '%s'", hal_proc_path));
- /* start watching /etc so we know when mtab is updated */
- etcfd = open ("/etc", O_RDONLY);
- if (etcfd < 0)
- DIE (("Could not open /etc"));
- fcntl (etcfd, F_NOTIFY, DN_MODIFY | DN_MULTISHOT);
-
- if (pipe (sigio_unix_signal_pipe_fds) != 0) {
- DIE (("Could not setup pipe: %s", strerror (errno)));
- }
- if ((sigio_iochn = g_io_channel_unix_new (sigio_unix_signal_pipe_fds[0])) == NULL)
- DIE (("Could not create GIOChannel"));
- sigio_iochn_listener_source_id = g_io_add_watch (sigio_iochn, G_IO_IN, sigio_iochn_data, NULL);
- signal (SIGIO, sigio_handler);
-
/* hook up to netlink socket to receive events from the Kernel Events
- * Layer (available since 2.6.10) - TODO: Don't use the constant 15
+ * Layer (available since 2.6.10) - TODO: Don't use the constant 15 but
+ * rather the NETLINK_KOBJECT_UEVENT symbol
*/
netlink_fd = socket (PF_NETLINK, SOCK_DGRAM, 15/*NETLINK_KOBJECT_UEVENT*/);
More information about the hal-commit
mailing list