18c2aff776a775d34a4c9893a4c72e0434d68e36artem/***************************************************************************
18c2aff776a775d34a4c9893a4c72e0434d68e36artem *
18c2aff776a775d34a4c9893a4c72e0434d68e36artem * hal-storage-zpool.c : ZFS pool methods
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 <stdlib.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <string.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <glib.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <glib/gstdio.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <sys/types.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <wait.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <unistd.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <bsm/adt.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <bsm/adt_event.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <libhal.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <libhal-storage.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_POLKIT
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include <libpolkit.h>
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#include "hal-storage-shared.h"
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemstatic void
18c2aff776a775d34a4c9893a4c72e0434d68e36artemusage (void)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "This program should only be started by hald.\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem exit (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid static
18c2aff776a775d34a4c9893a4c72e0434d68e36artemunknown_zpool_error (const char *detail)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "org.freedesktop.Hal.Device.Volume.UnknownFailure\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem fprintf (stderr, "%s\n", detail);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem exit (1);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemaudit_pool(const adt_export_data_t *imported_state, au_event_t event_id,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int result, const char *auth_used, const char *pool, const char *device)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem adt_session_data_t *ah;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem adt_event_data_t *event;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (adt_start_session(&ah, imported_state, 0) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("adt_start_session failed %d\n", errno);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((event = adt_alloc_event(ah, event_id)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("adt_alloc_event(ADT_attach)\n", errno);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem switch (event_id) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case ADT_pool_export:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem event->adt_pool_export.auth_used = (char *)auth_used;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem event->adt_pool_export.pool = (char *)pool;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem event->adt_pool_export.device = (char *)device;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem case ADT_pool_import:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem event->adt_pool_import.auth_used = (char *)auth_used;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem event->adt_pool_import.pool = (char *)pool;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem event->adt_pool_import.device = (char *)device;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem break;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem default:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem goto out;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (result == 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("adt_put_event(%d, success)\n", event_id);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem } else {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (adt_put_event(event, ADT_FAILURE, result) != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("adt_put_event(%d, failure)\n", event_id);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artemout:
18c2aff776a775d34a4c9893a4c72e0434d68e36artem adt_free_event(event);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (void) adt_end_session(ah);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemvoid
18c2aff776a775d34a4c9893a4c72e0434d68e36artemhandle_zpool (LibHalContext *hal_ctx,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_POLKIT
18c2aff776a775d34a4c9893a4c72e0434d68e36artem LibPolKitContext *pol_ctx,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *subcmd, const char *pool, const char *device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *invoked_by_uid, const char *invoked_by_syscon_name,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusConnection *system_bus)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem GError *err = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *sout = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *serr = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int exit_status = 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *args[10];
18c2aff776a775d34a4c9893a4c72e0434d68e36artem int na;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem adt_export_data_t *adt_data;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem size_t adt_data_size;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem au_event_t event_id;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef DEBUG
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("subcmd = %s\n", subcmd);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("pool = %s\n", pool);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("device = %s\n", device);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("invoked by uid = %s\n", invoked_by_uid);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem na = 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem args[na++] = "/usr/sbin/zpool";
18c2aff776a775d34a4c9893a4c72e0434d68e36artem args[na++] = subcmd;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((strcmp (subcmd, "import") == 0) &&
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (strncmp (device, "/dev/lofi", 9) == 0)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem args[na++] = "-d";
18c2aff776a775d34a4c9893a4c72e0434d68e36artem args[na++] = "/dev/lofi";
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem args[na++] = (char *) pool;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem args[na++] = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* invoke eject command */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (!g_spawn_sync ("/",
18c2aff776a775d34a4c9893a4c72e0434d68e36artem args,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem NULL,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem 0,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem NULL,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem NULL,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem &sout,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem &serr,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem &exit_status,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem &err)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("Cannot execute zpool %s\n", subcmd);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_zpool_error ("Cannot spawn zpool");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((adt_data = get_audit_export_data (system_bus,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem invoked_by_syscon_name, &adt_data_size)) != NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem event_id = (strcmp (subcmd, "import") == 0) ?
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ADT_pool_import : ADT_pool_export;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem audit_pool (adt_data, event_id, WEXITSTATUS(exit_status),
18c2aff776a775d34a4c9893a4c72e0434d68e36artem "solaris.device.mount.removable", pool, device);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem free (adt_data);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (exit_status != 0) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("zpool error %d, stdout='%s', stderr='%s'\n", exit_status, sout, serr);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_zpool_error (serr);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_free (sout);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem g_free (serr);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artemint
18c2aff776a775d34a4c9893a4c72e0434d68e36artemmain (int argc, char *argv[])
18c2aff776a775d34a4c9893a4c72e0434d68e36artem{
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *udi;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *device;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem const char *drive_udi;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem LibHalDrive *drive;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem LibHalVolume *volume;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusError error;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem LibHalContext *hal_ctx = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem DBusConnection *system_bus = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_POLKIT
18c2aff776a775d34a4c9893a4c72e0434d68e36artem LibPolKitContext *pol_ctx = NULL;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *invoked_by_uid;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem char *invoked_by_syscon_name;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem device = getenv ("HAL_PROP_BLOCK_DEVICE");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (device == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem usage ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem udi = getenv ("HAL_PROP_INFO_UDI");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (udi == NULL)
18c2aff776a775d34a4c9893a4c72e0434d68e36artem usage ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_init (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("Cannot connect to hald\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem LIBHAL_FREE_DBUS_ERROR (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem usage ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem dbus_error_init (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (system_bus == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("Cannot connect to the system bus\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem LIBHAL_FREE_DBUS_ERROR (&error);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem usage ();
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_POLKIT
18c2aff776a775d34a4c9893a4c72e0434d68e36artem pol_ctx = libpolkit_new_context (system_bus);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if (pol_ctx == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem printf ("Cannot get libpolkit context\n");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_zpool_error ("Cannot get libpolkit context");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem /* should be a volume */
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((volume = libhal_volume_from_udi (hal_ctx, udi)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_zpool_error ("Invalid volume");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((drive_udi = libhal_volume_get_storage_device_udi (volume)) == NULL ) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_zpool_error ("Cannot get drive udi");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((drive = libhal_drive_from_udi (hal_ctx, drive_udi)) == NULL) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_zpool_error ("Cannot get drive from udi");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((libhal_volume_get_fstype (volume) == NULL) ||
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (strcmp (libhal_volume_get_fstype (volume), "zfs") != 0)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_zpool_error ("Not a zpool");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem if ((libhal_volume_get_label (volume) == NULL) ||
18c2aff776a775d34a4c9893a4c72e0434d68e36artem (strlen (libhal_volume_get_label (volume)) == 0)) {
18c2aff776a775d34a4c9893a4c72e0434d68e36artem unknown_zpool_error ("Invalid zpool name");
18c2aff776a775d34a4c9893a4c72e0434d68e36artem }
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem handle_zpool (hal_ctx,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#ifdef HAVE_POLKIT
18c2aff776a775d34a4c9893a4c72e0434d68e36artem pol_ctx,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem#endif
18c2aff776a775d34a4c9893a4c72e0434d68e36artem ZPOOL_SUBCMD,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem libhal_volume_get_label (volume),
18c2aff776a775d34a4c9893a4c72e0434d68e36artem device,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem invoked_by_uid,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem invoked_by_syscon_name,
18c2aff776a775d34a4c9893a4c72e0434d68e36artem system_bus);
18c2aff776a775d34a4c9893a4c72e0434d68e36artem
18c2aff776a775d34a4c9893a4c72e0434d68e36artem return 0;
18c2aff776a775d34a4c9893a4c72e0434d68e36artem}
18c2aff776a775d34a4c9893a4c72e0434d68e36artem