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
osspec_init(void)452912Sartem osspec_init (void)
462912Sartem {
472912Sartem ids_init ();
482912Sartem sysevent_init ();
492912Sartem mnttab_event_init ();
502912Sartem }
512912Sartem
522912Sartem void
hotplug_queue_now_empty(void)532912Sartem hotplug_queue_now_empty (void)
542912Sartem {
552912Sartem if (hald_is_initialising) {
562912Sartem osspec_probe_done ();
572912Sartem }
582912Sartem }
592912Sartem
602912Sartem void
osspec_probe(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
osspec_device_rescan(HalDevice * d)712912Sartem osspec_device_rescan (HalDevice *d)
722912Sartem {
732912Sartem return (devinfo_device_rescan (d));
742912Sartem }
752912Sartem
762912Sartem gboolean
osspec_device_reprobe(HalDevice * d)772912Sartem osspec_device_reprobe (HalDevice *d)
782912Sartem {
792912Sartem return FALSE;
802912Sartem }
812912Sartem
822912Sartem DBusHandlerResult
osspec_filter_function(DBusConnection * connection,DBusMessage * message,void * user_data)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 *
hal_util_find_closest_ancestor(const gchar * devfs_path,gchar ** ancestor_devfs_path,gchar ** hotplug_devfs_path)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 *
dsk_to_rdsk(char * dsk)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
mnttab_event_init()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
mnttab_event(GIOChannel * channel,GIOCondition cond,gpointer user_data)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
osspec_refresh_mount_state_for_block_device(HalDevice * d)2322912Sartem osspec_refresh_mount_state_for_block_device (HalDevice *d)
2332912Sartem {
2342912Sartem devinfo_storage_mnttab_event (d);
2352912Sartem }
236