12912Sartem /*************************************************************************** 22912Sartem * 32912Sartem * osspec.c : Solaris HAL backend entry points 42912Sartem * 52912Sartem * Copyright 2006 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 12*2916Sartem #pragma ident "%Z%%M% %I% %E% SMI" 132912Sartem 142912Sartem #ifdef HAVE_CONFIG_H 152912Sartem # include <config.h> 162912Sartem #endif 172912Sartem 182912Sartem #include <stdio.h> 192912Sartem #include <unistd.h> 202912Sartem #include <strings.h> 212912Sartem #include <port.h> 222912Sartem #include <sys/stat.h> 232912Sartem #include <fcntl.h> 242912Sartem #include <sys/types.h> 252912Sartem #include <sys/mntent.h> 262912Sartem #include <sys/mnttab.h> 272912Sartem 282912Sartem #include "../osspec.h" 292912Sartem #include "../logger.h" 302912Sartem #include "../hald.h" 312912Sartem #include "../hald_dbus.h" 322912Sartem #include "../device_info.h" 332912Sartem #include "../util.h" 342912Sartem #include "../ids.h" 352912Sartem #include "osspec_solaris.h" 362912Sartem #include "hotplug.h" 372912Sartem #include "sysevent.h" 382912Sartem #include "devinfo.h" 392912Sartem #include "devinfo_storage.h" 402912Sartem 412912Sartem static void mnttab_event_init (); 422912Sartem static gboolean mnttab_event (GIOChannel *channel, GIOCondition cond, gpointer user_data); 432912Sartem 442912Sartem void 452912Sartem osspec_init (void) 462912Sartem { 472912Sartem ids_init (); 482912Sartem sysevent_init (); 492912Sartem mnttab_event_init (); 502912Sartem } 512912Sartem 522912Sartem void 532912Sartem hotplug_queue_now_empty (void) 542912Sartem { 552912Sartem if (hald_is_initialising) { 562912Sartem osspec_probe_done (); 572912Sartem } 582912Sartem } 592912Sartem 602912Sartem void 612912Sartem osspec_probe (void) 622912Sartem { 632912Sartem /* add entire device tree */ 642912Sartem devinfo_add (NULL, "/"); 652912Sartem 662912Sartem /* start processing events */ 672912Sartem hotplug_event_process_queue (); 682912Sartem } 692912Sartem 702912Sartem gboolean 712912Sartem osspec_device_rescan (HalDevice *d) 722912Sartem { 732912Sartem return (devinfo_device_rescan (d)); 742912Sartem } 752912Sartem 762912Sartem gboolean 772912Sartem osspec_device_reprobe (HalDevice *d) 782912Sartem { 792912Sartem return FALSE; 802912Sartem } 812912Sartem 822912Sartem DBusHandlerResult 832912Sartem osspec_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) 842912Sartem { 852912Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 862912Sartem } 872912Sartem 882912Sartem /** Find the closest ancestor by looking at devfs paths 892912Sartem * 902912Sartem * @param devfs_path Path into devfs, e.g. /pci@0,0/pci1025,57@10,2/storage@1 912912Sartem * @return Parent Hal Device Object or #NULL if there is none 922912Sartem */ 932912Sartem HalDevice * 942912Sartem hal_util_find_closest_ancestor (const gchar *devfs_path, gchar **ancestor_devfs_path, gchar **hotplug_devfs_path) 952912Sartem { 962912Sartem gchar buf[512]; 972912Sartem gchar c; 982912Sartem HalDevice *parent; 992912Sartem 1002912Sartem parent = NULL; 1012912Sartem 1022912Sartem strncpy (buf, devfs_path, sizeof (buf)); 1032912Sartem do { 1042912Sartem char *p; 1052912Sartem 1062912Sartem p = strrchr (buf, '/'); 1072912Sartem if (p == NULL) 1082912Sartem break; 1092912Sartem c = *p; 1102912Sartem *p = '\0'; 1112912Sartem 1122912Sartem parent = hal_device_store_match_key_value_string (hald_get_gdl (), 1132912Sartem "solaris.devfs_path", 1142912Sartem buf); 1152912Sartem if (parent != NULL) { 1162912Sartem if (ancestor_devfs_path != NULL) { 1172912Sartem *ancestor_devfs_path = g_strdup (buf); 1182912Sartem } 1192912Sartem if (hotplug_devfs_path != NULL) { 1202912Sartem *p = c; 1212912Sartem *hotplug_devfs_path = g_strdup (buf); 1222912Sartem } 1232912Sartem break; 1242912Sartem } 1252912Sartem 1262912Sartem } while (TRUE); 1272912Sartem 1282912Sartem return parent; 1292912Sartem } 1302912Sartem 1312912Sartem char * 1322912Sartem dsk_to_rdsk(char *dsk) 1332912Sartem { 1342912Sartem int len, pos; 1352912Sartem char *p; 1362912Sartem char *rdsk; 1372912Sartem 1382912Sartem if ((len = strlen (dsk)) < sizeof ("/dev/dsk/cN") - 1) { 1392912Sartem return (strdup("")); 1402912Sartem } 1412912Sartem if ((p = strstr (dsk, "/dsk/")) == NULL) { 1422912Sartem if ((p = strstr (dsk, "/lofi/")) == NULL) { 1432912Sartem p = strstr (dsk, "/diskette"); 1442912Sartem } 1452912Sartem } 1462912Sartem if (p == NULL) { 1472912Sartem return (strdup("")); 1482912Sartem } 1492912Sartem 1502912Sartem pos = (uintptr_t)p - (uintptr_t)dsk; 1512912Sartem if ((rdsk = (char *)calloc (len + 2, 1)) != NULL) { 1522912Sartem strncpy (rdsk, dsk, pos + 1); 1532912Sartem rdsk[pos + 1] = 'r'; 1542912Sartem strcpy (rdsk + pos + 2, dsk + pos + 1); 1552912Sartem } 1562912Sartem 1572912Sartem return (rdsk); 1582912Sartem } 1592912Sartem 1602912Sartem /* 1612912Sartem * Setup to watch mnttab changes 1622912Sartem * 1632912Sartem * When mnttab changes, POLLRDBAND is set. However, glib does not 1642912Sartem * support POLLRDBAND, so we use Solaris ports (see port_create(3C)) 1652912Sartem * to "map" POLLRDBAND to POLLIN: 1662912Sartem * 1672912Sartem * - create a port 1682912Sartem * - associate the port with mnttab file descriptor and POLLRDBAND 1692912Sartem * - now polling for POLLIN on the port descriptor will unblock when 1702912Sartem * the associated file descriptor receives POLLRDBAND 1712912Sartem */ 1722912Sartem static int mnttab_fd; 1732912Sartem static int mnttab_port; 1742912Sartem static GIOChannel *mnttab_channel; 1752912Sartem 1762912Sartem static void 1772912Sartem mnttab_event_init () 1782912Sartem { 1792912Sartem char buf[81]; 1802912Sartem 1812912Sartem if ((mnttab_fd = open (MNTTAB, O_RDONLY)) < 0) { 1822912Sartem return; 1832912Sartem } 1842912Sartem if ((mnttab_port = port_create ()) < 0) { 1852912Sartem (void) close (mnttab_fd); 1862912Sartem return; 1872912Sartem } 1882912Sartem if (port_associate (mnttab_port, PORT_SOURCE_FD, mnttab_fd, POLLRDBAND, 1892912Sartem NULL) != 0) { 1902912Sartem (void) close (mnttab_port); 1912912Sartem (void) close (mnttab_fd); 1922912Sartem return; 1932912Sartem } 1942912Sartem 1952912Sartem /* suppress initial event */ 1962912Sartem (void) read(mnttab_fd, buf, (size_t)(sizeof (buf) - 1)); 1972912Sartem (void) lseek(mnttab_fd, 0, SEEK_SET); 1982912Sartem 1992912Sartem mnttab_channel = g_io_channel_unix_new (mnttab_port); 2002912Sartem g_io_add_watch (mnttab_channel, G_IO_IN, mnttab_event, NULL); 2012912Sartem } 2022912Sartem 2032912Sartem static gboolean 2042912Sartem mnttab_event (GIOChannel *channel, GIOCondition cond, gpointer user_data) 2052912Sartem { 2062912Sartem port_event_t pe; 2072912Sartem timespec_t timeout; 2082912Sartem char buf[81]; 2092912Sartem 2102912Sartem /* if (cond & ~G_IO_ERR) 2112912Sartem return TRUE; 2122912Sartem */ 2132912Sartem HAL_INFO (("mnttab event")); 2142912Sartem 2152912Sartem /* we have to re-associate port with fd every time */ 2162912Sartem timeout.tv_sec = timeout.tv_nsec = 0; 2172912Sartem (void) port_get(mnttab_port, &pe, &timeout); 2182912Sartem (void) port_associate(mnttab_port, PORT_SOURCE_FD, 2192912Sartem mnttab_fd, POLLRDBAND, NULL); 2202912Sartem 2212912Sartem if (!hald_is_initialising) { 2222912Sartem devinfo_storage_mnttab_event (NULL); 2232912Sartem } 2242912Sartem 2252912Sartem (void) lseek(mnttab_fd, 0, SEEK_SET); 2262912Sartem (void) read(mnttab_fd, buf, (size_t)(sizeof (buf) - 1)); 2272912Sartem 2282912Sartem return TRUE; 2292912Sartem } 2302912Sartem 2312912Sartem void 2322912Sartem osspec_refresh_mount_state_for_block_device (HalDevice *d) 2332912Sartem { 2342912Sartem devinfo_storage_mnttab_event (d); 2352912Sartem } 236