12912Sartem /***************************************************************************
22912Sartem *
32912Sartem * hal-storage-zpool.c : ZFS pool methods
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 <stdlib.h>
202912Sartem #include <string.h>
212912Sartem #include <glib.h>
222912Sartem #include <glib/gstdio.h>
232912Sartem #include <sys/types.h>
242912Sartem #include <wait.h>
252912Sartem #include <unistd.h>
262912Sartem #include <bsm/adt.h>
272912Sartem #include <bsm/adt_event.h>
282912Sartem
292912Sartem #include <libhal.h>
302912Sartem #include <libhal-storage.h>
312912Sartem #ifdef HAVE_POLKIT
322912Sartem #include <libpolkit.h>
332912Sartem #endif
342912Sartem
352912Sartem #include "hal-storage-shared.h"
362912Sartem
372912Sartem static void
usage(void)382912Sartem usage (void)
392912Sartem {
402912Sartem fprintf (stderr, "This program should only be started by hald.\n");
412912Sartem exit (1);
422912Sartem }
432912Sartem
442912Sartem
452912Sartem void static
unknown_zpool_error(const char * detail)462912Sartem unknown_zpool_error (const char *detail)
472912Sartem {
482912Sartem fprintf (stderr, "org.freedesktop.Hal.Device.Volume.UnknownFailure\n");
492912Sartem fprintf (stderr, "%s\n", detail);
502912Sartem exit (1);
512912Sartem }
522912Sartem
532912Sartem void
audit_pool(const adt_export_data_t * imported_state,au_event_t event_id,int result,const char * auth_used,const char * pool,const char * device)542912Sartem audit_pool(const adt_export_data_t *imported_state, au_event_t event_id,
552912Sartem int result, const char *auth_used, const char *pool, const char *device)
562912Sartem {
572912Sartem adt_session_data_t *ah;
582912Sartem adt_event_data_t *event;
592912Sartem
602912Sartem if (adt_start_session(&ah, imported_state, 0) != 0) {
612912Sartem printf ("adt_start_session failed %d\n", errno);
622912Sartem return;
632912Sartem }
642912Sartem if ((event = adt_alloc_event(ah, event_id)) == NULL) {
652912Sartem printf ("adt_alloc_event(ADT_attach)\n", errno);
662912Sartem return;
672912Sartem }
682912Sartem
692912Sartem switch (event_id) {
702912Sartem case ADT_pool_export:
712912Sartem event->adt_pool_export.auth_used = (char *)auth_used;
722912Sartem event->adt_pool_export.pool = (char *)pool;
732912Sartem event->adt_pool_export.device = (char *)device;
742912Sartem break;
752912Sartem case ADT_pool_import:
762912Sartem event->adt_pool_import.auth_used = (char *)auth_used;
772912Sartem event->adt_pool_import.pool = (char *)pool;
782912Sartem event->adt_pool_import.device = (char *)device;
792912Sartem break;
802912Sartem default:
812912Sartem goto out;
822912Sartem }
832912Sartem
842912Sartem if (result == 0) {
852912Sartem if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
862912Sartem printf ("adt_put_event(%d, success)\n", event_id);
872912Sartem }
882912Sartem } else {
892912Sartem if (adt_put_event(event, ADT_FAILURE, result) != 0) {
902912Sartem printf ("adt_put_event(%d, failure)\n", event_id);
912912Sartem }
922912Sartem }
932912Sartem out:
942912Sartem adt_free_event(event);
952912Sartem (void) adt_end_session(ah);
962912Sartem }
972912Sartem
982912Sartem
992912Sartem void
handle_zpool(LibHalContext * hal_ctx,LibPolKitContext * pol_ctx,char * subcmd,const char * pool,const char * device,const char * invoked_by_uid,const char * invoked_by_syscon_name,DBusConnection * system_bus)1002912Sartem handle_zpool (LibHalContext *hal_ctx,
1012912Sartem #ifdef HAVE_POLKIT
1022912Sartem LibPolKitContext *pol_ctx,
1032912Sartem #endif
1042912Sartem char *subcmd, const char *pool, const char *device,
1052912Sartem const char *invoked_by_uid, const char *invoked_by_syscon_name,
1062912Sartem DBusConnection *system_bus)
1072912Sartem {
1082912Sartem GError *err = NULL;
1092912Sartem char *sout = NULL;
1102912Sartem char *serr = NULL;
1112912Sartem int exit_status = 0;
1122912Sartem char *args[10];
1132912Sartem int na;
1142912Sartem adt_export_data_t *adt_data;
1152912Sartem size_t adt_data_size;
1162912Sartem au_event_t event_id;
1172912Sartem
1182912Sartem #ifdef DEBUG
1192912Sartem printf ("subcmd = %s\n", subcmd);
1202912Sartem printf ("pool = %s\n", pool);
1212912Sartem printf ("device = %s\n", device);
1222912Sartem printf ("invoked by uid = %s\n", invoked_by_uid);
1232912Sartem printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
1242912Sartem #endif
1252912Sartem
1262912Sartem na = 0;
1272912Sartem args[na++] = "/usr/sbin/zpool";
1282912Sartem args[na++] = subcmd;
1292912Sartem if ((strcmp (subcmd, "import") == 0) &&
1302912Sartem (strncmp (device, "/dev/lofi", 9) == 0)) {
1312912Sartem args[na++] = "-d";
1322912Sartem args[na++] = "/dev/lofi";
1332912Sartem }
1342912Sartem args[na++] = (char *) pool;
1352912Sartem args[na++] = NULL;
1362912Sartem
1372912Sartem /* invoke eject command */
1382912Sartem if (!g_spawn_sync ("/",
1392912Sartem args,
1402912Sartem NULL,
1412912Sartem 0,
1422912Sartem NULL,
1432912Sartem NULL,
1442912Sartem &sout,
1452912Sartem &serr,
1462912Sartem &exit_status,
1472912Sartem &err)) {
1482912Sartem printf ("Cannot execute zpool %s\n", subcmd);
1492912Sartem unknown_zpool_error ("Cannot spawn zpool");
1502912Sartem }
1512912Sartem
1522912Sartem if ((adt_data = get_audit_export_data (system_bus,
1532912Sartem invoked_by_syscon_name, &adt_data_size)) != NULL) {
1542912Sartem event_id = (strcmp (subcmd, "import") == 0) ?
1552912Sartem ADT_pool_import : ADT_pool_export;
1562912Sartem audit_pool (adt_data, event_id, WEXITSTATUS(exit_status),
1572912Sartem "solaris.device.mount.removable", pool, device);
1582912Sartem free (adt_data);
1592912Sartem }
1602912Sartem
1612912Sartem if (exit_status != 0) {
1622912Sartem printf ("zpool error %d, stdout='%s', stderr='%s'\n", exit_status, sout, serr);
1632912Sartem
1642912Sartem unknown_zpool_error (serr);
1652912Sartem }
1662912Sartem
1672912Sartem g_free (sout);
1682912Sartem g_free (serr);
1692912Sartem }
1702912Sartem
1712912Sartem
1722912Sartem int
main(int argc,char * argv[])1732912Sartem main (int argc, char *argv[])
1742912Sartem {
1752912Sartem char *udi;
1762912Sartem char *device;
1772912Sartem const char *drive_udi;
1782912Sartem LibHalDrive *drive;
1792912Sartem LibHalVolume *volume;
1802912Sartem DBusError error;
1812912Sartem LibHalContext *hal_ctx = NULL;
1822912Sartem DBusConnection *system_bus = NULL;
1832912Sartem #ifdef HAVE_POLKIT
1842912Sartem LibPolKitContext *pol_ctx = NULL;
1852912Sartem #endif
1862912Sartem char *invoked_by_uid;
1872912Sartem char *invoked_by_syscon_name;
1882912Sartem
1892912Sartem device = getenv ("HAL_PROP_BLOCK_DEVICE");
1902912Sartem if (device == NULL)
1912912Sartem usage ();
1922912Sartem
1932912Sartem udi = getenv ("HAL_PROP_INFO_UDI");
1942912Sartem if (udi == NULL)
1952912Sartem usage ();
1962912Sartem
1972912Sartem invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
1982912Sartem
1992912Sartem invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
2002912Sartem
2012912Sartem dbus_error_init (&error);
2022912Sartem if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
2032912Sartem printf ("Cannot connect to hald\n");
2042912Sartem LIBHAL_FREE_DBUS_ERROR (&error);
2052912Sartem usage ();
2062912Sartem }
2072912Sartem
2082912Sartem dbus_error_init (&error);
2092912Sartem system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
2102912Sartem if (system_bus == NULL) {
2112912Sartem printf ("Cannot connect to the system bus\n");
2122912Sartem LIBHAL_FREE_DBUS_ERROR (&error);
2132912Sartem usage ();
2142912Sartem }
2152912Sartem #ifdef HAVE_POLKIT
2162912Sartem pol_ctx = libpolkit_new_context (system_bus);
2172912Sartem if (pol_ctx == NULL) {
2182912Sartem printf ("Cannot get libpolkit context\n");
2192912Sartem unknown_zpool_error ("Cannot get libpolkit context");
2202912Sartem }
2212912Sartem #endif
2222912Sartem
2232912Sartem /* should be a volume */
2242912Sartem if ((volume = libhal_volume_from_udi (hal_ctx, udi)) == NULL) {
2252912Sartem unknown_zpool_error ("Invalid volume");
2262912Sartem }
2272912Sartem if ((drive_udi = libhal_volume_get_storage_device_udi (volume)) == NULL ) {
2282912Sartem unknown_zpool_error ("Cannot get drive udi");
2292912Sartem }
2302912Sartem if ((drive = libhal_drive_from_udi (hal_ctx, drive_udi)) == NULL) {
2312912Sartem unknown_zpool_error ("Cannot get drive from udi");
2322912Sartem }
2332912Sartem if ((libhal_volume_get_fstype (volume) == NULL) ||
2342912Sartem (strcmp (libhal_volume_get_fstype (volume), "zfs") != 0)) {
2352912Sartem unknown_zpool_error ("Not a zpool");
2362912Sartem }
2372912Sartem if ((libhal_volume_get_label (volume) == NULL) ||
2382912Sartem (strlen (libhal_volume_get_label (volume)) == 0)) {
2392912Sartem unknown_zpool_error ("Invalid zpool name");
2402912Sartem }
2412912Sartem
2422912Sartem handle_zpool (hal_ctx,
2432912Sartem #ifdef HAVE_POLKIT
2442912Sartem pol_ctx,
2452912Sartem #endif
2462912Sartem ZPOOL_SUBCMD,
2472912Sartem libhal_volume_get_label (volume),
2482912Sartem device,
2492912Sartem invoked_by_uid,
2502912Sartem invoked_by_syscon_name,
2512912Sartem system_bus);
2522912Sartem
2532912Sartem return 0;
2542912Sartem }
2552912Sartem
256