Экран GNU зависает при попытке подключения

16

У меня есть несколько продолжительных сеансов экрана GNU. Я ssh к коробке, на которой они работают, и запускаю, screen -d -r fooчтобы отсоединить их, если они подключены где-либо еще, а затем прикрепить их в моем текущем окне.

99% времени это работает нормально, но иногда я получаю это:

$ screen -d -r foo
[2430.foo detached.]

... и ничего не происходит; Я не могу вернуться к раковине вообще. Попытка в другом окне делает то же самое, единственное, что я могу сделать, это уничтожить этот сеанс экрана (потеряв все программы, которые в нем работали) и воссоздать его

Почему это происходит? Как я могу избежать этого или восстановить соединение, когда это произойдет?


Редактировать : Мой .screenrc:

startup_message off
defwritelock off
bind q quit
caption always '%{gk}   (%n) %t                   %{y}%d %M %Y :: %c:%s                   %{b}%W%{d}'
screen -t ZSH
autodetach on
shelltitle ZSH
defutf8 on

Редактировать : конец straceжурнала при попытке присоединить:

readlink("/proc/self/fd/0", "/dev/pts/14", 4095) = 11
stat64("/dev/pts/14", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 14), ...}) = 0
stat64("/dev/pts/14", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 14), ...}) = 0
geteuid32()                             = 1000
getegid32()                             = 1000
open("/dev/pts/14", O_RDWR|O_NONBLOCK)  = 3
geteuid32()                             = 1000
getegid32()                             = 1000
close(3)                                = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
umask(0)                                = 022
lstat64("/var/run/screen", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
access("/var/run/screen/S-mrozekma", F_OK) = 0
stat64("/var/run/screen/S-mrozekma", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
umask(022)                              = 0
uname({sys="Linux", node="etudes-2", ...}) = 0
rt_sigaction(SIGHUP, {0x806e520, [], 0}, {SIG_DFL, [], 0}, 8) = 0
geteuid32()                             = 1000
getegid32()                             = 1000
open("/var/run/screen/S-mrozekma", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
getdents(3, /* 6 entries */, 32768)     = 124
stat64("/var/run/screen/S-mrozekma/2386.chat", {st_mode=S_IFIFO|0700, st_size=0, ...}) = 0
geteuid32()                             = 1000
getegid32()                             = 1000
open("/var/run/screen/S-mrozekma/2386.chat", O_WRONLY|O_NONBLOCK) = 4
geteuid32()                             = 1000
getegid32()                             = 1000
fcntl64(4, F_SETFL, O_RDONLY)           = 0
geteuid32()                             = 1000
getegid32()                             = 1000
getdents(3, /* 0 entries */, 32768)     = 0
close(3)                                = 0
geteuid32()                             = 1000
getegid32()                             = 1000
setuid32(1000)                          = 0
setgid32(1000)                          = 0
stat64("/var/run/screen/S-mrozekma/2386.chat", {st_mode=S_IFIFO|0700, st_size=0, ...}) = 0
getpid()                                = 30081
write(4, "\0gsm\4\0\0\0/dev/pts/14\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 12336
Михаил Мрозек
источник
публикация вашего ~ / .screenrc (и, возможно, / etc / screenrc, если он настроен) может быть полезна
user2387
Пожалуйста, опубликуйте выходные данные strace screen -d -r foo(вам может потребоваться сделать не установленную [ug] id копию screenисполняемого файла) и strace -p$(pidof SCREEN)примерно во время неудачного переподключения.
Жиль "ТАК ... перестать быть злым"
@ Жиль Это просто случилось снова; Я добавил straceжурнал. straceНа главном экране процесса показан похожий блок во время write()разговора
Майкл Мрозек
Похоже, это происходит, когда ранее подключенный экран не был отключен надлежащим образом (в этом случае он был подключен к другому компьютеру, который затем потерял сетевое подключение). Возможно, screenвы пытаетесь записать соединение, которого больше не существует?
Майкл Мрозек
Процесс основного экрана (тот, который называется SCREEN) все еще жив? Что он делает ( strace)?
Жиль "ТАК - перестань быть злым"

Ответы:

8

Не уверен, что у меня возникла та же проблема, что и у вас, но иногда у меня схожее поведение экрана каждый раз, когда я случайно отключался от сети.

Через некоторое время (около 10-15 минут) экран снова доступен для повторного подключения. После некоторых расследований я нашел небольшую заметку на странице руководства:

   nonblock [on|off|numsecs]

   Tell  screen  how to deal with user interfaces (displays) that cease to
   accept output. This can happen if a user presses ^S or a TCP/modem con‐
   nection gets cut but no hangup is received. If nonblock is off (this is
   the default) screen waits until the display restarts to accept the out‐
   put.  If  nonblock is on, screen waits until the timeout is reached (on
   is treated as 1s). If the display  still  doesn't  receive  characters,
   screen will consider it "blocked" and stop sending characters to it. If
   at some time it restarts to accept characters, screen will unblock  the
   display and redisplay the updated window contents.

Может быть, это кому-нибудь поможет, потому что это единственная страница о зависаниях экрана после отключения от Google.

порыв
источник
Я не совсем понимаю, как на основе этой записи справочной страницы, но это все исправило для меня. Я установил nonblock 5некоторое время назад, и просто столкнулся с проблемой снова, и через 5 секунд он неожиданно подключился нормально
Майкл Мрозек
6

Возможно, ваш экранный сеанс зависает в ожидании псевдотерминала оболочки, к которой вы последний раз подключали экран. Иногда потерянное соединение оставляет эту оболочку вокруг, и экран должен отключиться, чтобы отключиться от него.

Если вы запустите ls -l /proc/<screen_pid>/fd/<descriptor_of_hung_write>, вы должны увидеть, что это количество пунктов предыдущего сеанса оболочки.

После того, как вы завершите сеанс bash / shell, к которому вы подключились, вы сможете повторно присоединить его.

# ps auwxf|grep -B2 screen
root     23214  0.0  0.0 109304  4016 ?        Ssl  19:13   0:00  \_ sshd: root@pts/6 
root     23566  0.0  0.0 117400  2272 pts/6    Ss   19:13   0:00      \_ -bash
root     10445  0.0  0.0 125156  1156 pts/6    S+   19:23   0:00          \_ screen -ADR MYSCREEN

В этом случае процесс 23214 уничтожения освободит сеанс экрана, и вы можете снова присоединить его.

ZachL
источник
3
Что мне делать, если у него нет родительского процесса?
d33tah
Это помогло мне сегодня, снова убив экран, сделанный sshd! Часы и часы работы сохранены!
user230910
4

Был ли экран обновлен с тех пор, как были запущены эти сеансы экрана?

Я не могу вспомнить точные детали, но я помню, что примерно месяц или три назад apt-get dist-upgradeв моей системе обновлялся экран (до debian sid), и postinst предупреждал меня о несовместимом обновлении. Копия старого экрана была сохранена (где-то в / tmp IIRC) для повторного подключения к старым сеансам, но было рекомендовано убивать и перезапускать их.

Симптомы, о которых вы сообщаете, похожи на те, что я видел, когда случайно попытался подключиться к старому сеансу экрана с новым / usr / bin / screen.

Возможно, это было так, из dpkg.log еще в июне:

2012-06-14 08:11:51 upgrade screen:amd64 4.0.3-14 4.1.0~20120320gitdb59704-2

саз
источник
Эта проблема была исправлена ​​до выпуска Debian 7 Wheezy. Хотя он присутствует в соответствующих выпусках или git-снимках. См. Bugs.debian.org/683228
Аксель
Это случилось со мной сегодня на более старой установке Centos 6. Благодарность!
Майк Эндрюс
Я был просто укушен этим на Gentoo, я обновлял с 4.3 до 4.4.
JLH