There's a code snippet in user_drv.erl (lines 92-109) that does the
detection of whether it's possible to spawn things:
server(Pname, Shell) ->
process_flag(trap_exit, true),
case catch open_port({spawn,Pname}, [eof]) of
{'EXIT', _} ->
%% Let's try a dumb user instead
user:start();
Port ->
server1(Port, Port, Shell)
end.
server(Iname, Oname, Shell) ->
process_flag(trap_exit, true),
case catch open_port({spawn,Iname}, [eof]) of
{'EXIT', _} -> %% It might be a dumb terminal lets start dumb user
user:start();
Iport ->
Oport = open_port({spawn,Oname}, [eof]),
server1(Iport, Oport, Shell)
end.
The interesting clauses are the 'user:start()' fallbacks. Basically,
whenever the user_drv cannot spawn the desired port program (Erlang's
tty driver started as 'tty_sl -c -e'), it will fall back to the old
shell by default.
I'm thinking the two valid approaches are those I discussed with Robert
Virding and Andrew Thompson off the mailing list yesterday -- either
have lager not produce output to 'user' when it detects the old shell
(which is what Andrew and Scott ended up going with iirc), or fixing the
old shell the way I mentioned in another post. This would be the
solution where the function that currently blocks the shell is able to
forward output anyway -- something Robert told me he believes it did in
the past.
If the old behaviour was to forward the output and now it's gone (I
haven't checked, but I'm ready to trust Robert on that), then this would
be a regression bug that needs to be fixed by the OTP team (or any
contributor with the time to do it) within user.erl.
Regards,
Fred.
iv> Currently
iv> I've worked around this by forcing a `SHELL=screen` variable in the
iv> boot script and it seems to do the trick, but I don't really like
iv> this approach. Any suggestions?
Ignas, the Expect script that I put in my original/long message to this
list contains a magic workaround. In the case where run_erl (on box A)
is started via SSH from a remote box (call it box B).
If box B uses "ssh -t" to force the allocation of a pseudo-tty on box A
before executing "run_erl", then the problem goes away because the VM
can use the new shell.
If box B uses the ssh defaults, which on (all/most??) platforms does not
force allocation a pty, the problem exists.
Using 'screen' to force allocation of a pty is another hack. Using
"script" would be the same kind of hack. I agree, there's all a bit
disagreeable.
-Scott
On 04/25/2013 07:20 PM, Scott Lystig Fritchie wrote:
>> Ignas Vyšniauskas <bali...@gmail.com> wrote:
>>
>> Currently I've worked around this by forcing a `SHELL=screen`
>> variable in the boot script and it seems to do the trick, but I
>> don't really like this approach. Any suggestions?
[I obviously meant `TERM=screen`.]
> Ignas, the Expect script that I put in my original/long message to
> this list contains a magic workaround. In the case where run_erl
> (on box A) is started via SSH from a remote box (call it box B).
Well, in fact you don't need the whole "ssh and several boxes" setup to
reproduce the problem, I think this works too:
1. Generate a release of some project
2. Start the release pretending to have no tty capabilities: `TERM=
./rel/node/bin/node start`
3. Attach, input something without termination
4. Trigger some logging via `io:format(user, <..>)` (e.g. by lager)
5. Observe processes hanging, rejoice.
> If box B uses "ssh -t" to force the allocation of a pseudo-tty on
> box A before executing "run_erl", then the problem goes away because
> the VM can use the new shell.
Yes, but the problem with that is that it leaves it up to the user/admin
to ensure that the release is started in an environment which claims to
have decent term capabilities, which is something non-obvious and annoying.
After reading a bit, I realise setting TERM *is* essentially the only
way to advertise term capabilities, so I might settle for something like
if [[ -z $TERM || $TERM == "dumb" ]]; then export TERM=screen; done
inside of the release start script, which is hackish, but I think it
prevents the problem from happening regardless of how the node is
started and also has the nice side-effect of proper tab completion and
etc everywhere.
--
Ignas