Hi!
Сейчас ищу ошибку в коде backend'а KDM'a (он же вообщем-то XDM).
Имеются странные баги.
С клиента запускаю Xorg -query <IP сервера>.
На сервере запушен KDM.
Всё хорошо работает, появляется KDM greeter, я логинюсь, захожу в KDE.
Чудеса появляются после того, как я выхожу из сессии KDE.
По правилам Xorg должен переподключиться к KDM'у по XDMCP, что он и
делает.
Последовательность установки соединения следующая:
------- --------
| KDM | | Xorg |
------- --------
query
<---------------
willing
---------------->
request
<---------------
accept
---------------->
manage
<---------------
После того, как KDM получает manage, он выполняет XOpenDisplay
(всё это естественно в дочернем процессе).
Так вот, если при первом (успешном) логине XOpenDisplay возвращает
валидный display и затем запускается функция ManageSession (которая
запускает greeter и осуществляет что-то типа "dispatch loop"),
то при втором запуске XOpenDisplay зависает (не возращает управление).
Почему это может происходить???
А затем происходит совсем непонятная вешь - от XOrg'а снова приходит
query! Т.е. происходит новая установка соединения по XDMCP!
А в спецификации протокола XDMCP чётко сказано - при получении manage
убить все активные сессии.
Именно это и делается таким вот кодом в функции manage:
if ((d = FindDisplayByName( name )))
{
Debug( "terminating active session for %s\n", d->name );
StopDisplay( d );
}
Если раскрутить StopDisplay, то станет ясно, что оттуда посылается
SIGTERM дочернему процессу (тот который завис в XOpenDisplay).
Далее всё описанное выполняется в цикле.
И greeter вообще не появляется.
Воспрос - почему происходит второе подключение (при зависшем первом)?
Если обобщить, то получим что имея n-ое зависшее подключение
обязательно получим n+1, которое и прибъёт n-ое на шаге manage.
Также я дебажил код Xorg'а и в нём дошёл до системного вызова read().
Он в то же самое время возвращает -1, errno = ECONNRESET!
Т.е. получает RST сегмент по tcp (tcpdump подтверждает).
Есть идеи?