środa, 24 października 2012

Still + 1

The latest Wheezy update as of this writing still contains a buggy Xephyr, version xorg-server-1.12.4. The patch

http://patchwork.freedesktop.org/patch/12146/

still needs to be applied. But Xephyr needs to be recompiled with -enable-kdrive-evdev anyway for our purposes, so applying this one-liner won't hurt. Other than that, it works fine.

poniedziałek, 8 października 2012

Too much patch will kill you

In the recent Debian wheezy there is a new Xephyr which has broken options parsing due to a mismerged patch. The bug is fixed by Keith Packard, I will post more soon.


http://lists.debian.org/debian-x/2012/10/msg00071.html


http://patchwork.freedesktop.org/patch/12146/

Looks like the patch is not going to make it soon to Wheezy, so there you go, you can use the patch from freedesktop.

poniedziałek, 24 września 2012

helper-functions

. /etc/default/multiseat

#
# private implementation of get_sect
#
# get given section's contents from the given config file
#
# $1 filename
# $2 section number
#
__get_sect()
{
    cat $1 | awk -v sect=$2 '
    BEGIN {
        SECT="^\\[" sect "\\]"
        NEXT_SECT="^\\[" (sect + 1) "\\]"
    }
    $0 ~ SECT, $0 ~ NEXT_SECT {
        if ($0 ~ SECT)
            next;
        if ($0 ~ NEXT_SECT)
            next;
        if (substr($1, 1, 1) == "#")
            next;
        print
    }
    '
}

#
# private implementation of get_conf
#
# get given key's contents from the given section
# from the given config file
#
# does not work for tables in the config file
#
# $1 filename
# $2 section name
# $3 key name
#
__get_conf()
{
    __get_sect $1 $2 | awk -F"=" -v key=$3 '
    BEGIN {
        KEY=key
    }
    $1==KEY {
        print substr($0, index($0, "=") + 1)
    }
    '
}

#
# private implementation of get_num_seats
#
# get number of seats from the default config file
#
# $1 filename
#
__get_num_seats()
{
    cat $1 | awk '
    BEGIN {
        count=0
    }
    /^\[[0-9]*\]/ {count++}
    END {
        print count - 1
    }
    '
}

#
# get given section's contents from the default config file
#
# $1 section name
#
get_sect()
{
    __get_sect $CONFIG $1
}

#
# private implementation of get_table
#
# $1 filename
# $2 section number
# $3 table name
# $4 size/entry switch [-size => size, <number> for entry]
#
__get_table()
{
    SIZE=0;
    ENTRY=-1

    if [ $4 == "-size" ];
    then
        SIZE=1;
    else
        ENTRY=$4
    fi

    RESULT=`__get_sect $1 $2 | awk -v table=$3 -v get_size=$SIZE -v entry=$ENTRY '
    BEGIN {
        print BEGIn
        TABLE=table "\\\=" "\\\("
        GET_SIZE=get_size
        ENTRY=entry
        size=0
    }
    $0 ~ TABLE, /^\)/ {
        if ($0 ~ TABLE)
            next;
        if ($0 ~ /^\)/)
            next;
        if (substr($1, 1, 1) == "#")
            next;
        if (get_size == 0 && size == entry){
                print
                exit
        }
        size++;
    }
    END {
        if (get_size)
            print size;
    }
    '`
    RESULT=`echo $RESULT | sed 's/^[ \t]*//g'`

    echo $RESULT
}

#
# get given key's contents from the given section
# from the default config file
#
# does not work for tables in the config file
#
# $1 section name
# $2 key name
#
get_conf()
{
    __get_conf $CONFIG $1 $2
}

#
# get number of seats from the default config file
#
get_num_seats()
{
    __get_num_seats $CONFIG
}

#
# get size of a given table in the given section of the config file or
# get specified entry of the table
#
# $1 section number
# $2 table name
# $3 size/entry switch [-size => size, <number> for entry]
#
get_table()
{
    __get_table $CONFIG $1 $2 $3
}

Escape characters alive forever

The multiseat config is never managed once and for ever...

I wanted the scripts to be as little dependent as possible, so for parsing the multiseat.conf file I used only bash&sed&awk, no fancy tools like python. The helper-functions have been written in the mawk dialect of awk, and the awk found in Debian used to be mawk. Alas, no longer. So there are two options to consider: modify the helper-functions, so that mawk is used explicitly instead of awk (and make sure mawk is installed), or modify the helper-functions to speak gnu awk found in Debian now. I chose the second option. In fact only some escaping craziness differs. Instead of one backslash now two or three (!) are required here and there. You can find the new script here.

czwartek, 23 sierpnia 2012

Multiseat - final thoughts (so far)

Now I am happily running an up-to-date Debian Wheezy. However, some precautions must be made when upgrading. I wrote such a script:


#!/bin/bash

SENSITIVE="wmctrl xserver-xephyr lightdm policykit"

PACKAGES=`apt-get --dry-run dist-upgrade | awk '/^The following packages will be upgraded:/,/^[1-9]./' | tail -n +2 | head -n -1`

echo "Searching sensitive packages:"
echo
echo $SENSITIVE
echo
echo "in:"
echo
echo $PACKAGES
echo

FOUND=0

for i in $SENSITIVE; do
    echo $PACKAGES | grep $i 2>&1 >/dev/null && echo Found: $i && FOUND=1
done

if [ $FOUND -eq 0 ]; then
echo No sensitive packages found in upgrade.
fi

The script can be run after apt-get update to see if any of the packages enumerated in "SENSITIVE" are to be upgraded this time. If yes, care must be taken.

Policy kit needs a paragraph of its own. At this moment Debian Wheezy comes with policykit-1 version 0.105. This is the last version in which the actions' permissions are customized using .pkla files. From 0.106 on (0.107 is the latest now) the format and naming of the directories and files has changed.

Another thing is systemd, which one day can become The Right Way of doing things.

USB in multiseat

Here is how I configured my machine in order for users @ multiseat can mount USB drives.

First of all, in modern Debian distributions there is polkit-1. The policy kit infrastructure consists of, among others, a D-BUS service org.freedesktop.PolicyKit1 implemented as /usr/lib/policykit-1/polkitd. The service is used on behalf of user applications wanting to talk to privileged processes, the latter being described by so called actions stored in /usr/share/polkit-1/actions/. Policy kit's job is either to grant permission for an application to talk to a privileged process, or not. Each action, apart from the service it describes, provides default permissions for different kinds of sessions: active sessions, inactive sessions and any kind of sessions. For example, org.freedesktop.udisks.policy file contains descriptions of a number of actions related to disks (like mount/unmount and such).

It turns out, that of the n + 1 X sessions (Xinerama + n seats), only the Xinerama session happens to be ACTIVE. All other sessions, started through Xephyrs, are PASSIVE. And by default PASSIVE sessions are not allowed to mount USB drives, which is expressed by <allow_inactive>no</allow_inactive> in org.freedesktop.udisks.policy. Nor are they allowed to suspend the machine, see org.freedesktop.upower.policy. In different places advice can be found to edit .policy files. Don't! It is not the right way to do it. Instead, create files in /etc/polkit-1/localauthority/50-local.d/. I use the following two:

10-org.freedesktop.upower.pkla:
[Suspend/hibernate permissions]
Identity=unix-group:power
Action=org.freedesktop.upower.suspend
ResultAny=yes
ResultInactive=yes
ResultActive=yes

20-org.freedesktop.udisks.pkla:
[Storage Permissions]
Identity=unix-group:storage
Action=org.freedesktop.udisks.change;org.freedesktop.udisks.drive-detach;org.freedesktop.udisks.drive-eject;org.freedesktop.udisks.filesystem-mount;org.freedesktop.udisks.filesystem-unmount-others
ResultAny=yes
ResultInactive=yes
ResultActive=yes

In order for this setup to work, the users in question must belong to groups power and storage.


I handle mounting USB drives manually, that is, in a file manager drives show up automatically after plugging in, but one of the users (each time it can be a different user) must explicitly mount them for him/herself. In LXDE's pcmanfm->Edit->Preferences->Volume management "Mount removable media automatically when they are inserted" and "Mount mountable volumes automatically on program startup" are unchecked. In other words, the multiseat users must collaborate to decide who mounts the newly inserted USB drive. If it were to happen automatically, the user whose file manager mounts the drive first wins the race. And race is not what we want here.

As you might have noticed, I use LXDE. Gnome-3 looks to heavy. And besides, with Xephyr's lack of GLX support, only the classic appearance is available, so I choose the lighter alternative.

Debian Wheezy - on hard disk

I just wanted to let you know that as of today, 23rd August 2012, I am using the most up-to-date Debian Wheezy with lightdm and LXDE, installed to the hard disk of my computer. It just works.