V Solarisu 11.4 máme zvláštní problém.
Problém nastává, když je z Perlu spouštěn následující kód
my $emptystring = "";
syswrite STDOUT, $emptystring;
Provedení volání syswrite s prázdnou proměnnou vyvolá, že relace OpenSSH je ukončena 🙁
Problém je pro nás nový a nastal po migraci ze Solaris 11.3 na Solaris 11.4 a OpenSSH 8.1 (u předchozí verze 7.9 problém není)
K této chybě dochází pouze v případě, že výstup je standardní výstup . Pokud je výstup skriptu přesměrován do souboru, vše funguje v pořádku
Pokud je skript trasován pomocí truss
k chybě dochází při write
volejte takto:
23886: write(1, 0x004B6450, 0) = 0
Zobrazené volání zápisu je pro případy, kdy je vše v pořádku, když dojde k chybě, relace je ukončena a výstup krovu je zastaven a na tomto řádku se nezobrazuje vše, co následuje.
Další informace: Testovali jsme binární soubory zkompilované pro Solaris 11.3 a fungují!. Problém tedy zřejmě pochází z naší kompilace, ale zatím nevíme proč…. Pokračovat…
Další informace: Mezi la kompilací není žádný významný rozdíl. Protokoly serveru OpenSSH ukazují, že prázdná hodnota je brána jako EOF , jak můžeme vidět na následujícím obrázku, které ukazují rozdíl mezi OpenSSH s touto chybou a jiným, který se chová správně.
Řádky zobrazující to jsou následující:
debug2: channel 0: read<=0 rfd 16 len 0
debug2: channel 0: read failed
debug2: channel 0: chan_shutdown_read (i0 o0 sock -1 wfd 16 efd -1 [closed])
debug2: channel 0: input open -> drain
debug2: channel 0: ibuf empty
debug2: channel 0: send eof
debug3: send packet: type 96
debug2: channel 0: input drain -> closed
Nějaký nápad?
Přijatá odpověď:
Řešení nalezeno! 🙂 Stručně řečeno, musíme nastavit příznak C PTY_ZEROREAD
ve fázi konfigurace kompilace .
V channels.c
souboru zdrojového kódu můžeme vidět, kde je vyvolána chyba …
#ifndef PTY_ZEROREAD
if (len <= 0) {
#else
if ((!c->isatty && len <= 0) ||
(c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
#endif
debug2("channel %d: read<=0 rfd %d len %zd",
c->self, c->rfd, len);
if (c->type != SSH_CHANNEL_OPEN) {
debug2("channel %d: not open", c->self);
chan_mark_dead(ssh, c);
return -1;
} else {
chan_read_failed(ssh, c);
}
return -1;
}
A můžeme vidět, že příznak kompilace PTY_ZEROREAD
změní způsob zacházení se zprávami s nulovou délkou v terminálech.
Chcete-li problém vyřešit, configure
příkaz musí být proveden s nastaveným příznakem C, jak je znázorněno na posledním řádku následujícího příkazu:
./configure --with-zlib \
--with-pam \
--with-md5-passwords \
CFLAGS="-DPTY_ZEROREAD=1"