18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * addon-storage.c : watch removable media state changes
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine * Copyright 2009 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
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_CONFIG_H
18c2aff776a775d34a4c9893a4c72e0434d68e36artem# include <config.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <errno.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <string.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <strings.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <stdlib.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <stdio.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/ioctl.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/types.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/stat.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/types.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/wait.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <fcntl.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <unistd.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/mnttab.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/dkio.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <priv.h>
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine#include <libsysevent.h>
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine#include <sys/sysevent/dev.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <libhal.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "../../hald/logger.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#define SLEEP_PERIOD 5
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic char *udi;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic char *devfs_path;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem KachitchkineLibHalContext *ctx = NULL;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic sysevent_handle_t *shp = NULL;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic void sysevent_dev_handler(sysevent_t *);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemmy_dbus_error_free(DBusError *error)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (dbus_error_is_set(error)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_free(error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic void
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinesysevent_init ()
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine{
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine const char *subcl[1];
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine shp = sysevent_bind_handle (sysevent_dev_handler);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if (shp == NULL) {
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine HAL_DEBUG (("sysevent_bind_handle failed %d", errno));
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine return;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine }
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine subcl[0] = ESC_DEV_EJECT_REQUEST;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if (sysevent_subscribe_event (shp, EC_DEV_STATUS, subcl, 1) != 0) {
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine HAL_INFO (("subscribe(dev_status) failed %d", errno));
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine sysevent_unbind_handle (shp);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine return;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine }
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine}
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic void
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinesysevent_fini ()
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine{
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if (shp != NULL) {
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine sysevent_unbind_handle (shp);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine shp = NULL;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine }
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine}
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic void
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinesysevent_dev_handler (sysevent_t *ev)
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine{
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine char *class;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine char *subclass;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine nvlist_t *attr_list;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine char *phys_path, *path;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine char *p;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine int len;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine DBusError error;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if ((class = sysevent_get_class_name (ev)) == NULL)
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine return;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if ((subclass = sysevent_get_subclass_name (ev)) == NULL)
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine return;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if ((strcmp (class, EC_DEV_STATUS) != 0) ||
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine (strcmp (subclass, ESC_DEV_EJECT_REQUEST) != 0))
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine return;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if (sysevent_get_attr_list (ev, &attr_list) != 0)
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine return;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if (nvlist_lookup_string (attr_list, DEV_PHYS_PATH, &phys_path) != 0) {
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine goto out;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine }
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine /* see if event belongs to our LUN (ignore slice and "/devices" ) */
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if (strncmp (phys_path, "/devices", sizeof ("/devices") - 1) == 0)
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine path = phys_path + sizeof ("/devices") - 1;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine else
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine path = phys_path;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if ((p = strrchr (path, ':')) == NULL)
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine goto out;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine len = (uintptr_t)p - (uintptr_t)path;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if (strncmp (path, devfs_path, len) != 0)
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine goto out;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine HAL_DEBUG (("sysevent_dev_handler %s %s", subclass, phys_path));
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine /* we got it, tell the world */
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine dbus_error_init (&error);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine libhal_device_emit_condition (ctx, udi, "EjectPressed", "", &error);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine dbus_error_free (&error);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkineout:
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine nvlist_free(attr_list);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine}
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemforce_unmount (LibHalContext *ctx, const char *udi)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusError error;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusMessage *msg = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusMessage *reply = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char **options = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unsigned int num_options = 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusConnection *dbus_connection;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *device_file;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_init (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_connection = libhal_ctx_get_dbus_connection (ctx);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "org.freedesktop.Hal.Device.Volume",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "Unmount");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (msg == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Could not create dbus message for %s", udi));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem options = calloc (1, sizeof (char *));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (options == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Could not allocate options array"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem device_file = libhal_device_get_property_string (ctx, udi, "block.device", &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (device_file != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_free_string (device_file);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!dbus_message_append_args (msg,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &options, num_options,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBUS_TYPE_INVALID)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Could not append args to dbus message for %s", udi));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!(reply = dbus_connection_send_with_reply_and_block (dbus_connection, msg, -1, &error))) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Unmount failed for %s: %s : %s\n", udi, error.name, error.message));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (dbus_error_is_set (&error)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Unmount failed for %s\n%s : %s\n", udi, error.name, error.message));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Succesfully unmounted udi '%s'", udi));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemout:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (options != NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem free (options);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (msg != NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_message_unref (msg);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (reply != NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_message_unref (reply);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemunmount_childs (LibHalContext *ctx, const char *udi)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusError error;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int num_volumes;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char **volumes;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_init (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* need to force unmount all partitions */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((volumes = libhal_manager_find_device_string_match (
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ctx, "block.storage_device", udi, &num_volumes, &error)) != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int i;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0; i < num_volumes; i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *vol_udi;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem vol_udi = volumes[i];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (libhal_device_get_property_bool (ctx, vol_udi, "block.is_volume", &error)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (libhal_device_get_property_bool (ctx, vol_udi, "volume.is_mounted", &error)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Forcing unmount of child '%s'", vol_udi));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem force_unmount (ctx, vol_udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_free_string_array (volumes);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/** Check if a filesystem on a special device file is mounted
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @param device_file Special device file, e.g. /dev/cdrom
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * @return TRUE iff there is a filesystem system mounted
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * on the special device file
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic dbus_bool_t
18c2aff776a775d34a4c9893a4c72e0434d68e36artemis_mounted (const char *device_file)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem FILE *f;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_bool_t rc = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem struct mnttab mp;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem struct mnttab mpref;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((f = fopen ("/etc/mnttab", "r")) == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return rc;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem bzero(&mp, sizeof (mp));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem bzero(&mpref, sizeof (mpref));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem mpref.mnt_special = (char *)device_file;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (getmntany(f, &mp, &mpref) == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem rc = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fclose (f);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return rc;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemclose_device (int *fd)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (*fd > 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem close (*fd);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *fd = -1;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemdrop_privileges ()
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem priv_set_t *pPrivSet = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem priv_set_t *lPrivSet = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /*
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Start with the 'basic' privilege set and then remove any
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * of the 'basic' privileges that will not be needed.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Clear privileges we will not need from the 'basic' set */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* to open logindevperm'd devices */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) priv_addset(pPrivSet, PRIV_FILE_DAC_READ);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine /* to receive sysevents */
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine (void) priv_addset(pPrivSet, PRIV_SYS_CONFIG);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Set the permitted privilege set. */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Clear the limit set. */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((lPrivSet = priv_allocset()) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem priv_emptyset(lPrivSet);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem priv_freeset(lPrivSet);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemint
18c2aff776a775d34a4c9893a4c72e0434d68e36artemmain (int argc, char *argv[])
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *device_file, *raw_device_file;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusError error;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *bus;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *drive_type;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int state, last_state;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *support_media_changed_str;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int support_media_changed;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int fd = -1;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((udi = getenv ("UDI")) == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((device_file = getenv ("HAL_PROP_BLOCK_DEVICE")) == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((raw_device_file = getenv ("HAL_PROP_BLOCK_SOLARIS_RAW_DEVICE")) == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((bus = getenv ("HAL_PROP_STORAGE_BUS")) == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((drive_type = getenv ("HAL_PROP_STORAGE_DRIVE_TYPE")) == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if ((devfs_path = getenv ("HAL_PROP_SOLARIS_DEVFS_PATH")) == NULL)
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem drop_privileges ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem setup_logger ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine sysevent_init ();
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine
18c2aff776a775d34a4c9893a4c72e0434d68e36artem support_media_changed_str = getenv ("HAL_PROP_STORAGE_CDROM_SUPPORT_MEDIA_CHANGED");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (support_media_changed_str != NULL && strcmp (support_media_changed_str, "true") == 0)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem support_media_changed = TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem else
18c2aff776a775d34a4c9893a4c72e0434d68e36artem support_media_changed = FALSE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_init (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((ctx = libhal_ctx_init_direct (&error)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!libhal_device_addon_is_ready (ctx, udi, &error)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("Doing addon-storage for %s (bus %s) (drive_type %s) (udi %s)\n", device_file, bus, drive_type, udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem last_state = state = DKIO_NONE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Linux version of this addon attempts to re-open the device O_EXCL
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * every 2 seconds, trying to figure out if some other app,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * like a cd burner, is using the device. Aside from questionable
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * value of this (apps should use HAL's locked property or/and
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Solaris in_use facility), but also frequent opens/closes
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * keeps media constantly spun up. All this needs more thought.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (;;) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (is_mounted (device_file)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem close_device (&fd);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sleep (SLEEP_PERIOD);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else if ((fd < 0) && ((fd = open (raw_device_file, O_RDONLY | O_NONBLOCK)) < 0)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("open failed for %s: %s", raw_device_file, strerror (errno)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sleep (SLEEP_PERIOD);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* Check if a disc is in the drive */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* XXX initial call always returns inserted
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * causing unnecessary rescan - optimize?
18c2aff776a775d34a4c9893a4c72e0434d68e36artem */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (ioctl (fd, DKIOCSTATE, &state) == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (state == last_state) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("state has not changed %d %s", state, device_file));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem continue;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("new state %d %s", state, device_file));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem switch (state) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case DKIO_EJECTED:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Media removal detected on %s", device_file));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem last_state = state;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* attempt to unmount all childs */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unmount_childs (ctx, udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* could have a fs on the main block device; do a rescan to remove it */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_rescan (ctx, udi, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case DKIO_INSERTED:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Media insertion detected on %s", device_file));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem last_state = state;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* could have a fs on the main block device; do a rescan to add it */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_device_rescan (ctx, udi, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case DKIO_DEV_GONE:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("Device gone detected on %s", device_file));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem last_state = state;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unmount_childs (ctx, udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem close_device (&fd);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case DKIO_NONE:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem default:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem HAL_DEBUG (("DKIOCSTATE failed: %s\n", strerror(errno)));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sleep (SLEEP_PERIOD);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemout:
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine sysevent_fini ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (ctx != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem my_dbus_error_free (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_ctx_shutdown (ctx, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_ctx_free (ctx);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}