-module(mnesia_corrupts_data).
-compile(export_all).

-record(foo, {key, data}).

doit() ->
    %% set up initial db with foo.DCD and foo.DCL,
    %% foo contains records with keys [0,N[
    N = init_db(),
    io:format("Initial DB:\n~s", [os:cmd("ls -l Mnesia.nonode@nohost")]),
    FDs = open_all_available_fds(),
    %% free enough FDs so mnesia can start, but not enough for it
    %% to be able to open foo.DCL
    close_some_fds(FDs),
    check_db(N).

init_db() ->
    ok = mnesia:create_schema([node()]),
    ok = mnesia:start(),
    {atomic, ok} = mnesia:create_table(foo,
				       [{attributes, record_info(fields, foo)},
					{disc_copies, [node()]}]),
    N = create_dcl(0),
    stopped = mnesia:stop(),
    N.

create_dcl(N) ->
    case prim_file:read_file_info("Mnesia.nonode@nohost/foo.DCL") of
	{error, enoent} ->
	    {atomic, ok} =
		mnesia:transaction(fun() -> mnesia:write(#foo{key = N, data = "bar"}) end),
	    create_dcl(N + 1);
	{ok, _} ->
	    io:format("DCL created after ~p records written\n", [N]),
	    N
    end.

check_db(N) ->
    ok = mnesia:start(),
    ok = mnesia:wait_for_tables([foo], 5*1000),
    check_foo(0, N).

check_foo(I, N) when I < N ->
    [{foo, I, "bar"}] = mnesia:dirty_read(foo, I),
    check_foo(I + 1, N);
check_foo(I, N) when I >= N ->
    ok.

open_all_available_fds() ->
    ok = file:write_file("dummy.txt", <<"whatever\n">>),
    open_all_available_fds([], 0).

open_all_available_fds(FDs, N) ->
    case prim_file:open("dummy.txt", [read]) of
	{ok, FD} ->
	    open_all_available_fds([FD | FDs], N + 1);
	{error, emfile} ->
	    io:format("managed to open ~p files\n", [N]),
	    FDs
    end.

close_some_fds([FD1, FD2 | _]) ->
    prim_file:close(FD1),
    prim_file:close(FD2).
