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"
24 #include <sys/types.h>
25 #include <sys/mntent.h>
26 #include <sys/mnttab.h>
28 #include "../osspec.h"
29 #include "../logger.h"
31 #include "../hald_dbus.h"
32 #include "../device_info.h"
35 #include "osspec_solaris.h"
39 #include "devinfo_storage.h"
41 static void mnttab_event_init ();
42 static gboolean
mnttab_event (GIOChannel
*channel
, GIOCondition cond
, gpointer user_data
);
53 hotplug_queue_now_empty (void)
55 if (hald_is_initialising
) {
63 /* add entire device tree */
64 devinfo_add (NULL
, "/");
66 /* start processing events */
67 hotplug_event_process_queue ();
71 osspec_device_rescan (HalDevice
*d
)
73 return (devinfo_device_rescan (d
));
77 osspec_device_reprobe (HalDevice
*d
)
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
94 hal_util_find_closest_ancestor (const gchar
*devfs_path
, gchar
**ancestor_devfs_path
, gchar
**hotplug_devfs_path
)
102 strncpy (buf
, devfs_path
, sizeof (buf
));
106 p
= strrchr (buf
, '/');
112 parent
= hal_device_store_match_key_value_string (hald_get_gdl (),
113 "solaris.devfs_path",
115 if (parent
!= NULL
) {
116 if (ancestor_devfs_path
!= NULL
) {
117 *ancestor_devfs_path
= g_strdup (buf
);
119 if (hotplug_devfs_path
!= NULL
) {
121 *hotplug_devfs_path
= g_strdup (buf
);
132 dsk_to_rdsk(char *dsk
)
138 if ((len
= strlen (dsk
)) < sizeof ("/dev/dsk/cN") - 1) {
141 if ((p
= strstr (dsk
, "/dsk/")) == NULL
) {
142 if ((p
= strstr (dsk
, "/lofi/")) == NULL
) {
143 p
= strstr (dsk
, "/diskette");
150 pos
= (uintptr_t)p
- (uintptr_t)dsk
;
151 if ((rdsk
= (char *)calloc (len
+ 2, 1)) != NULL
) {
152 strncpy (rdsk
, dsk
, pos
+ 1);
154 strcpy (rdsk
+ pos
+ 2, dsk
+ pos
+ 1);
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:
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
;
181 if ((mnttab_fd
= open (MNTTAB
, O_RDONLY
)) < 0) {
184 if ((mnttab_port
= port_create ()) < 0) {
185 (void) close (mnttab_fd
);
188 if (port_associate (mnttab_port
, PORT_SOURCE_FD
, mnttab_fd
, POLLRDBAND
,
190 (void) close (mnttab_port
);
191 (void) close (mnttab_fd
);
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
);
204 mnttab_event (GIOChannel
*channel
, GIOCondition cond
, gpointer user_data
)
210 /* if (cond & ~G_IO_ERR)
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));
232 osspec_refresh_mount_state_for_block_device (HalDevice
*d
)
234 devinfo_storage_mnttab_event (d
);