xref: /onnv-gate/usr/src/cmd/hal/tools/hal-storage-zpool.c (revision 2916:ba92c662e4ef)
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