118c2aff7Sartem /***************************************************************************
218c2aff7Sartem *
318c2aff7Sartem * hal-storage-zpool.c : ZFS pool methods
418c2aff7Sartem *
518c2aff7Sartem * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
618c2aff7Sartem * Use is subject to license terms.
718c2aff7Sartem *
818c2aff7Sartem * Licensed under the Academic Free License version 2.1
918c2aff7Sartem *
1018c2aff7Sartem **************************************************************************/
1118c2aff7Sartem
1218c2aff7Sartem #ifdef HAVE_CONFIG_H
1318c2aff7Sartem # include <config.h>
1418c2aff7Sartem #endif
1518c2aff7Sartem
1618c2aff7Sartem #include <stdio.h>
1718c2aff7Sartem #include <stdlib.h>
1818c2aff7Sartem #include <string.h>
1918c2aff7Sartem #include <glib.h>
2018c2aff7Sartem #include <glib/gstdio.h>
2118c2aff7Sartem #include <sys/types.h>
2218c2aff7Sartem #include <wait.h>
2318c2aff7Sartem #include <unistd.h>
2418c2aff7Sartem #include <bsm/adt.h>
2518c2aff7Sartem #include <bsm/adt_event.h>
2618c2aff7Sartem
2718c2aff7Sartem #include <libhal.h>
2818c2aff7Sartem #include <libhal-storage.h>
2918c2aff7Sartem #ifdef HAVE_POLKIT
3018c2aff7Sartem #include <libpolkit.h>
3118c2aff7Sartem #endif
3218c2aff7Sartem
3318c2aff7Sartem #include "hal-storage-shared.h"
3418c2aff7Sartem
3518c2aff7Sartem static void
usage(void)3618c2aff7Sartem usage (void)
3718c2aff7Sartem {
3818c2aff7Sartem fprintf (stderr, "This program should only be started by hald.\n");
3918c2aff7Sartem exit (1);
4018c2aff7Sartem }
4118c2aff7Sartem
4218c2aff7Sartem
4318c2aff7Sartem void static
unknown_zpool_error(const char * detail)4418c2aff7Sartem unknown_zpool_error (const char *detail)
4518c2aff7Sartem {
4618c2aff7Sartem fprintf (stderr, "org.freedesktop.Hal.Device.Volume.UnknownFailure\n");
4718c2aff7Sartem fprintf (stderr, "%s\n", detail);
4818c2aff7Sartem exit (1);
4918c2aff7Sartem }
5018c2aff7Sartem
5118c2aff7Sartem 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)5218c2aff7Sartem audit_pool(const adt_export_data_t *imported_state, au_event_t event_id,
5318c2aff7Sartem int result, const char *auth_used, const char *pool, const char *device)
5418c2aff7Sartem {
5518c2aff7Sartem adt_session_data_t *ah;
5618c2aff7Sartem adt_event_data_t *event;
5718c2aff7Sartem
5818c2aff7Sartem if (adt_start_session(&ah, imported_state, 0) != 0) {
5918c2aff7Sartem printf ("adt_start_session failed %d\n", errno);
6018c2aff7Sartem return;
6118c2aff7Sartem }
6218c2aff7Sartem if ((event = adt_alloc_event(ah, event_id)) == NULL) {
6318c2aff7Sartem printf ("adt_alloc_event(ADT_attach)\n", errno);
6418c2aff7Sartem return;
6518c2aff7Sartem }
6618c2aff7Sartem
6718c2aff7Sartem switch (event_id) {
6818c2aff7Sartem case ADT_pool_export:
6918c2aff7Sartem event->adt_pool_export.auth_used = (char *)auth_used;
7018c2aff7Sartem event->adt_pool_export.pool = (char *)pool;
7118c2aff7Sartem event->adt_pool_export.device = (char *)device;
7218c2aff7Sartem break;
7318c2aff7Sartem case ADT_pool_import:
7418c2aff7Sartem event->adt_pool_import.auth_used = (char *)auth_used;
7518c2aff7Sartem event->adt_pool_import.pool = (char *)pool;
7618c2aff7Sartem event->adt_pool_import.device = (char *)device;
7718c2aff7Sartem break;
7818c2aff7Sartem default:
7918c2aff7Sartem goto out;
8018c2aff7Sartem }
8118c2aff7Sartem
8218c2aff7Sartem if (result == 0) {
8318c2aff7Sartem if (adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS) != 0) {
8418c2aff7Sartem printf ("adt_put_event(%d, success)\n", event_id);
8518c2aff7Sartem }
8618c2aff7Sartem } else {
8718c2aff7Sartem if (adt_put_event(event, ADT_FAILURE, result) != 0) {
8818c2aff7Sartem printf ("adt_put_event(%d, failure)\n", event_id);
8918c2aff7Sartem }
9018c2aff7Sartem }
9118c2aff7Sartem out:
9218c2aff7Sartem adt_free_event(event);
9318c2aff7Sartem (void) adt_end_session(ah);
9418c2aff7Sartem }
9518c2aff7Sartem
9618c2aff7Sartem
9718c2aff7Sartem 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)98*2a8bcb4eSToomas Soome handle_zpool (LibHalContext *hal_ctx,
9918c2aff7Sartem #ifdef HAVE_POLKIT
100*2a8bcb4eSToomas Soome LibPolKitContext *pol_ctx,
10118c2aff7Sartem #endif
10218c2aff7Sartem char *subcmd, const char *pool, const char *device,
10318c2aff7Sartem const char *invoked_by_uid, const char *invoked_by_syscon_name,
10418c2aff7Sartem DBusConnection *system_bus)
10518c2aff7Sartem {
10618c2aff7Sartem GError *err = NULL;
10718c2aff7Sartem char *sout = NULL;
10818c2aff7Sartem char *serr = NULL;
10918c2aff7Sartem int exit_status = 0;
11018c2aff7Sartem char *args[10];
11118c2aff7Sartem int na;
11218c2aff7Sartem adt_export_data_t *adt_data;
11318c2aff7Sartem size_t adt_data_size;
11418c2aff7Sartem au_event_t event_id;
11518c2aff7Sartem
11618c2aff7Sartem #ifdef DEBUG
11718c2aff7Sartem printf ("subcmd = %s\n", subcmd);
11818c2aff7Sartem printf ("pool = %s\n", pool);
11918c2aff7Sartem printf ("device = %s\n", device);
12018c2aff7Sartem printf ("invoked by uid = %s\n", invoked_by_uid);
12118c2aff7Sartem printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
12218c2aff7Sartem #endif
12318c2aff7Sartem
12418c2aff7Sartem na = 0;
12518c2aff7Sartem args[na++] = "/usr/sbin/zpool";
12618c2aff7Sartem args[na++] = subcmd;
12718c2aff7Sartem if ((strcmp (subcmd, "import") == 0) &&
12818c2aff7Sartem (strncmp (device, "/dev/lofi", 9) == 0)) {
12918c2aff7Sartem args[na++] = "-d";
13018c2aff7Sartem args[na++] = "/dev/lofi";
13118c2aff7Sartem }
13218c2aff7Sartem args[na++] = (char *) pool;
13318c2aff7Sartem args[na++] = NULL;
13418c2aff7Sartem
13518c2aff7Sartem /* invoke eject command */
13618c2aff7Sartem if (!g_spawn_sync ("/",
13718c2aff7Sartem args,
13818c2aff7Sartem NULL,
13918c2aff7Sartem 0,
14018c2aff7Sartem NULL,
14118c2aff7Sartem NULL,
14218c2aff7Sartem &sout,
14318c2aff7Sartem &serr,
14418c2aff7Sartem &exit_status,
14518c2aff7Sartem &err)) {
14618c2aff7Sartem printf ("Cannot execute zpool %s\n", subcmd);
14718c2aff7Sartem unknown_zpool_error ("Cannot spawn zpool");
14818c2aff7Sartem }
14918c2aff7Sartem
15018c2aff7Sartem if ((adt_data = get_audit_export_data (system_bus,
15118c2aff7Sartem invoked_by_syscon_name, &adt_data_size)) != NULL) {
15218c2aff7Sartem event_id = (strcmp (subcmd, "import") == 0) ?
15318c2aff7Sartem ADT_pool_import : ADT_pool_export;
15418c2aff7Sartem audit_pool (adt_data, event_id, WEXITSTATUS(exit_status),
15518c2aff7Sartem "solaris.device.mount.removable", pool, device);
15618c2aff7Sartem free (adt_data);
15718c2aff7Sartem }
15818c2aff7Sartem
15918c2aff7Sartem if (exit_status != 0) {
16018c2aff7Sartem printf ("zpool error %d, stdout='%s', stderr='%s'\n", exit_status, sout, serr);
16118c2aff7Sartem
16218c2aff7Sartem unknown_zpool_error (serr);
16318c2aff7Sartem }
16418c2aff7Sartem
16518c2aff7Sartem g_free (sout);
16618c2aff7Sartem g_free (serr);
16718c2aff7Sartem }
16818c2aff7Sartem
16918c2aff7Sartem
17018c2aff7Sartem int
main(int argc,char * argv[])17118c2aff7Sartem main (int argc, char *argv[])
17218c2aff7Sartem {
17318c2aff7Sartem char *udi;
17418c2aff7Sartem char *device;
17518c2aff7Sartem const char *drive_udi;
17618c2aff7Sartem LibHalDrive *drive;
17718c2aff7Sartem LibHalVolume *volume;
17818c2aff7Sartem DBusError error;
17918c2aff7Sartem LibHalContext *hal_ctx = NULL;
18018c2aff7Sartem DBusConnection *system_bus = NULL;
18118c2aff7Sartem #ifdef HAVE_POLKIT
18218c2aff7Sartem LibPolKitContext *pol_ctx = NULL;
18318c2aff7Sartem #endif
18418c2aff7Sartem char *invoked_by_uid;
18518c2aff7Sartem char *invoked_by_syscon_name;
18618c2aff7Sartem
18718c2aff7Sartem device = getenv ("HAL_PROP_BLOCK_DEVICE");
18818c2aff7Sartem if (device == NULL)
18918c2aff7Sartem usage ();
19018c2aff7Sartem
19118c2aff7Sartem udi = getenv ("HAL_PROP_INFO_UDI");
19218c2aff7Sartem if (udi == NULL)
19318c2aff7Sartem usage ();
19418c2aff7Sartem
19518c2aff7Sartem invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
19618c2aff7Sartem
19718c2aff7Sartem invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
19818c2aff7Sartem
19918c2aff7Sartem dbus_error_init (&error);
20018c2aff7Sartem if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
20118c2aff7Sartem printf ("Cannot connect to hald\n");
20218c2aff7Sartem LIBHAL_FREE_DBUS_ERROR (&error);
20318c2aff7Sartem usage ();
20418c2aff7Sartem }
20518c2aff7Sartem
20618c2aff7Sartem dbus_error_init (&error);
20718c2aff7Sartem system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
20818c2aff7Sartem if (system_bus == NULL) {
20918c2aff7Sartem printf ("Cannot connect to the system bus\n");
21018c2aff7Sartem LIBHAL_FREE_DBUS_ERROR (&error);
21118c2aff7Sartem usage ();
21218c2aff7Sartem }
21318c2aff7Sartem #ifdef HAVE_POLKIT
21418c2aff7Sartem pol_ctx = libpolkit_new_context (system_bus);
21518c2aff7Sartem if (pol_ctx == NULL) {
21618c2aff7Sartem printf ("Cannot get libpolkit context\n");
21718c2aff7Sartem unknown_zpool_error ("Cannot get libpolkit context");
21818c2aff7Sartem }
21918c2aff7Sartem #endif
22018c2aff7Sartem
22118c2aff7Sartem /* should be a volume */
22218c2aff7Sartem if ((volume = libhal_volume_from_udi (hal_ctx, udi)) == NULL) {
22318c2aff7Sartem unknown_zpool_error ("Invalid volume");
22418c2aff7Sartem }
22518c2aff7Sartem if ((drive_udi = libhal_volume_get_storage_device_udi (volume)) == NULL ) {
22618c2aff7Sartem unknown_zpool_error ("Cannot get drive udi");
22718c2aff7Sartem }
22818c2aff7Sartem if ((drive = libhal_drive_from_udi (hal_ctx, drive_udi)) == NULL) {
22918c2aff7Sartem unknown_zpool_error ("Cannot get drive from udi");
23018c2aff7Sartem }
23118c2aff7Sartem if ((libhal_volume_get_fstype (volume) == NULL) ||
23218c2aff7Sartem (strcmp (libhal_volume_get_fstype (volume), "zfs") != 0)) {
23318c2aff7Sartem unknown_zpool_error ("Not a zpool");
23418c2aff7Sartem }
23518c2aff7Sartem if ((libhal_volume_get_label (volume) == NULL) ||
23618c2aff7Sartem (strlen (libhal_volume_get_label (volume)) == 0)) {
23718c2aff7Sartem unknown_zpool_error ("Invalid zpool name");
23818c2aff7Sartem }
23918c2aff7Sartem
24018c2aff7Sartem handle_zpool (hal_ctx,
24118c2aff7Sartem #ifdef HAVE_POLKIT
24218c2aff7Sartem pol_ctx,
24318c2aff7Sartem #endif
24418c2aff7Sartem ZPOOL_SUBCMD,
24518c2aff7Sartem libhal_volume_get_label (volume),
24618c2aff7Sartem device,
24718c2aff7Sartem invoked_by_uid,
24818c2aff7Sartem invoked_by_syscon_name,
24918c2aff7Sartem system_bus);
25018c2aff7Sartem
25118c2aff7Sartem return 0;
25218c2aff7Sartem }
25318c2aff7Sartem
254