dbus: terminate mechanism daemons after a while

This commit is contained in:
Lennart Poettering 2011-09-03 03:26:58 +02:00
parent 43de46ab92
commit ad740100d1
6 changed files with 137 additions and 18 deletions

11
TODO
View File

@ -7,18 +7,14 @@ Bugfixes:
* make anaconda write timeout=0 for encrypted devices
* fix broken Sockets=syslog-ng.socket packaging
* logind: ensure ACLs are updated on login and logout
* fix CUPS .path unit for globbing
* service: pid file reading after reload doesn't work, since we don't reset the pid variable
* make sure timeouts are applied to Type=oneshot services.
Features:
* when a bus name of a service disappears from the bus make sure to queue further activation requests
* something like ConditionExec= or ExecStartPre= without failure state
* service restart retry configuration
@ -106,7 +102,6 @@ Features:
* move readahead files into /var, look for them with .path units
* teach dbus to activate all services it finds in /etc/systemd/services/org-*.service
* figure out what happened to bluez patch
* support systemd.mask= on the kernel command line.
@ -122,8 +117,6 @@ Features:
* maybe introduce ExecRestartPre=
* Patch systemd-fsck to use -C and pass console fd to it
* configurable jitter for timer events
* timer events with system resume

View File

@ -971,3 +971,77 @@ int generic_print_property(const char *name, DBusMessageIter *iter, bool all) {
return 0;
}
static void release_name_pending_cb(DBusPendingCall *pending, void *userdata) {
DBusMessage *reply;
DBusConnection *bus = userdata;
assert_se(reply = dbus_pending_call_steal_reply(pending));
dbus_message_unref(reply);
dbus_connection_close(bus);
}
void bus_async_unregister_and_exit(DBusConnection *bus, const char *name) {
DBusMessage *m = NULL;
DBusPendingCall *pending = NULL;
assert(bus);
/* We unregister the name here, but we continue to process
* requests, until we get the response for it, so that all
* requests are guaranteed to be processed. */
m = dbus_message_new_method_call(
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS,
"ReleaseName");
if (!m)
goto oom;
if (!dbus_message_append_args(
m,
DBUS_TYPE_STRING,
&name,
DBUS_TYPE_INVALID))
goto oom;
if (!dbus_connection_send_with_reply(bus, m, &pending, -1))
goto oom;
if (!dbus_pending_call_set_notify(pending, release_name_pending_cb, bus, NULL))
goto oom;
dbus_message_unref(m);
dbus_pending_call_unref(pending);
return;
oom:
log_error("Out of memory");
if (pending) {
dbus_pending_call_cancel(pending);
dbus_pending_call_unref(pending);
}
if (m)
dbus_message_unref(m);
}
DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata) {
usec_t *remain_until = userdata;
assert(bus);
assert(m);
assert(remain_until);
/* Everytime we get a new message we reset out timeout */
*remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
if (dbus_message_is_signal(m, DBUS_INTERFACE_LOCAL, "Disconnected"))
dbus_connection_close(bus);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

View File

@ -167,4 +167,8 @@ int bus_iter_get_basic_and_next(DBusMessageIter *iter, int type, void *data, boo
int generic_print_property(const char *name, DBusMessageIter *iter, bool all);
void bus_async_unregister_and_exit(DBusConnection *bus, const char *name);
DBusHandlerResult bus_exit_idle_filter(DBusConnection *bus, DBusMessage *m, void *userdata);
#endif

View File

@ -30,6 +30,7 @@
#include "strv.h"
#include "dbus-common.h"
#include "polkit.h"
#include "def.h"
#define INTERFACE \
" <interface name=\"org.freedesktop.hostname1\">\n" \
@ -85,6 +86,8 @@ static char *data[_PROP_MAX] = {
NULL
};
static usec_t remain_until = 0;
static void free_data(void) {
int p;
@ -518,7 +521,10 @@ static int connect_bus(DBusConnection **_bus) {
goto fail;
}
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL)) {
dbus_connection_set_exit_on_disconnect(bus, FALSE);
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL) ||
!dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) {
log_error("Not enough memory");
r = -ENOMEM;
goto fail;
@ -554,6 +560,7 @@ fail:
int main(int argc, char *argv[]) {
int r;
DBusConnection *bus = NULL;
bool exiting = false;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@ -588,8 +595,17 @@ int main(int argc, char *argv[]) {
if (r < 0)
goto finish;
while (dbus_connection_read_write_dispatch(bus, -1))
;
remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
for (;;) {
if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
break;
if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
exiting = true;
bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1");
}
}
r = 0;

View File

@ -29,6 +29,7 @@
#include "strv.h"
#include "dbus-common.h"
#include "polkit.h"
#include "def.h"
#define INTERFACE \
" <interface name=\"org.freedesktop.locale1\">\n" \
@ -108,6 +109,8 @@ static char *data[_PROP_MAX] = {
NULL
};
static usec_t remain_until = 0;
static void free_data(void) {
int p;
@ -537,7 +540,10 @@ static int connect_bus(DBusConnection **_bus) {
goto fail;
}
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/locale1", &locale_vtable, NULL)) {
dbus_connection_set_exit_on_disconnect(bus, FALSE);
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/locale1", &locale_vtable, NULL) ||
!dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) {
log_error("Not enough memory");
r = -ENOMEM;
goto fail;
@ -573,6 +579,7 @@ fail:
int main(int argc, char *argv[]) {
int r;
DBusConnection *bus = NULL;
bool exiting = false;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@ -604,8 +611,17 @@ int main(int argc, char *argv[]) {
if (r < 0)
goto finish;
while (dbus_connection_read_write_dispatch(bus, -1))
;
remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
for (;;) {
if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
break;
if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
exiting = true;
bus_async_unregister_and_exit(bus, "org.freedesktop.locale1");
}
}
r = 0;

View File

@ -29,6 +29,7 @@
#include "strv.h"
#include "dbus-common.h"
#include "polkit.h"
#include "def.h"
#define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
@ -77,6 +78,8 @@ static char *zone = NULL;
static bool local_rtc = false;
static int use_ntp = -1;
static usec_t remain_until = 0;
static void free_data(void) {
free(zone);
zone = NULL;
@ -788,7 +791,10 @@ static int connect_bus(DBusConnection **_bus) {
goto fail;
}
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/timedate1", &timedate_vtable, NULL)) {
dbus_connection_set_exit_on_disconnect(bus, FALSE);
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/timedate1", &timedate_vtable, NULL) ||
!dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) {
log_error("Not enough memory");
r = -ENOMEM;
goto fail;
@ -824,6 +830,7 @@ fail:
int main(int argc, char *argv[]) {
int r;
DBusConnection *bus = NULL;
bool exiting = false;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@ -861,8 +868,17 @@ int main(int argc, char *argv[]) {
goto finish;
}
while (dbus_connection_read_write_dispatch(bus, -1))
;
remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
for (;;) {
if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
break;
if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
exiting = true;
bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1");
}
}
r = 0;