static void boot_manager_service_stop_unit_reply (GObject *object,
GAsyncResult *result,
gpointer user_data);
+static gboolean boot_manager_service_handle_kill (BootManager *interface,
+ GDBusMethodInvocation *invocation,
+ const gchar *unit,
+ BootManagerService *service);
+static void boot_manager_service_handle_kill_finish (BootManagerService *service,
+ const gchar *unit,
+ const gchar *result,
+ GError *error,
+ gpointer user_data);
+static void boot_manager_service_kill_unit_reply (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data);
static void boot_manager_service_job_removed (SystemdManager *manager,
guint id,
const gchar *job_name,
/* implement the Stop() method handler */
g_signal_connect (service->interface, "handle-stop",
G_CALLBACK (boot_manager_service_handle_stop), service);
+
+ /* implement the Kill() method handler */
+ g_signal_connect (service->interface, "handle-kill",
+ G_CALLBACK (boot_manager_service_handle_kill), service);
}
if (!systemd_manager_call_start_unit_finish (job->service->systemd_manager,
&job_name, result, &error))
{
- /* there was an error; let the caller now */
+ /* there was an error; let the caller know */
job->callback (job->service, job->unit, "failed", error, job->user_data);
g_error_free (error);
g_free (job_name);
+static gboolean
+boot_manager_service_handle_kill (BootManager *interface,
+ GDBusMethodInvocation *invocation,
+ const gchar *unit,
+ BootManagerService *service)
+{
+ g_return_val_if_fail (IS_BOOT_MANAGER (interface), FALSE);
+ g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);
+ g_return_val_if_fail (unit != NULL, FALSE);
+ g_return_val_if_fail (BOOT_MANAGER_IS_SERVICE (service), FALSE);
+
+ /* ask systemd to kill the unit, send a D-Bus reply in the finish callback */
+ boot_manager_service_kill (service, unit, NULL, boot_manager_service_handle_kill_finish,
+ invocation);
+
+ return TRUE;
+}
+
+
+
+static void
+boot_manager_service_handle_kill_finish (BootManagerService *service,
+ const gchar *unit,
+ const gchar *result,
+ GError *error,
+ gpointer user_data)
+{
+ GDBusMethodInvocation *invocation = G_DBUS_METHOD_INVOCATION (user_data);
+
+ g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
+ g_return_if_fail (unit!= NULL);
+ g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
+
+ /* log any potential errors */
+ if (error != NULL)
+ g_warning ("there was an error: %s", error->message);
+
+ /* report the result back to the boot manager client */
+ boot_manager_complete_kill (service->interface, invocation, result);
+}
+
+
+
+static void
+boot_manager_service_kill_unit_reply (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ BootManagerServiceJob *job = user_data;
+ GError *error = NULL;
+
+ g_return_if_fail (IS_SYSTEMD_MANAGER (object));
+ g_return_if_fail (G_IS_ASYNC_RESULT (result));
+ g_return_if_fail (user_data != NULL);
+
+ /* finish the kill unit call */
+ systemd_manager_call_kill_unit_finish (job->service->systemd_manager,
+ result, &error);
+
+ /* got a reply from systemd; let the caller know we're done */
+ job->callback (job->service, job->unit, (error == NULL) ? "done" : "failed", error,
+ job->user_data);
+ if (error != NULL)
+ g_error_free (error);
+
+ /* finish the job */
+ boot_manager_service_job_unref (job);
+}
+
+
+
static void
boot_manager_service_job_removed (SystemdManager *manager,
guint id,
systemd_manager_call_stop_unit (service->systemd_manager, unit, "fail", cancellable,
boot_manager_service_stop_unit_reply, job);
}
+
+
+
+void
+boot_manager_service_kill (BootManagerService *service,
+ const gchar *unit,
+ GCancellable *cancellable,
+ BootManagerServiceCallback callback,
+ gpointer user_data)
+{
+ BootManagerServiceJob *job;
+
+ g_return_if_fail (BOOT_MANAGER_IS_SERVICE (service));
+ g_return_if_fail (unit != NULL);
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+ g_return_if_fail (callback != NULL);
+
+ /* create a new job object */
+ job = boot_manager_service_job_new (service, unit, cancellable, callback, user_data);
+
+ /* ask systemd to stop the unit asynchronously */
+ systemd_manager_call_kill_unit (service->systemd_manager, unit, "all", "control-group",
+ SIGKILL, cancellable,
+ boot_manager_service_kill_unit_reply, job);
+}