Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sd-bus: action on socket close #15879

Closed
rfjakob opened this issue May 21, 2020 · 7 comments
Closed

sd-bus: action on socket close #15879

rfjakob opened this issue May 21, 2020 · 7 comments

Comments

@rfjakob
Copy link
Contributor

rfjakob commented May 21, 2020

Is your feature request related to a problem? Please describe.

I wrote a small daemon for picking up notifications from system services and displaying them as a desktop notification: systembus-notify

When lingering is enabled, systembus-notify stays running when the user logs out. This kills the user d-bus daemon, but systembus-notify does not notice that the socket gets closed. It only notices when it tries to send the next notification.

Describe the solution you'd like

Unblock sd_bus_wait() on socket close and return an error value

Describe alternatives you've considered
Maybe expose the socket close event somehow to sd-event

@poettering
Copy link
Member

Hmm? this is not how this works. dbus-daemon --user runs as service of systemd --user, and thus remains running as long as the service manager itself.

sd-bus actually watches the connection and by default exits the program if gets disconnected (which is controllable with sd_bus_set_close_on_exit()).

Hence, I think there must be a misunderstanding somewhere?

@rfjakob
Copy link
Contributor Author

rfjakob commented May 21, 2020

Maybe I'm doing something wrong here, but the docs say sd_bus_set_close_on_exit is enabled per default. I see this when I start a new dbus server, attach my client to it, and kill the dbus server:

$ eval "dbus-launch --sh-syntax"
DBUS_SESSION_BUS_ADDRESS='unix:abstract=/tmp/dbus-5VTQPHcfJd,guid=2606200a75d8089fca35d9fd5ec6e905';
export DBUS_SESSION_BUS_ADDRESS;
DBUS_SESSION_BUS_PID=4568;
DBUS_SESSION_BUS_WINDOWID=48234497;

$ strace ./systembus-notify
[...]
epoll_wait(5, 

When I now kill the dbus server (pid 4568), nothing happens in strace.

@poettering
Copy link
Member

are you sure it connects to the daemon you started there and not the one --user started?

@rfjakob
Copy link
Contributor Author

rfjakob commented May 21, 2020

No, and it was the wrong one. That eval line I used was missing the backticks. But now I am sure, and this looks better:

epoll_wait(5, 

### kill dbus daemon from other terminal ###

[{EPOLLIN|EPOLLHUP, {u32=16883984, u64=16883984}}], 6, -1) = 1
recvmsg(3, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="", iov_len=24}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_CMSG_CLOEXEC}, MSG_DONTWAIT|MSG_CMSG_CLOEXEC) = 0
gettid()                                = 5157
epoll_ctl(5, EPOLL_CTL_MOD, 3, {0, {u32=16883984, u64=16883984}}) = 0
timerfd_settime(6, TFD_TIMER_ABSTIME, {it_interval={tv_sec=0, tv_nsec=0}, it_value={tv_sec=0, tv_nsec=1}}, NULL) = 0
epoll_wait(5, [{EPOLLHUP, {u32=16883984, u64=16883984}}, {EPOLLIN, {u32=16881872, u64=16881872}}], 6, -1) = 2
read(6, "\1\0\0\0\0\0\0\0", 8)          = 8
epoll_ctl(5, EPOLL_CTL_DEL, 3, NULL)    = 0
close(3)                                = 0
gettid()                                = 5157
epoll_wait(5, 

Ok, so sd-bus notices it. Then I only have missed the way to attach a callback to EPOLLHUP.

@poettering
Copy link
Member

If you want to hook into the disconnection, add a match to the Disconnected signal, as per dbus spec.

I guess we can close this again, right?

@rfjakob rfjakob closed this as completed May 21, 2020
@rfjakob
Copy link
Contributor Author

rfjakob commented May 21, 2020

Yes, thanks!

rfjakob added a commit to rfjakob/systembus-notify that referenced this issue May 21, 2020
It does not make sense to keep running when we
lose connection to one of our dbus connections.

systemd/systemd#15879
@rfjakob
Copy link
Contributor Author

rfjakob commented May 21, 2020

PS: For future reference: the simplest way to react to a disconnect seems to be to call sd_bus_set_exit_on_disconnect(bus, 1).

Docs for sd_bus_set_exit_on_disconnect are not yet at https://www.freedesktop.org/software/systemd/man/sd-bus.html, but already merged in git: https://github.com/systemd/systemd/blob/master/man/sd_bus_set_exit_on_disconnect.xml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants