A tela do GNU congela ao tentar reconectar

16

Eu tenho várias sessões de tela GNU de longa duração. Eu ssh na caixa em que eles estão executando e corro screen -d -r foopara desanexá-los, se estiverem conectados em qualquer outro lugar, e depois os anexo na minha janela atual.

99% do tempo, isso funciona bem, mas às vezes eu entendo:

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

... e nada acontece; Eu não posso voltar para a concha. Tentar em outra janela faz a mesma coisa, a única coisa que posso fazer é destruir a sessão da tela (perdendo todos os programas em execução nela) e recriá-la

Por que isso acontece? Como posso evitá-lo ou reconectar-me com êxito quando isso acontece?


Editar : Meu .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

Editar : o final de um stracelog ao tentar anexar:

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
Michael Mrozek
fonte
publicar a sua ~ / .screenrc (e talvez / etc / screenrc se ele é personalizado) poderia ser útil
user2387
Poste a saída de strace screen -d -r foo(pode ser necessário fazer uma cópia de ID [ screenexecutável ] não definida do executável) e por strace -p$(pidof SCREEN)volta da hora de uma falha na reconexão.
Gilles 'SO- stop be evil'
@Gilles Aconteceu de novo; Eu adicionei o stracelog. straceO processo da tela principal mostra um bloqueio semelhante em uma write()chamada
Michael Mrozek
Parece que acontece quando a tela conectada anteriormente não foi desconectada corretamente (nesse caso, eu a conectei de outro computador que perdeu a conexão de rede). Pode screenestar tentando gravar em uma conexão que não existe mais?
Michael Mrozek
O processo da tela principal (o chamado SCREEN) ainda está vivo? O que está fazendo ( strace)?
Gilles 'SO- stop be evil'

Respostas:

8

Não tenho certeza se tive o mesmo problema que você, mas às vezes tenho o mesmo comportamento de tela toda vez que a rede foi desconectada acidentalmente.

Depois de um tempo (cerca de 10 a 15 minutos), a tela fica disponível novamente para a reconexão. Após algumas investigações, encontrei uma pequena nota na página do manual:

   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.

Pode ser que isso ajude alguém, porque esta é a única página sobre o congelamento da tela após a desconexão que o Google me deu.

pressa
fonte
Eu não entendo exatamente como é baseado nessa entrada da página de manual, mas isso corrigiu isso para mim. Eu definir nonblock 5um tempo atrás, e apenas correu para a questão novamente, e depois de 5 segundos, de repente anexado normalmente
Michael Mrozek
6

Sua sessão de tela provavelmente está travada, aguardando o pseudo-terminal do shell ao qual você se conectou pela última vez. Às vezes, uma conexão perdida deixa esse shell em movimento e a tela precisa expirar para se desconectar dela.

Se você executar ls -l /proc/<screen_pid>/fd/<descriptor_of_hung_write>, deverá ver que são os pontos da sessão anterior do shell.

Depois de encerrar a sessão do bash / shell à qual você se conectou, você poderá se reconectar.

# 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

Nesse caso, o processo de interrupção 23214 libera a sessão de tela e você pode reconectar.

ZachL
fonte
3
O que devo fazer se não tiver um processo pai?
d33tah
Este ajudou para mim hoje, matar o sshd tornou a tela responsiva novamente! Horas e horas de trabalho economizadas!
user230910
4

A tela foi atualizada desde que essas sessões foram iniciadas?

Não me lembro dos detalhes exatos, mas lembro-me de que há um ou três meses, uma apt-get dist-upgradetela atualizada (para debian sid) no meu sistema e o postinst me avisaram sobre uma atualização incompatível. Uma cópia da tela antiga havia sido mantida (em algum lugar sob / tmp IIRC) para permitir a recolocação em sessões antigas, mas recomenda-se matá-las e reiniciá-las.

Os sintomas relatados são parecidos com os que eu vi quando acidentalmente tentei me reconectar a uma sessão de tela antiga com a nova / usr / bin / screen.

Possivelmente foi isso, do dpkg.log em junho:

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

cas
fonte
Este problema foi corrigido antes do lançamento do Debian 7 Wheezy. Embora esteja presente nas versões anteriores do upstream ou nas capturas instantâneas do git. Veja bugs.debian.org/683228
Axel Beckert
Isso aconteceu comigo hoje em uma instalação mais antiga do Centos 6. Obrigado!
Mike Andrews
Eu fui mordido por isso no Gentoo, eu estava atualizando de 4.3 para 4.4.
JLH