18c2aff776a775d34a4c9893a4c72e0434d68e36artem * CDDL HEADER START
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * The contents of this file are subject to the terms of the
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Common Development and Distribution License (the "License").
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * You may not use this file except in compliance with the License.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * See the License for the specific language governing permissions
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * and limitations under the License.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * When distributing Covered Code, include this CDDL HEADER in each
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * If applicable, add the following below this CDDL HEADER, with the
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * fields enclosed by brackets "[]" replaced with your own identifying
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * information: Portions Copyright [yyyy] [name of copyright owner]
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * CDDL HEADER END
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Use is subject to license terms.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * rmvolmgr daemon
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#define RMVOLMGR_FMRI "svc:/system/filesystem/rmvolmgr:default"
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic boolean_t opt_c; /* disable CDE compatibility */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic boolean_t opt_n; /* disable legacy mountpoint symlinks */
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine/* SMF property "eject_button" */
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic boolean_t rmm_prop_eject_button = B_TRUE;
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void rmm_device_added(LibHalContext *ctx, const char *udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void rmm_device_removed(LibHalContext *ctx, const char *udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void rmm_property_modified(LibHalContext *ctx, const char *udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *key, dbus_bool_t is_removed, dbus_bool_t is_added);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinestatic void rmm_device_condition(LibHalContext *ctx, const char *udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void rmm_mount_all();
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void rmm_unmount_all();
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic gboolean sigexit_ioch_func(GIOChannel *source, GIOCondition condition,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) fprintf(stderr, gettext("\nusage: rmvolmgr [-v]\n"));
18c2aff776a775d34a4c9893a4c72e0434d68e36artem switch (c) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (0);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (geteuid() != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Drop unused privileges. Remain root for HAL interaction
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * and to create legacy symlinks.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Need PRIV_FILE_DAC_WRITE to write to users'
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * /tmp/.removable/notify* files.
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem rmm_vold_actions_enabled ? PRIV_FILE_DAC_WRITE : NULL,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* basic privileges we don't need */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_PROC_EXEC,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem PRIV_PROC_INFO, PRIV_FILE_LINK_ANY, PRIV_PROC_SESSION,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * signal mainloop integration using pipes
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem sigexit_ioch = g_io_channel_unix_new(sigexit_pipe[0]);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_io_add_watch(sigexit_ioch, G_IO_IN, sigexit_ioch_func, NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((hal_ctx = rmm_hal_init(rmm_device_added, rmm_device_removed,
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine rmm_property_modified, rmm_device_condition,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* user instance should claim devices */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!rmm_hal_claim_branch(hal_ctx, HAL_BRANCH_LOCAL)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((mainloop = g_main_loop_new(NULL, B_FALSE)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (0);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((val = scf_simple_prop_next_boolean(prop)) != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((val = scf_simple_prop_next_boolean(prop)) != NULL) {
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if ((prop = scf_simple_prop_get(NULL, RMVOLMGR_FMRI,
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if ((val = scf_simple_prop_next_boolean(prop)) != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* ARGSUSED */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* ARGSUSED */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemsigexit_ioch_func(GIOChannel *source, GIOCondition condition,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (g_io_channel_read_chars(source, buf, 1, &bytes_read, &error) !=
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dprintf("g_io_channel_read_chars failed %s", error->message);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((v = calloc(1, sizeof (managed_volume_t))) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!rmm_volume_aa_from_prop(ctx, udi, NULL, &v->aa)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return (v);
18c2aff776a775d34a4c9893a4c72e0434d68e36artemrmm_managed_compare_udi(gconstpointer a, gconstpointer b)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* get the backing storage device */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!(storage_device = libhal_device_get_property_string(hal_ctx, udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* we handle either removable or hotpluggable */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!libhal_device_get_property_bool(hal_ctx, storage_device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem !libhal_device_get_property_bool(hal_ctx, storage_device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* ignore if claimed by another volume manager */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (libhal_device_get_property_bool(hal_ctx, storage_device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem l = g_slist_find_custom(managed_volumes, udi, rmm_managed_compare_udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (v != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (rmm_action(hal_ctx, udi, INSERT, &v->aa, 0, 0, 0)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem managed_volumes = g_slist_prepend(managed_volumes, v);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem l = g_slist_find_custom(managed_volumes, udi, rmm_managed_compare_udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (v == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* HAL will unmount, just do the vold legacy stuff */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem managed_volumes = g_slist_delete_link(managed_volumes, l);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* ARGSUSED */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (libhal_device_query_capability(hal_ctx, udi, "volume", NULL)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* ARGSUSED */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemrmm_device_removed(LibHalContext *ctx, const char *udi)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (libhal_device_query_capability(hal_ctx, udi, "volume", NULL)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem/* ARGSUSED */
18c2aff776a775d34a4c9893a4c72e0434d68e36artemrmm_property_modified(LibHalContext *ctx, const char *udi, const char *key,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem is_mounted = libhal_device_get_property_bool(hal_ctx, udi, key, NULL);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem l = g_slist_find_custom(managed_volumes, udi, rmm_managed_compare_udi);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (v != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* volume mounted by us is already taken care of */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem managed_volumes = g_slist_prepend(managed_volumes, v);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (v == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem managed_volumes = g_slist_delete_link(managed_volumes, l);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine /* ignore if disabled via SMF or claimed by another volume manager */
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine libhal_device_get_property_bool(hal_ctx, udi, "info.claimed",
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine (void) rmm_hal_eject(hal_ctx, udi, &error);
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkinermm_device_condition(LibHalContext *ctx, const char *udi,
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine if ((strcmp(name, "EjectPressed") == 0) &&
97ddcdce0091922bf2049977a3d42ba4fc0857a6Artem Kachitchkine libhal_device_query_capability(hal_ctx, udi, "storage", NULL)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Mount all mountable volumes
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* get all volumes */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((udis = libhal_find_device_by_capability(hal_ctx, "volume",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = 0; i < num_udis; i++) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* skip if already mounted */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((v = rmm_managed_alloc(hal_ctx, udis[i])) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (rmm_action(hal_ctx, udis[i], INSERT, &v->aa, 0, 0, 0)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem managed_volumes = g_slist_prepend(managed_volumes, v);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * Mount all volumes mounted by this program
18c2aff776a775d34a4c9893a4c72e0434d68e36artem for (i = managed_volumes; i != NULL; i = managed_volumes) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (v->my && libhal_device_get_property_bool(hal_ctx, v->udi,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem &v->aa, 0, 0, 0);