1 /***************************************************************************
3 * hal-storage-zpool.c : ZFS pool methods
5 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
6 * Use is subject to license terms.
8 * Licensed under the Academic Free License version 2.1
10 **************************************************************************/
12 #pragma ident "%Z%%M% %I% %E% SMI"
22 #include <glib/gstdio.h>
23 #include <sys/types.h>
27 #include <bsm/adt_event.h>
30 #include <libhal-storage.h>
32 #include <libpolkit.h>
35 #include "hal-storage-shared.h"
40 fprintf (stderr
, "This program should only be started by hald.\n");
46 unknown_zpool_error (const char *detail
)
48 fprintf (stderr
, "org.freedesktop.Hal.Device.Volume.UnknownFailure\n");
49 fprintf (stderr
, "%s\n", detail
);
54 audit_pool(const adt_export_data_t
*imported_state
, au_event_t event_id
,
55 int result
, const char *auth_used
, const char *pool
, const char *device
)
57 adt_session_data_t
*ah
;
58 adt_event_data_t
*event
;
60 if (adt_start_session(&ah
, imported_state
, 0) != 0) {
61 printf ("adt_start_session failed %d\n", errno
);
64 if ((event
= adt_alloc_event(ah
, event_id
)) == NULL
) {
65 printf ("adt_alloc_event(ADT_attach)\n", errno
);
71 event
->adt_pool_export
.auth_used
= (char *)auth_used
;
72 event
->adt_pool_export
.pool
= (char *)pool
;
73 event
->adt_pool_export
.device
= (char *)device
;
76 event
->adt_pool_import
.auth_used
= (char *)auth_used
;
77 event
->adt_pool_import
.pool
= (char *)pool
;
78 event
->adt_pool_import
.device
= (char *)device
;
85 if (adt_put_event(event
, ADT_SUCCESS
, ADT_SUCCESS
) != 0) {
86 printf ("adt_put_event(%d, success)\n", event_id
);
89 if (adt_put_event(event
, ADT_FAILURE
, result
) != 0) {
90 printf ("adt_put_event(%d, failure)\n", event_id
);
94 adt_free_event(event
);
95 (void) adt_end_session(ah
);
100 handle_zpool (LibHalContext
*hal_ctx
,
102 LibPolKitContext
*pol_ctx
,
104 char *subcmd
, const char *pool
, const char *device
,
105 const char *invoked_by_uid
, const char *invoked_by_syscon_name
,
106 DBusConnection
*system_bus
)
114 adt_export_data_t
*adt_data
;
115 size_t adt_data_size
;
119 printf ("subcmd = %s\n", subcmd
);
120 printf ("pool = %s\n", pool
);
121 printf ("device = %s\n", device
);
122 printf ("invoked by uid = %s\n", invoked_by_uid
);
123 printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name
);
127 args
[na
++] = "/usr/sbin/zpool";
129 if ((strcmp (subcmd
, "import") == 0) &&
130 (strncmp (device
, "/dev/lofi", 9) == 0)) {
132 args
[na
++] = "/dev/lofi";
134 args
[na
++] = (char *) pool
;
137 /* invoke eject command */
138 if (!g_spawn_sync ("/",
148 printf ("Cannot execute zpool %s\n", subcmd
);
149 unknown_zpool_error ("Cannot spawn zpool");
152 if ((adt_data
= get_audit_export_data (system_bus
,
153 invoked_by_syscon_name
, &adt_data_size
)) != NULL
) {
154 event_id
= (strcmp (subcmd
, "import") == 0) ?
155 ADT_pool_import
: ADT_pool_export
;
156 audit_pool (adt_data
, event_id
, WEXITSTATUS(exit_status
),
157 "solaris.device.mount.removable", pool
, device
);
161 if (exit_status
!= 0) {
162 printf ("zpool error %d, stdout='%s', stderr='%s'\n", exit_status
, sout
, serr
);
164 unknown_zpool_error (serr
);
173 main (int argc
, char *argv
[])
177 const char *drive_udi
;
179 LibHalVolume
*volume
;
181 LibHalContext
*hal_ctx
= NULL
;
182 DBusConnection
*system_bus
= NULL
;
184 LibPolKitContext
*pol_ctx
= NULL
;
186 char *invoked_by_uid
;
187 char *invoked_by_syscon_name
;
189 device
= getenv ("HAL_PROP_BLOCK_DEVICE");
193 udi
= getenv ("HAL_PROP_INFO_UDI");
197 invoked_by_uid
= getenv ("HAL_METHOD_INVOKED_BY_UID");
199 invoked_by_syscon_name
= getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
201 dbus_error_init (&error
);
202 if ((hal_ctx
= libhal_ctx_init_direct (&error
)) == NULL
) {
203 printf ("Cannot connect to hald\n");
204 LIBHAL_FREE_DBUS_ERROR (&error
);
208 dbus_error_init (&error
);
209 system_bus
= dbus_bus_get (DBUS_BUS_SYSTEM
, &error
);
210 if (system_bus
== NULL
) {
211 printf ("Cannot connect to the system bus\n");
212 LIBHAL_FREE_DBUS_ERROR (&error
);
216 pol_ctx
= libpolkit_new_context (system_bus
);
217 if (pol_ctx
== NULL
) {
218 printf ("Cannot get libpolkit context\n");
219 unknown_zpool_error ("Cannot get libpolkit context");
223 /* should be a volume */
224 if ((volume
= libhal_volume_from_udi (hal_ctx
, udi
)) == NULL
) {
225 unknown_zpool_error ("Invalid volume");
227 if ((drive_udi
= libhal_volume_get_storage_device_udi (volume
)) == NULL
) {
228 unknown_zpool_error ("Cannot get drive udi");
230 if ((drive
= libhal_drive_from_udi (hal_ctx
, drive_udi
)) == NULL
) {
231 unknown_zpool_error ("Cannot get drive from udi");
233 if ((libhal_volume_get_fstype (volume
) == NULL
) ||
234 (strcmp (libhal_volume_get_fstype (volume
), "zfs") != 0)) {
235 unknown_zpool_error ("Not a zpool");
237 if ((libhal_volume_get_label (volume
) == NULL
) ||
238 (strlen (libhal_volume_get_label (volume
)) == 0)) {
239 unknown_zpool_error ("Invalid zpool name");
242 handle_zpool (hal_ctx
,
247 libhal_volume_get_label (volume
),
250 invoked_by_syscon_name
,