X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fbscan.c;h=8f1c1faec41b8e6dd0cd48d01473854cda8e269d;hb=2499795e233e43bd4eb4d99e0473b67e6c6b60d8;hp=2bdeac3f0480228d5734b3b6cfbdeca7ffddb641;hpb=20fc7f2a60430f0c87f182aa7e8dc60d5afe168a;p=bacula%2Fbacula diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index 2bdeac3f04..8f1c1faec4 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2008 Free Software Foundation Europe e.V. + Copyright (C) 2001-2010 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Bacula® is a registered trademark of John Walker. + Bacula® is a registered trademark of Kern Sibbald. The licensor of Bacula is the Free Software Foundation Europe (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, Switzerland, email:ftf@fsfeurope.org. @@ -33,8 +33,6 @@ * * Kern E. Sibbald, December 2001 * - * - * Version $Id$ */ #include "bacula.h" @@ -44,6 +42,7 @@ /* Dummy functions */ int generate_daemon_event(JCR *jcr, const char *event) { return 1; } +extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code); /* Forward referenced functions */ static void do_scan(void); @@ -82,10 +81,12 @@ static ATTR *attr; static time_t lasttime = 0; +static const char *db_driver = "NULL"; static const char *db_name = "bacula"; static const char *db_user = "bacula"; static const char *db_password = ""; static const char *db_host = NULL; +static int db_port = 0; static const char *wd = NULL; static bool update_db = false; static bool update_vol_info = false; @@ -100,6 +101,7 @@ static int num_pools = 0; static int num_media = 0; static int num_files = 0; +static CONFIG *config; #define CONFIG_FILE "bacula-sd.conf" char *configfile = NULL; STORES *me = NULL; /* our Global resource */ @@ -119,10 +121,12 @@ PROG_COPYRIGHT " -d set debug level to \n" " -dt print timestamp in debug output\n" " -m update media info in database\n" +" -D specify the driver database name (default NULL)\n" " -n specify the database name (default bacula)\n" " -u specify database user name (default bacula)\n" " -P specify database password (default none)\n" " -h specify database host (default NULL)\n" +" -t specify database port (default 0)\n" " -p proceed inspite of I/O errors\n" " -r list records\n" " -s synchronize or store in database\n" @@ -144,13 +148,14 @@ int main (int argc, char *argv[]) bindtextdomain("bacula", LOCALEDIR); textdomain("bacula"); init_stack_dump(); + lmgr_init_thread(); my_name_is(argc, argv, "bscan"); init_msg(NULL, NULL); OSDependentInit(); - while ((ch = getopt(argc, argv, "b:c:d:h:mn:pP:rsSu:vV:w:?")) != -1) { + while ((ch = getopt(argc, argv, "b:c:d:D:h:p:mn:pP:rsSt:u:vV:w:?")) != -1) { switch (ch) { case 'S' : showProgress = true; @@ -166,6 +171,10 @@ int main (int argc, char *argv[]) configfile = bstrdup(optarg); break; + case 'D': + db_driver = optarg; + break; + case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; @@ -180,6 +189,10 @@ int main (int argc, char *argv[]) case 'h': db_host = optarg; break; + + case 't': + db_port = atoi(optarg); + break; case 'm': update_vol_info = true; @@ -239,7 +252,8 @@ int main (int argc, char *argv[]) configfile = bstrdup(CONFIG_FILE); } - parse_config(configfile); + config = new_config_parser(); + parse_sd_config(config, configfile, M_ERROR_TERM); LockRes(); me = (STORES *)GetNextRes(R_STORAGE, NULL); if (!me) { @@ -278,12 +292,12 @@ int main (int argc, char *argv[]) struct stat sb; fstat(dev->fd(), &sb); currentVolumeSize = sb.st_size; - Pmsg1(000, _("First Volume Size = %sn"), + Pmsg1(000, _("First Volume Size = %s\n"), edit_uint64(currentVolumeSize, ed1)); } - if ((db=db_init_database(NULL, db_name, db_user, db_password, - db_host, 0, NULL, 0)) == NULL) { + if ((db=db_init(NULL, db_driver, db_name, db_user, db_password, + db_host, db_port, NULL, 0)) == NULL) { Emsg0(M_ERROR_TERM, 0, _("Could not init Bacula database\n")); } if (!db_open_database(NULL, db)) { @@ -317,7 +331,7 @@ static bool bscan_mount_next_read_volume(DCR *dcr) { DEVICE *dev = dcr->dev; DCR *mdcr; - Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName); + Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->getVolCatName()); foreach_dlist(mdcr, dev->attached_dcrs) { JCR *mjcr = mdcr->jcr; Dmsg1(000, "========== JobId=%u ========\n", mjcr->JobId); @@ -335,7 +349,7 @@ static bool bscan_mount_next_read_volume(DCR *dcr) mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex; if (!create_jobmedia_record(db, mjcr)) { Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"), - dev->VolCatInfo.VolCatName, mjcr->Job); + dev->getVolCatName(), mjcr->Job); } } @@ -352,7 +366,7 @@ static bool bscan_mount_next_read_volume(DCR *dcr) struct stat sb; fstat(dev->fd(), &sb); currentVolumeSize = sb.st_size; - Pmsg1(000, _("First Volume Size = %sn"), + Pmsg1(000, _("First Volume Size = %s\n"), edit_uint64(currentVolumeSize, ed1)); } return stat; @@ -513,9 +527,9 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) } } /* Create Client record if not already there */ - bstrncpy(cr.Name, label.ClientName, sizeof(cr.Name)); - create_client_record(db, &cr); - jr.ClientId = cr.ClientId; + bstrncpy(cr.Name, label.ClientName, sizeof(cr.Name)); + create_client_record(db, &cr); + jr.ClientId = cr.ClientId; /* process label, if Job record exists don't update db */ mjcr = create_job_record(db, &jr, &label, rec); @@ -523,22 +537,8 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) update_db = save_update_db; jr.PoolId = pr.PoolId; -#ifdef xxx - /* Set start positions into JCR */ - if (dev->is_tape()) { - /* - * Note, we have already advanced past current block, - * so the correct number is block_num - 1 - */ - dcr->StartBlock = dev->block_num - 1; - dcr->StartFile = dev->file; - } else { - dcr->StartBlock = (uint32_t)dev->file_addr; - dcr->StartFile = (uint32_t)(dev->file_addr >> 32); - } -#endif mjcr->start_time = jr.StartTime; - mjcr->JobLevel = jr.JobLevel; + mjcr->set_JobLevel(jr.JobLevel); mjcr->client_name = get_pool_memory(PM_FNAME); pm_strcpy(mjcr->client_name, label.ClientName); @@ -592,7 +592,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) /* Create JobMedia record */ mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex; create_jobmedia_record(db, mjcr); - detach_dcr_from_dev(mjcr->read_dcr); + free_dcr(mjcr->read_dcr); free_jcr(mjcr); break; @@ -662,15 +662,10 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: - if (!unpack_attributes_record(bjcr, rec->Stream, rec->data, attr)) { + if (!unpack_attributes_record(bjcr, rec->Stream, rec->data, rec->data_len, attr)) { Emsg0(M_ERROR_TERM, 0, _("Cannot continue.\n")); } - if (attr->file_index != rec->FileIndex) { - Emsg2(M_ERROR_TERM, 0, _("Record header file index %ld not equal record index %ld\n"), - rec->FileIndex, attr->file_index); - } - if (verbose > 1) { decode_stat(attr->attr, &attr->statp, &attr->LinkFI); build_attr_output_fnames(bjcr, attr); @@ -692,6 +687,11 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) free_jcr(mjcr); break; + case STREAM_RESTORE_OBJECT: + /* ****FIXME*****/ + /* Implement putting into catalog */ + break; + /* Data stream */ case STREAM_WIN32_DATA: case STREAM_FILE_DATA: @@ -790,9 +790,33 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec) } break; - case STREAM_UNIX_ACCESS_ACL: /* Standard ACL attributes on UNIX */ - case STREAM_UNIX_DEFAULT_ACL: /* Default ACL attributes on UNIX */ - /* Ignore Unix attributes */ + case STREAM_UNIX_ACCESS_ACL: /* Deprecated Standard ACL attributes on UNIX */ + case STREAM_UNIX_DEFAULT_ACL: /* Deprecated Default ACL attributes on UNIX */ + case STREAM_ACL_AIX_TEXT: + case STREAM_ACL_DARWIN_ACCESS_ACL: + case STREAM_ACL_FREEBSD_DEFAULT_ACL: + case STREAM_ACL_FREEBSD_ACCESS_ACL: + case STREAM_ACL_HPUX_ACL_ENTRY: + case STREAM_ACL_IRIX_DEFAULT_ACL: + case STREAM_ACL_IRIX_ACCESS_ACL: + case STREAM_ACL_LINUX_DEFAULT_ACL: + case STREAM_ACL_LINUX_ACCESS_ACL: + case STREAM_ACL_TRU64_DEFAULT_ACL: + case STREAM_ACL_TRU64_DEFAULT_DIR_ACL: + case STREAM_ACL_TRU64_ACCESS_ACL: + case STREAM_ACL_SOLARIS_ACLENT: + case STREAM_ACL_SOLARIS_ACE: + /* Ignore Unix ACL attributes */ + break; + + case STREAM_XATTR_OPENBSD: + case STREAM_XATTR_SOLARIS_SYS: + case STREAM_XATTR_SOLARIS: + case STREAM_XATTR_DARWIN: + case STREAM_XATTR_FREEBSD: + case STREAM_XATTR_LINUX: + case STREAM_XATTR_NETBSD: + /* Ignore Unix Extended attributes */ break; default: @@ -847,7 +871,11 @@ static int create_file_attributes_record(B_DB *db, JCR *mjcr, ar.ClientId = mjcr->ClientId; ar.JobId = mjcr->JobId; ar.Stream = rec->Stream; - ar.FileIndex = rec->FileIndex; + if (type == FT_DELETED) { + ar.FileIndex = 0; + } else { + ar.FileIndex = rec->FileIndex; + } ar.attr = ap; if (dcr->VolFirstIndex == 0) { dcr->VolFirstIndex = rec->FileIndex; @@ -884,6 +912,7 @@ static int create_media_record(B_DB *db, MEDIA_DBR *mr, VOLUME_LABEL *vl) mr->VolRetention = 365 * 3600 * 24; /* 1 year */ mr->Enabled = 1; if (vl->VerNum >= 11) { + mr->set_first_written = true; /* Save FirstWritten during update_media */ mr->FirstWritten = btime_to_utime(vl->write_btime); mr->LabelDate = btime_to_utime(vl->label_btime); } else { @@ -1109,6 +1138,9 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel, jr->JobStatus = elabel->JobStatus; mjcr->JobStatus = elabel->JobStatus; jr->JobFiles = elabel->JobFiles; + if (jr->JobFiles > 0) { /* If we found files, force PurgedFiles */ + jr->PurgedFiles = 0; + } jr->JobBytes = elabel->JobBytes; jr->VolSessionId = rec->VolSessionId; jr->VolSessionTime = rec->VolSessionTime; @@ -1127,7 +1159,7 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel, } if (verbose) { Pmsg3(000, _("Updated Job termination record for JobId=%u Level=%s TermStat=%c\n"), - jr->JobId, job_level_to_str(mjcr->JobLevel), jr->JobStatus); + jr->JobId, job_level_to_str(mjcr->getJobLevel()), jr->JobStatus); } if (verbose > 1) { const char *term_msg; @@ -1139,6 +1171,9 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel, case JS_Terminated: term_msg = _("Backup OK"); break; + case JS_Warnings: + term_msg = _("Backup OK -- with warnings"); + break; case JS_FatalError: case JS_ErrorTerminated: term_msg = _("*** Backup Error ***"); @@ -1171,7 +1206,7 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel, mjcr->JobId, mjcr->Job, mjcr->fileset_name, - job_level_to_str(mjcr->JobLevel), + job_level_to_str(mjcr->getJobLevel()), mjcr->client_name, sdt, edt, @@ -1268,8 +1303,8 @@ static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId) * the JobId and the ClientId. */ jobjcr = new_jcr(sizeof(JCR), bscan_free_jcr); - jobjcr->JobType = jr->JobType; - jobjcr->JobLevel = jr->JobLevel; + jobjcr->set_JobType(jr->JobType); + jobjcr->set_JobLevel(jr->JobLevel); jobjcr->JobStatus = jr->JobStatus; bstrncpy(jobjcr->Job, jr->Job, sizeof(jobjcr->Job)); jobjcr->JobId = JobId; /* this is JobId on tape */ @@ -1286,7 +1321,7 @@ static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId) /* Dummies to replace askdir.c */ bool dir_find_next_appendable_volume(DCR *dcr) { return 1;} bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten) { return 1; } -bool dir_create_jobmedia_record(DCR *dcr) { return 1; } +bool dir_create_jobmedia_record(DCR *dcr, bool zero) { return 1; } bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; } bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;} bool dir_send_job_status(JCR *jcr) {return 1;} @@ -1307,8 +1342,8 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /*mode*/) bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { Dmsg0(100, "Fake dir_get_volume_info\n"); - bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName)); + dcr->setVolCatName(dcr->VolumeName); dcr->VolCatInfo.VolCatParts = find_num_dvd_parts(dcr); - Dmsg2(500, "Vol=%s num_parts=%d\n", dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatParts); + Dmsg2(500, "Vol=%s num_parts=%d\n", dcr->getVolCatName(), dcr->VolCatInfo.VolCatParts); return 1; }