]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
bus/containers: Implement methods to stop containers explicitly
authorSimon McVittie <smcv@collabora.com>
Thu, 22 Jun 2017 21:18:34 +0000 (22:18 +0100)
committerSimon McVittie <smcv@collabora.com>
Tue, 12 Dec 2017 16:22:34 +0000 (16:22 +0000)
Signed-off-by: Simon McVittie <smcv@collabora.com>
Reviewed-by: Philip Withnall <withnall@endlessm.com>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=101354

bus/containers.c
bus/containers.h
bus/driver.c
dbus/dbus-protocol.h

index 91806dbe34a7b86560d2600cca8050125c846192..9e81eb08aa1a5ad8c2700d89819054f6d131e1ad 100644 (file)
@@ -38,6 +38,7 @@
 #include "dbus/dbus-sysdeps-unix.h"
 
 #include "connection.h"
+#include "driver.h"
 #include "utils.h"
 
 /*
@@ -786,6 +787,105 @@ bus_containers_supported_arguments_getter (BusContext *context,
          dbus_message_iter_close_container (var_iter, &arr_iter);
 }
 
+dbus_bool_t
+bus_containers_handle_stop_instance (DBusConnection *connection,
+                                     BusTransaction *transaction,
+                                     DBusMessage    *message,
+                                     DBusError      *error)
+{
+  BusContext *context;
+  BusContainers *containers;
+  BusContainerInstance *instance = NULL;
+  DBusList *iter;
+  const char *path;
+
+  if (!dbus_message_get_args (message, error,
+                              DBUS_TYPE_OBJECT_PATH, &path,
+                              DBUS_TYPE_INVALID))
+    goto failed;
+
+  context = bus_transaction_get_context (transaction);
+  containers = bus_context_get_containers (context);
+
+  if (containers->instances_by_path != NULL)
+    {
+      instance = _dbus_hash_table_lookup_string (containers->instances_by_path,
+                                                 path);
+    }
+
+  if (instance == NULL)
+    {
+      dbus_set_error (error, DBUS_ERROR_NOT_CONTAINER,
+                      "There is no container with path '%s'", path);
+      goto failed;
+    }
+
+  bus_container_instance_ref (instance);
+  bus_container_instance_stop_listening (instance);
+
+  for (iter = _dbus_list_get_first_link (&instance->connections);
+       iter != NULL;
+       iter = _dbus_list_get_next_link (&instance->connections, iter))
+    dbus_connection_close (iter->data);
+
+  bus_container_instance_unref (instance);
+
+  if (!bus_driver_send_ack_reply (connection, transaction, message, error))
+    goto failed;
+
+  return TRUE;
+
+failed:
+  _DBUS_ASSERT_ERROR_IS_SET (error);
+  return FALSE;
+}
+
+dbus_bool_t
+bus_containers_handle_stop_listening (DBusConnection *connection,
+                                      BusTransaction *transaction,
+                                      DBusMessage    *message,
+                                      DBusError      *error)
+{
+  BusContext *context;
+  BusContainers *containers;
+  BusContainerInstance *instance = NULL;
+  const char *path;
+
+  if (!dbus_message_get_args (message, error,
+                              DBUS_TYPE_OBJECT_PATH, &path,
+                              DBUS_TYPE_INVALID))
+    goto failed;
+
+  context = bus_transaction_get_context (transaction);
+  containers = bus_context_get_containers (context);
+
+  if (containers->instances_by_path != NULL)
+    {
+      instance = _dbus_hash_table_lookup_string (containers->instances_by_path,
+                                                 path);
+    }
+
+  if (instance == NULL)
+    {
+      dbus_set_error (error, DBUS_ERROR_NOT_CONTAINER,
+                      "There is no container with path '%s'", path);
+      goto failed;
+    }
+
+  bus_container_instance_ref (instance);
+  bus_container_instance_stop_listening (instance);
+  bus_container_instance_unref (instance);
+
+  if (!bus_driver_send_ack_reply (connection, transaction, message, error))
+    goto failed;
+
+  return TRUE;
+
+failed:
+  _DBUS_ASSERT_ERROR_IS_SET (error);
+  return FALSE;
+}
+
 void
 bus_containers_stop_listening (BusContainers *self)
 {
index e51d6ba125ec054803d0a1c174e6e2a914b92852..f3ecf1d4db287a96c5dd4ebe77ffed1072a6b6a6 100644 (file)
@@ -36,6 +36,14 @@ dbus_bool_t bus_containers_handle_add_server          (DBusConnection  *connecti
                                                        BusTransaction  *transaction,
                                                        DBusMessage     *message,
                                                        DBusError       *error);
+dbus_bool_t bus_containers_handle_stop_instance       (DBusConnection  *connection,
+                                                       BusTransaction  *transaction,
+                                                       DBusMessage     *message,
+                                                       DBusError       *error);
+dbus_bool_t bus_containers_handle_stop_listening      (DBusConnection  *connection,
+                                                       BusTransaction  *transaction,
+                                                       DBusMessage     *message,
+                                                       DBusError       *error);
 dbus_bool_t bus_containers_supported_arguments_getter (BusContext      *context,
                                                        DBusMessageIter *var_iter);
 
index 9529b07c6a096c56e3fa4d69c49a7facba176df9..bcf38d05cb10c58a250a70991264211d13441d7d 100644 (file)
@@ -2522,6 +2522,10 @@ static const MessageHandler introspectable_message_handlers[] = {
 static const MessageHandler containers_message_handlers[] = {
   { "AddServer", "ssa{sv}a{sv}", "oays", bus_containers_handle_add_server,
     METHOD_FLAG_PRIVILEGED },
+  { "StopInstance", "o", "", bus_containers_handle_stop_instance,
+    METHOD_FLAG_PRIVILEGED },
+  { "StopListening", "o", "", bus_containers_handle_stop_listening,
+    METHOD_FLAG_PRIVILEGED },
   { NULL, NULL, NULL, NULL }
 };
 static const PropertyHandler containers_property_handlers[] = {
index 933c3658c366ed3a1a5ebaedc7172ee8d39228f9..56be98328e80c6f69935ede1ea8f673832c50137 100644 (file)
@@ -455,6 +455,9 @@ extern "C" {
  * but could have succeeded if an interactive authorization step was
  * allowed. */
 #define DBUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired"
+/** The connection is not from a container, or the specified container instance
+ * does not exist. */
+#define DBUS_ERROR_NOT_CONTAINER "org.freedesktop.DBus.Error.NotContainer"
 
 /* XML introspection format */