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 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 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 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 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 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