Why an epmd process doesn't exit? - erlang

Is it a bug or a feature that epmd process still exists after I exit from an erlang shell ?

It is quite normal: EPMD is a host daemon process. Its presence is required when one intends to use distributed nodes. It is also useful when just using many nodes on the same machine.

Related

Erlang cluster synchronization issues

I have an erlang cluster of 4 nodes running on different hosts. I recently encountered an issue with the cluster in a way that beam process is running in one of the nodes but the application was not running. I could see that my OTP application was still holding client connections. The client connections are tcp connection.
Every node was able to ping the others but this node appeared to have stopped to other nodes.
Very weird but pretty much the same thing happened. Do you have any clue what might be wrong with them.
Can tcp retransmissions cause this?

Connection attempt from disallowed node 'ejabberdctl-1#localhost'

The title is what appears in my ejabberd log files after an unsuccessful start. I did some googling and have noticed it is probably related to my cookies..
Running get_cookie() in the erlang shell prints 'nocookie'. Is this typical for a fresh install of erlang? How should I ideally go about setting the cookie?
nocookie would likely mean that the node hasn't been started in distributed mode. All distributed nodes otherwise have a cookie.
You will have to make sure your node is started in distributed mode (through -name or -sname arguments) for things to work.
In case the node is already started and you have access to a shell, you can start the distributed kernel by hand with net_kernel:start([Name, shortnames]) or net_kernel:start([Name, longnames]).

Starting the erlang VM without epmd

I'm trying to startup epmd separately from the erlang vm, in order to do monitoring on the connection handling.
This works fine, except for cases when the vm starts up before epmd.
Is there a way to make the erlang vm start without it starting the epmd on its own?
As of Erlang/OTP 19.0, there is a -start_epmd command line option which can be set to true (the default) or false.
If you pass -start_epmd false on the command line and epmd is running, the Erlang node starts as usual. If epmd is not running, the Erlang node fails to start with this message:
$ erl -start_epmd false -sname foo
Protocol 'inet_tcp': register/listen error: econnrefused
If the Erlang node is not started as a distributed node (i.e., without passing -name or -sname), it neither starts nor attempts to connect to epmd, regardless of the -start_epmd setting.
Possible helpful questions/answers:
Is there a way to stop Erlang servers from automatically starting epmd?
Ensure epmd started
So inline with those questions/answers, I'd suggest to make the erlang vm service depend on epmd (which should be another service on its own). Also, if you run epmd as one of your very first services to run, it should be possible to make it start before erlang every time. But how to do this will actually depend on your operating system and deployment implementation details.
Also, a not-so-elegant solution, would be to change your init script, so it will wait for epmd to start, but manually. Your mileage may vary, and a very naive approach (but useful as an example) would be something like:
while [ true ]; do
pid=`pidof epmd`;
if [ "$pid" == "" ]; then
sleep 1; # Wait a bit more
else
break;
fi
done
# Continue initialization
Note that the code should contemplate a maximum number of attempts, also pidof only works on linux, etc. Not sure I like this solution, but can do the job.
And as less elegant solutions, you could replace the epmd that erlang will run with a binary of your own, that does whatever you need (like faking the epmd start or running your own, like in the code above).
Hope it helps!

Simplest way to inform a local erlang node from a shell command

I'm running a distributed erlang system with one node per machine.
Since DNS is not available I all start them with the same -sname param e.g.
erl -sname foo ...
A operating-system daemon has the feature to execute shell (/bin/sh) commands when a certain event occurs (when a USB stick is pugged into the system).
I'm looking for a simple way to call a function on the erlang node local on this machine with this shell command (taking further action after the USB stick was detected and mounted).
I was thinking of calling erl -sname bar from the shell and run some code that looks like
[_,Host] = string:tokens(atom_to_list(node()), "#"),
The_node = list_to_atom("foo#" ++ Host),
spawn(The_node, My_fun),
Is this the way to go? Or is starting a whole new erlang node overkill (won't be doing it often though)
Or is it better to talk a socket opened by gen_tcp, or read a named pipe.
Or any other suggestions?
BTW this is running on a Unix system.
What you want to use is actually erl_call, an application that lets you contact currently distributed nodes and run arbitrary code.
erl_call makes it possible to start and/or communicate with a distributed Erlang node. It is built upon the erl_interface library as an example application. Its purpose is to use an Unix shell script to interact with a distributed Erlang node.
You can either give it commands, an escript or pretty much just code to evaluate and it will do it. You have more details and actual example in its documentation.

How to run pman on a remote node in erlang?

I need debug my ejabberd server and I want use pman for this purpose. But I have only access via ssh and server worked in screen.
I do:
ssh mydoman#example.com
erl -sname test#localhost
(test#localhost)1> pman:start().
<0.123.0>
and it works but I need get access to 'ejabberd#localhost' node from same machine
now I press Ctrl+G
--> r'ejabberd#localhos'
--> c
(ejabberd#localhost)1> pman:start().
** exited: {startup_timeout,pman} **
And my question is - how do I run pman properly?
Pman needs access to the screen on which it runs. I understand that you are running distributed erlang on both nodes and that they are connected and know of each other. The easiest way is then to run pman locally on your node, pman:start(). There is a Nodes menu which should contain all known nodes and if you pick ejabbered#localhost you should see all the processes on that node.
Not sure about pman, but if you want to monitor a remote node I've create entop for that purpose. It might not work exactly like pman but should be close enough.
https://github.com/mazenharake/entop

Resources