I have done almost exactly the same research yesterday evening.

On Thu, Oct 09, 2014 at 09:16:07PM +0100, OmegaPhil wrote:
> It looks like polkit has a hard dependency on systemd as init currently
> - the 'session' being sought goes through
> src/polkit/polkit/polkitunixsession-systemd.c:polkit_unix_session_initable_init,
> which then calls into sd_pid_get_session from the libsystemd0 package.
> This uses the PID of the pkcheck-calling process to read the proc file
> '/proc/<pid>/cgroup' - it looks for a line containing 'systemd', and
> then extracts the 'path', the bit at the end, to get at the session.

It bothers me a bit. As I see this logind has its internal list of
sessions in its memory. On the other hand there is a hierarchy in
/sys/fs/cgroup/systemd which (using some specially formatted names)
codes session names. What happens if they desynchronize (for example
when the logind daemon dies)?

> On my current session, every single process has '/' as this path - in
> libsystemd0/systemd-215/src/shared/cgroup-util.c:cg_path_get_session
> line 1320, this path is explicitly rejected - its checked for and
> '-ENOENT' is returned.

Same here.

> Under a systemd-as-init system, a valid example of a path would be
> '/user.slice/user-1000.slice/session-1.scope'.

I have done an experiment:
/sys/fs/cgroup/systemd/user.slice/user-1000.slice/session-1.scope
echo SHELLPID > 
/sys/fs/cgroup/systemd/user.slice/user-1000.slice/session-1.scope/tasks

Calls to polkit from that shell started working again.

After adding all the gvfs processes to that cgroup (using pgrep and echo
to tasks) I was able to mount a USB drive.

> So far I haven't seen logind factor in here.

The question is: who is responsible for adding my X11 process during its
startup to that specially named cgroup?

There are so many actors. pid eins, cgmanager, logind, lightdm, X11
scripts in /etc/X11, polkit, consolekit and PAM session modules (for
both consolekit and systemd).

One thing that seriously bothers me is that Jos van Wolput has
reported[1] that things started to work again after upgrading polkit
from 0.105-4 to 0.112-2. I really do not want to mess around with
experimental packages, so I have not checked it. But does it use
ConsoleKit again? Or does polkit has anything to do with assigning a
process to that specially named cgroup?

> I can see that polkit used to use ConsoleKit (I was originally
> expecting to be investigating src/polkit/polkitunixsession.c rather
> than the systemd version), I hope next session to turn back time a bit
> and see how this process worked properly under ConsoleKit.

That was a surprise for me as well. I have enabled eavesdropping[2][3]
for the system bus. I have launched dbus-monitors for both system and
session buses but nothing important has been sent through DBus.

ltrace was very helpful in finding out how is the session for a PID
found (partial ltrace output attached).

I also attach two simple programs that can be used to test if we are
able to find the session for a PID. One calls systemd directly, the
second one calls polkit (which currently calls the same systemd
function).


[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=728361#203
[2] https://wiki.ubuntu.com/DebuggingDBus
[3] https://bugs.freedesktop.org/show_bug.cgi?id=80186

-- 
Marcin Szewczyk                       http://wodny.org
mailto:marcin.szewc...@wodny.borg  <- remove b / usuĊ„ b
xmpp:wo...@ubuntu.pl                  xmpp:wo...@jabster.pl
CFLAGS := -Wall

targets := direct-systemd-call polkit-call

all: $(targets)

direct-systemd-call: direct-systemd-call.c
        gcc $(CFLAGS) $< -o $@ $$(pkg-config --cflags --libs libsystemd)

polkit-call: polkit-call.c
        gcc $(CFLAGS) $< -o $@ $$(pkg-config --cflags glib-2.0) $$(pkg-config 
--libs --cflags polkit-agent-1)

clean:
        rm -f $(targets)
#include <stdio.h>
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE
#include <polkitagent/polkitagent.h>
#include <glib-2.0/glib.h>

int main () {
    GError *error = NULL;
    PolkitSubject* session;

    session = polkit_unix_session_new_for_process_sync (getpid (), NULL, &error);
    if (session == NULL) {
        g_warning ("Unable to determine the session we are in: %s", error->message);
        g_error_free (error);
    }

    printf ("subject: %s\n", polkit_subject_to_string (session));

    return 0;
}
                libgobject-2.0.so.0->g_mutex_lock(0x7fa3c42cc6b8, 1, 0x1558e70, 
0x7fff479d9440) = 0
                libgobject-2.0.so.0->g_hash_table_lookup(0x15520c0, 0x1559230, 
4, 4) = 0
                libgobject-2.0.so.0->g_mutex_unlock(0x7fa3c42cc6b8, 0x1559201, 
1, 1) = 1
                libgobject-2.0.so.0->g_free(0, 1, 1, 1) = 0
            <... g_object_new_valist resumed> )  = 0x1559230
            libgio-2.0.so.0->g_type_check_instance_is_a(0x1559230, 0x1559030, 
0x7fff479d9a20, 2) = 1
            libgio-2.0.so.0->g_type_interface_peek(0x1554c80, 0x1559030, 1, 
0x1556258) = 0x1554db0
            libpolkit-gobject-1.so.0->polkit_unix_session_get_type(0x1559230, 
0, 0x7fff479d9a20, 0x1556258) = 0x1558e70
            libpolkit-gobject-1.so.0->g_type_check_instance_cast(0x1559230, 
0x1558e70, 0x7fff479d9a20, 0) = 0x1559230
            libpolkit-gobject-1.so.0->sd_pid_get_session(6781, 0x7fff479d98b0, 
0x1558e70, 1 <unfinished ...>
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
's') = "stuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
'y') = "yzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
's') = "stuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
't') = "tuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
'e') = "efghijklmnopqrstuvwxyzABCDEFGHIJ"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
'm') = "mnopqrstuvwxyzABCDEFGHIJKLMNOPQR"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
'd') = "defghijklmnopqrstuvwxyzABCDEFGHI"...
                libsystemd.so.0->__sprintf_chk(0x7fff479d8fb0, 1, 26, 
0x7fa3c3375111) = 17
                libsystemd.so.0->fopen("/proc/6781/cgroup", "re" <unfinished 
...>
                    libc.so.6->memalign(568, 0x7fa3c3375121, 1, 10) = 0x155c000
                <... fopen resumed> )            = 0x155c000
                libsystemd.so.0->fgets("10:name=systemd:/\n", 2048, 0x155c000) 
= 0x7fff479d9010
                libsystemd.so.0->strchr("10:name=systemd:/", ':') = 
":name=systemd:/"
                libsystemd.so.0->strchr("name=systemd:/", ':') = ":/"
                libsystemd.so.0->strspn("name=systemd", ",") = 0
                libsystemd.so.0->strcspn("name=systemd", ",") = 12
                libsystemd.so.0->memcmp(0x7fff479d9013, 0x7fa3c3375126, 5, 12) 
= 0
                libsystemd.so.0->memcmp(0x7fff479d9018, 0x7fa3c33750f7, 7, 
0x656d616e) = 0
                libsystemd.so.0->__strdup(0x7fff479d9020, 0x7fa3c33750fe, 7, 
0x646d6574 <unfinished ...>
                    libc.so.6->memalign(2, 0x7fa3c33750fe, 0xc0c6, 32) = 
0x155af10
                <... __strdup resumed> )         = 0x155af10
                libsystemd.so.0->fclose(0x155c000 <unfinished ...>
                    libc.so.6->(0x155c000, 0, 0x155c0e0, 0xfbad000c) = 1
                <... fclose resumed> )           = 0
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
's') = "stuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
'y') = "yzABCDEFGHIJKLMNOPQRSTUVWXYZ_"
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
's') = "stuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
't') = "tuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
'e') = "efghijklmnopqrstuvwxyzABCDEFGHIJ"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
'm') = "mnopqrstuvwxyzABCDEFGHIJKLMNOPQR"...
                libsystemd.so.0->strchr("0123456789abcdefghijklmnopqrstuv"..., 
'd') = "defghijklmnopqrstuvwxyzABCDEFGHI"...
                libsystemd.so.0->__sprintf_chk(0x7fff479d8fb0, 1, 26, 
0x7fa3c3375111) = 14
                libsystemd.so.0->fopen("/proc/1/cgroup", "re" <unfinished ...>
                    libc.so.6->memalign(568, 0x7fa3c3375121, 1, 7) = 0x155c000
                <... fopen resumed> )            = 0x155c000
                libsystemd.so.0->fgets("10:name=systemd:/\n", 2048, 0x155c000) 
= 0x7fff479d9010
                libsystemd.so.0->strchr("10:name=systemd:/", ':') = 
":name=systemd:/"
                libsystemd.so.0->strchr("name=systemd:/", ':') = ":/"
                libsystemd.so.0->strspn("name=systemd", ",") = 0
                libsystemd.so.0->strcspn("name=systemd", ",") = 12
                libsystemd.so.0->memcmp(0x7fff479d9013, 0x7fa3c3375126, 5, 12) 
= 0
                libsystemd.so.0->memcmp(0x7fff479d9018, 0x7fa3c33750f7, 7, 
0x656d616e) = 0
                libsystemd.so.0->__strdup(0x7fff479d9020, 0x7fa3c33750fe, 7, 
0x646d6574 <unfinished ...>
                    libc.so.6->memalign(2, 0x7fa3c33750fe, 0xc0c6, 32) = 
0x15548b0
                <... __strdup resumed> )         = 0x15548b0
                libsystemd.so.0->fclose(0x155c000 <unfinished ...>
                    libc.so.6->(0x155c000, 0, 0x155c0e0, 0xfbad000c) = 1
                <... fclose resumed> )           = 0
                libsystemd.so.0->strlen("/")     = 1
                libsystemd.so.0->strlen("/system.slice") = 13
                libsystemd.so.0->free(0x15548b0) = <void>
                libsystemd.so.0->free(0)         = <void>
                libsystemd.so.0->strchrnul(0x155af11, 47, 0x7fa3c3b48630, 0) = 
0x155af11
                libsystemd.so.0->free(0x155af10) = <void>
            <... sd_pid_get_session resumed> )   = 0xfffffffe
            libpolkit-gobject-1.so.0->polkit_error_quark(0, 0xffffffff, 
0x7fa3c3b48628, 0 <unfinished ...>
                
libpolkit-gobject-1.so.0->g_dbus_error_register_error_domain(0x7fa3c465b8af, 
0x7fa3c4862898, 0x7fa3c4861c00, 4 <unfinished ...>
                    libgio-2.0.so.0->g_once_init_enter(0x7fa3c4862898, 
0x7fa3c4862898, 0x7fa3c4861c00, 4 <unfinished ...>
                        libglib-2.0.so.0->pthread_getspecific(0, 
0x7fa3c4862898, 0x7fa3c4861c00, 4) = 0x15515c0
                    <... g_once_init_enter resumed> ) = 1
                    libgio-2.0.so.0->g_quark_from_static_string(0x7fa3c465b8af, 
1, 1, 0x1556350) = 64
                    libgio-2.0.so.0->g_mutex_lock(0x7fa3c46465e0, 0, 
0x7fa3c465b8c8, 0x7fa3c3da3630) = 0
                    libgio-2.0.so.0->g_hash_table_new(0x7fa3c4392c20, 
0x7fa3c4392be0, 0x7fa3c465b8c8, 0x7fa3c3da3630 <unfinished ...>
                        libglib-2.0.so.0->pthread_getspecific(0, 
0x7fa3c4392be0, 0, 0) = 0x15515c0
--
    <... g_log resumed> )                        = 0
    test->g_error_free(0x1556360, 0xffffffff, 0x7fa3c3b48640, 0 <unfinished ...>
        libglib-2.0.so.0->pthread_getspecific(0, 0x1556360, 0x7fa3c3b48628, 0) 
= 0x15515c0
    <... g_error_free resumed> )                 = 0x1556350
    libc.so.6->_dl_find_dso_for_object(0x7fa3c3b47d90, 0x7fa3c3b485a8, 1, 160) 
= 0x7fa3c4c5f7c0
    libpolkit-agent-1.so.0->__cxa_finalize(0x7fa3c4a6d558, 0, 0, 0) = 
0x7fa3c3b4a070
    libpolkit-gobject-1.so.0->__cxa_finalize(0x7fa3c4862800, 0, 0, 0) = 
0x7fa3c3b4a070
    libgio-2.0.so.0->__cxa_finalize(0x7fa3c4644a80, 0, 0, 0) = 0x7fa3c3b4a070
    libgobject-2.0.so.0->__cxa_finalize(0x7fa3c42cc3a0, 0, 0, 0) = 
0x7fa3c3b4a070
    libexpat.so.1->__cxa_finalize(0x7fa3c37a5078, 0, 0, 0) = 0x7fa3c3b4a070
    libsystemd.so.0->__cxa_finalize(0x7fa3c357b000, 0, 0, 0) = 0x7fa3c3b4a070
    libgmodule-2.0.so.0->__cxa_finalize(0x7fa3c3358140, 0, 0, 0) = 
0x7fa3c3b4a070
    libglib-2.0.so.0->__cxa_finalize(0x7fa3c4078680, 0, 0, 0) = 0x7fa3c3b4a070
    libz.so.1->__cxa_finalize(0x7fa3c31541a0, 0, 0, 0) = 0x7fa3c3b4a070
    libselinux.so.1->free(0)                     = <void>
    libselinux.so.1->free(0)                     = <void>
    libselinux.so.1->free(0)                     = <void>
    libselinux.so.1->free(0)                     = <void>
    libselinux.so.1->free(0)                     = <void>
    libselinux.so.1->free(0)                     = <void>
    libselinux.so.1->free(0)                     = <void>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <systemd/sd-login.h>

int main () {
    int retval;
    char *sd_session = NULL;
    retval = sd_pid_get_session (getpid (), &sd_session);
    printf ("sd_pid_get_session: %s\n", strerror (-retval));
    perror ("errno");
    printf ("session: %p \"%s\"\n", sd_session, sd_session);

    return 0;
}

Reply via email to