From 2493d8bb30ff4f813e094ffe0659cccb6698412b Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Wed, 15 Jan 2014 22:06:41 +0100 Subject: [PATCH 01/10] Quick hack to make plugin compile with Bareos. --- fdapi.h | 2 - keylist.h | 2 +- pgsql-archlog.c | 2 +- pgsql-fd.c | 136 +++++++++++++++++------------------------------- pgsql-restore.c | 4 +- pgsqllib.h | 14 ++--- pluglib.c | 2 +- pluglib.h | 2 +- utils.c | 2 +- utils.h | 2 +- 10 files changed, 64 insertions(+), 104 deletions(-) delete mode 100644 fdapi.h diff --git a/fdapi.h b/fdapi.h deleted file mode 100644 index 9cd90cd..0000000 --- a/fdapi.h +++ /dev/null @@ -1,2 +0,0 @@ -/* #define FDAPI 2041 */ -#define FDAPI FD_PLUGIN_INTERFACE_VERSION diff --git a/keylist.h b/keylist.h index 9637286..2ce8857 100644 --- a/keylist.h +++ b/keylist.h @@ -11,7 +11,7 @@ #define _KEYLIST_H_ #ifndef __WIN32__ - #include "bacula.h" +#include "bareos.h" #endif #define KEY_NO_ATTR (-1) diff --git a/pgsql-archlog.c b/pgsql-archlog.c index 14b231e..90ea728 100644 --- a/pgsql-archlog.c +++ b/pgsql-archlog.c @@ -99,7 +99,7 @@ enum ARCHEXITS { EXITARCHDSTDIR = 14, EXITARCHDSTACC = 15, EXITCATDBTRANS = 16, - EXITARCHERROR = 17, + EXITARCHERROR = 17 }; /* diff --git a/pgsql-fd.c b/pgsql-fd.c index 28260f1..58faccf 100644 --- a/pgsql-fd.c +++ b/pgsql-fd.c @@ -2,7 +2,7 @@ * Copyright (c) 2013 Inteos Sp. z o.o. * All right reserved. See LICENSE.pgsql for details. * - * This is a Bacula plugin for making backup and restore of PostgreSQL database. + * This is a Bareos plugin for making backup and restore of PostgreSQL database. * * config file: pgsql.conf @@ -36,9 +36,8 @@ * prepare a docummentation about plugin */ -#include "bacula.h" +#include "bareos.h" #include "fd_plugins.h" -#include "fdapi.h" /* it is PostgreSQL backup plugin, so we need a libpq library */ #include @@ -89,17 +88,13 @@ static bRC checkFile(bpContext *ctx, char *fname); keylist * get_file_list ( bpContext *ctx, keylist * list, const char * base, const char * path ); -/* Pointers to Bacula functions */ +/* Pointers to Bareos functions */ static bFuncs *bfuncs = NULL; static bInfo *binfo = NULL; -static pInfo pluginInfo = { - sizeof(pluginInfo), -#ifdef FDAPI - FDAPI, -#else +static genpInfo pluginInfo = { + sizeof(genpInfo), FD_PLUGIN_INTERFACE_VERSION, -#endif FD_PLUGIN_MAGIC, PLUGIN_LICENSE, PLUGIN_AUTHOR, @@ -130,7 +125,7 @@ static pFuncs pluginFuncs = { /* * pgsql plugin requires working PostgreSQL catalog database - * it could be Bacula catalog database if it is postgresql + * it could be Bareos catalog database if it is postgresql * it can't be database which we backup, because it has to be available * during instance shutdown, when WAls are generated. */ @@ -140,36 +135,35 @@ enum PGSQLMode { PGSQL_ARCH_BACKUP, PGSQL_DB_BACKUP, PGSQL_ARCH_RESTORE, - PGSQL_DB_RESTORE, + PGSQL_DB_RESTORE }; enum PGFileType { PG_NONE = 0, PG_FILE, PG_LINK, - PG_DIR, + PG_DIR }; typedef enum { PARSE_BACKUP, - PARSE_RESTORE, + PARSE_RESTORE } ParseMode; -typedef struct _pg_plug_inst pg_plug_inst; -struct _pg_plug_inst { - int JobId; - PGconn * catdb; - char * restore_command_value; - char * configfile; - keylist * paramlist; - int mode; - keylist * filelist; - keyitem * curfile; - int curfd; - int diropen; - char * linkval; - int linkread; -}; +typedef struct _pg_plug_inst { + int JobId; + PGconn *catdb; + char *restore_command_value; + char *configfile; + keylist *paramlist; + int mode; + keylist *filelist; + keyitem *curfile; + int curfd; + int diropen; + char * linkval; + int linkread; +} pg_plug_inst; /* * TODO: @@ -221,7 +215,7 @@ struct _pg_plug_inst { ptr = NULL; /* - * TODO: extend with additional calls for Bacula-FD: baculaAddOptions + * TODO: extend with additional calls for Bareos-FD: bareosAddOptions */ #define JMSG0(ctx,type,msg) \ @@ -259,13 +253,16 @@ struct _pg_plug_inst { /* * Plugin called here when it is first loaded */ -bRC loadPlugin ( bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs ) +bRC DLL_IMP_EXP loadPlugin(bInfo *lbinfo, + bFuncs *lbfuncs, + genpInfo **pinfo, + pFuncs **pfuncs) { - bfuncs = lbfuncs; /* set Bacula funct pointers */ + bfuncs = lbfuncs; /* set Bareos funct pointers */ binfo = lbinfo; printf ( PLUGIN_INFO "version %s %s (c) 2011 by Inteos\n", PLUGIN_VERSION, PLUGIN_DATE ); - printf ( PLUGIN_INFO "connected to Bacula version %d\n", binfo->version ); + printf ( PLUGIN_INFO "connected to Bareos version %d\n", binfo->version ); *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ @@ -274,7 +271,7 @@ bRC loadPlugin ( bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs } /* - * Plugin called here when it is unloaded, normally when Bacula is going to exit. + * Plugin called here when it is unloaded, normally when Bareos is going to exit. */ bRC unloadPlugin() { @@ -306,9 +303,15 @@ static bRC newPlugin ( bpContext *ctx ) /* initialize pinst contents */ memset ( pinst, 0, sizeof ( pg_plug_inst ) ); - bfuncs->getBaculaValue ( ctx, bVarJobId, (void *)&pinst->JobId ); + bfuncs->getBareosValue ( ctx, bVarJobId, (void *)&pinst->JobId ); DMSG1 ( ctx, D1, "newPlugin JobId=%d\n", pinst->JobId ); + bfuncs->registerBareosEvents(ctx, + 4, + bEventEndBackupJob, + bEventStartRestoreJob, + bEventRestoreCommand, + bEventBackupCommand); return bRC_OK; } @@ -325,7 +328,7 @@ static bRC freePlugin ( bpContext *ctx ) pinst = (pg_plug_inst *) ctx->pContext; ASSERT_bfuncs; - bfuncs->getBaculaValue ( ctx, bVarJobId, (void *)&JobId ); + bfuncs->getBareosValue ( ctx, bVarJobId, (void *)&JobId ); if ( pinst->JobId != JobId ) { JMSG0 ( ctx, M_ERROR, "freePlugin JobId mismatch" ); @@ -381,7 +384,7 @@ static bRC setPluginValue ( bpContext *ctx, pVariable var, void *value ) */ bRC parse_plugin_command ( bpContext *ctx, const ParseMode parse_mode, const char * command ) { - /* pgsql:/usr/local/bacula/etc/pgsql.phobos.conf:[wal,db] */ + /* pgsql:/usr/local/bareos/etc/pgsql.phobos.conf:[wal,db] */ char * s; char * n; pg_plug_inst * pinst; @@ -1139,7 +1142,7 @@ keylist * get_file_list ( bpContext *ctx, keylist * list, const char * base, con closedir ( dirp ); /* finally at the end (?) we add en entry for directory - * entry is required for Bacula to archive directory atributes */ + * entry is required for Bareos to archive directory atributes */ nlist = add_dir_list ( ctx, nlist, base, path, bpath ); } else @@ -1179,7 +1182,7 @@ bRC get_dbf_list ( bpContext *ctx ){ } /* - * Called by Bacula when there are certain events that the + * Called by Bareos when there are certain events that the * plugin might want to know. The value depends on the * event. */ @@ -1195,18 +1198,6 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value){ DMSG1 ( ctx, D1, "handlePluginEvent: %i\n", event->eventType ); switch (event->eventType) { - case bEventJobStart: - // unused in ur case, information only - DMSG1 ( ctx, D2, "bEventJobStart value=%s\n", NPRT((char *)value) ); - break; - case bEventJobEnd: - // unused in ur case, information only - DMSG1 ( ctx, D2, "bEventJobEnd value=%s\n", NPRT((char *)value) ); - break; - case bEventStartBackupJob: - // unused in ur case, information only - DMSG1 ( ctx, D2, "bEventStartBackupJob value=%s\n", NPRT((char *)value) ); - break; case bEventEndBackupJob: // closing database connection DMSG1 ( ctx, D2, "bEventEndBackupJob value=%s\n", NPRT((char *)value)); @@ -1217,25 +1208,11 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value){ } } break; - case bEventLevel: - // unused in ur case, information only - // XXX: it could be usefull - DMSG1 ( ctx, D2, "bEventLevel=%c\n", (char) ( (intptr_t)value & 0xff) ); - break; - case bEventSince: - // unused in ur case, information only - DMSG1 ( ctx, D2, "bEventSince=%ld\n", (intptr_t)value); - break; case bEventStartRestoreJob: /* Test if restored database works or not, but we have very limited info about it, * it should be realized by external utility */ DMSG1 ( ctx, D2, "StartRestoreJob value=%s\n", NPRT((char *)value)); break; - case bEventEndRestoreJob: - // unused in ur case, information only - DMSG0 ( ctx, D2, "bEventEndRestoreJob\n"); - break; - /* Plugin command e.g. plugin = ::command */ case bEventRestoreCommand: /* setup a plugin parameters: plugin = pgsql::[wal,db] */ @@ -1245,7 +1222,6 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value){ return bRC_Error; } break; - case bEventBackupCommand: /* setup a plugin parameters: plugin = pgsql::[wal,db] */ DMSG1 ( ctx, D2, "bEventBackupCommand value=%s\n", NPRT((char *)value) ); @@ -1299,32 +1275,18 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value){ //print_keylist ( pinst->filelist ); } break; - case bEventPluginCommand: - // unused in ur case, information only - DMSG1 ( ctx, D2, "bEventPluginCommand value=%s\n", NPRT((char *)value) ); - break; - - case bEventEndFileSet: - // unused in ur case, information only - DMSG1 ( ctx, D2, "bEventEndFileSet value=%s\n", NPRT((char *)value) ); - break; - - case bEventRestoreObject: - // unused in ur case, information only - DMSG1 ( ctx, D2, "bEventRestoreObject value=%s\n", NPRT((char *)value) ); - break; - default: // enabled only for Debug DMSG1 ( ctx, D2, "unknown event=%d\n", event->eventType ); } + return bRC_OK; } /* * Called when starting to backup a file. Here the plugin must * return the "stat" packet for the directory/file and provide - * certain information so that Bacula knows what the file is. + * certain information so that Bareos knows what the file is. * The plugin can create "Virtual" files by giving them a * name that is not normally found on the file system. */ @@ -1351,7 +1313,7 @@ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp){ buf = MALLOC ( PATH_MAX ); ASSERT_p ( buf ); /* pgsqlarch:/ */ - /* above sentence will be splited in Bacula catalog on / */ + /* above sentence will be splited in Bareos catalog on / */ snprintf ( buf, PATH_MAX, "pgsqlarch:%s/%s", search_key ( pinst->paramlist, "ARCHCLIENT" ), pinst->curfile->value ); @@ -1399,7 +1361,7 @@ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp){ } DMSG2 ( ctx, D3, "filename=%s, vfilename=%s\n", filename, vfilename ); } else { - /* if we return a value different from bRC_OK then Bacula will finish + /* if we return a value different from bRC_OK then Bareos will finish * backup process, which at first call means no files to archive */ return bRC_Max; } @@ -1412,7 +1374,7 @@ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp){ /* real filename || $ROOT$ if vfilename is absolute, check this out */ if ( strncmp ( pinst->curfile->key, "$ROOT$", PATH_MAX ) == 0 ){ /* pgsqltbs:/ */ - /* above sentence will be splited in Bacula catalog on / */ + /* above sentence will be splited in Bareos catalog on / */ snprintf ( buf, PATH_MAX, "pgsqltbs:%s%s", search_key ( pinst->paramlist, "ARCHCLIENT" ), pinst->curfile->value ); @@ -1420,7 +1382,7 @@ static bRC startBackupFile(bpContext *ctx, struct save_pkt *sp){ filename = pinst->curfile->value; } else { /* pgsqldb:/ */ - /* above sentence will be splited in Bacula catalog on / */ + /* above sentence will be splited in Bareos catalog on / */ snprintf ( buf, PATH_MAX, "pgsqldb:%s/%s", search_key ( pinst->paramlist, "ARCHCLIENT" ), pinst->curfile->value ); @@ -1869,7 +1831,7 @@ bRC perform_arch_close ( bpContext *ctx, struct io_pkt *io ) { } /* - * Do actual I/O. Bacula calls this after startBackupFile + * Do actual I/O. Bareos calls this after startBackupFile * or after startRestoreFile to do the actual file * input or output. */ diff --git a/pgsql-restore.c b/pgsql-restore.c index 1ff77df..2b85995 100644 --- a/pgsql-restore.c +++ b/pgsql-restore.c @@ -1425,7 +1425,7 @@ void clear_receive_buffer ( pgsqldata * pdata ){ enum FILESETTYPE { DBFILESET = 0, - ARCHFILESET = 1, + ARCHFILESET = 1 }; static const char * fstemplate[2][2] = @@ -2231,7 +2231,7 @@ int delete_recovery_conf ( pgsqldata * pdata ){ enum WALLOC { WAL_LOC_NOTFOUND = 1, WAL_LOC_BACULA, - WAL_LOC_ARCHDEST, + WAL_LOC_ARCHDEST }; int find_wal_location ( pgsqldata * pdata ){ diff --git a/pgsqllib.h b/pgsqllib.h index 685a647..2d2f5b3 100644 --- a/pgsqllib.h +++ b/pgsqllib.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "keylist.h" #include "parseconfig.h" @@ -211,14 +211,14 @@ typedef enum { PG_NONE = 0, PG_FILE, PG_LINK, - PG_DIR, + PG_DIR } PGSQL_FILETYPE_T; /* log levels (utils only) */ typedef enum { LOGERROR, LOGWARNING, - LOGINFO, + LOGINFO } LOG_LEVEL_T; /* pgsql plugin or utils backup/restore modes */ @@ -228,14 +228,14 @@ typedef enum { PGSQL_ARCH_CTL_BACKUP, PGSQL_DB_BACKUP, PGSQL_DB_RESTORE, - PGSQL_ARCH_RESTORE, + PGSQL_ARCH_RESTORE } PGSQL_MODE_T; /* restore point-in-time */ typedef enum { PITR_CURRENT, PITR_TIME, - PITR_XID, + PITR_XID } PGSQL_PITR_T; /* pgsql_status definitions */ @@ -261,7 +261,7 @@ typedef enum { PGSQL_STATUS_DB_OFFLINE_START = 14, /* unimplemented */ PGSQL_STATUS_DB_OFFLINE_INPROG = 15, /* unimplemented */ PGSQL_STATUS_DB_OFFLINE_FINISH = 16, /* unimplemented */ - PGSQL_STATUS_DB_OFFLINE_FAILED = 17, /* unimplemented */ + PGSQL_STATUS_DB_OFFLINE_FAILED = 17 /* unimplemented */ } PGSQL_STATUS_T; #define PGSQL_STATUS_WAL_OK "3,5,8" @@ -312,7 +312,7 @@ struct _pgugid { }; /* - * bacula console communication message structure + * BAREOS console communication message structure */ #define MSGBUFLEN 1024 typedef struct _consmsgbuf consmsgbuf; diff --git a/pluglib.c b/pluglib.c index 3c01849..5c3a604 100644 --- a/pluglib.c +++ b/pluglib.c @@ -10,7 +10,7 @@ #include #include -#include "bacula.h" +#include "bareos.h" #include "fd_plugins.h" #include "pluglib.h" diff --git a/pluglib.h b/pluglib.h index bbdfcb5..6a674d4 100644 --- a/pluglib.h +++ b/pluglib.h @@ -13,7 +13,7 @@ #include #include -#include "bacula.h" +#include "bareos.h" #include "utils.h" /* definitions */ diff --git a/utils.c b/utils.c index e2d7fd4..4939713 100644 --- a/utils.c +++ b/utils.c @@ -265,7 +265,7 @@ char * format_btime ( const char * str ){ } #endif -#ifdef __sun__ +#if defined(__sun__) || defined(__SUNPRO_CC) /* * missing routine in Solaris */ diff --git a/utils.h b/utils.h index 33f461b..9b1f910 100644 --- a/utils.h +++ b/utils.h @@ -168,7 +168,7 @@ int readline ( int fd, char * buf, int size ); int freadline ( FILE * stream, char * buf, int size ); //char * format_btime ( const char * str ); int strisprintable ( char * str, int len ); -#ifdef __sun__ +#if defined(__sun__) || defined(__SUNPRO_CC) int getgrouplist (const char *uname, gid_t agroup, gid_t *groups, int *grpcnt); #endif #ifdef __WIN32__ From aad8964cee5e568bd1571e629a4a5866720f3419 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Wed, 15 Jan 2014 22:06:46 +0100 Subject: [PATCH 02/10] Teach program to use getopt. --- pgsql-restore.c | 84 +++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/pgsql-restore.c b/pgsql-restore.c index 2b85995..48e00ad 100644 --- a/pgsql-restore.c +++ b/pgsql-restore.c @@ -181,7 +181,8 @@ void dbconnect ( pgsqldata * pdata ){ void parse_args ( pgsqldata * pdata, int argc, char* argv[] ){ int i; - char * fullconfpath; + char *fullconfpath; + char ch; if ( argc < 3 ){ /* TODO - add help screen */ @@ -189,44 +190,53 @@ void parse_args ( pgsqldata * pdata, int argc, char* argv[] ){ abortprg ( pdata, 1, "Not enough parameters!" ); } - for (i = 1; i < argc; i++) { -// printf ( "%s\n", argv[i] ); - if ( !strcmp ( argv[i], "-c" ) ){ + while ((ch = getopt(argc, argv, "c:t:x:w:r:v")) != -1) { + switch (ch) { + case 'c': /* we have got a custom config file */ - fullconfpath = MALLOC ( BUFLEN ); - ASSERT_NVAL_RET ( fullconfpath ); - realpath ( argv [ i + 1 ], fullconfpath ); - pdata->configfile = bstrdup ( fullconfpath ); - FREE ( fullconfpath ); - i++; - continue; - } - if ( !strcmp ( argv[i], "-t" ) && pdata->pitr == PITR_CURRENT ){ - pdata->restorepit = format_btime ( argv [ i + 1 ] ); - pdata->pitr = PITR_TIME; - i++; - continue; - } - if ( !strcmp ( argv[i], "-x" ) && pdata->pitr == PITR_CURRENT ){ - pdata->restorepit = bstrdup ( argv [ i + 1 ] ); - pdata->pitr = PITR_XID; - i++; - continue; - } - if ( !strcmp ( argv[i], "-w" ) ){ - pdata->where = bstrdup ( argv [ i + 1 ] ); - i++; - continue; - } - if ( !strcmp ( argv[i], "-r" ) ){ - pdata->restoreclient = bstrdup ( argv [ i + 1 ] ); - i++; - continue; - } - if ( !strcasecmp ( argv[i], "-v" ) ){ - pdata->verbose = 1; - continue; + fullconfpath = MALLOC(BUFLEN); + ASSERT_NVAL_RET(fullconfpath); + realpath(optarg, fullconfpath ); + pdata->configfile = bstrdup(fullconfpath); + FREE (fullconfpath); + break; + + case 't': + if (pdata->pitr == PITR_CURRENT) { + pdata->restorepit = format_btime (optarg); + pdata->pitr = PITR_TIME; + } + break; + + case 'x': + if (pdata->pitr == PITR_CURRENT) { + pdata->restorepit = bstrdup(optarg); + pdata->pitr = PITR_XID; + } + break; + + case 'w': + pdata->where = bstrdup(optarg); + break; + + case 'r': + pdata->restoreclient = bstrdup(optarg); + break; + + case 'v': + pdata->verbose = true; + break; + + case '?': + default: + print_help ( pdata ); + abortprg ( pdata, 1, "Usage!" ); } + } + argc -= optind; + argv += optind; + + for (i = 0; i < argc; i++) { if ( !strcasecmp ( argv[i], "restore" ) ){ pdata->mode = PGSQL_DB_RESTORE; continue; From e947a59f93674cbcbfe34793a3a297becab9bcc9 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Wed, 15 Jan 2014 22:06:52 +0100 Subject: [PATCH 03/10] Add some grants and reformat the create DDL. --- pgsql-grants.sql | 11 ++++++++ pgsql-tables.sql | 66 ++++++++++++++++++++++++------------------------ 2 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 pgsql-grants.sql diff --git a/pgsql-grants.sql b/pgsql-grants.sql new file mode 100644 index 0000000..59eadc9 --- /dev/null +++ b/pgsql-grants.sql @@ -0,0 +1,11 @@ +CREATE USER pgcat PASSWORD 'pgcat'; + +-- For tables +GRANT ALL ON pgsql_version TO pgcat; +GRANT ALL ON pgsql_status TO pgcat; +GRANT ALL ON pgsql_backupdbs TO pgcat; +GRANT ALL ON pgsql_archivelogs TO pgcat; + +-- For sequences ON those tables +GRANT SELECT, UPDATE ON pgsql_archivelogs_id_seq TO pgcat; +GRANT SELECT, UPDATE ON pgsql_backupdbs_id_seq TO pgcat; diff --git a/pgsql-tables.sql b/pgsql-tables.sql index 1cf9d57..6467d0b 100644 --- a/pgsql-tables.sql +++ b/pgsql-tables.sql @@ -6,15 +6,15 @@ -- -- version table -drop table pgsql_version cascade; -create table pgsql_version ( - versionid integer not null +DROP TABLE IF EXISTS pgsql_version CASCADE; +CREATE TABLE pgsql_version ( + versionid INTEGER NOT NULL ); -insert into pgsql_version ( versionid ) values ('1'); +INSERT INTO pgsql_version ( versionid ) VALUES ('1'); -drop table pgsql_status cascade; -create table pgsql_status ( - statusid integer unique not null, +DROP TABLE IF EXISTS pgsql_status CASCADE; +CREATE TABLE pgsql_status ( + statusid INTEGER UNIQUE NOT NULL, notes varchar ); @@ -38,30 +38,30 @@ create table pgsql_status ( -- PGSQL_STATUS_DB_OFFLINE_START = 14, -- PGSQL_STATUS_DB_OFFLINE_INPROG = 15, -- PGSQL_STATUS_DB_OFFLINE_FINISH = 16, --- PGSQL_STATUS_DB_OFFLINE_FAILED = 17, +-- PGSQL_STATUS_DB_OFFLINE_FAILED = 17 -- } PGSQL_STATUS; -- -insert into pgsql_status values ('0','Unknown'); -insert into pgsql_status values ('1','WAL archiving started'); -insert into pgsql_status values ('2','WAL archiving in progress'); -insert into pgsql_status values ('3','WAL archiving finished'); -insert into pgsql_status values ('4','WAL archiving failed'); -insert into pgsql_status values ('5','WAL multiply archiving occured'); -insert into pgsql_status values ('6','WAL backup started'); -insert into pgsql_status values ('7','WAL backup in progress'); -insert into pgsql_status values ('8','WAL backup done'); -insert into pgsql_status values ('9','WAL backup failed'); -insert into pgsql_status values ('10','DB online backup started'); -insert into pgsql_status values ('11','DB online backup in progress'); -insert into pgsql_status values ('12','DB online backup finished'); -insert into pgsql_status values ('13','DB online backup failed'); -insert into pgsql_status values ('14','DB offline backup started'); -insert into pgsql_status values ('15','DB offline backup in progress'); -insert into pgsql_status values ('16','DB offline backup finished'); -insert into pgsql_status values ('17','DB offline backup failed'); +INSERT INTO pgsql_status values ('0','Unknown'); +INSERT INTO pgsql_status values ('1','WAL archiving started'); +INSERT INTO pgsql_status values ('2','WAL archiving in progress'); +INSERT INTO pgsql_status values ('3','WAL archiving finished'); +INSERT INTO pgsql_status values ('4','WAL archiving failed'); +INSERT INTO pgsql_status values ('5','WAL multiply archiving occured'); +INSERT INTO pgsql_status values ('6','WAL backup started'); +INSERT INTO pgsql_status values ('7','WAL backup in progress'); +INSERT INTO pgsql_status values ('8','WAL backup done'); +INSERT INTO pgsql_status values ('9','WAL backup failed'); +INSERT INTO pgsql_status values ('10','DB online backup started'); +INSERT INTO pgsql_status values ('11','DB online backup in progress'); +INSERT INTO pgsql_status values ('12','DB online backup finished'); +INSERT INTO pgsql_status values ('13','DB online backup failed'); +INSERT INTO pgsql_status values ('14','DB offline backup started'); +INSERT INTO pgsql_status values ('15','DB offline backup in progress'); +INSERT INTO pgsql_status values ('16','DB offline backup finished'); +INSERT INTO pgsql_status values ('17','DB offline backup failed'); -drop table pgsql_backupdbs cascade; -create table pgsql_backupdbs ( +DROP TABLE IF EXISTS pgsql_backupdbs CASCADE; +CREATE TABLE pgsql_backupdbs ( id serial, client varchar not null, start_date timestamp default now(), @@ -70,17 +70,17 @@ create table pgsql_backupdbs ( end_xid varchar not null, blevel integer not null default 0, status integer not null default 0, - foreign key (status) references pgsql_status (statusid) + FOREIGN KEY (status) REFERENCES pgsql_status (statusid) ); -drop table pgsql_archivelogs cascade; -create table pgsql_archivelogs ( +DROP TABLE IF EXISTS pgsql_archivelogs CASCADE; +CREATE TABLE pgsql_archivelogs ( id serial, client varchar not null, filename varchar not null, create_date timestamp default now(), mod_date timestamp default now(), status integer not null default 0, - unique (client, filename), - foreign key (status) references pgsql_status (statusid) + UNIQUE (client, filename), + FOREIGN KEY (status) REFERENCES pgsql_status (statusid) ); From 7fdd260d12f410787f6cfb433f2ebc282bf61c4a Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Wed, 15 Jan 2014 22:09:33 +0100 Subject: [PATCH 04/10] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 203d3b7..f87f915 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -pgsql-plugin +contrib-pgsql-plugin ============ -PGSQL Plugin is a Bacula File Daemon plugin wich perform PostgreSQL database on-line backup and point-in-time recovery. +PGSQL Plugin is a Bareos File Daemon plugin wich perform PostgreSQL database on-line backup and point-in-time recovery. From 205cb19c90353967e422a19cf54e54d0e0b7f913 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Fri, 19 Dec 2014 18:58:31 +0100 Subject: [PATCH 05/10] Added sample BAREOS Makefile. --- Makefile.bareos | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 Makefile.bareos diff --git a/Makefile.bareos b/Makefile.bareos new file mode 100644 index 0000000..2aef031 --- /dev/null +++ b/Makefile.bareos @@ -0,0 +1,93 @@ +# +# Makefile for inteos-pgsql-plugin on Linux +# + +# Flags & libs +BAREOSSRC = +BAREOSVERSION = $(shell bconsole help 2>&1|grep Version:|awk '{print $$2}') +PGSQLVERSION = $(shell grep PLUGIN_VERSION pgsql-fd.c|grep define|awk '{print $$3}'|sed 's/"//g') + +plugindir = /usr/lib/bareos/plugins +sbindir = /usr/sbin +libdir = /usr/lib/bareos +confdir = /etc/bareos + +CFLAGS = -g -Wall -fno-strict-aliasing -fno-exceptions -fPIC +CPPFLAGS = -g -fno-strict-aliasing -fno-exceptions -fno-rtti -Wall -fPIC +LDFLAGS = +BAREOS_H = -I../$(BAREOS_SRC)/src -I../$(BAREOS_SRC)/src/filed +DB_H = -I/usr/include/postgresql +BAREOS_LIBS = -L$(libdir) -lbareos +DB_LIBS = -L/usr/lib -lpq -lcrypt + +PGSQLSRC = pgsql-fd.c pgsql-archlog.c pgsql-restore.c pgsqllib.c +PGSQLOBJ = $(PGSQLSRC:.c=.lo) +BACSRC = keylist.c parseconfig.c pluglib.c utils.c +BACOBJ = $(BACSRC:.c=.lo) + +all: pgsql Makefile + +clean: libtool-clean pgsql-clean + @echo "Cleaning objects ..." + @rm -rf *.o *.lo + +%.lo : %.c Makefile + @echo "Compiling $(@:.lo=.c) ..." + @libtool --silent --tag=CXX --mode=compile g++ $(CPPFLAGS) -c $(@:.lo=.c) + +$(BACOBJ): Makefile $(BACSRC) + @echo "Compiling BAClib required $(@:.lo=.c) ..." + @libtool --silent --tag=CXX --mode=compile g++ $(CPPFLAGS) $(BAREOS_H) -c $(@:.lo=.c) + +pgsql: Makefile pgsql-fd.la pgsql-archlog pgsql-restore + +$(PGSQLOBJ): Makefile $(PGSQLSRC) + @echo "Compiling PGSQL $(@:.lo=.c) ..." + @libtool --silent --tag=CXX --mode=compile g++ $(CPPFLAGS) $(BAREOS_H) $(DB_H) -c $(@:.lo=.c) + +pgsql-fd.la: pgsql-fd.lo keylist.lo parseconfig.lo pluglib.lo utils.lo + @echo "Building PGSQL $(@:.la=.so) ..." + @libtool --silent --tag=CXX --mode=link g++ -shared $(LDFLAGS) $^ -o $@ -rpath $(plugindir) -module \ + -export-dynamic -avoid-version $(DB_LIBS) + +pgsql-archlog: pgsql-archlog.lo parseconfig.lo keylist.lo pgsqllib.lo utils.lo pluglib.lo + @echo "Making $@ ..." + @libtool --silent --tag=CXX --mode=link g++ -o $@ $^ $(BAREOS_LIBS) $(DB_LIBS) + +pgsql-restore: pgsql-restore.lo parseconfig.lo keylist.lo pgsqllib.lo utils.lo pluglib.lo + @echo "Making $@ ..." + @libtool --silent --tag=CXX --mode=link g++ -o $@ $^ $(BAREOS_LIBS) $(DB_LIBS) + +pgsql-clean: + @echo "Cleaning pgsql ..." + @rm -f pgsql-archlog pgsql-restore pgsql-fd.so pgsql-fd.la pgsql-fd.lo + +libtool-clean: + @echo "Cleaning libtool ..." + @rm -rf .libs _libs + +install-pgsql-fd: pgsql-fd.la + @echo "Installing plugin ... $(^:.la=.so)" + @mkdir -p $(DESTDIR)$(plugindir) + @libtool --silent --tag=CXX --mode=install /usr/bin/install -c -m 0750 $^ $(DESTDIR)$(plugindir) + @rm -f $(DESTDIR)$(plugindir)/$^ + +install-pgsql-utils: pgsql-archlog pgsql-restore + @echo "Installing utils ... $^" + @mkdir -p $(DESTDIR)$(sbindir) + @libtool --silent --tag=CXX --mode=install /usr/bin/install -c -m 0755 $^ $(DESTDIR)$(sbindir) + +install-pgsql-config: pgsql.conf + @echo "Installing config ... $^" + @mkdir -p $(DESTDIR)$(confdir) + @libtool --silent --tag=CXX --mode=install /usr/bin/install -c -m 0640 pgsql.conf $(DESTDIR)$(confdir)/pgsql.conf.example + +install-pgsql: install-pgsql-fd install-pgsql-config install-pgsql-utils + +install: install-pgsql + +package-pgsql: install-pgsql inteos-pgsql.spec + @echo "Package pgsql $(PGSQLVERSION) for Bacula $(BAREOSVERSION)" + @tar cjvPf ../pgsql-$(PGSQLVERSION)_$(BAREOSVERSION).tar.bz2 $(DESTDIR)$(confdir)/pgsql.conf.example $(DESTDIR)$(sbindir)/pgsql-archlog $(DESTDIR)$(sbindir)/pgsql-restore $(DESTDIR)$(plugindir)/pgsql-fd.so + @cp ../pgsql-$(PGSQLVERSION)_$(BAREOSVERSION).tar.bz2 /root/rpmbuild/SOURCES + @rpmbuild -bb inteos-pgsql.spec From 508f1821ef967e93373402566fe07a72fe98bae5 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Fri, 19 Dec 2014 19:59:15 +0100 Subject: [PATCH 06/10] Add patch so things compile with Bareos 14.2 and newer. --- pgsql-restore.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pgsql-restore.c b/pgsql-restore.c index 48e00ad..20e8bf4 100644 --- a/pgsql-restore.c +++ b/pgsql-restore.c @@ -1133,7 +1133,7 @@ int remove_pgdata_tablespaces ( pgsqldata * pdata ){ */ char * pasword_md5digest ( pgsqldata * pdata ){ - struct MD5Context md5c; + MD5_CTX md5c; unsigned char digest[CRYPTO_DIGEST_MD5_SIZE]; char * password; char * p; @@ -1144,10 +1144,10 @@ char * pasword_md5digest ( pgsqldata * pdata ){ abortprg ( pdata, 14, "out of memory!" ); } - MD5Init(&md5c); + MD5_Init(&md5c); p = search_key ( pdata->paramlist, "DIRPASSWD" ); - MD5Update(&md5c, (unsigned char *) p, strlen ( p ) ); - MD5Final(digest, &md5c); + MD5_Update(&md5c, (unsigned char *) p, strlen ( p ) ); + MD5_Final(digest, &md5c); for (i = j = 0; i < sizeof(digest); i++) { sprintf ( &password[j], "%02x", digest[i] ); j += 2; From a03c216613620a459d64c22826823154e43266a7 Mon Sep 17 00:00:00 2001 From: Marco van Wieringen Date: Wed, 20 May 2015 16:43:34 +0200 Subject: [PATCH 07/10] Update BAREOS Makefile to allow building using SRCDIR. Some changes to the Makefile to make it somewhat more portable and allow building of the plugin using a SRCDIR with the current build of BAREOS. --- Makefile.bareos | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/Makefile.bareos b/Makefile.bareos index 2aef031..04ae461 100644 --- a/Makefile.bareos +++ b/Makefile.bareos @@ -2,23 +2,29 @@ # Makefile for inteos-pgsql-plugin on Linux # +# Absolute or relative PATH to BAREOS source dir with build libraries and binaries. +BAREOS_SRC = + # Flags & libs -BAREOSSRC = -BAREOSVERSION = $(shell bconsole help 2>&1|grep Version:|awk '{print $$2}') -PGSQLVERSION = $(shell grep PLUGIN_VERSION pgsql-fd.c|grep define|awk '{print $$3}'|sed 's/"//g') +BAREOS_VERSION = $(shell bconsole help 2>&1|grep Version:|awk '{print $$2}') +PGSQL_VERSION = $(shell grep PLUGIN_VERSION pgsql-fd.c|grep define|awk '{print $$3}'|sed 's/"//g') +LIBTOOL = $(BAREOS_SRC)/libtool -plugindir = /usr/lib/bareos/plugins +plugindir = /usr/lib64/bareos/plugins sbindir = /usr/sbin libdir = /usr/lib/bareos confdir = /etc/bareos +CXX = g++ CFLAGS = -g -Wall -fno-strict-aliasing -fno-exceptions -fPIC -CPPFLAGS = -g -fno-strict-aliasing -fno-exceptions -fno-rtti -Wall -fPIC +CXXFLAGS = -g -fno-strict-aliasing -fno-exceptions -fno-rtti -Wall -fPIC LDFLAGS = -BAREOS_H = -I../$(BAREOS_SRC)/src -I../$(BAREOS_SRC)/src/filed +BAREOS_H = -I$(BAREOS_SRC)/src -I$(BAREOS_SRC)/src/include -I$(BAREOS_SRC)/src/filed DB_H = -I/usr/include/postgresql -BAREOS_LIBS = -L$(libdir) -lbareos -DB_LIBS = -L/usr/lib -lpq -lcrypt +DB_LIB = /usr/lib +BAREOS_LIBS = -L$(BAREOS_SRC)/src/lib -lbareos +DB_LIBS = -L$(DB_LIB) -R $(DB_LIB) -lpq -lcrypt +INSTALL = /usr/bin/install -c PGSQLSRC = pgsql-fd.c pgsql-archlog.c pgsql-restore.c pgsqllib.c PGSQLOBJ = $(PGSQLSRC:.c=.lo) @@ -33,30 +39,30 @@ clean: libtool-clean pgsql-clean %.lo : %.c Makefile @echo "Compiling $(@:.lo=.c) ..." - @libtool --silent --tag=CXX --mode=compile g++ $(CPPFLAGS) -c $(@:.lo=.c) + @$(LIBTOOL) --silent --tag=CXX --mode=compile $(CXX) $(CXXFLAGS) -c $(@:.lo=.c) $(BACOBJ): Makefile $(BACSRC) @echo "Compiling BAClib required $(@:.lo=.c) ..." - @libtool --silent --tag=CXX --mode=compile g++ $(CPPFLAGS) $(BAREOS_H) -c $(@:.lo=.c) + @$(LIBTOOL) --silent --tag=CXX --mode=compile $(CXX)$(CXXFLAGS) $(BAREOS_H) -c $(@:.lo=.c) pgsql: Makefile pgsql-fd.la pgsql-archlog pgsql-restore $(PGSQLOBJ): Makefile $(PGSQLSRC) @echo "Compiling PGSQL $(@:.lo=.c) ..." - @libtool --silent --tag=CXX --mode=compile g++ $(CPPFLAGS) $(BAREOS_H) $(DB_H) -c $(@:.lo=.c) + @$(LIBTOOL) --silent --tag=CXX --mode=compile $(CXX) $(CXXFLAGS) $(BAREOS_H) $(DB_H) -c $(@:.lo=.c) pgsql-fd.la: pgsql-fd.lo keylist.lo parseconfig.lo pluglib.lo utils.lo @echo "Building PGSQL $(@:.la=.so) ..." - @libtool --silent --tag=CXX --mode=link g++ -shared $(LDFLAGS) $^ -o $@ -rpath $(plugindir) -module \ + @$(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) -shared $(LDFLAGS) $^ -o $@ -rpath $(plugindir) -module \ -export-dynamic -avoid-version $(DB_LIBS) pgsql-archlog: pgsql-archlog.lo parseconfig.lo keylist.lo pgsqllib.lo utils.lo pluglib.lo @echo "Making $@ ..." - @libtool --silent --tag=CXX --mode=link g++ -o $@ $^ $(BAREOS_LIBS) $(DB_LIBS) + @$(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) -o $@ $^ $(BAREOS_LIBS) $(DB_LIBS) pgsql-restore: pgsql-restore.lo parseconfig.lo keylist.lo pgsqllib.lo utils.lo pluglib.lo @echo "Making $@ ..." - @libtool --silent --tag=CXX --mode=link g++ -o $@ $^ $(BAREOS_LIBS) $(DB_LIBS) + @$(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) -o $@ $^ $(BAREOS_LIBS) $(DB_LIBS) pgsql-clean: @echo "Cleaning pgsql ..." @@ -69,25 +75,25 @@ libtool-clean: install-pgsql-fd: pgsql-fd.la @echo "Installing plugin ... $(^:.la=.so)" @mkdir -p $(DESTDIR)$(plugindir) - @libtool --silent --tag=CXX --mode=install /usr/bin/install -c -m 0750 $^ $(DESTDIR)$(plugindir) + @$(LIBTOOL) --silent --tag=CXX --mode=install $(INSTALL) -m 0750 $^ $(DESTDIR)$(plugindir) @rm -f $(DESTDIR)$(plugindir)/$^ install-pgsql-utils: pgsql-archlog pgsql-restore @echo "Installing utils ... $^" @mkdir -p $(DESTDIR)$(sbindir) - @libtool --silent --tag=CXX --mode=install /usr/bin/install -c -m 0755 $^ $(DESTDIR)$(sbindir) + @$(LIBTOOL) --silent --tag=CXX --mode=install $(INSTALL) -m 0755 $^ $(DESTDIR)$(sbindir) install-pgsql-config: pgsql.conf @echo "Installing config ... $^" @mkdir -p $(DESTDIR)$(confdir) - @libtool --silent --tag=CXX --mode=install /usr/bin/install -c -m 0640 pgsql.conf $(DESTDIR)$(confdir)/pgsql.conf.example + @$(LIBTOOL) --silent --tag=CXX --mode=install $(INSTALL) -m 0640 pgsql.conf $(DESTDIR)$(confdir)/pgsql.conf.example install-pgsql: install-pgsql-fd install-pgsql-config install-pgsql-utils install: install-pgsql package-pgsql: install-pgsql inteos-pgsql.spec - @echo "Package pgsql $(PGSQLVERSION) for Bacula $(BAREOSVERSION)" + @echo "Package pgsql $(PGSQL_VERSION) for Bacula $(BAREOS_VERSION)" @tar cjvPf ../pgsql-$(PGSQLVERSION)_$(BAREOSVERSION).tar.bz2 $(DESTDIR)$(confdir)/pgsql.conf.example $(DESTDIR)$(sbindir)/pgsql-archlog $(DESTDIR)$(sbindir)/pgsql-restore $(DESTDIR)$(plugindir)/pgsql-fd.so @cp ../pgsql-$(PGSQLVERSION)_$(BAREOSVERSION).tar.bz2 /root/rpmbuild/SOURCES @rpmbuild -bb inteos-pgsql.spec From e7ed96eb64ecc71bedc9ff47e3621fe1b87d6e06 Mon Sep 17 00:00:00 2001 From: Ben Mehlman Date: Wed, 24 Feb 2016 20:15:06 -0500 Subject: [PATCH 08/10] ignore editor backup files generated by 'joe' and possibly other editors --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 96a940e..a796d4d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ pgsql-archlog pgsql-restore Makefile .libs + +# Editor Backup Files +*~ From 76e00cd729ec45b280d83b587a2c54e026da55c3 Mon Sep 17 00:00:00 2001 From: Ben Mehlman Date: Wed, 24 Feb 2016 20:16:52 -0500 Subject: [PATCH 09/10] fix bad allocated memory handling that was causing crash in pgsqllibinit() when realpath() returns NULL --- pgsqllib.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pgsqllib.c b/pgsqllib.c index be4579d..df806e9 100644 --- a/pgsqllib.c +++ b/pgsqllib.c @@ -46,22 +46,18 @@ void pgsqllibinit ( int argc, char * argv[] ){ char * prg; char * nprg; - char * dirtmp; prg = bstrdup ( argv[0] ); nprg = basename ( prg ); program_name = bstrdup ( nprg ); FREE ( prg ); - dirtmp = MALLOC ( PATH_MAX ); - if ( realpath ( argv[0], dirtmp ) == NULL ){ + program_directory = MALLOC ( PATH_MAX ); + if ( realpath ( argv[0], program_directory ) == NULL ){ /* error in resolving path */ - FREE ( dirtmp ); - dirtmp = argv[0]; + FREE ( program_directory ); + program_directory = argv[0]; } - program_directory = bstrdup ( dirtmp ); - - FREE ( dirtmp ); } /* returns a pointer into program name variable */ From 84c947e966cef77fe09ec6cfaa40baf2cc22562c Mon Sep 17 00:00:00 2001 From: Ben Mehlman Date: Wed, 24 Feb 2016 22:05:32 -0500 Subject: [PATCH 10/10] Fix false 'Success' status with zero length backup when config file cannot be opened. --- pgsql-fd.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pgsql-fd.c b/pgsql-fd.c index d104d5f..2564862 100644 --- a/pgsql-fd.c +++ b/pgsql-fd.c @@ -452,8 +452,14 @@ bRC parse_plugin_command ( bpContext *ctx, const ParseMode parse_mode, const cha FREE ( pinst->configfile ); return bRC_Error; } - - pinst->paramlist = parse_config_file ( pinst->configfile ); + + if((pinst->paramlist = parse_config_file ( pinst->configfile )) == NULL) { + char errbuf[255]; + JMSG2(ctx, M_FATAL, "Error reading config file: %s (%s)", pinst->configfile, + strerror_r(errno, errbuf, sizeof(errbuf))); + FREE( pinst->configfile ); + return bRC_Error; + } pinst->restore_command_value = bstrdup ( command ); } return bRC_OK;