xref: /onnv-gate/usr/src/cmd/hal/hald/solaris/hotplug.c (revision 8100:1c162fabbdb8)
12912Sartem /***************************************************************************
22912Sartem  *
32912Sartem  * hotplug.c : HAL-internal hotplug events
42912Sartem  *
5*8100SLin.Guo@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
62912Sartem  * Use is subject to license terms.
72912Sartem  *
82912Sartem  * Licensed under the Academic Free License version 2.1
92912Sartem  *
102912Sartem  **************************************************************************/
112912Sartem 
122912Sartem 
132912Sartem #ifdef HAVE_CONFIG_H
142912Sartem #  include <config.h>
152912Sartem #endif
162912Sartem 
172912Sartem #include <stdio.h>
182912Sartem #include <string.h>
192912Sartem #include <errno.h>
202912Sartem #include <sys/types.h>
212912Sartem #include <sys/stat.h>
222912Sartem #include <sys/un.h>
232912Sartem #include <sys/utsname.h>
242912Sartem #include <unistd.h>
252912Sartem 
262912Sartem #include <glib.h>
272912Sartem #include <dbus/dbus.h>
282912Sartem #include <dbus/dbus-glib.h>
292912Sartem 
302912Sartem #include "../osspec.h"
312912Sartem #include "../logger.h"
322912Sartem #include "../hald.h"
332912Sartem #include "../device_info.h"
342912Sartem 
352912Sartem #include "osspec_solaris.h"
362912Sartem #include "hotplug.h"
372912Sartem #include "devinfo.h"
382912Sartem 
392912Sartem /** Queue of ordered hotplug events */
402912Sartem GQueue *hotplug_event_queue;
412912Sartem 
422912Sartem /** List of HotplugEvent objects we are currently processing */
432912Sartem GSList *hotplug_events_in_progress = NULL;
442912Sartem 
452912Sartem static void hotplug_event_begin (HotplugEvent *hotplug_event);
462912Sartem 
472912Sartem void
hotplug_event_end(void * end_token)482912Sartem hotplug_event_end (void *end_token)
492912Sartem {
502912Sartem 	HotplugEvent *hotplug_event = (HotplugEvent *) end_token;
512912Sartem 
522912Sartem 	hotplug_events_in_progress = g_slist_remove (hotplug_events_in_progress, hotplug_event);
532912Sartem 	g_free (hotplug_event);
542912Sartem 	hotplug_event_process_queue ();
552912Sartem }
562912Sartem 
572912Sartem static void
hotplug_event_begin_devfs_add(HotplugEvent * hotplug_event,HalDevice * d)582912Sartem hotplug_event_begin_devfs_add (HotplugEvent *hotplug_event, HalDevice *d)
592912Sartem {
602912Sartem 	HalDevice *parent;
612912Sartem 	const gchar *parent_udi;
622912Sartem 	void (*begin_add_func) (HalDevice *, HalDevice *, DevinfoDevHandler *, void *);
632912Sartem 
642912Sartem 	if (d != NULL) {
652912Sartem 		/* XXX */
662912Sartem 		HAL_ERROR (("devpath %s already present in store, ignore event", hotplug_event->un.devfs.devfs_path));
67*8100SLin.Guo@Sun.COM 
68*8100SLin.Guo@Sun.COM 		goto out;
692912Sartem 	}
702912Sartem 
712912Sartem 	/* find parent */
722912Sartem 	parent_udi = hal_device_property_get_string (hotplug_event->d, "info.parent");
732912Sartem 	if (parent_udi == NULL || strlen(parent_udi) == 0) {
742912Sartem 		parent = NULL;
752912Sartem 	} else {
762912Sartem 		parent = hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", parent_udi);
772912Sartem 	}
782912Sartem 	/* only root node is allowed to be orphan */
792912Sartem 	if (parent == NULL) {
802912Sartem 		if (strcmp(hotplug_event->un.devfs.devfs_path, "/") != 0) {
812912Sartem 			HAL_ERROR (("Parent is NULL devfs_path=%s parent_udi=%s", hotplug_event->un.devfs.devfs_path, parent_udi ? parent_udi : "<null>"));
82*8100SLin.Guo@Sun.COM 
83*8100SLin.Guo@Sun.COM 			goto out;
842912Sartem 		}
852912Sartem 	}
862912Sartem 
872912Sartem 	/* children of ignored parent should be ignored */
883121Sartem 	if (parent != NULL && hal_device_property_get_bool (parent, "info.ignore")) {
892912Sartem 		HAL_INFO (("parent ignored %s", parent_udi));
90*8100SLin.Guo@Sun.COM 
91*8100SLin.Guo@Sun.COM 		goto out;
922912Sartem 	}
932912Sartem 
942912Sartem 	/* custom or generic add function */
952912Sartem 	begin_add_func = hotplug_event->un.devfs.handler->hotplug_begin_add;
962912Sartem 	if (begin_add_func == NULL) {
972912Sartem 		begin_add_func = hotplug_event_begin_add_devinfo;
982912Sartem 	}
992912Sartem 	begin_add_func (hotplug_event->d,
1002912Sartem 			 parent,
1012912Sartem 			 hotplug_event->un.devfs.handler,
1022912Sartem 			 (void *) hotplug_event);
103*8100SLin.Guo@Sun.COM 	 return;
104*8100SLin.Guo@Sun.COM 
105*8100SLin.Guo@Sun.COM out:
106*8100SLin.Guo@Sun.COM 	g_object_unref (hotplug_event->d);
107*8100SLin.Guo@Sun.COM 	hotplug_event_end ((void *) hotplug_event);
108*8100SLin.Guo@Sun.COM 
109*8100SLin.Guo@Sun.COM 	return;
1102912Sartem }
1112912Sartem 
1122912Sartem static void
hotplug_event_begin_devfs_remove(HotplugEvent * hotplug_event,HalDevice * d)1132912Sartem hotplug_event_begin_devfs_remove (HotplugEvent *hotplug_event, HalDevice *d)
1142912Sartem {
1152912Sartem 	if (d == NULL) {
1162912Sartem 		HAL_ERROR (("devpath %s not present in store, ignore event", hotplug_event->un.devfs.devfs_path));
1172912Sartem 		hotplug_event_end ((void *) hotplug_event);
1182912Sartem 		return;
1192912Sartem 	}
1203121Sartem 	HAL_INFO (("hotplug_event_begin_devfs_remove %s", hal_device_get_udi (d)));
1212912Sartem 
1222912Sartem 	hotplug_event_begin_remove_devinfo(d,
1232912Sartem 			 hotplug_event->un.devfs.devfs_path,
1242912Sartem 			 (void *) hotplug_event);
1252912Sartem }
1262912Sartem 
1272912Sartem static void
hotplug_event_begin_devfs(HotplugEvent * hotplug_event)1282912Sartem hotplug_event_begin_devfs (HotplugEvent *hotplug_event)
1292912Sartem {
1302912Sartem 	HalDevice *d;
1312912Sartem 
1322912Sartem 	HAL_INFO (("hotplug_event_begin_devfs: %s", hotplug_event->un.devfs.devfs_path));
1332912Sartem 	d = hal_device_store_match_key_value_string (hald_get_gdl (),
1342912Sartem 						"solaris.devfs_path",
1352912Sartem 						hotplug_event->un.devfs.devfs_path);
1362912Sartem 
1372912Sartem 	if (hotplug_event->action == HOTPLUG_ACTION_ADD) {
1382912Sartem 		hotplug_event_begin_devfs_add (hotplug_event, d);
1392912Sartem 	} else if (hotplug_event->action == HOTPLUG_ACTION_REMOVE) {
1402912Sartem 		hotplug_event_begin_devfs_remove (hotplug_event, d);
1412912Sartem 	} else {
142*8100SLin.Guo@Sun.COM 		HAL_ERROR (("unsupported action %d", hotplug_event->action));
143*8100SLin.Guo@Sun.COM 		g_object_unref (hotplug_event->d);
1442912Sartem 		hotplug_event_end ((void *) hotplug_event);
1452912Sartem 	}
1462912Sartem }
1472912Sartem 
1482912Sartem static void
hotplug_event_begin(HotplugEvent * hotplug_event)1492912Sartem hotplug_event_begin (HotplugEvent *hotplug_event)
1502912Sartem {
1512912Sartem 	switch (hotplug_event->type) {
1522912Sartem 
1532912Sartem 	case HOTPLUG_EVENT_DEVFS:
1542912Sartem 		hotplug_event_begin_devfs (hotplug_event);
1552912Sartem 		break;
1562912Sartem 
1572912Sartem 	default:
1582912Sartem 		HAL_ERROR (("Unknown hotplug event type %d", hotplug_event->type));
159*8100SLin.Guo@Sun.COM 		g_object_unref (hotplug_event->d);
1602912Sartem 		hotplug_event_end ((void *) hotplug_event);
1612912Sartem 		break;
1622912Sartem 	}
1632912Sartem }
1642912Sartem 
1652912Sartem void
hotplug_event_enqueue(HotplugEvent * hotplug_event,int front)1662912Sartem hotplug_event_enqueue (HotplugEvent *hotplug_event, int front)
1672912Sartem {
1682912Sartem 	if (hotplug_event_queue == NULL)
1692912Sartem 		hotplug_event_queue = g_queue_new ();
1702912Sartem 
1712912Sartem 	if (front) {
1722912Sartem 		g_queue_push_head (hotplug_event_queue, hotplug_event);
1732912Sartem 	} else {
1742912Sartem 		g_queue_push_tail (hotplug_event_queue, hotplug_event);
1752912Sartem 	}
1762912Sartem }
1772912Sartem 
1782912Sartem void
hotplug_event_process_queue(void)1792912Sartem hotplug_event_process_queue (void)
1802912Sartem {
1812912Sartem 	HotplugEvent *hotplug_event;
1822912Sartem 
1832912Sartem 	if (hotplug_events_in_progress == NULL &&
1842912Sartem 	    (hotplug_event_queue == NULL || g_queue_is_empty (hotplug_event_queue))) {
1852912Sartem 		hotplug_queue_now_empty ();
1862912Sartem 		goto out;
1872912Sartem 	}
1882912Sartem 
1892912Sartem 	/* do not process events if some other event is in progress */
1902912Sartem 	if (hotplug_events_in_progress != NULL && g_slist_length (hotplug_events_in_progress) > 0)
1912912Sartem 		goto out;
1922912Sartem 
1932912Sartem 	hotplug_event = g_queue_pop_head (hotplug_event_queue);
1942912Sartem 	if (hotplug_event == NULL)
1952912Sartem 		goto out;
1962912Sartem 
1972912Sartem 	hotplug_events_in_progress = g_slist_append (hotplug_events_in_progress, hotplug_event);
1982912Sartem 	hotplug_event_begin (hotplug_event);
1992912Sartem 
2002912Sartem out:
2012912Sartem 	;
2022912Sartem }
203