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