/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- * * Copyright (C) 2015 Peter Hatina * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include "udisksiscsitypes.h" #include "udisksiscsiutil.h" #include "udiskslinuxiscsisession.h" #include "udiskslinuxiscsisessionobject.h" /** * SECTION:udiskslinuxiscsisession * @title: UDisksLinuxISCSISession * @short_description: Linux implementation of #UDisksISCSISession * * This type provides an implementation of #UDisksISCSISession interface * on Linux. */ /** * UDisksLinuxISCSISession: * * The #UDisksLinuxISCSISession structure contains only private data and * should only be accessed using provided API. */ struct _UDisksLinuxISCSISession { UDisksISCSISessionSkeleton parent_instance; }; struct _UDisksLinuxISCSISessionClass { UDisksISCSISessionSkeletonClass parent_class; }; static void udisks_linux_iscsi_session_iface_init (UDisksISCSISessionIface *iface); G_DEFINE_TYPE_WITH_CODE (UDisksLinuxISCSISession, udisks_linux_iscsi_session, UDISKS_TYPE_ISCSI_SESSION_SKELETON, G_IMPLEMENT_INTERFACE (UDISKS_TYPE_ISCSI_SESSION, udisks_linux_iscsi_session_iface_init)); static void udisks_linux_iscsi_session_class_init (UDisksLinuxISCSISessionClass *klass) { } static void udisks_linux_iscsi_session_init (UDisksLinuxISCSISession *self) { g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (self), G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD); } /** * udisks_linux_iscsi_session_new: * * Creates a new #UDisksLinuxISCSISession instance. * * Returns: A new #UDisksLinuxISCSISession. Free with g_object_unref(). */ UDisksLinuxISCSISession * udisks_linux_iscsi_session_new (void) { return g_object_new (UDISKS_TYPE_LINUX_ISCSI_SESSION, NULL); } /** * udisks_linux_iscsi_session_update: * @session: A #UDisksLinuxISCSISession * @object: The enclosing #UDisksLinuxISCSISessionObject instance. * * Updates the interface. * * Returns: %TRUE if configuration has changed, %FALSE otherwise. */ gboolean udisks_linux_iscsi_session_update (UDisksLinuxISCSISession *session, UDisksLinuxISCSISessionObject *object) { return FALSE; } static gboolean handle_logout_interface (UDisksISCSISession *session, GDBusMethodInvocation *invocation, const gchar *arg_iface, GVariant *arg_options) { UDisksLinuxModuleISCSI *module; UDisksDaemon *daemon; UDisksLinuxISCSISessionObject *object; GError *error = NULL; gchar *errorstr = NULL; gint err; const gchar *name; const gchar *address; guint32 tpgt; guint32 port; object = udisks_daemon_util_dup_object (session, &error); if (! object) { g_dbus_method_invocation_take_error (invocation, error); goto out; } module = udisks_linux_iscsi_session_object_get_module (object); daemon = udisks_module_get_daemon (UDISKS_MODULE (module)); /* Policy check. */ UDISKS_DAEMON_CHECK_AUTHORIZATION (daemon, UDISKS_OBJECT (object), ISCSI_MODULE_POLICY_ACTION_ID, arg_options, N_("Authentication is required to perform iSCSI logout"), invocation); /* Parameters */ name = udisks_iscsi_session_get_target_name (session); address = udisks_iscsi_session_get_address (session); tpgt = udisks_iscsi_session_get_tpgt (session); port = udisks_iscsi_session_get_persistent_port (session); /* Enter a critical section. */ udisks_linux_module_iscsi_lock_libiscsi_context (module); /* Logout */ err = iscsi_logout (module, name, tpgt, address, port, arg_iface, arg_options, &errorstr); /* Leave the critical section. */ udisks_linux_module_iscsi_unlock_libiscsi_context (module); if (err != 0) { /* Logout failed. */ g_dbus_method_invocation_return_error (invocation, UDISKS_ERROR, UDISKS_ERROR_FAILED, N_("Logout failed: %s"), errorstr); goto out; } /* now sit and wait until the device and session disappear on dbus */ if (!udisks_daemon_wait_for_object_to_disappear_sync (daemon, wait_for_iscsi_object, g_strdup (name), g_free, UDISKS_DEFAULT_WAIT_TIMEOUT, &error)) { g_prefix_error (&error, "Error waiting for iSCSI device to disappear: "); g_dbus_method_invocation_take_error (invocation, error); goto out; } if (!udisks_daemon_wait_for_object_to_disappear_sync (daemon, wait_for_iscsi_session_object, g_strdup (name), g_free, UDISKS_DEFAULT_WAIT_TIMEOUT, &error)) { g_prefix_error (&error, "Error waiting for iSCSI session object to disappear: "); g_dbus_method_invocation_take_error (invocation, error); goto out; } /* Complete DBus call. */ udisks_iscsi_session_complete_logout (session, invocation); out: g_clear_object (&object); g_free (errorstr); /* Indicate that we handled the method invocation. */ return TRUE; } static gboolean handle_logout (UDisksISCSISession *object, GDBusMethodInvocation *invocation, GVariant *arg_options) { /* Logout the "default" interface. */ return handle_logout_interface (object, invocation, "default", arg_options); } /* -------------------------------------------------------------------------- */ void udisks_linux_iscsi_session_iface_init (UDisksISCSISessionIface *iface) { iface->handle_logout_interface = handle_logout_interface; iface->handle_logout = handle_logout; }