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