xref: /titanic_44/usr/src/cmd/hal/tools/hal-storage-zpool.c (revision 92f381329ebf1c2209df9608670666b32b291e05)
1*18c2aff7Sartem /***************************************************************************
2*18c2aff7Sartem  *
3*18c2aff7Sartem  * hal-storage-zpool.c : ZFS pool methods
4*18c2aff7Sartem  *
5*18c2aff7Sartem  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
6*18c2aff7Sartem  * Use is subject to license terms.
7*18c2aff7Sartem  *
8*18c2aff7Sartem  * Licensed under the Academic Free License version 2.1
9*18c2aff7Sartem  *
10*18c2aff7Sartem  **************************************************************************/
11*18c2aff7Sartem 
12*18c2aff7Sartem #pragma ident	"%Z%%M%	%I%	%E% SMI"
13*18c2aff7Sartem 
14*18c2aff7Sartem #ifdef HAVE_CONFIG_H
15*18c2aff7Sartem #  include <config.h>
16*18c2aff7Sartem #endif
17*18c2aff7Sartem 
18*18c2aff7Sartem #include <stdio.h>
19*18c2aff7Sartem #include <stdlib.h>
20*18c2aff7Sartem #include <string.h>
21*18c2aff7Sartem #include <glib.h>
22*18c2aff7Sartem #include <glib/gstdio.h>
23*18c2aff7Sartem #include <sys/types.h>
24*18c2aff7Sartem #include <wait.h>
25*18c2aff7Sartem #include <unistd.h>
26*18c2aff7Sartem #include <bsm/adt.h>
27*18c2aff7Sartem #include <bsm/adt_event.h>
28*18c2aff7Sartem 
29*18c2aff7Sartem #include <libhal.h>
30*18c2aff7Sartem #include <libhal-storage.h>
31*18c2aff7Sartem #ifdef HAVE_POLKIT
32*18c2aff7Sartem #include <libpolkit.h>
33*18c2aff7Sartem #endif
34*18c2aff7Sartem 
35*18c2aff7Sartem #include "hal-storage-shared.h"
36*18c2aff7Sartem 
37*18c2aff7Sartem static void
usage(void)38*18c2aff7Sartem usage (void)
39*18c2aff7Sartem {
40*18c2aff7Sartem 	fprintf (stderr, "This program should only be started by hald.\n");
41*18c2aff7Sartem 	exit (1);
42*18c2aff7Sartem }
43*18c2aff7Sartem 
44*18c2aff7Sartem 
45*18c2aff7Sartem void static
unknown_zpool_error(const char * detail)46*18c2aff7Sartem unknown_zpool_error (const char *detail)
47*18c2aff7Sartem {
48*18c2aff7Sartem 	fprintf (stderr, "org.freedesktop.Hal.Device.Volume.UnknownFailure\n");
49*18c2aff7Sartem 	fprintf (stderr, "%s\n", detail);
50*18c2aff7Sartem 	exit (1);
51*18c2aff7Sartem }
52*18c2aff7Sartem 
53*18c2aff7Sartem 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)54*18c2aff7Sartem audit_pool(const adt_export_data_t *imported_state, au_event_t event_id,
55*18c2aff7Sartem     int result, const char *auth_used, const char *pool, const char *device)
56*18c2aff7Sartem {
57*18c2aff7Sartem 	adt_session_data_t      *ah;
58*18c2aff7Sartem 	adt_event_data_t        *event;
59*18c2aff7Sartem 
60*18c2aff7Sartem 	if (adt_start_session(&ah, imported_state, 0) != 0) {
61*18c2aff7Sartem         	printf ("adt_start_session failed %d\n", errno);
62*18c2aff7Sartem         	return;
63*18c2aff7Sartem 	}
64*18c2aff7Sartem 	if ((event = adt_alloc_event(ah, event_id)) == NULL) {
65*18c2aff7Sartem         	printf ("adt_alloc_event(ADT_attach)\n", errno);
66*18c2aff7Sartem         	return;
67*18c2aff7Sartem 	}
68*18c2aff7Sartem 
69*18c2aff7Sartem 	switch (event_id) {
70*18c2aff7Sartem 	case ADT_pool_export:
71*18c2aff7Sartem 		event->adt_pool_export.auth_used = (char *)auth_used;
72*18c2aff7Sartem 		event->adt_pool_export.pool = (char *)pool;
73*18c2aff7Sartem 		event->adt_pool_export.device = (char *)device;
74*18c2aff7Sartem 		break;
75*18c2aff7Sartem 	case ADT_pool_import:
76*18c2aff7Sartem 		event->adt_pool_import.auth_used = (char *)auth_used;
77*18c2aff7Sartem 		event->adt_pool_import.pool = (char *)pool;
78*18c2aff7Sartem 		event->adt_pool_import.device = (char *)device;
79*18c2aff7Sartem 		break;
80*18c2aff7Sartem 	default:
81*18c2aff7Sartem 		goto out;
82*18c2aff7Sartem 	}
83*18c2aff7Sartem 
84*18c2aff7Sartem 	if (result == 0) {
85*18c2aff7Sartem 		if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
86*18c2aff7Sartem 			printf ("adt_put_event(%d, success)\n", event_id);
87*18c2aff7Sartem 		}
88*18c2aff7Sartem 	} else {
89*18c2aff7Sartem 		if (adt_put_event(event, ADT_FAILURE, result) != 0) {
90*18c2aff7Sartem 			printf ("adt_put_event(%d, failure)\n", event_id);
91*18c2aff7Sartem 		}
92*18c2aff7Sartem 	}
93*18c2aff7Sartem out:
94*18c2aff7Sartem 	adt_free_event(event);
95*18c2aff7Sartem 	(void) adt_end_session(ah);
96*18c2aff7Sartem }
97*18c2aff7Sartem 
98*18c2aff7Sartem 
99*18c2aff7Sartem 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)100*18c2aff7Sartem handle_zpool (LibHalContext *hal_ctx,
101*18c2aff7Sartem #ifdef HAVE_POLKIT
102*18c2aff7Sartem 	      LibPolKitContext *pol_ctx,
103*18c2aff7Sartem #endif
104*18c2aff7Sartem 	      char *subcmd, const char *pool, const char *device,
105*18c2aff7Sartem 	      const char *invoked_by_uid, const char *invoked_by_syscon_name,
106*18c2aff7Sartem 	      DBusConnection *system_bus)
107*18c2aff7Sartem {
108*18c2aff7Sartem 	GError *err = NULL;
109*18c2aff7Sartem 	char *sout = NULL;
110*18c2aff7Sartem 	char *serr = NULL;
111*18c2aff7Sartem 	int exit_status = 0;
112*18c2aff7Sartem 	char *args[10];
113*18c2aff7Sartem 	int na;
114*18c2aff7Sartem 	adt_export_data_t *adt_data;
115*18c2aff7Sartem 	size_t adt_data_size;
116*18c2aff7Sartem 	au_event_t event_id;
117*18c2aff7Sartem 
118*18c2aff7Sartem #ifdef DEBUG
119*18c2aff7Sartem 	printf ("subcmd                           = %s\n", subcmd);
120*18c2aff7Sartem 	printf ("pool                             = %s\n", pool);
121*18c2aff7Sartem 	printf ("device                           = %s\n", device);
122*18c2aff7Sartem 	printf ("invoked by uid                   = %s\n", invoked_by_uid);
123*18c2aff7Sartem 	printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
124*18c2aff7Sartem #endif
125*18c2aff7Sartem 
126*18c2aff7Sartem 	na = 0;
127*18c2aff7Sartem 	args[na++] = "/usr/sbin/zpool";
128*18c2aff7Sartem 	args[na++] = subcmd;
129*18c2aff7Sartem 	if ((strcmp (subcmd, "import") == 0) &&
130*18c2aff7Sartem 	    (strncmp (device, "/dev/lofi", 9) == 0)) {
131*18c2aff7Sartem 		args[na++] = "-d";
132*18c2aff7Sartem 		args[na++] = "/dev/lofi";
133*18c2aff7Sartem 	}
134*18c2aff7Sartem 	args[na++] = (char *) pool;
135*18c2aff7Sartem 	args[na++] = NULL;
136*18c2aff7Sartem 
137*18c2aff7Sartem 	/* invoke eject command */
138*18c2aff7Sartem 	if (!g_spawn_sync ("/",
139*18c2aff7Sartem 			   args,
140*18c2aff7Sartem 			   NULL,
141*18c2aff7Sartem 			   0,
142*18c2aff7Sartem 			   NULL,
143*18c2aff7Sartem 			   NULL,
144*18c2aff7Sartem 			   &sout,
145*18c2aff7Sartem 			   &serr,
146*18c2aff7Sartem 			   &exit_status,
147*18c2aff7Sartem 			   &err)) {
148*18c2aff7Sartem 		printf ("Cannot execute zpool %s\n", subcmd);
149*18c2aff7Sartem 		unknown_zpool_error ("Cannot spawn zpool");
150*18c2aff7Sartem 	}
151*18c2aff7Sartem 
152*18c2aff7Sartem 	if ((adt_data = get_audit_export_data (system_bus,
153*18c2aff7Sartem 	    invoked_by_syscon_name, &adt_data_size)) != NULL) {
154*18c2aff7Sartem 		event_id = (strcmp (subcmd, "import") == 0) ?
155*18c2aff7Sartem 		    ADT_pool_import : ADT_pool_export;
156*18c2aff7Sartem 		audit_pool (adt_data, event_id, WEXITSTATUS(exit_status),
157*18c2aff7Sartem 		    "solaris.device.mount.removable", pool, device);
158*18c2aff7Sartem 		free (adt_data);
159*18c2aff7Sartem 	}
160*18c2aff7Sartem 
161*18c2aff7Sartem 	if (exit_status != 0) {
162*18c2aff7Sartem 		printf ("zpool error %d, stdout='%s', stderr='%s'\n", exit_status, sout, serr);
163*18c2aff7Sartem 
164*18c2aff7Sartem 		unknown_zpool_error (serr);
165*18c2aff7Sartem 	}
166*18c2aff7Sartem 
167*18c2aff7Sartem 	g_free (sout);
168*18c2aff7Sartem 	g_free (serr);
169*18c2aff7Sartem }
170*18c2aff7Sartem 
171*18c2aff7Sartem 
172*18c2aff7Sartem int
main(int argc,char * argv[])173*18c2aff7Sartem main (int argc, char *argv[])
174*18c2aff7Sartem {
175*18c2aff7Sartem 	char *udi;
176*18c2aff7Sartem 	char *device;
177*18c2aff7Sartem 	const char *drive_udi;
178*18c2aff7Sartem 	LibHalDrive *drive;
179*18c2aff7Sartem 	LibHalVolume *volume;
180*18c2aff7Sartem 	DBusError error;
181*18c2aff7Sartem 	LibHalContext *hal_ctx = NULL;
182*18c2aff7Sartem 	DBusConnection *system_bus = NULL;
183*18c2aff7Sartem #ifdef HAVE_POLKIT
184*18c2aff7Sartem 	LibPolKitContext *pol_ctx = NULL;
185*18c2aff7Sartem #endif
186*18c2aff7Sartem 	char *invoked_by_uid;
187*18c2aff7Sartem 	char *invoked_by_syscon_name;
188*18c2aff7Sartem 
189*18c2aff7Sartem 	device = getenv ("HAL_PROP_BLOCK_DEVICE");
190*18c2aff7Sartem 	if (device == NULL)
191*18c2aff7Sartem 		usage ();
192*18c2aff7Sartem 
193*18c2aff7Sartem 	udi = getenv ("HAL_PROP_INFO_UDI");
194*18c2aff7Sartem 	if (udi == NULL)
195*18c2aff7Sartem 		usage ();
196*18c2aff7Sartem 
197*18c2aff7Sartem 	invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
198*18c2aff7Sartem 
199*18c2aff7Sartem 	invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
200*18c2aff7Sartem 
201*18c2aff7Sartem 	dbus_error_init (&error);
202*18c2aff7Sartem 	if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
203*18c2aff7Sartem 		printf ("Cannot connect to hald\n");
204*18c2aff7Sartem 		LIBHAL_FREE_DBUS_ERROR (&error);
205*18c2aff7Sartem 		usage ();
206*18c2aff7Sartem 	}
207*18c2aff7Sartem 
208*18c2aff7Sartem 	dbus_error_init (&error);
209*18c2aff7Sartem 	system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
210*18c2aff7Sartem 	if (system_bus == NULL) {
211*18c2aff7Sartem 		printf ("Cannot connect to the system bus\n");
212*18c2aff7Sartem 		LIBHAL_FREE_DBUS_ERROR (&error);
213*18c2aff7Sartem 		usage ();
214*18c2aff7Sartem 	}
215*18c2aff7Sartem #ifdef HAVE_POLKIT
216*18c2aff7Sartem 	pol_ctx = libpolkit_new_context (system_bus);
217*18c2aff7Sartem 	if (pol_ctx == NULL) {
218*18c2aff7Sartem 		printf ("Cannot get libpolkit context\n");
219*18c2aff7Sartem 		unknown_zpool_error ("Cannot get libpolkit context");
220*18c2aff7Sartem 	}
221*18c2aff7Sartem #endif
222*18c2aff7Sartem 
223*18c2aff7Sartem 	/* should be a volume */
224*18c2aff7Sartem 	if ((volume = libhal_volume_from_udi (hal_ctx, udi)) == NULL) {
225*18c2aff7Sartem 		unknown_zpool_error ("Invalid volume");
226*18c2aff7Sartem 	}
227*18c2aff7Sartem 	if ((drive_udi = libhal_volume_get_storage_device_udi (volume)) == NULL ) {
228*18c2aff7Sartem 		unknown_zpool_error ("Cannot get drive udi");
229*18c2aff7Sartem 	}
230*18c2aff7Sartem 	if ((drive = libhal_drive_from_udi (hal_ctx, drive_udi)) == NULL) {
231*18c2aff7Sartem 		unknown_zpool_error ("Cannot get drive from udi");
232*18c2aff7Sartem 	}
233*18c2aff7Sartem 	if ((libhal_volume_get_fstype (volume) == NULL) ||
234*18c2aff7Sartem 	    (strcmp (libhal_volume_get_fstype (volume), "zfs") != 0)) {
235*18c2aff7Sartem 		unknown_zpool_error ("Not a zpool");
236*18c2aff7Sartem 	}
237*18c2aff7Sartem 	if ((libhal_volume_get_label (volume) == NULL) ||
238*18c2aff7Sartem 	    (strlen (libhal_volume_get_label (volume)) == 0)) {
239*18c2aff7Sartem 		unknown_zpool_error ("Invalid zpool name");
240*18c2aff7Sartem 	}
241*18c2aff7Sartem 
242*18c2aff7Sartem         handle_zpool (hal_ctx,
243*18c2aff7Sartem #ifdef HAVE_POLKIT
244*18c2aff7Sartem 		      pol_ctx,
245*18c2aff7Sartem #endif
246*18c2aff7Sartem                       ZPOOL_SUBCMD,
247*18c2aff7Sartem                       libhal_volume_get_label (volume),
248*18c2aff7Sartem 		      device,
249*18c2aff7Sartem                       invoked_by_uid,
250*18c2aff7Sartem                       invoked_by_syscon_name,
251*18c2aff7Sartem 		      system_bus);
252*18c2aff7Sartem 
253*18c2aff7Sartem 	return 0;
254*18c2aff7Sartem }
255*18c2aff7Sartem 
256