Skip to content

Commit

Permalink
Implemented CORE-4462 (Make it possible to restore compressed .nbk fi…
Browse files Browse the repository at this point in the history
…les without explicitly decompressing them) for POSIX systems
  • Loading branch information
AlexPeshkoff committed Jun 17, 2014
1 parent 4b000ab commit 685b5f1
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 15 deletions.
2 changes: 2 additions & 0 deletions lang_helpers/gds_codes.ftn
Expand Up @@ -2488,6 +2488,8 @@ C --
PARAMETER (GDS__nbackup_switchd_parameter = 337117255)
INTEGER*4 GDS__nbackup_user_stop
PARAMETER (GDS__nbackup_user_stop = 337117257)
INTEGER*4 GDS__nbackup_deco_parse
PARAMETER (GDS__nbackup_deco_parse = 337117259)
INTEGER*4 GDS__trace_conflict_acts
PARAMETER (GDS__trace_conflict_acts = 337182750)
INTEGER*4 GDS__trace_act_notfound
Expand Down
1 change: 1 addition & 0 deletions lang_helpers/gds_codes.pas
Expand Up @@ -1251,6 +1251,7 @@
gds_nbackup_lostguid_l0bk = 337117251;
gds_nbackup_switchd_parameter = 337117255;
gds_nbackup_user_stop = 337117257;
gds_nbackup_deco_parse = 337117259;
gds_trace_conflict_acts = 337182750;
gds_trace_act_notfound = 337182751;
gds_trace_switch_once = 337182752;
Expand Down
1 change: 1 addition & 0 deletions src/include/gen/codetext.h
Expand Up @@ -1240,6 +1240,7 @@ static const struct {
{"nbackup_lostguid_l0bk", 337117251},
{"nbackup_switchd_parameter", 337117255},
{"nbackup_user_stop", 337117257},
{"nbackup_deco_parse", 337117259},
{"trace_conflict_acts", 337182750},
{"trace_act_notfound", 337182751},
{"trace_switch_once", 337182752},
Expand Down
6 changes: 4 additions & 2 deletions src/include/gen/iberror.h
Expand Up @@ -1274,6 +1274,7 @@ const ISC_STATUS isc_nbackup_err_eofhdr_restdb = 337117250L;
const ISC_STATUS isc_nbackup_lostguid_l0bk = 337117251L;
const ISC_STATUS isc_nbackup_switchd_parameter = 337117255L;
const ISC_STATUS isc_nbackup_user_stop = 337117257L;
const ISC_STATUS isc_nbackup_deco_parse = 337117259L;
const ISC_STATUS isc_trace_conflict_acts = 337182750L;
const ISC_STATUS isc_trace_act_notfound = 337182751L;
const ISC_STATUS isc_trace_switch_once = 337182752L;
Expand All @@ -1285,7 +1286,7 @@ const ISC_STATUS isc_trace_switch_user_only = 337182757L;
const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
const ISC_STATUS isc_err_max = 1229;
const ISC_STATUS isc_err_max = 1230;

#else /* c definitions */

Expand Down Expand Up @@ -2529,6 +2530,7 @@ const ISC_STATUS isc_err_max = 1229;
#define isc_nbackup_lostguid_l0bk 337117251L
#define isc_nbackup_switchd_parameter 337117255L
#define isc_nbackup_user_stop 337117257L
#define isc_nbackup_deco_parse 337117259L
#define isc_trace_conflict_acts 337182750L
#define isc_trace_act_notfound 337182751L
#define isc_trace_switch_once 337182752L
Expand All @@ -2540,7 +2542,7 @@ const ISC_STATUS isc_err_max = 1229;
#define isc_trace_switch_param_miss 337182758L
#define isc_trace_param_act_notcompat 337182759L
#define isc_trace_mandatory_switch_miss 337182760L
#define isc_err_max 1229
#define isc_err_max 1230

#endif

Expand Down
1 change: 1 addition & 0 deletions src/include/gen/msgs.h
Expand Up @@ -1243,6 +1243,7 @@ Data source : @4"}, /* eds_statement */
{337117251, "Cannot get backup guid clumplet from L0 backup"}, /* nbackup_lostguid_l0bk */
{337117255, "Wrong parameter @1 for switch -D, need ON or OFF"}, /* nbackup_switchd_parameter */
{337117257, "Terminated due to user request"}, /* nbackup_user_stop */
{337117259, "Too complex decompress command (> @1 arguments)"}, /* nbackup_deco_parse */
{337182750, "conflicting actions \"@1\" and \"@2\" found"}, /* trace_conflict_acts */
{337182751, "action switch not found"}, /* trace_act_notfound */
{337182752, "switch \"@1\" must be set only once"}, /* trace_switch_once */
Expand Down
1 change: 1 addition & 0 deletions src/include/gen/sql_code.h
Expand Up @@ -1239,6 +1239,7 @@ static const struct {
{337117251, -901}, /* 67 nbackup_lostguid_l0bk */
{337117255, -901}, /* 71 nbackup_switchd_parameter */
{337117257, -901}, /* 73 nbackup_user_stop */
{337117259, -901}, /* 75 nbackup_deco_parse */
{337182750, -901}, /* 30 trace_conflict_acts */
{337182751, -901}, /* 31 trace_act_notfound */
{337182752, -901}, /* 32 trace_switch_once */
Expand Down
1 change: 1 addition & 0 deletions src/include/gen/sql_state.h
Expand Up @@ -1239,6 +1239,7 @@ static const struct {
{337117251, "00000"}, // 67 nbackup_lostguid_l0bk
{337117255, "00000"}, // 71 nbackup_switchd_parameter
{337117257, "08006"}, // 73 nbackup_user_stop
{337117259, "54023"}, // 75 nbackup_deco_parse
{337182750, "00000"}, // 30 trace_conflict_acts
{337182751, "00000"}, // 31 trace_act_notfound
{337182752, "00000"}, // 32 trace_switch_once
Expand Down
2 changes: 1 addition & 1 deletion src/msgs/facilities2.sql
Expand Up @@ -18,7 +18,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM
('2012-05-25 19:59:42', 'GSTAT', 21, 56)
('2013-12-19 17:31:31', 'FBSVCMGR', 22, 58)
('2009-07-18 12:12:12', 'UTL', 23, 2)
('2011-05-25 16:17:34', 'NBACKUP', 24, 74)
('2014-06-16 18:16:16', 'NBACKUP', 24, 76)
('2009-07-20 07:55:48', 'FBTRACEMGR', 25, 41)
stop

Expand Down
2 changes: 2 additions & 0 deletions src/msgs/messages2.sql
Expand Up @@ -3301,6 +3301,8 @@ Analyzing database pages ...', NULL, NULL);
('nbackup_switchd_parameter', 'main', 'nbackup.cpp', NULL, 24, 71, NULL, 'Wrong parameter @1 for switch -D, need ON or OFF', NULL, NULL)
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 72, NULL, 'special options are:', NULL, NULL)
('nbackup_user_stop', 'checkCtrlC()', 'nbackup.cpp', NULL, 24, 73, NULL, 'Terminated due to user request', NULL, NULL)
(NULL, 'usage', 'nbackup.cpp', NULL, 24, 74, NULL, ' -DE(COMPRESS) <command> Command to extract archives during restore', NULL, NULL)
('nbackup_deco_parse', 'NBackup::open_backup_scan', 'nbackup.cpp', NULL, 24, 75, NULL, 'Too complex decompress command (> @1 arguments)', NULL, NULL)
-- FBTRACEMGR
-- All messages use the new format.
(NULL, 'usage', 'TraceCmdLine.cpp', NULL, 25, 1, NULL, 'Firebird Trace Manager version @1', NULL, NULL)
Expand Down
1 change: 1 addition & 0 deletions src/msgs/system_errors2.sql
Expand Up @@ -1238,6 +1238,7 @@ COMMIT WORK;
(-901, '00', '000', 24, 67, 'nbackup_lostguid_l0bk', NULL, NULL)
(-901, '00', '000', 24, 71, 'nbackup_switchd_parameter', NULL, NULL)
(-901, '08', '006', 24, 73, 'nbackup_user_stop', NULL, NULL)
(-901, '54', '023', 24, 75, 'nbackup_deco_parse', NULL, NULL)
-- FBTRACEMGR
(-901, '00', '000', 25, 30, 'trace_conflict_acts', NULL, NULL)
(-901, '00', '000', 25, 31, 'trace_act_notfound', NULL, NULL)
Expand Down
134 changes: 123 additions & 11 deletions src/utilities/nbackup/nbackup.cpp
Expand Up @@ -65,6 +65,14 @@
#include <errno.h>
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif

#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
Expand Down Expand Up @@ -266,11 +274,12 @@ class NBackup
public:
NBackup(UtilSvc* _uSvc, const PathName& _database, const string& _username,
const string& _password, bool _run_db_triggers/*, const string& _trustedUser,
bool _trustedRole*/, bool _direct_io)
bool _trustedRole*/, bool _direct_io, const PathName& _deco)
: uSvc(_uSvc), newdb(0), trans(0), database(_database),
username(_username), password(_password), /*trustedUser(_trustedUser),*/
run_db_triggers(_run_db_triggers), /*trustedRole(_trustedRole), */direct_io(_direct_io),
dbase(0), backup(0), db_size_pages(0), m_odsNumber(0), m_silent(false), m_printed(false)
dbase(0), backup(0), decompress(_deco), childId(0), db_size_pages(0),
m_odsNumber(0), m_silent(false), m_printed(false)
{
// Recognition of local prefix allows to work with
// database using TCP/IP loopback while reading file locally.
Expand Down Expand Up @@ -325,6 +334,8 @@ class NBackup
PathName bakname;
FILE_HANDLE dbase;
FILE_HANDLE backup;
PathName decompress;
int childId;
ULONG db_size_pages; // In pages
USHORT m_odsNumber;
bool m_silent; // are we already handling an exception?
Expand Down Expand Up @@ -363,17 +374,36 @@ size_t NBackup::read_file(FILE_HANDLE &file, void *buffer, size_t bufsize)
DWORD bytesDone;
if (ReadFile(file, buffer, bufsize, &bytesDone, NULL))
return bytesDone;
#else
const ssize_t res = read(file, buffer, bufsize);
if (res >= 0)
return res;
#endif

status_exception::raise(Arg::Gds(isc_nbackup_err_read) <<
(&file == &dbase ? dbname.c_str() :
&file == &backup ? bakname.c_str() : "unknown") <<
Arg::OsError());

return 0; // silence compiler
#else
size_t rc = 0;
while (bufsize)
{
const ssize_t res = read(file, buffer, bufsize);
if (res < 0)
status_exception::raise(Arg::Gds(isc_nbackup_err_read) <<
(&file == &dbase ? dbname.c_str() :
&file == &backup ? bakname.c_str() : "unknown") <<
Arg::OsError());

if (!res)
break;

rc += res;
bufsize -= res;
buffer = &((UCHAR*) buffer)[res];
}

return rc;
#endif


return 0; // silence compiler
}

Expand Down Expand Up @@ -543,9 +573,79 @@ void NBackup::open_backup_scan()
if (backup != INVALID_HANDLE_VALUE)
return;
#else
backup = open(nm.c_str(), O_RDONLY | O_LARGEFILE);
if (backup >= 0)
if (decompress.hasData())
{
PathName command = decompress;
PathName::size_type n = command.find('@');
if (n == PathName::npos)
{
command += ' ';
command += bakname;
}
else
{
command.replace(n, 1, bakname);
}

const unsigned ARGCOUNT = 20;
unsigned narg = 0;
char* args[ARGCOUNT + 1];
bool inStr = false;
for(unsigned i = 0; i < command.length(); ++i)
{
switch(command[i])
{
case ' ':
case '\t':
command[i] = '\0';
inStr = false;
break;
default:
if (!inStr)
{
if (narg >= ARGCOUNT)
{
status_exception::raise(Arg::Gds(isc_nbackup_deco_parse) << Arg::Num(ARGCOUNT));
}
inStr = true;
args[narg++] = &command[i];
}
break;
}
}
args[narg] = NULL;

int pfd[2];
if (pipe(pfd) < 0)
system_call_failed::raise("pipe");

fb_assert(!newdb); // FB 2.5 & 3 can't fork when attached to database
childId = fork();
if (childId < 0)
system_call_failed::raise("fork");

if (childId == 0)
{
close(pfd[0]);
dup2(pfd[1], 1);
close(pfd[1]);

execvp(args[0], args);
}
else
{
backup = pfd[0];
close(pfd[1]);
}

return;
}
else
{
backup = open(nm.c_str(), O_RDONLY | O_LARGEFILE);
if (backup >= 0)
return;
}
#endif

status_exception::raise(Arg::Gds(isc_nbackup_err_openbk) << bakname.c_str() << Arg::OsError());
Expand Down Expand Up @@ -587,6 +687,11 @@ void NBackup::close_backup()
CloseHandle(backup);
#else
close(backup);
if (childId > 0)
{
wait(NULL);
childId = 0;
}
#endif
}

Expand Down Expand Up @@ -1459,7 +1564,7 @@ void nbackup(UtilSvc* uSvc)

NbOperation op = nbNone;
string username, password;
PathName database, filename;
PathName database, filename, decompress;
bool run_db_triggers = true;
bool direct_io =
#ifdef WIN_NT
Expand Down Expand Up @@ -1541,6 +1646,13 @@ void nbackup(UtilSvc* uSvc)
usage(uSvc, isc_nbackup_switchd_parameter, onOff.c_str());
break;

case IN_SW_NBK_DECOMPRESS:
if (++itr >= argc)
missingParameterForSwitch(uSvc, argv[itr - 1]);

decompress = argv[itr];
break;

case IN_SW_NBK_FIXUP:
if (op != nbNone)
singleAction(uSvc);
Expand Down Expand Up @@ -1670,7 +1782,7 @@ void nbackup(UtilSvc* uSvc)
usage(uSvc, isc_nbackup_size_with_lock);
}

NBackup nbk(uSvc, database, username, password, run_db_triggers, /*trustedUser, trustedRole, */direct_io);
NBackup nbk(uSvc, database, username, password, run_db_triggers, /*trustedUser, trustedRole, */direct_io, decompress);
try
{
switch (op)
Expand Down
4 changes: 3 additions & 1 deletion src/utilities/nbackup/nbkswi.h
Expand Up @@ -48,6 +48,7 @@ const int IN_SW_NBK_TRUSTED_USER = 12;
const int IN_SW_NBK_TRUSTED_ROLE = 13;
const int IN_SW_NBK_HELP = 14;
const int IN_SW_NBK_DIRECT = 15;
const int IN_SW_NBK_DECOMPRESS = 16;


static const struct Switches::in_sw_tab_t nbackup_in_sw_table [] =
Expand All @@ -61,14 +62,15 @@ enum NbakOptionType { nboGeneral, nboSpecial, nboExclusive };

static const struct Switches::in_sw_tab_t nbackup_action_in_sw_table [] =
{
{IN_SW_NBK_LOCK, 0, "LOCK", 0, 0, 0, false, 8, 1, NULL ,nboExclusive},
{IN_SW_NBK_LOCK, 0, "LOCK", 0, 0, 0, false, 8, 1, NULL, nboExclusive},
{IN_SW_NBK_UNLOCK, 0, "N", 0, 0, 0, false, 0, 1, NULL, nboExclusive},
{IN_SW_NBK_UNLOCK, 0, "UNLOCK", 0, 0, 0, false, 9, 2, NULL, nboExclusive},
{IN_SW_NBK_FIXUP, 0, "FIXUP", 0, 0, 0, false, 10, 1, NULL, nboExclusive},
{IN_SW_NBK_BACKUP, isc_action_svc_nbak, "BACKUP", 0, 0, 0, false, 11, 1, NULL, nboExclusive},
{IN_SW_NBK_RESTORE, isc_action_svc_nrest, "RESTORE", 0, 0, 0, false, 12, 1, NULL, nboExclusive},
{IN_SW_NBK_DIRECT, 0, "DIRECT", 0, 0, 0, false, 70, 1, NULL, nboSpecial},
{IN_SW_NBK_SIZE, 0, "SIZE", 0, 0, 0, false, 17, 1, NULL, nboSpecial},
{IN_SW_NBK_DECOMPRESS, 0, "DECOMPRESS", 0, 0, 0, false, 74, 2, NULL, nboSpecial},
{IN_SW_NBK_NODBTRIG, 0, "T", 0, 0, 0, false, 0, 1, NULL, nboGeneral},
{IN_SW_NBK_NODBTRIG, 0, "NODBTRIGGERS", 0, 0, 0, false, 16, 3, NULL, nboGeneral},
{IN_SW_NBK_USER_NAME, 0, "USER", 0, 0, 0, false, 13, 1, NULL, nboGeneral},
Expand Down

0 comments on commit 685b5f1

Please sign in to comment.