118c2aff7Sartem /***************************************************************************
218c2aff7Sartem *
318c2aff7Sartem * hotplug.c : HAL-internal hotplug events
418c2aff7Sartem *
5*8b80e8cbSLin Guo - Sun Microsystems * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
618c2aff7Sartem * Use is subject to license terms.
718c2aff7Sartem *
818c2aff7Sartem * Licensed under the Academic Free License version 2.1
918c2aff7Sartem *
1018c2aff7Sartem **************************************************************************/
1118c2aff7Sartem
1218c2aff7Sartem
1318c2aff7Sartem #ifdef HAVE_CONFIG_H
1418c2aff7Sartem # include <config.h>
1518c2aff7Sartem #endif
1618c2aff7Sartem
1718c2aff7Sartem #include <stdio.h>
1818c2aff7Sartem #include <string.h>
1918c2aff7Sartem #include <errno.h>
2018c2aff7Sartem #include <sys/types.h>
2118c2aff7Sartem #include <sys/stat.h>
2218c2aff7Sartem #include <sys/un.h>
2318c2aff7Sartem #include <sys/utsname.h>
2418c2aff7Sartem #include <unistd.h>
2518c2aff7Sartem
2618c2aff7Sartem #include <glib.h>
2718c2aff7Sartem #include <dbus/dbus.h>
2818c2aff7Sartem #include <dbus/dbus-glib.h>
2918c2aff7Sartem
3018c2aff7Sartem #include "../osspec.h"
3118c2aff7Sartem #include "../logger.h"
3218c2aff7Sartem #include "../hald.h"
3318c2aff7Sartem #include "../device_info.h"
3418c2aff7Sartem
3518c2aff7Sartem #include "osspec_solaris.h"
3618c2aff7Sartem #include "hotplug.h"
3718c2aff7Sartem #include "devinfo.h"
3818c2aff7Sartem
3918c2aff7Sartem /** Queue of ordered hotplug events */
4018c2aff7Sartem GQueue *hotplug_event_queue;
4118c2aff7Sartem
4218c2aff7Sartem /** List of HotplugEvent objects we are currently processing */
4318c2aff7Sartem GSList *hotplug_events_in_progress = NULL;
4418c2aff7Sartem
4518c2aff7Sartem static void hotplug_event_begin (HotplugEvent *hotplug_event);
4618c2aff7Sartem
4718c2aff7Sartem void
hotplug_event_end(void * end_token)4818c2aff7Sartem hotplug_event_end (void *end_token)
4918c2aff7Sartem {
5018c2aff7Sartem HotplugEvent *hotplug_event = (HotplugEvent *) end_token;
5118c2aff7Sartem
5218c2aff7Sartem hotplug_events_in_progress = g_slist_remove (hotplug_events_in_progress, hotplug_event);
5318c2aff7Sartem g_free (hotplug_event);
5418c2aff7Sartem hotplug_event_process_queue ();
5518c2aff7Sartem }
5618c2aff7Sartem
5718c2aff7Sartem static void
hotplug_event_begin_devfs_add(HotplugEvent * hotplug_event,HalDevice * d)5818c2aff7Sartem hotplug_event_begin_devfs_add (HotplugEvent *hotplug_event, HalDevice *d)
5918c2aff7Sartem {
6018c2aff7Sartem HalDevice *parent;
6118c2aff7Sartem const gchar *parent_udi;
6218c2aff7Sartem void (*begin_add_func) (HalDevice *, HalDevice *, DevinfoDevHandler *, void *);
6318c2aff7Sartem
6418c2aff7Sartem if (d != NULL) {
6518c2aff7Sartem /* XXX */
6618c2aff7Sartem HAL_ERROR (("devpath %s already present in store, ignore event", hotplug_event->un.devfs.devfs_path));
67*8b80e8cbSLin Guo - Sun Microsystems
68*8b80e8cbSLin Guo - Sun Microsystems goto out;
6918c2aff7Sartem }
7018c2aff7Sartem
7118c2aff7Sartem /* find parent */
7218c2aff7Sartem parent_udi = hal_device_property_get_string (hotplug_event->d, "info.parent");
7318c2aff7Sartem if (parent_udi == NULL || strlen(parent_udi) == 0) {
7418c2aff7Sartem parent = NULL;
7518c2aff7Sartem } else {
7618c2aff7Sartem parent = hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", parent_udi);
7718c2aff7Sartem }
7818c2aff7Sartem /* only root node is allowed to be orphan */
7918c2aff7Sartem if (parent == NULL) {
8018c2aff7Sartem if (strcmp(hotplug_event->un.devfs.devfs_path, "/") != 0) {
8118c2aff7Sartem HAL_ERROR (("Parent is NULL devfs_path=%s parent_udi=%s", hotplug_event->un.devfs.devfs_path, parent_udi ? parent_udi : "<null>"));
82*8b80e8cbSLin Guo - Sun Microsystems
83*8b80e8cbSLin Guo - Sun Microsystems goto out;
8418c2aff7Sartem }
8518c2aff7Sartem }
8618c2aff7Sartem
8718c2aff7Sartem /* children of ignored parent should be ignored */
8800687e57Sartem if (parent != NULL && hal_device_property_get_bool (parent, "info.ignore")) {
8918c2aff7Sartem HAL_INFO (("parent ignored %s", parent_udi));
90*8b80e8cbSLin Guo - Sun Microsystems
91*8b80e8cbSLin Guo - Sun Microsystems goto out;
9218c2aff7Sartem }
9318c2aff7Sartem
9418c2aff7Sartem /* custom or generic add function */
9518c2aff7Sartem begin_add_func = hotplug_event->un.devfs.handler->hotplug_begin_add;
9618c2aff7Sartem if (begin_add_func == NULL) {
9718c2aff7Sartem begin_add_func = hotplug_event_begin_add_devinfo;
9818c2aff7Sartem }
9918c2aff7Sartem begin_add_func (hotplug_event->d,
10018c2aff7Sartem parent,
10118c2aff7Sartem hotplug_event->un.devfs.handler,
10218c2aff7Sartem (void *) hotplug_event);
103*8b80e8cbSLin Guo - Sun Microsystems return;
104*8b80e8cbSLin Guo - Sun Microsystems
105*8b80e8cbSLin Guo - Sun Microsystems out:
106*8b80e8cbSLin Guo - Sun Microsystems g_object_unref (hotplug_event->d);
107*8b80e8cbSLin Guo - Sun Microsystems hotplug_event_end ((void *) hotplug_event);
108*8b80e8cbSLin Guo - Sun Microsystems
109*8b80e8cbSLin Guo - Sun Microsystems return;
11018c2aff7Sartem }
11118c2aff7Sartem
11218c2aff7Sartem static void
hotplug_event_begin_devfs_remove(HotplugEvent * hotplug_event,HalDevice * d)11318c2aff7Sartem hotplug_event_begin_devfs_remove (HotplugEvent *hotplug_event, HalDevice *d)
11418c2aff7Sartem {
11518c2aff7Sartem if (d == NULL) {
11618c2aff7Sartem HAL_ERROR (("devpath %s not present in store, ignore event", hotplug_event->un.devfs.devfs_path));
11718c2aff7Sartem hotplug_event_end ((void *) hotplug_event);
11818c2aff7Sartem return;
11918c2aff7Sartem }
12000687e57Sartem HAL_INFO (("hotplug_event_begin_devfs_remove %s", hal_device_get_udi (d)));
12118c2aff7Sartem
12218c2aff7Sartem hotplug_event_begin_remove_devinfo(d,
12318c2aff7Sartem hotplug_event->un.devfs.devfs_path,
12418c2aff7Sartem (void *) hotplug_event);
12518c2aff7Sartem }
12618c2aff7Sartem
12718c2aff7Sartem static void
hotplug_event_begin_devfs(HotplugEvent * hotplug_event)12818c2aff7Sartem hotplug_event_begin_devfs (HotplugEvent *hotplug_event)
12918c2aff7Sartem {
13018c2aff7Sartem HalDevice *d;
13118c2aff7Sartem
13218c2aff7Sartem HAL_INFO (("hotplug_event_begin_devfs: %s", hotplug_event->un.devfs.devfs_path));
13318c2aff7Sartem d = hal_device_store_match_key_value_string (hald_get_gdl (),
13418c2aff7Sartem "solaris.devfs_path",
13518c2aff7Sartem hotplug_event->un.devfs.devfs_path);
13618c2aff7Sartem
13718c2aff7Sartem if (hotplug_event->action == HOTPLUG_ACTION_ADD) {
13818c2aff7Sartem hotplug_event_begin_devfs_add (hotplug_event, d);
13918c2aff7Sartem } else if (hotplug_event->action == HOTPLUG_ACTION_REMOVE) {
14018c2aff7Sartem hotplug_event_begin_devfs_remove (hotplug_event, d);
14118c2aff7Sartem } else {
142*8b80e8cbSLin Guo - Sun Microsystems HAL_ERROR (("unsupported action %d", hotplug_event->action));
143*8b80e8cbSLin Guo - Sun Microsystems g_object_unref (hotplug_event->d);
14418c2aff7Sartem hotplug_event_end ((void *) hotplug_event);
14518c2aff7Sartem }
14618c2aff7Sartem }
14718c2aff7Sartem
14818c2aff7Sartem static void
hotplug_event_begin(HotplugEvent * hotplug_event)14918c2aff7Sartem hotplug_event_begin (HotplugEvent *hotplug_event)
15018c2aff7Sartem {
15118c2aff7Sartem switch (hotplug_event->type) {
15218c2aff7Sartem
15318c2aff7Sartem case HOTPLUG_EVENT_DEVFS:
15418c2aff7Sartem hotplug_event_begin_devfs (hotplug_event);
15518c2aff7Sartem break;
15618c2aff7Sartem
15718c2aff7Sartem default:
15818c2aff7Sartem HAL_ERROR (("Unknown hotplug event type %d", hotplug_event->type));
159*8b80e8cbSLin Guo - Sun Microsystems g_object_unref (hotplug_event->d);
16018c2aff7Sartem hotplug_event_end ((void *) hotplug_event);
16118c2aff7Sartem break;
16218c2aff7Sartem }
16318c2aff7Sartem }
16418c2aff7Sartem
16518c2aff7Sartem void
hotplug_event_enqueue(HotplugEvent * hotplug_event,int front)16618c2aff7Sartem hotplug_event_enqueue (HotplugEvent *hotplug_event, int front)
16718c2aff7Sartem {
16818c2aff7Sartem if (hotplug_event_queue == NULL)
16918c2aff7Sartem hotplug_event_queue = g_queue_new ();
17018c2aff7Sartem
17118c2aff7Sartem if (front) {
17218c2aff7Sartem g_queue_push_head (hotplug_event_queue, hotplug_event);
17318c2aff7Sartem } else {
17418c2aff7Sartem g_queue_push_tail (hotplug_event_queue, hotplug_event);
17518c2aff7Sartem }
17618c2aff7Sartem }
17718c2aff7Sartem
17818c2aff7Sartem void
hotplug_event_process_queue(void)17918c2aff7Sartem hotplug_event_process_queue (void)
18018c2aff7Sartem {
18118c2aff7Sartem HotplugEvent *hotplug_event;
18218c2aff7Sartem
18318c2aff7Sartem if (hotplug_events_in_progress == NULL &&
18418c2aff7Sartem (hotplug_event_queue == NULL || g_queue_is_empty (hotplug_event_queue))) {
18518c2aff7Sartem hotplug_queue_now_empty ();
18618c2aff7Sartem goto out;
18718c2aff7Sartem }
18818c2aff7Sartem
18918c2aff7Sartem /* do not process events if some other event is in progress */
19018c2aff7Sartem if (hotplug_events_in_progress != NULL && g_slist_length (hotplug_events_in_progress) > 0)
19118c2aff7Sartem goto out;
19218c2aff7Sartem
19318c2aff7Sartem hotplug_event = g_queue_pop_head (hotplug_event_queue);
19418c2aff7Sartem if (hotplug_event == NULL)
19518c2aff7Sartem goto out;
19618c2aff7Sartem
19718c2aff7Sartem hotplug_events_in_progress = g_slist_append (hotplug_events_in_progress, hotplug_event);
19818c2aff7Sartem hotplug_event_begin (hotplug_event);
19918c2aff7Sartem
20018c2aff7Sartem out:
20118c2aff7Sartem ;
20218c2aff7Sartem }
203