[ejabberd] Possible race condition in mod_muc? (multiple ejabberd nodes)

Talk Erlang talkerlang at gmail.com
Tue Nov 22 12:09:47 MSK 2011

Hello everyone,

I have a vanilla distributed erlang environment with two ejabberd nodes(I guess there could be more but assuming two for simplicity), with Mnesia replication on both.
I think the following piece of code can lead to a race condition if two ejabberd nodes are started at the same time:

load_permanent_rooms(Host, ServerHost, Access, HistorySize, RoomShaper) ->
    case catch mnesia:dirty_select(
                 muc_room, [{#muc_room{name_host = {'_', Host}, _ = '_'},
                             ['$_']}]) of
        {'EXIT', Reason} ->
            ?ERROR_MSG("~p", [Reason]),
        Rs ->
              fun(R) ->
                      {Room, Host} = R#muc_room.name_host,
                      case mnesia:dirty_read(muc_online_room, {Room, Host}) of
                          [] ->
                              {ok, Pid} = mod_muc_room:start(
                              register_room(Host, Room, Pid);

If two nodes start at the same time, they both will probably execute the same code, i.e. read from Mnesia(muc_room, which is a persistent room table) at the same time, and there is a possibility that if the table is empty, might even try to spawn the same mod_muc_room(s) processes.

Should it not be a protected/locked read & write? I imagine the sequence should be somewhat like:
Lock DB --> Read --> Write(if table does not exist) --> Unclock DB.

Please correct me if I'm wrong.

Thanks a lot!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.jabber.ru/pipermail/ejabberd/attachments/20111122/42f1f46d/attachment.html>

More information about the ejabberd mailing list