1
%% ``The contents of this file are subject to the Erlang Public License,
2
%% Version 1.1, (the "License"); you may not use this file except in
3
%% compliance with the License. You should have received a copy of the
4
%% Erlang Public License along with this software. If not, it can be
5
%% retrieved via the world wide web at http://www.erlang.org/.
7
%% Software distributed under the License is distributed on an "AS IS"
8
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
%% the License for the specific language governing rights and limitations
12
%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
%% AB. All Rights Reserved.''
16
%% $Id: mnesia_backup.erl,v 1.1 2008/12/17 09:53:37 mikpe Exp $
20
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22
%% This module contains one implementation of callback functions
23
%% used by Mnesia at backup and restore. The user may however
24
%% write an own module the same interface as mnesia_backup and
25
%% configure Mnesia so the alternate module performs the actual
26
%% accesses to the backup media. This means that the user may put
27
%% the backup on medias that Mnesia does not know about, possibly
28
%% on hosts where Erlang is not running.
30
%% The OpaqueData argument is never interpreted by other parts of
31
%% Mnesia. It is the property of this module. Alternate implementations
32
%% of this module may have different interpretations of OpaqueData.
33
%% The OpaqueData argument given to open_write/1 and open_read/1
34
%% are forwarded directly from the user.
36
%% All functions must return {ok, NewOpaqueData} or {error, Reason}.
38
%% The NewOpaqueData arguments returned by backup callback functions will
39
%% be given as input when the next backup callback function is invoked.
40
%% If any return value does not match {ok, _} the backup will be aborted.
42
%% The NewOpaqueData arguments returned by restore callback functions will
43
%% be given as input when the next restore callback function is invoked
44
%% If any return value does not match {ok, _} the restore will be aborted.
46
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48
-module(mnesia_backup).
49
-behaviour(mnesia_backup).
51
-include_lib("kernel/include/file.hrl").
66
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67
%% Backup callback interface
68
-record(backup, {tmp_file, file, file_desc}).
70
%% Opens backup media for write
72
%% Returns {ok, OpaqueData} or {error, Reason}
73
open_write(OpaqueData) ->
75
Tmp = lists:concat([File,".BUPTMP"]),
78
case disk_log:open([{name, make_ref()},
83
{ok, #backup{tmp_file = Tmp, file = File, file_desc = Fd}};
88
%% Writes BackupItems to the backup media
90
%% Returns {ok, OpaqueData} or {error, Reason}
91
write(OpaqueData, BackupItems) ->
93
case disk_log:log_terms(B#backup.file_desc, BackupItems) of
101
%% Closes the backup media after a successful backup
103
%% Returns {ok, ReturnValueToUser} or {error, Reason}
104
commit_write(OpaqueData) ->
106
case disk_log:sync(B#backup.file_desc) of
108
case disk_log:close(B#backup.file_desc) of
110
case file:rename(B#backup.tmp_file, B#backup.file) of
123
%% Closes the backup media after an interrupted backup
125
%% Returns {ok, ReturnValueToUser} or {error, Reason}
126
abort_write(BackupRef) ->
127
Res = disk_log:close(BackupRef#backup.file_desc),
128
file:delete(BackupRef#backup.tmp_file),
131
{ok, BackupRef#backup.file};
136
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
137
%% Restore callback interface
139
-record(restore, {file, file_desc, cont}).
141
%% Opens backup media for read
143
%% Returns {ok, OpaqueData} or {error, Reason}
144
open_read(OpaqueData) ->
146
case file:read_file_info(File) of
149
_FileInfo -> %% file exists
150
case disk_log:open([{file, File},
154
{linkto, self()}]) of
156
{ok, #restore{file = File, file_desc = Fd, cont = start}};
157
{repaired, Fd, _, {badbytes, 0}} ->
158
{ok, #restore{file = File, file_desc = Fd, cont = start}};
159
{repaired, Fd, _, _} ->
160
{ok, #restore{file = File, file_desc = Fd, cont = start}};
166
%% Reads BackupItems from the backup media
168
%% Returns {ok, OpaqueData, BackupItems} or {error, Reason}
170
%% BackupItems == [] is interpreted as eof
173
Fd = R#restore.file_desc,
174
case disk_log:chunk(Fd, R#restore.cont) of
176
{error, {"Possibly truncated", Reason}};
180
read(R#restore{cont = Cont});
181
{Cont, BackupItems} ->
182
{ok, R#restore{cont = Cont}, BackupItems}
185
%% Closes the backup media after restore
187
%% Returns {ok, ReturnValueToUser} or {error, Reason}
188
close_read(OpaqueData) ->
190
case disk_log:close(R#restore.file_desc) of
191
ok -> {ok, R#restore.file};
192
{error, Reason} -> {error, Reason}