tape drivers.
Changes submitted this submission:
+03Jan03
+- Add scripts make_catalog_backup and delete_catalog_backup that makes and
+ deletes an ASCII copy of the catalog for backup. An example of how
+ to use it is in the <bacula-src/src/dird/bacula-dir.conf file.
+- Made a nicer column oriented listing of scheduled jobs for "status dir".
+02Jan03
+- Added backup/restore of raw partitions.
+- Corrected restoration of files in root directory (problem with
+ splitting path from file).
+01Jan03
+- Finally decided to cleanup handling of splitting path and filenames
+ in the cats directory. Now the code is in one place sql.c and it
+ is done using Pool memory, so there are no length restrictions.
31Dec02
- Add start of Solaris bare metal recovery
- Add Site Visit usage statistics to Web page
chmod 755 src/cats/make_bdb_tables src/cats/drop_bdb_tables
chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
chmod 755 src/cats/create_mysql_database
+ chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
chmod 755 src/cats/alter_mysql_tables
chmod 755 src/cats/create_sqlite_database
chmod 755 src/cats/alter_sqlite_tables
Bacula code: Total files = 226 Total lines = 61,863 (*.h *.c *.in)
Major Changes this Release:
-- Bare Metal Recovery for Linux systems and manually for Solaris
+- Bare Metal Recovery mostly automated for Linux systems and
+ partially automated for Solaris
- Optimized restore, forward spaces to correct tape file and
stops reading the archive when all files are restored.
- Schedule permits specification of 1st, 2nd, ... week e.g.
1st Sun ...
Minor Changes this Release:
+- Allow backup of raw partitions.
- Fixed Restore options (never,ifnewer, ...). They now work.
- New bidirectional timed pipe mechanism for running child processes
permits better error messages.
daemons and the console program.
- Added a --enable-client-only option that will cause "make" to only
build the File daemon and the libraries it needs.
+- Documented how to save the Catalog database (with included script).
Items to note:
- Nothing in particular.
src/filed/bacula-fd.conf \
src/filed/win32/Makefile \
src/cats/Makefile \
+ src/cats/make_catalog_backup \
+ src/cats/delete_catalog_backup \
src/cats/alter_mysql_tables \
src/cats/make_mysql_tables \
src/cats/drop_mysql_tables \
chmod 755 src/cats/make_mysql_tables src/cats/drop_mysql_tables
chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
chmod 755 src/cats/create_mysql_database
+chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
chmod 755 src/cats/alter_mysql_tables
chmod 755 src/cats/grant_mysql_privileges
chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables
src/filed/bacula-fd.conf \
src/filed/win32/Makefile \
src/cats/Makefile \
+ src/cats/make_catalog_backup \
+ src/cats/delete_catalog_backup \
src/cats/alter_mysql_tables \
src/cats/make_mysql_tables \
src/cats/drop_mysql_tables \
src/filed/bacula-fd.conf \
src/filed/win32/Makefile \
src/cats/Makefile \
+ src/cats/make_catalog_backup \
+ src/cats/delete_catalog_backup \
src/cats/alter_mysql_tables \
src/cats/make_mysql_tables \
src/cats/drop_mysql_tables \
chmod 755 src/cats/make_mysql_tables src/cats/drop_mysql_tables
chmod 755 src/cats/make_test_tables src/cats/drop_test_tables
chmod 755 src/cats/create_mysql_database
+chmod 755 src/cats/make_catalog_backup src/cats/delete_catalog_backup
chmod 755 src/cats/alter_mysql_tables
chmod 755 src/cats/grant_mysql_privileges
chmod 755 src/cats/make_sqlite_tables src/cats/drop_sqlite_tables
- Backup of raw partitions
For 1.29 release:
+- Implement SHA1
+- Implement disk spooling
+- Implement finer multiprocessing options.
- Solaris -I on tar for include list
- Add whereln to where or not where absolute links
- Figure out some way to automatically backup all local partitions
$(RMF) make_mysql_tables grant_mysql_privileges drop_mysql_tables
$(RMF) create_mysql_database make_sqlite_tables sqlite
$(RMF) create_bdb_database drop_bdb_tables make_dbd_tables
+ $(RMF) make_catalog_backup delete_catalog_backup
distclean: realclean
if test $(srcdir) = .; then $(MAKE) realclean; fi
$(INSTALL_SCRIPT) make_@DB_NAME@_tables $(DESTDIR)$(sysconfdir)/make_@DB_NAME@_tables
$(INSTALL_SCRIPT) drop_bacula_tables $(DESTDIR)$(sysconfdir)/drop_bacula_tables
$(INSTALL_SCRIPT) make_bacula_tables $(DESTDIR)$(sysconfdir)/make_bacula_tables
+ $(INSTALL_SCRIPT) make_catalog_backup $(DESTDIR)$(sysconfdir)/make_catalog_backup
+ $(INSTALL_SCRIPT) delete_catalog_backup $(DESTDIR)$(sysconfdir)/delete_catalog_backup
uninstall:
(cd $(DESTDIR)$(sysconfdir); $(RMF) create_@DB_NAME@_database)
(cd $(DESTDIR)$(sysconfdir); $(RMF) make_@DB_NAME@_tables)
(cd $(DESTDIR)$(sysconfdir); $(RMF) drop_bacula_tables)
(cd $(DESTDIR)$(sysconfdir); $(RMF) make_bacula_tables)
+ (cd $(DESTDIR)$(sysconfdir); $(RMF) make_catalog_backup)
+ (cd $(DESTDIR)$(sysconfdir); $(RMF) delete_catalog_backup)
# Semi-automatic generation of dependencies:
--- /dev/null
+#!/bin/sh
+#
+# This script deletes a catalog dump
+#
+rm -f @working_dir@/bacula.sql
--- /dev/null
+#!/bin/sh
+#
+# This script dumps your Bacula catalog in ASCII format
+# It works for either MySQL or SQLite
+#
+cd @working_dir@
+rm -f bacula.sql
+if test xsqlite = x@DB_NAME@ ; then
+echo ".dump" | @SQL_BINDIR@/sqlite bacula.db >bacula.sql
+else
+@SQL_BINDIR@/mysqldump -f --opt bacula >bacula.sql
+fi
+#
+# To read back a MySQL database use:
+# cd @working_dir@
+# rm -f @SQL_BINDIR@/../var/bacula/*
+# mysql <bacula.sql
+#
+# To read back a SQLite database use:
+# cd @working_dir@
+# rm -f bacula.db
+# sqlite bacula.db <bacula.sql
+#
Messages = Standard
}
-# Define the backup Job
+# Define the main nightly save backup job
Job {
Name = "NightlySave"
Type = Backup
Pool = Default
}
+# Backup the catalog database (after the nightly save)
+Job {
+ Name = "BackupCatalog"
+ Type = Backup
+ Client=@hostname@-fd
+ FileSet="Catalog"
+ Schedule = "WeeklyCycleAfterBackup"
+ Storage = DLTDrive
+ Messages = Standard
+ Pool = Default
+ # This creates an ASCII copy of the catalog
+ RunBeforeJob = "@sysconfdir@/make_catalog_backup"
+ # This deletes the copy of the catalog
+ RunAfterJob = "@sysconfdir@/delete_catalog_backup"
+}
+
# Standard Restore template, to be changed by Console program
Job {
Name = "RestoreFiles"
Exclude = { }
}
-# When to do the backups
+#
+# When to do the backups, full backup on first sunday of the month,
+# differential (i.e. incremental since full) every other sunday,
+# and incremental backups other days
Schedule {
Name = "WeeklyCycle"
- Run = Full sun at 1:05
+ Run = Full 1st sun at 1:05
+ Run = Differential 2nd-5th sun at 1:05
Run = Incremental mon-sat at 1:05
}
+# This schedule does the catalog. It starts after the WeeklyCycle
+Schedule {
+ Name = "WeeklyCycleAfterBackup
+ Run = Full sun-sat at 1:10
+}
+
+# This is the backup of the catalog
+FileSet {
+ Name = "Catalog"
+ Include = signature=MD5 {
+ @working_directory@/bacula.sql
+ }
+}
+
+
# Client (File Services) to backup
Client {
Name = @hostname@-fd
strcpy(buf, " hour=");
for (i=0; i<24; i++) {
if (bit_is_set(i, run->hour)) {
- sprintf(num, "%d ", i+1);
+ sprintf(num, "%d ", i);
strcat(buf, num);
}
}
}
strcat(buf, "\n");
sendit(sock, buf);
+ strcpy(buf, " wpos=");
+ for (i=0; i<5; i++) {
+ if (bit_is_set(i, run->wpos)) {
+ sprintf(num, "%d ", i+1);
+ strcat(buf, num);
+ }
+ }
+ strcat(buf, "\n");
+ sendit(sock, buf);
sendit(sock, " mins=%d\n", run->minute);
if (run->pool) {
sendit(sock, " --> ");
return;
}
-static void prt_runtime(UAContext *ua, JOB *job, time_t runtime)
+static void prt_runhdr(UAContext *ua)
+{
+ bsendmsg(ua, _("Level Type Scheduled Name\n"));
+ bsendmsg(ua, _("=================================================================\n"));
+}
+
+static void prt_runtime(UAContext *ua, JOB *job, int level, time_t runtime)
{
char dt[MAX_TIME_LENGTH];
bstrftime(dt, sizeof(dt), runtime);
- bsendmsg(ua, _("%s job \"%s\" scheduled for %s\n"),
- job_type_to_str(job->JobType), job->hdr.name, dt);
+ bsendmsg(ua, _("%-14s %-8s %-18s %s\n"),
+ level_to_str(level), job_type_to_str(job->JobType), dt, job->hdr.name);
}
/*
int mday, wday, month, wpos, tmday, twday, tmonth, twpos, i, hour;
int tod, tom;
int found;
+ int hdr_printed = FALSE;
+ int level;
Dmsg0(200, "enter find_runs()\n");
/* Loop through all jobs */
LockRes();
for (job=NULL; (job=(JOB *)GetNextRes(R_JOB, (RES *)job)); ) {
+ level = job->level;
sched = job->schedule;
if (sched == NULL) { /* scheduled? */
continue; /* no, skip this job */
}
for (run=sched->run; run; run=run->next) {
+ if (run->level) {
+ level = run->level;
+ }
/*
* Find runs in next 24 hours
*/
tm.tm_sec = 0;
runtime = mktime(&tm);
if (runtime > now) {
- prt_runtime(ua, job, runtime);
+ if (!hdr_printed) {
+ hdr_printed = TRUE;
+ prt_runhdr(ua);
+ }
+ prt_runtime(ua, job, level, runtime);
found = TRUE;
break;
}
runtime = mktime(&tm);
Dmsg2(200, "truntime=%d now=%d\n", runtime, now);
if (runtime < tomorrow) {
- prt_runtime(ua, job, runtime);
+ if (!hdr_printed) {
+ hdr_printed = TRUE;
+ prt_runhdr(ua);
+ }
+ prt_runtime(ua, job, level, runtime);
}
}
}