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

Pax Displayicus Managerius (or: a proposal on how to get display managers to stop conflicting with each other)



[Please reply to debian-x.]

This will ultimately need to be come a policy proposal.  I will not cover
here why it's a bad thing to have, say, gdm and xdm both trying to manage
display :0 on the local host.  If you're curious, check the Debian X FAQ.

I'd appreciate comments from folks to see if I am overlooking something
important.  I'm also CC'ing Joey Hess because I'm using debconf to
accomplish this and he's the best person to apply the clue stick if I am
abusing it; e.g., using it as a registry.

Here are excerpts from the IRC discussion that led to this.  It was mainly
a discussion between RevKrusty (Ivan E. Moore II, kdm maintainer) and me
(Overfiend, xdm maintainer).

Fellow display manager maintaines: does the following sound reasonable to
you?  This will get most of us out of the ghetto (Priority: extra).

<Overfiend> All we need is a shared template.
<Overfiend> "You have a bunch of display managers installed.  Which one do
you want to manage :0?"  written in newbie-language.
<Overfiend> RK: The user picks which one he wants to run :0.  That's the
easy part.
<Overfiend> The point is to solve this needless package conflict.
<Overfiend> RK: All the dm init scripts look in /etc for a non-conffile
that is created by the .config script in whichever package the user
selected.
<Overfiend> RK: some simple mechanism is used -- such as just having the
package name in this file.  The one that finds its name actually starts the
daemon.
<Overfiend> RK: if somebody wants 1 display manager on each of vt{7,8,9,10}
they can set that up manually; likewise if they want to do XDMCP
<RevKrusty> OF: couldn't we just do something like an alternative and a
common init.d script provided by X...if nothing provides the alternatie it
isn't started...
<Overfiend> RK: I don't see how that is an advantage.  This still allows
each package maintainer a lot of autonomy.
<RevKrusty> hmmm...the debconf way would be easier for the end-user...
<Overfiend> RK: this violates some expectations with respect to init
scripts a little bit, but I think this cure *is* better than the disease.
<Overfiend> RK: all dm's can continue to assume they can manage :0
<Overfiend> RK: But this way, they won't ever contend for it.
<Overfiend> (unless the user deliberately takes the gun to his foot)
<RevKrusty> true...
<bod> the debconf way is only going to work if you can have a shared init
script, and debconf writes /etc/default/display-manager
<aj> Overfiend: make the init scripts say "NOT starting foodm." if they're
not?
<Overfiend> bod: wrong and right.
<bod> probably neater than alternatives
<Overfiend> bod: everybody can still have their own init script, as long as
they follow the rules
<Overfiend> but yes, the .config scripts are going to have to write some
file
<Overfiend> I don't see that there is any need to "source" anything.
<Overfiend> you just cat the file and compare it against a string defined
in your init script
<Overfiend> DAEMON=/usr/bin/X11/xdm
<Overfiend> RK: anyway, most or all of the other *dm guys have ripped off
my init script anyway
<Overfiend> RK: so everyone probably has the DAEMON variable, which is just
itching for this sort of application.
<RevKrusty> OF: hell..mine started out as yours until the kdm upstream
maintainer started hacking on it. :)
<Overfiend> RK: so, are you sold on this idea?
<RevKrusty> OF: sounds good to me.
<Overfiend> Okay.  I'll implement it in xdm for -3 and send mail to other
guys.
<Overfiend> Who all do we have?  me, wdm, gdm, kdm...what about login.app?
<Overfiend> Is there anything else?
<bod> is there a pseudo package?
<aj> could be a virtual package or a metapackage
ð aj suspects the former
<Overfiend> a metapackage would make no sense
<Overfiend> gnome could Depend: gdm | x-display-manager
<Overfiend> kde could Depend: kdm | x-display-manager
<Overfiend> etc.
<RevKrusty> yes..I like x-display-manager...
<Overfiend> RK: this is going to demand Policy
<RevKrusty> it stinks of policy. :)
<Overfiend> because someone who breaks this covenant may nuke someone's
console
<RevKrusty> anything that provides x-display-manager must conform to the
rest of what you described a bit ago...
<Overfiend> RK: more than that.
<Overfiend> RK: anything that DOESN'T provide x-display-manager must be
forbidden from trying to start a local X server
<Overfiend> RK: the more I think about it, the more I think usage of the
full path in /etc/X11/default-display-manager  (or whatever)  would be
better than just the package name
<Overfiend> RK: in case somebody has a display manager in /usr/local, or
something
<RevKrusty> OF: very true.
<Overfiend> RK: okay, I'll write up a draft policy proposal
<Overfiend> RK: us dm maintainers can discuss it, implement it, and then
hand it to -policy as a fait accompli
<Overfiend> RK: I'll provide the code I use for xdm as an appendix to the
draft
<RevKrusty> OF: heh..sounds good.
<Overfiend> RK: an important detail will be to only check the magic init
file when calling the script with the start argument
<Overfiend> RK: e.g., having "if I'm not the default && exit 0" at the top
is BAD
<doogie_> stupid.
<Overfiend> because then /etc/init.d/whatever stop won't work
<doogie_> you can say 'bitch' on tv, but not 'son of a bitch'
<Overfiend> which will make people rightfully angry
<RevKrusty> ahh
<RevKrusty> yea
<Overfiend> RK: also, if that were the case, it might be impossible, or at
least unreasonably difficult, to CHANGE the default with debconf
<Overfiend> RK: because debconf would change the config file and the old
daemon wouldn't be able to stop
<RevKrusty> very good point
<Overfiend> you could stop the old, change the file, and start the new, I
guess that would work.  And is probably the way it should be done anyway.
<Overfiend> But still
<Overfiend> I hate it when an init script won't let me STOP things

I don't have a draft policy proposal yet, but substantially all of it is
covered in the discussion above.  Also, I *do* have some sample code
written, which I am attaching.

The new stuff to implement this putative proposal in the scripts in
prefixed by "###", because I do not want to ship this enabled.

Anthony Towns doesn't seem to think we can't get this accomplished in time
for woody.  Heck, I'll CC him as well to make sure.

-- 
G. Branden Robinson                |       The software said it required
Debian GNU/Linux                   |       Windows 3.1 or better, so I
branden@debian.org                 |       installed Linux.
http://people.debian.org/~branden/ |
Template: shared/default-x-display-manager
Type: select
Choices: ${choices}
Description: Select the desired default display manager.
 A display manager is a program that provides graphical login capabilities
 for the X Window System.
 .
 Only one display manager can manage a given X server, but multiple display
 manager packages are installed.  Please select which display manager
 should run by default.
 .
 (Multiple display managers can run simultaneously if they are configured
 to manage different servers; to achieve this, configure the display
 managers accordingly, edit each of their init scripts in /etc/init.d, and
 disable the check for a default display manager.)

Template: xdm/default_nolisten_udp
Type: note
Description: xdm does not listen on a UDP port by default.
 Because xdm (the X Display Manager) is a daemon that runs with superuser
 privileges, by default it runs with UDP port listening disabled as a security
 measure.  This means that, as shipped, xdm is not reachable via the network
 and is unable to manage X servers running on remote hosts.  Most people do
 not need to enable UDP port listening in xdm; it can manage local X servers
 without this functionality enabled.
 .
 xdm can be configured to manage remote X servers by appropriately editing
 /etc/X11/xdm/Xaccess and /etc/X11/xdm/xdm-config.  See the xdm(1) manual page
 for more information.

Template: xdm/default_servers_100dpi
Type: note
Description: xdm starts X servers using 100 dpi.
 You should be aware that, by default, xdm (the X Display Manager) manages a
 local X server using the "-dpi 100" argument, which forces the X server to
 treat the display as having 100 dots per inch.  This particularly affects the
 visible font size.  Another common default is 75 dpi; some font rasterizers
 do not deal well with dpi settings other than 75 or 100.
 .
 The "-dpi 100" setting can be changed or removed by editing
 /etc/X11/xdm/Xservers.

Template: xdm/default_servers_nolisten_tcp
Type: note
Description: X servers started with xdm do not listen on a TCP port by default.
 Because the X server runs with superuser privileges, by default it operates
 with TCP port listening disabled as a security measure.  This means that, as
 shipped, X servers started with xdm are not reachable via the network and
 will refuse connections from X clients running on remote hosts.   (Outbound
 connections, such as those to X font servers, are not affected; neither are
 sessions tunneled or forwarded with ssh.)
 .
 Many people do not need to enable TCP port listening in their X servers; if
 you do, for instance to display remote X clients to your local X server, you
 can edit /etc/X11/xdm/Xservers to remove the "-nolisten tcp" option.  Note
 that editing this file has no effect on X servers started with startx, xinit,
 or other display managers.
#!/bin/sh
# Debian xdm package configuration script
# Copyright 2000-2001 Branden Robinson.
# Licensed under the GNU General Public License, version 2.  See the file
# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.

set -e

# source debconf library
. /usr/share/debconf/confmodule

THIS_PACKAGE=xdm
DEFAULT_DISPLAY_MANAGER_FILE=/etc/X11/default-display-manager

# set default display manager

###db_get shared/default-x-display-manager
###OLD_DEFAULT="$RET"

###db_metaget shared/default-x-display-manager owners
###OWNERS="$RET"
###db_metaget shared/default-x-display-manager choices
###CHOICES="$RET"
###
###if [ "$OWNERS" != "$CHOICES" ]; then
###  db_subst shared/default-x-display-manager choices $OWNERS
###  db_fset shared/default-x-display-manager isdefault true
###fi
###
###db_input high shared/default-x-display-manager || true
###db_go
###
#### using this display manager?
###db_get shared/default-x-display-manager
###CURRENT_DEFAULT="$RET"
###if [ "$CURRENT_DEFAULT" = "$THIS_PACKAGE" ]; then
  # give 'em the news
  db_input medium xdm/default_nolisten_udp || true
  db_input medium xdm/default_servers_100dpi || true
  db_input medium xdm/default_servers_nolisten_tcp || true
  db_go
###  if [ "$OLD_DEFAULT" != "$CURRENT_DEFAULT" ]; then
###    # remove the default display manager file since we're going to change it
###    rm -f $DEFAULT_DISPLAY_MANAGER_FILE
###  fi
###fi

exit 0

# vim:set ai et sts=2 sw=2 tw=0:
#!/bin/sh
# Debian xdm package post-installation script
# Copyright 1998-2001 Branden Robinson.
# Licensed under the GNU General Public License, version 2.  See the file
# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
# Acknowlegements to Stephen Early, Mark Eichin, and Manoj Srivastava.

set -e

# source debconf library
. /usr/share/debconf/confmodule

THIS_PACKAGE=xdm
THIS_DISPLAY_MANAGER=/usr/bin/X11/xdm
DEFAULT_DISPLAY_MANAGER_FILE=/etc/X11/default-display-manager

#INCLUDE_SHELL_LIB#

trap "message ;\
      message 'Received signal.  Aborting xdm package postinst script.' ;\
      message ;\
      exit 1" 1 2 3 15

check_symlinks_and_bomb /usr/X11R6/lib/X11/xdm

# now safe to remove old xserver dir
if [ -e /usr/X11R6/lib/X11/xdm.moved-by-preinst -a -L /usr/X11R6/lib/X11/xdm ]; then
  rm -r /usr/X11R6/lib/X11/xdm.moved-by-preinst
fi

# deal with a bug in very old versions of xbase
for DIR in rc0.d rc1.d rc6.d; do
  if [ -L /etc/$DIR/K1xdm ]; then
    mv /etc/$DIR/K1xdm /etc/$DIR/K01xdm
  fi
done

#### debconf is not a registry, so we only fiddle with the default file if it
#### does not exist
###if [ ! -e $DEFAULT_DISPLAY_MANAGER_FILE ]; then
###  db_get shared/default-x-display-manager
###  if [ "$RET" = "$THIS_PACKAGE" ]; then
###    if [ "$(cat $DEFAULT_DISPLAY_MANAGER_FILE)" != "$THIS_DISPLAY_MANAGER" ]; then
###    echo "$THIS_DISPLAY_MANAGER" > $DEFAULT_DISPLAY_MANAGER_FILE
###  fi
###fi

NOSTART=
XDM_RUNNING=
# don't start xdm if we are upgrading without stopping it
if [ -e /var/run/xdm.upgrade ]; then
  NOSTART=yes
fi
# or if we're currently in X on the display it attempts to manage by default
for HOSTNAME in "" "localhost" "$(hostname)" "$(hostname -f)"; do
  if echo $DISPLAY | grep -q "^$HOSTNAME:0.*"; then
    NOSTART=yes
  fi
done
# or if it's already running
if start-stop-daemon --stop --quiet --signal 0 --pid /var/run/xdm.pid --exec /usr/bin/X11/xdm; then
  NOSTART=yes
  XDM_RUNNING=yes
fi
# or if the options file says not to
if ! grep -qs ^restart-on-upgrade /etc/X11/xdm/xdm.options; then
  NOSTART=yes
fi

if [ "$XDM_RUNNING" ]; then
  if [ -d /var/state/xdm ]; then
    message "Note: obsolete directory /var/state/xdm cannot be removed" \
            "because xdm is still running.  Reinstall the xdm package" \
            "(or remove the directory manually) when xdm is not running."
  fi
else
  if [ -d /var/state/xdm ]; then
    rm -r /var/state/xdm
  fi
fi

update-rc.d xdm defaults 99 01 > /dev/null 2>&1

[ "$NOSTART" ] || /etc/init.d/xdm start || true

#DEBHELPER#

exit 0

# vim:set ai et sts=2 sw=2 tw=0:
#!/bin/sh
# Debian xdm package pre-removal script
# Copyright 1998-2001 Branden Robinson.
# Licensed under the GNU General Public License, version 2.  See the file
# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
# Acknowlegements to Stephen Early, Mark Eichin, and Manoj Srivastava.

set -e

THIS_PACKAGE=xdm

#INCLUDE_SHELL_LIB#

parseans () {
  if [ ! $1 ]; then
    echo $DEFAULT
  else
    echo $1 | cut -c1 | tr '[A-Z]' '[a-z]';
  fi;
}

trap "message ;\
      message 'Received signal.  Aborting xdm package prerm script.' ;\
      message ;\
      exit 1" 1 3 15

trap "message ;\
      message 'Received keyboard interrupt.  Not stopping xdm daemon.' ;\
      message 'To activate the new version of the xdm daemon, type the' ;\
      message 'command \"/etc/init.d/xdm restart\" at the shell prompt.' ;\
      message ;\
      exit 0" 2

case "$1" in
  # we NEVER want to stop xdm without doing some checks first, see below
  upgrade|failed-upgrade)
    REMOVING=
    ;;
  remove|deconfigure)
    update-alternatives --remove xdm-greeter /usr/X11R6/lib/libXdmGreet.so.1
    rm -f /usr/X11R6/lib/libXdmGreet.so
    REMOVING=yes
    ;;
esac

STOP=
# are we supposed to restart on upgrade?  if REMOVING xdm, we don't care
if grep -qs ^restart-on-upgrade /etc/X11/xdm/xdm.options || [ "$REMOVING" ]; then
  # is there an xdm process running?
  if start-stop-daemon --stop --quiet --signal 0 --exec /usr/bin/X11/xdm; then
    # any children?
    PARENTS=$(pidof /usr/bin/X11/xdm || true)
    CHILDREN=
    for PROCESS in $PARENTS; do
      # make sure we got numbers back
      if ! [ $PROCESS -eq $PROCESS ] 2> /dev/null; then
        # freak out
        errormsg "ERROR: pidof returned non-numeric value!"
      fi
      # we could use grep -q here if ps would ignore SIGPIPE :-P
      if (ps axj | grep "^ *$PROCESS" > /dev/null 2>&1); then
        CHILDREN=yes
      fi
    done
    if [ "$CHILDREN" ]; then
      message "WARNING: Preparing to stop X display manager (xdm) daemon, " \
              "and it appears to be managing at least one running X " \
              "session.  If xdm is stopped now, any X sessions it manages " \
              "will be terminated.  Otherwise you may leave xdm running, " \
              "and the new version will take effect the next time xdm is " \
              "restarted."
      message
      DEFAULT=n
      VALID_ANSWER=
      while [ ! "$VALID_ANSWER" ]; do
        message_nonl "Do you wish to stop the xdm daemon? (y/n) [$DEFAULT] "
        read ANSWER
        ANSWER=$(parseans $ANSWER)
        case "$ANSWER" in
          y) VALID_ANSWER=true; STOP=yes ;;
          n) VALID_ANSWER=true ;;
          *) message "\"$ANSWER\" not understood." ;;
        esac
      done
    else
      STOP=yes
    fi
  fi
fi

if [ "$STOP" ]; then
  /etc/init.d/xdm stop || true
else
  if [ "$1" = "upgrade" -o "$1" = "failed-upgrade" ]; then
    touch /var/run/xdm.upgrade
  fi
fi

###if [ "$1" = "remove" -o "$1" = "deconfigure" ]; then
###  if [ -e /usr/share/debconf/confmodule ]; then
###    . /usr/share/debconf/confmodule
###    # disown this question
###    db_unregister shared/default-x-display-manager
###    # does the question still exist?
###    if db_get shared/default-x-display-manager; then
###      db_metaget shared/default-x-display-manager owners
###      db_subst shared/default-x-display-manager choices "$RET"
###      db_metaget shared/default-x-display-manager value
###      if [ "$THIS_PACKAGE" = "$RET" ]; then
###        db_fset shared/default-x-display-manager isdefault true
###        db_input critical shared/default-x-display-manager || true
###        db_go
###        db_get shared/default-x-display-manager
###        message "Please be sure to run \"dpkg-reconfigure $RET\"."
###      fi
###    fi
###  fi
###fi

#DEBHELPER#

exit 0

# vim:set ai et sts=2 sw=2 tw=0:
#!/bin/sh
# /etc/init.d/xdm: start or stop the X display manager

set -e

# To start xdm even if it is not the default display manager, change
# HEED_DEFAULT_DISPLAY_MANAGER to "false."
HEED_DEFAULT_DISPLAY_MANAGER=true
DEFAULT_DISPLAY_MANAGER_FILE=/etc/X11/default-display-manager

PATH=/bin:/usr/bin:/sbin:/usr/sbin
DAEMON=/usr/bin/X11/xdm
PIDFILE=/var/run/xdm.pid
UPGRADEFILE=/var/run/xdm.upgrade

test -x $DAEMON || exit 0

# If we upgraded the daemon, we can't use the --exec argument to
# start-stop-daemon since the inode will have changed.  The risk here is that
# in a situation where the daemon died, its pidfile was not cleaned up, and
# some other process is now running under that pid, start-stop-daemon will send
# signals to an innocent process.  However, this seems like a corner case.
# C'est la vie!
if [ -e $UPGRADEFILE ]; then
  SSD_ARGS="--pidfile $PIDFILE --startas $DAEMON"
else
  SSD_ARGS="--pidfile $PIDFILE --exec $DAEMON"
fi

stillrunning () {
  if [ "$DAEMON" = "$(cat /proc/$DAEMONPID/cmdline 2> /dev/null)" ]; then
    true
  else
    # if the daemon does not remove its own pidfile, we will
    rm -f $PIDFILE $UPGRADEFILE
    false
  fi;
}

case "$1" in
  start)
###    if [ "$HEED_DEFAULT_DISPLAY_MANAGER" = "true" -a "$(cat $DEFAULT_DISPLAY_MANAGER_FILE)" != "$DAEMON" ]; then
###      echo "Not starting X display manager (xdm); it is not the default display manager."
###    else
      echo -n "Starting X display manager: xdm"
      start-stop-daemon --start --quiet $SSD_ARGS || echo -n " already running"
      echo "."
###    fi
  ;;

  restart)
    /etc/init.d/xdm stop
    if [ -f $PIDFILE ]; then
      if stillrunning; then
        exit 1
      fi
    fi
    /etc/init.d/xdm start
  ;;

  reload)
    echo -n "Reloading X display manager configuration..."
    if start-stop-daemon --stop --signal 1 --quiet $SSD_ARGS; then
      echo "done."
    else
      echo "xdm not running."
    fi
  ;;

  force-reload)
    /etc/init.d/xdm reload
  ;;

  stop)
    echo -n "Stopping X display manager: xdm"
    if [ ! -f $PIDFILE ]; then
      echo " not running ($PIDFILE not found)."
      exit 0
    else
      DAEMONPID=$(cat $PIDFILE | tr -d '[:blank:]')
      KILLCOUNT=1
      if [ ! -e $UPGRADEFILE ]; then
        start-stop-daemon --stop --quiet $SSD_ARGS || echo -n " not running"
      fi
      while [ $KILLCOUNT -le 5 ]; do
        if stillrunning; then
          kill $DAEMONPID
        else
          break
        fi
        sleep 1
        KILLCOUNT=$(expr $KILLCOUNT + 1)
      done
      if stillrunning; then
        echo -n " not responding to TERM signal (pid $DAEMONPID)"
      else
        rm -f $UPGRADEFILE
      fi
    fi
    echo "."
  ;;

  *)
    echo "Usage: /etc/init.d/xdm {start|stop|restart|reload|force-reload}"
    exit 1
    ;;
esac

exit 0

# vim:set ai et sts=2 sw=2 tw=0:

Attachment: pgp68H6uxnQN3.pgp
Description: PGP signature


Reply to: