18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * hotplug.c : HAL-internal hotplug events
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Use is subject to license terms.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Licensed under the Academic Free License version 2.1
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem **************************************************************************/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_CONFIG_H
18c2aff776a775d34a4c9893a4c72e0434d68e36artem# include <config.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <stdio.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <string.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <errno.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/types.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/stat.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/un.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/utsname.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <unistd.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <glib.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <dbus/dbus.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <dbus/dbus-glib.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../osspec.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../logger.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../hald.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../device_info.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "osspec_solaris.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "hotplug.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "devinfo.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Queue of ordered hotplug events */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemGQueue *hotplug_event_queue;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** List of HotplugEvent objects we are currently processing */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemGSList *hotplug_events_in_progress = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void hotplug_event_begin (HotplugEvent *hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_end (void *end_token)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HotplugEvent *hotplug_event = (HotplugEvent *) end_token;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_events_in_progress = g_slist_remove (hotplug_events_in_progress, hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_free (hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_process_queue ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_begin_devfs_add (HotplugEvent *hotplug_event, HalDevice *d)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HalDevice *parent;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const gchar *parent_udi;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem void (*begin_add_func) (HalDevice *, HalDevice *, DevinfoDevHandler *, void *);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (d != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* XXX */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_ERROR (("devpath %s already present in store, ignore event", hotplug_event->un.devfs.devfs_path));
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* find parent */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem parent_udi = hal_device_property_get_string (hotplug_event->d, "info.parent");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (parent_udi == NULL || strlen(parent_udi) == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem parent = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem parent = hal_device_store_match_key_value_string (hald_get_gdl (), "info.udi", parent_udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* only root node is allowed to be orphan */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (parent == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (strcmp(hotplug_event->un.devfs.devfs_path, "/") != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_ERROR (("Parent is NULL devfs_path=%s parent_udi=%s", hotplug_event->un.devfs.devfs_path, parent_udi ? parent_udi : "<null>"));
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* children of ignored parent should be ignored */
00687e57f8c568d4f8fb446b6530a2942842292fartem if (parent != NULL && hal_device_property_get_bool (parent, "info.ignore")) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("parent ignored %s", parent_udi));
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* custom or generic add function */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem begin_add_func = hotplug_event->un.devfs.handler->hotplug_begin_add;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (begin_add_func == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem begin_add_func = hotplug_event_begin_add_devinfo;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem begin_add_func (hotplug_event->d,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem parent,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event->un.devfs.handler,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void *) hotplug_event);
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems return;
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystemsout:
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems g_object_unref (hotplug_event->d);
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems hotplug_event_end ((void *) hotplug_event);
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_begin_devfs_remove (HotplugEvent *hotplug_event, HalDevice *d)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (d == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_ERROR (("devpath %s not present in store, ignore event", hotplug_event->un.devfs.devfs_path));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_end ((void *) hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
00687e57f8c568d4f8fb446b6530a2942842292fartem HAL_INFO (("hotplug_event_begin_devfs_remove %s", hal_device_get_udi (d)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_begin_remove_devinfo(d,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event->un.devfs.devfs_path,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void *) hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_begin_devfs (HotplugEvent *hotplug_event)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HalDevice *d;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("hotplug_event_begin_devfs: %s", hotplug_event->un.devfs.devfs_path));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem d = hal_device_store_match_key_value_string (hald_get_gdl (),
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "solaris.devfs_path",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event->un.devfs.devfs_path);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hotplug_event->action == HOTPLUG_ACTION_ADD) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_begin_devfs_add (hotplug_event, d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if (hotplug_event->action == HOTPLUG_ACTION_REMOVE) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_begin_devfs_remove (hotplug_event, d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems HAL_ERROR (("unsupported action %d", hotplug_event->action));
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems g_object_unref (hotplug_event->d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_end ((void *) hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_begin (HotplugEvent *hotplug_event)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem switch (hotplug_event->type) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case HOTPLUG_EVENT_DEVFS:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_begin_devfs (hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem default:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_ERROR (("Unknown hotplug event type %d", hotplug_event->type));
8b80e8cb6855118d46f605e91b5ed4ce83417395Lin Guo - Sun Microsystems g_object_unref (hotplug_event->d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_end ((void *) hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_enqueue (HotplugEvent *hotplug_event, int front)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hotplug_event_queue == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_queue = g_queue_new ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (front) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_queue_push_head (hotplug_event_queue, hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_queue_push_tail (hotplug_event_queue, hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_event_process_queue (void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HotplugEvent *hotplug_event;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hotplug_events_in_progress == NULL &&
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (hotplug_event_queue == NULL || g_queue_is_empty (hotplug_event_queue))) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_queue_now_empty ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* do not process events if some other event is in progress */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hotplug_events_in_progress != NULL && g_slist_length (hotplug_events_in_progress) > 0)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event = g_queue_pop_head (hotplug_event_queue);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hotplug_event == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_events_in_progress = g_slist_append (hotplug_events_in_progress, hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_begin (hotplug_event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemout:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}