guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Invoking user shepherd; Was: Re: Defining *user* services in Guix


From: Danny Milosavljevic
Subject: Invoking user shepherd; Was: Re: Defining *user* services in Guix
Date: Sun, 11 Jun 2017 03:29:00 +0200

Hi,

I'm revisiting this topic because I want to have a dbus user bus to be 
available as "${XDG_RUNTIME_DIR}/bus".

> > With the attached patch, it is possibe to use (gnu services herd) to
> > interact with a user shepherd instance.

Nice!  It works!

But while testing it I noticed:

For a real user shepherd, it would be nice if when I logged in twice using the 
same user account (without logging out in-between - so resulting in two 
sessions of that user) it would still only have one shepherd instance for that 
user account in total - and if that instance (and remaining user processes for 
that matter) went away only when I logged out from *all* sessions of that user.

I thought I could fake that by just trying to invoke shepherd on each session 
start and have it fail on the second attempt - but apparently we will happily 
start an infinite number of shepherds for one user.  Is that on purpose?

The relevant place (in shepherd) is:

(define (open-server-socket file-name)
  "Open a socket at FILE-NAME, and listen for connections there."
  (with-fluids ((%default-port-encoding "UTF-8"))
    (let ((sock    (socket PF_UNIX SOCK_STREAM 0))
          (address (make-socket-address AF_UNIX file-name)))
      (false-if-exception (delete-file file-name)) ;  <===== [dannym: WTF.  
Would it be better to try to connect first?]
      (bind sock address)
      (listen sock 10)
      sock)))

Probably not good.

Maybe better:

(define (server-present? file-name)
  "Open a socket at FILE-NAME, and connect to the server, if any.  Return #t if 
that worked."
  (with-fluids ((%default-port-encoding "UTF-8"))
    (let ((sock    (socket PF_UNIX SOCK_STREAM 0))
          (address (make-socket-address AF_UNIX file-name)))
      (false-if-exception (connect sock address))))) ; probably missing a 
"[catch] close".  How to do that best?

(define (open-server-socket file-name)
  "Open a socket at FILE-NAME, and listen for connections there."
  (if (server-present? file-name)
      (exit 0) ; User's shepherd is already running, so let it do its work.
  (with-fluids ((%default-port-encoding "UTF-8"))
    (let ((sock    (socket PF_UNIX SOCK_STREAM 0))
          (address (make-socket-address AF_UNIX file-name)))
      (false-if-exception (delete-file file-name)) ; we could get rid of that 
if we put the shepherd socket into /run/user/xxx (i.e. XDG_RUNTIME_DIR) 
instead, because that's on a tmpfs.  That's also where it's supposed to go 
according to the standard.
      (bind sock address)
      (listen sock 10)
      sock)))

elogind already sends a message to the dbus system bus whenever a user really 
stops or starts (all their sessions closed, one session opened, respectively):

p = "/org/freedesktop/login1/user/_"UID_FMT;
sd_bus_emit_signal(     u->manager->bus,
                        "/org/freedesktop/login1",
                        "org.freedesktop.login1.Manager",
                        new_user ? "UserNew" : "UserRemoved",
                        "uo", (uint32_t) u->uid, p);

I'm trying to find the right place to insert my "dbus-daemon" invocation for 
providing the user bus (note: not session bus)...

At first I thought of hard-coding the "dbus-daemon" invocation somewhere but 
then I thought the option with the most user freedom would be to only invoke 
the user shepherd [and nothing else] when the user logs in - and if he has a 
user service launching "dbus-daemon", good for him...

Should we make a system shepherd service that invokes the user shepherd service 
on behalf of users?  Would that be that safe?

Or should we just expect the user to put a (shepherd with fix) invocation into 
their HOME startup scripts like .xinitrc ?  Note that if we did that there's 
some session-specific stuff in the session's environment that shepherd will 
inherit.  Probably not that bad if invoked early enough.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]