18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * osspec.c : Solaris HAL backend entry points
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Use is subject to license terms.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Licensed under the Academic Free License version 2.1
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem **************************************************************************/
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
92f381329ebf1c2209df9608670666b32b291e05artem#pragma ident "%Z%%M% %I% %E% SMI"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_CONFIG_H
18c2aff776a775d34a4c9893a4c72e0434d68e36artem# include <config.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <stdio.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <unistd.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <strings.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <port.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/stat.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <fcntl.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/types.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/mntent.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/mnttab.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../osspec.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../logger.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../hald.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../hald_dbus.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../device_info.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../util.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../ids.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "osspec_solaris.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "hotplug.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "sysevent.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "devinfo.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "devinfo_storage.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void mnttab_event_init ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic gboolean mnttab_event (GIOChannel *channel, GIOCondition cond, gpointer user_data);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemosspec_init (void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ids_init ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sysevent_init ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem mnttab_event_init ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhotplug_queue_now_empty (void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hald_is_initialising) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem osspec_probe_done ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemosspec_probe (void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* add entire device tree */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devinfo_add (NULL, "/");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* start processing events */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem hotplug_event_process_queue ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemgboolean
18c2aff776a775d34a4c9893a4c72e0434d68e36artemosspec_device_rescan (HalDevice *d)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (devinfo_device_rescan (d));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemgboolean
18c2aff776a775d34a4c9893a4c72e0434d68e36artemosspec_device_reprobe (HalDevice *d)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemDBusHandlerResult
18c2aff776a775d34a4c9893a4c72e0434d68e36artemosspec_filter_function (DBusConnection *connection, DBusMessage *message, void *user_data)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Find the closest ancestor by looking at devfs paths
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param devfs_path Path into devfs, e.g. /pci@0,0/pci1025,57@10,2/storage@1
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @return Parent Hal Device Object or #NULL if there is none
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemHalDevice *
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhal_util_find_closest_ancestor (const gchar *devfs_path, gchar **ancestor_devfs_path, gchar **hotplug_devfs_path)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gchar buf[512];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem gchar c;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HalDevice *parent;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem parent = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem strncpy (buf, devfs_path, sizeof (buf));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem do {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *p;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem p = strrchr (buf, '/');
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (p == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem c = *p;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *p = '\0';
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem parent = hal_device_store_match_key_value_string (hald_get_gdl (),
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "solaris.devfs_path",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem buf);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (parent != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (ancestor_devfs_path != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *ancestor_devfs_path = g_strdup (buf);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (hotplug_devfs_path != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *p = c;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *hotplug_devfs_path = g_strdup (buf);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } while (TRUE);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return parent;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemchar *
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdsk_to_rdsk(char *dsk)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int len, pos;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *p;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *rdsk;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((len = strlen (dsk)) < sizeof ("/dev/dsk/cN") - 1) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (strdup(""));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((p = strstr (dsk, "/dsk/")) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((p = strstr (dsk, "/lofi/")) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem p = strstr (dsk, "/diskette");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (p == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (strdup(""));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem pos = (uintptr_t)p - (uintptr_t)dsk;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((rdsk = (char *)calloc (len + 2, 1)) != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem strncpy (rdsk, dsk, pos + 1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem rdsk[pos + 1] = 'r';
18c2aff776a775d34a4c9893a4c72e0434d68e36artem strcpy (rdsk + pos + 2, dsk + pos + 1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (rdsk);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/*
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Setup to watch mnttab changes
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * When mnttab changes, POLLRDBAND is set. However, glib does not
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * support POLLRDBAND, so we use Solaris ports (see port_create(3C))
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * to "map" POLLRDBAND to POLLIN:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * - create a port
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * - associate the port with mnttab file descriptor and POLLRDBAND
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * - now polling for POLLIN on the port descriptor will unblock when
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * the associated file descriptor receives POLLRDBAND
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic int mnttab_fd;
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic int mnttab_port;
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic GIOChannel *mnttab_channel;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemmnttab_event_init ()
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char buf[81];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((mnttab_fd = open (MNTTAB, O_RDONLY)) < 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((mnttab_port = port_create ()) < 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) close (mnttab_fd);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (port_associate (mnttab_port, PORT_SOURCE_FD, mnttab_fd, POLLRDBAND,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem NULL) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) close (mnttab_port);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) close (mnttab_fd);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* suppress initial event */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) read(mnttab_fd, buf, (size_t)(sizeof (buf) - 1));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) lseek(mnttab_fd, 0, SEEK_SET);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem mnttab_channel = g_io_channel_unix_new (mnttab_port);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_io_add_watch (mnttab_channel, G_IO_IN, mnttab_event, NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic gboolean
18c2aff776a775d34a4c9893a4c72e0434d68e36artemmnttab_event (GIOChannel *channel, GIOCondition cond, gpointer user_data)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem port_event_t pe;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem timespec_t timeout;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char buf[81];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* if (cond & ~G_IO_ERR)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_INFO (("mnttab event"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* we have to re-associate port with fd every time */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem timeout.tv_sec = timeout.tv_nsec = 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) port_get(mnttab_port, &pe, &timeout);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) port_associate(mnttab_port, PORT_SOURCE_FD,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem mnttab_fd, POLLRDBAND, NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!hald_is_initialising) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devinfo_storage_mnttab_event (NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) lseek(mnttab_fd, 0, SEEK_SET);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) read(mnttab_fd, buf, (size_t)(sizeof (buf) - 1));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemosspec_refresh_mount_state_for_block_device (HalDevice *d)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem devinfo_storage_mnttab_event (d);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}