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