1*18c2aff7Sartem /*************************************************************************** 2*18c2aff7Sartem * 3*18c2aff7Sartem * osspec.c : Solaris HAL backend entry points 4*18c2aff7Sartem * 5*18c2aff7Sartem * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 6*18c2aff7Sartem * Use is subject to license terms. 7*18c2aff7Sartem * 8*18c2aff7Sartem * Licensed under the Academic Free License version 2.1 9*18c2aff7Sartem * 10*18c2aff7Sartem **************************************************************************/ 11*18c2aff7Sartem 12*18c2aff7Sartem #pragma ident "%Z%%M% %I% %E% SMI" 13*18c2aff7Sartem 14*18c2aff7Sartem #ifdef HAVE_CONFIG_H 15*18c2aff7Sartem # include <config.h> 16*18c2aff7Sartem #endif 17*18c2aff7Sartem 18*18c2aff7Sartem #include <stdio.h> 19*18c2aff7Sartem #include <unistd.h> 20*18c2aff7Sartem #include <strings.h> 21*18c2aff7Sartem #include <port.h> 22*18c2aff7Sartem #include <sys/stat.h> 23*18c2aff7Sartem #include <fcntl.h> 24*18c2aff7Sartem #include <sys/types.h> 25*18c2aff7Sartem #include <sys/mntent.h> 26*18c2aff7Sartem #include <sys/mnttab.h> 27*18c2aff7Sartem 28*18c2aff7Sartem #include "../osspec.h" 29*18c2aff7Sartem #include "../logger.h" 30*18c2aff7Sartem #include "../hald.h" 31*18c2aff7Sartem #include "../hald_dbus.h" 32*18c2aff7Sartem #include "../device_info.h" 33*18c2aff7Sartem #include "../util.h" 34*18c2aff7Sartem #include "../ids.h" 35*18c2aff7Sartem #include "osspec_solaris.h" 36*18c2aff7Sartem #include "hotplug.h" 37*18c2aff7Sartem #include "sysevent.h" 38*18c2aff7Sartem #include "devinfo.h" 39*18c2aff7Sartem #include "devinfo_storage.h" 40*18c2aff7Sartem 41*18c2aff7Sartem static void mnttab_event_init (); 42*18c2aff7Sartem static gboolean mnttab_event (GIOChannel *channel, GIOCondition cond, gpointer user_data); 43*18c2aff7Sartem 44*18c2aff7Sartem void 45*18c2aff7Sartem osspec_init (void) 46*18c2aff7Sartem { 47*18c2aff7Sartem ids_init (); 48*18c2aff7Sartem sysevent_init (); 49*18c2aff7Sartem mnttab_event_init (); 50*18c2aff7Sartem } 51*18c2aff7Sartem 52*18c2aff7Sartem void 53*18c2aff7Sartem hotplug_queue_now_empty (void) 54*18c2aff7Sartem { 55*18c2aff7Sartem if (hald_is_initialising) { 56*18c2aff7Sartem osspec_probe_done (); 57*18c2aff7Sartem } 58*18c2aff7Sartem } 59*18c2aff7Sartem 60*18c2aff7Sartem void 61*18c2aff7Sartem osspec_probe (void) 62*18c2aff7Sartem { 63*18c2aff7Sartem /* add entire device tree */ 64*18c2aff7Sartem devinfo_add (NULL, "/"); 65*18c2aff7Sartem 66*18c2aff7Sartem /* start processing events */ 67*18c2aff7Sartem hotplug_event_process_queue (); 68*18c2aff7Sartem } 69*18c2aff7Sartem 70*18c2aff7Sartem gboolean 71*18c2aff7Sartem osspec_device_rescan (HalDevice *d) 72*18c2aff7Sartem { 73*18c2aff7Sartem return (devinfo_device_rescan (d)); 74*18c2aff7Sartem } 75*18c2aff7Sartem 76*18c2aff7Sartem gboolean 77*18c2aff7Sartem osspec_device_reprobe (HalDevice *d) 78*18c2aff7Sartem { 79*18c2aff7Sartem return FALSE; 80*18c2aff7Sartem } 81*18c2aff7Sartem 82*18c2aff7Sartem DBusHandlerResult 83*18c2aff7Sartem osspec_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) 84*18c2aff7Sartem { 85*18c2aff7Sartem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 86*18c2aff7Sartem } 87*18c2aff7Sartem 88*18c2aff7Sartem /** Find the closest ancestor by looking at devfs paths 89*18c2aff7Sartem * 90*18c2aff7Sartem * @param devfs_path Path into devfs, e.g. /pci@0,0/pci1025,57@10,2/storage@1 91*18c2aff7Sartem * @return Parent Hal Device Object or #NULL if there is none 92*18c2aff7Sartem */ 93*18c2aff7Sartem HalDevice * 94*18c2aff7Sartem hal_util_find_closest_ancestor (const gchar *devfs_path, gchar **ancestor_devfs_path, gchar **hotplug_devfs_path) 95*18c2aff7Sartem { 96*18c2aff7Sartem gchar buf[512]; 97*18c2aff7Sartem gchar c; 98*18c2aff7Sartem HalDevice *parent; 99*18c2aff7Sartem 100*18c2aff7Sartem parent = NULL; 101*18c2aff7Sartem 102*18c2aff7Sartem strncpy (buf, devfs_path, sizeof (buf)); 103*18c2aff7Sartem do { 104*18c2aff7Sartem char *p; 105*18c2aff7Sartem 106*18c2aff7Sartem p = strrchr (buf, '/'); 107*18c2aff7Sartem if (p == NULL) 108*18c2aff7Sartem break; 109*18c2aff7Sartem c = *p; 110*18c2aff7Sartem *p = '\0'; 111*18c2aff7Sartem 112*18c2aff7Sartem parent = hal_device_store_match_key_value_string (hald_get_gdl (), 113*18c2aff7Sartem "solaris.devfs_path", 114*18c2aff7Sartem buf); 115*18c2aff7Sartem if (parent != NULL) { 116*18c2aff7Sartem if (ancestor_devfs_path != NULL) { 117*18c2aff7Sartem *ancestor_devfs_path = g_strdup (buf); 118*18c2aff7Sartem } 119*18c2aff7Sartem if (hotplug_devfs_path != NULL) { 120*18c2aff7Sartem *p = c; 121*18c2aff7Sartem *hotplug_devfs_path = g_strdup (buf); 122*18c2aff7Sartem } 123*18c2aff7Sartem break; 124*18c2aff7Sartem } 125*18c2aff7Sartem 126*18c2aff7Sartem } while (TRUE); 127*18c2aff7Sartem 128*18c2aff7Sartem return parent; 129*18c2aff7Sartem } 130*18c2aff7Sartem 131*18c2aff7Sartem char * 132*18c2aff7Sartem dsk_to_rdsk(char *dsk) 133*18c2aff7Sartem { 134*18c2aff7Sartem int len, pos; 135*18c2aff7Sartem char *p; 136*18c2aff7Sartem char *rdsk; 137*18c2aff7Sartem 138*18c2aff7Sartem if ((len = strlen (dsk)) < sizeof ("/dev/dsk/cN") - 1) { 139*18c2aff7Sartem return (strdup("")); 140*18c2aff7Sartem } 141*18c2aff7Sartem if ((p = strstr (dsk, "/dsk/")) == NULL) { 142*18c2aff7Sartem if ((p = strstr (dsk, "/lofi/")) == NULL) { 143*18c2aff7Sartem p = strstr (dsk, "/diskette"); 144*18c2aff7Sartem } 145*18c2aff7Sartem } 146*18c2aff7Sartem if (p == NULL) { 147*18c2aff7Sartem return (strdup("")); 148*18c2aff7Sartem } 149*18c2aff7Sartem 150*18c2aff7Sartem pos = (uintptr_t)p - (uintptr_t)dsk; 151*18c2aff7Sartem if ((rdsk = (char *)calloc (len + 2, 1)) != NULL) { 152*18c2aff7Sartem strncpy (rdsk, dsk, pos + 1); 153*18c2aff7Sartem rdsk[pos + 1] = 'r'; 154*18c2aff7Sartem strcpy (rdsk + pos + 2, dsk + pos + 1); 155*18c2aff7Sartem } 156*18c2aff7Sartem 157*18c2aff7Sartem return (rdsk); 158*18c2aff7Sartem } 159*18c2aff7Sartem 160*18c2aff7Sartem /* 161*18c2aff7Sartem * Setup to watch mnttab changes 162*18c2aff7Sartem * 163*18c2aff7Sartem * When mnttab changes, POLLRDBAND is set. However, glib does not 164*18c2aff7Sartem * support POLLRDBAND, so we use Solaris ports (see port_create(3C)) 165*18c2aff7Sartem * to "map" POLLRDBAND to POLLIN: 166*18c2aff7Sartem * 167*18c2aff7Sartem * - create a port 168*18c2aff7Sartem * - associate the port with mnttab file descriptor and POLLRDBAND 169*18c2aff7Sartem * - now polling for POLLIN on the port descriptor will unblock when 170*18c2aff7Sartem * the associated file descriptor receives POLLRDBAND 171*18c2aff7Sartem */ 172*18c2aff7Sartem static int mnttab_fd; 173*18c2aff7Sartem static int mnttab_port; 174*18c2aff7Sartem static GIOChannel *mnttab_channel; 175*18c2aff7Sartem 176*18c2aff7Sartem static void 177*18c2aff7Sartem mnttab_event_init () 178*18c2aff7Sartem { 179*18c2aff7Sartem char buf[81]; 180*18c2aff7Sartem 181*18c2aff7Sartem if ((mnttab_fd = open (MNTTAB, O_RDONLY)) < 0) { 182*18c2aff7Sartem return; 183*18c2aff7Sartem } 184*18c2aff7Sartem if ((mnttab_port = port_create ()) < 0) { 185*18c2aff7Sartem (void) close (mnttab_fd); 186*18c2aff7Sartem return; 187*18c2aff7Sartem } 188*18c2aff7Sartem if (port_associate (mnttab_port, PORT_SOURCE_FD, mnttab_fd, POLLRDBAND, 189*18c2aff7Sartem NULL) != 0) { 190*18c2aff7Sartem (void) close (mnttab_port); 191*18c2aff7Sartem (void) close (mnttab_fd); 192*18c2aff7Sartem return; 193*18c2aff7Sartem } 194*18c2aff7Sartem 195*18c2aff7Sartem /* suppress initial event */ 196*18c2aff7Sartem (void) read(mnttab_fd, buf, (size_t)(sizeof (buf) - 1)); 197*18c2aff7Sartem (void) lseek(mnttab_fd, 0, SEEK_SET); 198*18c2aff7Sartem 199*18c2aff7Sartem mnttab_channel = g_io_channel_unix_new (mnttab_port); 200*18c2aff7Sartem g_io_add_watch (mnttab_channel, G_IO_IN, mnttab_event, NULL); 201*18c2aff7Sartem } 202*18c2aff7Sartem 203*18c2aff7Sartem static gboolean 204*18c2aff7Sartem mnttab_event (GIOChannel *channel, GIOCondition cond, gpointer user_data) 205*18c2aff7Sartem { 206*18c2aff7Sartem port_event_t pe; 207*18c2aff7Sartem timespec_t timeout; 208*18c2aff7Sartem char buf[81]; 209*18c2aff7Sartem 210*18c2aff7Sartem /* if (cond & ~G_IO_ERR) 211*18c2aff7Sartem return TRUE; 212*18c2aff7Sartem */ 213*18c2aff7Sartem HAL_INFO (("mnttab event")); 214*18c2aff7Sartem 215*18c2aff7Sartem /* we have to re-associate port with fd every time */ 216*18c2aff7Sartem timeout.tv_sec = timeout.tv_nsec = 0; 217*18c2aff7Sartem (void) port_get(mnttab_port, &pe, &timeout); 218*18c2aff7Sartem (void) port_associate(mnttab_port, PORT_SOURCE_FD, 219*18c2aff7Sartem mnttab_fd, POLLRDBAND, NULL); 220*18c2aff7Sartem 221*18c2aff7Sartem if (!hald_is_initialising) { 222*18c2aff7Sartem devinfo_storage_mnttab_event (NULL); 223*18c2aff7Sartem } 224*18c2aff7Sartem 225*18c2aff7Sartem (void) lseek(mnttab_fd, 0, SEEK_SET); 226*18c2aff7Sartem (void) read(mnttab_fd, buf, (size_t)(sizeof (buf) - 1)); 227*18c2aff7Sartem 228*18c2aff7Sartem return TRUE; 229*18c2aff7Sartem } 230*18c2aff7Sartem 231*18c2aff7Sartem void 232*18c2aff7Sartem osspec_refresh_mount_state_for_block_device (HalDevice *d) 233*18c2aff7Sartem { 234*18c2aff7Sartem devinfo_storage_mnttab_event (d); 235*18c2aff7Sartem } 236