From: Kern Sibbald Date: Mon, 29 Sep 2003 16:36:21 +0000 (+0000) Subject: FreeBSD fixes; manual updates X-Git-Tag: Release-1.32~3 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=84a05f3bfbde64c606b014d68b45b2d060e2a478;p=bacula%2Fbacula FreeBSD fixes; manual updates git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@716 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/autoconf/aclocal.m4 b/bacula/autoconf/aclocal.m4 index 819b8b5958..8f0aab87b2 100644 --- a/bacula/autoconf/aclocal.m4 +++ b/bacula/autoconf/aclocal.m4 @@ -328,7 +328,7 @@ then elif test -f /etc/engarde-version then DISTNAME=engarde -elif test "$ac_cv_cygwin" = yes +elif test "$CYGWIN" = yes then DISTNAME=cygwin AC_DEFINE(HAVE_CYGWIN) @@ -1428,4 +1428,3 @@ AC_DEFUN(PKG_CHECK_MODULES, [ ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) fi ]) - diff --git a/bacula/configure b/bacula/configure index ea8b2cac36..89b636774c 100755 --- a/bacula/configure +++ b/bacula/configure @@ -4186,7 +4186,7 @@ then elif test -f /etc/engarde-version then DISTNAME=engarde -elif test "$ac_cv_cygwin" = yes +elif test "$CYGWIN" = yes then DISTNAME=cygwin cat >>confdefs.h <<\_ACEOF diff --git a/bacula/kernstodo b/bacula/kernstodo index 217f116396..3edeac324b 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -33,15 +33,21 @@ For 1.32 Testing/Documentation: - Add counter variable test. For 1.32: -- Look at Cleaning tape in ua_label.c for media create/update -- Fix get_storage_from_media_type (ua_restore) to use command line - storage= -- Document list nextvol and status output. - Add GUI interface to manual -- Add regression testing to the manual - +- Document that Volume pruning can delete last Full backup and + hence you will not have a valid backup. +- Clarify the fact that having the Bacula cygwin1.dll loaded + is not the same as having cygwin installed. +- Fix sparse file handeling so that it always reads a multiple + of 512. Currently, it subtracts 8 bytes (for faddr). +- Separate Dir heartbeat in FD from the SD heartbeat. For 1.33 +- When job rescheduled, status gives is waiting for Client Rufus + to connect to Storage File. Dir needs to inform SD that job + is rescheduled. +- Fix get_storage_from_media_type (ua_restore) to use command line + storage= - Enhance "update slots" to include a "scan" feature scan 1; scan 1-5; scan 1,2,4 ... to update the catalog - Allow a slot or range of slots on the label barcodes command. @@ -947,3 +953,7 @@ Done: (see kernsdone for more) - Figure out some way to ignore or get past checksum errors in reading. - The SD spooling file gets created even if it is not used. +- Look at Cleaning tape in ua_label.c for media create/update +- Add regression testing to the manual +- End time: in job output of rescheduled job is time of first run. +- Document list nextvol and status output. diff --git a/bacula/src/dird/bacula-dir.conf.in b/bacula/src/dird/bacula-dir.conf.in index fd5b8ecd46..be3f7e3626 100644 --- a/bacula/src/dird/bacula-dir.conf.in +++ b/bacula/src/dird/bacula-dir.conf.in @@ -130,8 +130,8 @@ Client { FDPort = @fd_port@ Catalog = MyCatalog Password = "@fd_password@" # password for FileDaemon - File Retention = 30d # 30 days - Job Retention = 180d # six months + File Retention = 30 days # 30 days + Job Retention = 6 months # six months AutoPrune = yes # Prune expired Jobs/Files } @@ -196,6 +196,6 @@ Pool { Pool Type = Backup Recycle = yes # Bacula can automatically recycle Volumes AutoPrune = yes # Prune expired volumes - Volume Retention = 365d # one year + Volume Retention = 365 days # one year Accept Any Volume = yes # write on any volume in the pool } diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index 1827194306..597edcfafb 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -69,6 +69,7 @@ void run_job(JCR *jcr) set_jcr_job_status(jcr, JS_Created); jcr->jr.SchedTime = jcr->sched_time; jcr->jr.StartTime = jcr->start_time; + jcr->jr.EndTime = 0; /* perhaps rescheduled, clear it */ jcr->jr.Type = jcr->JobType; jcr->jr.Level = jcr->JobLevel; jcr->jr.JobStatus = jcr->JobStatus; diff --git a/bacula/src/dird/jobq.c b/bacula/src/dird/jobq.c index 10cffd0f1c..eb4640efcd 100755 --- a/bacula/src/dird/jobq.c +++ b/bacula/src/dird/jobq.c @@ -242,9 +242,7 @@ int jobq_add(jobq_t *jq, JCR *jcr) /* Ensure that at least one server looks at the queue. */ stat = start_server(jq); - if (stat == 0) { - pthread_mutex_unlock(&jq->mutex); - } + pthread_mutex_unlock(&jq->mutex); Dmsg0(100, "Return jobq_add\n"); return stat; } @@ -288,9 +286,7 @@ int jobq_remove(jobq_t *jq, JCR *jcr) jq->ready_jobs->prepend(item); stat = start_server(jq); - if (stat != 0) { - return stat; - } + pthread_mutex_unlock(&jq->mutex); Dmsg0(100, "Return jobq_remove\n"); return stat; @@ -309,7 +305,6 @@ static int start_server(jobq_t *jq) if (jq->idle_workers > 0) { Dmsg0(100, "Signal worker to wake up\n"); if ((stat = pthread_cond_signal(&jq->work)) != 0) { - pthread_mutex_unlock(&jq->mutex); return stat; } } else if (jq->num_workers < jq->max_workers) { @@ -317,10 +312,8 @@ static int start_server(jobq_t *jq) /* No idle threads so create a new one */ set_thread_concurrency(jq->max_workers + 1); if ((stat = pthread_create(&id, &jq->attr, jobq_server, (void *)jq)) != 0) { - pthread_mutex_unlock(&jq->mutex); return stat; } - jq->num_workers++; } return stat; } @@ -344,6 +337,7 @@ static void *jobq_server(void *arg) if ((stat = pthread_mutex_lock(&jq->mutex)) != 0) { return NULL; } + jq->num_workers++; for (;;) { struct timeval tv; @@ -386,12 +380,15 @@ static void *jobq_server(void *arg) if (!jq->ready_jobs->empty()) { Dmsg0(100, "ready queue not empty start server\n"); if (start_server(jq) != 0) { + jq->num_workers--; + pthread_mutex_unlock(&jq->mutex); return NULL; } } jq->running_jobs->append(je); Dmsg1(100, "Took jobid=%d from ready and appended to run\n", jcr->JobId); if ((stat = pthread_mutex_unlock(&jq->mutex)) != 0) { + jq->num_workers--; return NULL; } /* Call user's routine here */ @@ -399,6 +396,7 @@ static void *jobq_server(void *arg) jq->engine(je->jcr); Dmsg1(100, "Back from user engine jobid=%d.\n", jcr->JobId); if ((stat = pthread_mutex_lock(&jq->mutex)) != 0) { + jq->num_workers--; free(je); /* release job entry */ return NULL; } diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index 27af6a471c..028c5e74b7 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -355,14 +355,21 @@ static void label_from_barcodes(UAContext *ua) * send_label_request() below */ if (is_cleaning_tape(ua, &mr, &pr)) { - set_pool_dbr_defaults_in_media_dbr(&mr, &pr); - if (db_create_media_record(ua->jcr, ua->db, &mr)) { - bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"), - mr.VolumeName); - } else { - bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db)); + if (media_record_exists) { /* we update it */ + mr.VolBytes = 1; + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + bsendmsg(ua, "%s", db_strerror(ua->db)); + } + } else { /* create the media record */ + set_pool_dbr_defaults_in_media_dbr(&mr, &pr); + if (db_create_media_record(ua->jcr, ua->db, &mr)) { + bsendmsg(ua, _("Catalog record for cleaning tape \"%s\" successfully created.\n"), + mr.VolumeName); + } else { + bsendmsg(ua, "Catalog error on cleaning tape: %s", db_strerror(ua->db)); + } } - continue; + continue; /* done, go handle next volume */ } bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); if (ua->jcr->store_bsock) { diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 65bd47c26d..44ca5bac40 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -223,84 +223,86 @@ static void do_director_status(UAContext *ua, char *cmd) continue; } switch (jcr->JobStatus) { - case JS_Created: - msg = _("is waiting execution"); - break; - case JS_Running: - msg = _("is running"); - break; - case JS_Blocked: - msg = _("is blocked"); - break; - case JS_Terminated: - msg = _("has terminated"); - break; - case JS_ErrorTerminated: - msg = _("has erred"); - break; - case JS_Canceled: - msg = _("has been canceled"); - break; - case JS_WaitFD: - msg = (char *) get_pool_memory(PM_FNAME); - Mmsg(&msg, _("is waiting on Client %s"), jcr->client->hdr.name); - pool_mem = TRUE; - break; - case JS_WaitSD: - msg = (char *) get_pool_memory(PM_FNAME); - Mmsg(&msg, _("is waiting on Storage %s"), jcr->store->hdr.name); - pool_mem = TRUE; - break; - case JS_WaitStoreRes: - msg = _("is waiting on max Storage jobs"); - break; - case JS_WaitClientRes: - msg = _("is waiting on max Client jobs"); - break; - case JS_WaitJobRes: - msg = _("is waiting on max Job jobs"); - break; - case JS_WaitPriority: - msg = _("is waiting for higher priority jobs to finish"); - break; - case JS_WaitMaxJobs: - msg = _("is waiting on max total jobs"); - break; - case JS_WaitStartTime: - msg = _("is waiting for its start time"); - break; + case JS_Created: + msg = _("is waiting execution"); + break; + case JS_Running: + msg = _("is running"); + break; + case JS_Blocked: + msg = _("is blocked"); + break; + case JS_Terminated: + msg = _("has terminated"); + break; + case JS_ErrorTerminated: + msg = _("has erred"); + break; + case JS_Canceled: + msg = _("has been canceled"); + break; + case JS_WaitFD: + msg = (char *) get_pool_memory(PM_FNAME); + Mmsg(&msg, _("is waiting on Client %s"), jcr->client->hdr.name); + pool_mem = TRUE; + break; + case JS_WaitSD: + msg = (char *) get_pool_memory(PM_FNAME); + Mmsg(&msg, _("is waiting on Storage %s"), jcr->store->hdr.name); + pool_mem = TRUE; + break; + case JS_WaitStoreRes: + msg = _("is waiting on max Storage jobs"); + break; + case JS_WaitClientRes: + msg = _("is waiting on max Client jobs"); + break; + case JS_WaitJobRes: + msg = _("is waiting on max Job jobs"); + break; + case JS_WaitPriority: + msg = _("is waiting for higher priority jobs to finish"); + break; + case JS_WaitMaxJobs: + msg = _("is waiting on max total jobs"); + break; + case JS_WaitStartTime: + msg = _("is waiting for its start time"); + break; - default: - msg = (char *) get_pool_memory(PM_FNAME); - Mmsg(&msg, _("is in unknown state %c"), jcr->JobStatus); - pool_mem = TRUE; - break; + default: + msg = (char *) get_pool_memory(PM_FNAME); + Mmsg(&msg, _("is in unknown state %c"), jcr->JobStatus); + pool_mem = TRUE; + break; } + /* + * Now report Storage daemon status code + */ switch (jcr->SDJobStatus) { - case JS_WaitMount: - if (pool_mem) { - free_pool_memory(msg); - pool_mem = FALSE; - } - msg = _("is waiting for a mount request"); - break; - case JS_WaitMedia: - if (pool_mem) { - free_pool_memory(msg); - pool_mem = FALSE; - } - msg = _("is waiting for an appendable Volume"); - break; - case JS_WaitFD: - if (!pool_mem) { - msg = (char *) get_pool_memory(PM_FNAME); - pool_mem = TRUE; - } - Mmsg(&msg, _("is waiting for Client %s to connect to Storage %s"), - jcr->client->hdr.name, jcr->store->hdr.name); - break; - + case JS_WaitMount: + if (pool_mem) { + free_pool_memory(msg); + pool_mem = FALSE; + } + msg = _("is waiting for a mount request"); + break; + case JS_WaitMedia: + if (pool_mem) { + free_pool_memory(msg); + pool_mem = FALSE; + } + msg = _("is waiting for an appendable Volume"); + break; + case JS_WaitFD: + if (!pool_mem) { + msg = (char *) get_pool_memory(PM_FNAME); + pool_mem = TRUE; + } + Mmsg(&msg, _("is waiting for Client %s to connect to Storage %s"), + jcr->client->hdr.name, jcr->store->hdr.name); + break; } bsendmsg(ua, _("JobId %d Job %s %s.\n"), jcr->JobId, jcr->Job, msg); if (pool_mem) { diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index cb0b56be41..68c475df97 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -346,6 +346,13 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) if (ff_pkt->flags & FO_SPARSE) { rbuf += SPARSE_FADDR_SIZE; rsize -= SPARSE_FADDR_SIZE; +#ifdef HAVE_FREEBSD_OS + /* + * To read FreeBSD partitions, the read size must be + * a multiple of 512. + */ + rsize = (rsize/512) * 512; +#endif } /* diff --git a/bacula/src/filed/heartbeat.c b/bacula/src/filed/heartbeat.c index 458871d372..bda617ee11 100644 --- a/bacula/src/filed/heartbeat.c +++ b/bacula/src/filed/heartbeat.c @@ -63,8 +63,9 @@ static void *sd_heartbeat_thread(void *arg) jcr->hb_bsock = sd; /* Hang reading the socket to the SD, and every time we get - * a heartbeat, we simply send it on to the Director to - * keep him alive. + * a heartbeat or we get a wait timeout (1 minute), we + * check to see if we need to send a heartbeat to the + * Directory. */ for ( ; !is_bnet_stop(sd); ) { n = bnet_wait_data_intr(sd, WAIT_INTERVAL); diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index ff1c0df442..ae7c984746 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -381,7 +381,18 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * a block device, we do a raw backup of it or if it is * a fifo, we simply read it. */ +#ifdef HAVE_FREEBSD_OS + /* + * On FreeBSD, all block devices are character devices, so + * to be able to read a raw disk, we need the check for + * a character device. +    * crw-r-----  1 root  operator  - 116, 0x00040002 Jun  9 19:32 /dev/ad0s3 +    * crw-r-----  1 root  operator  - 116, 0x00040002 Jun  9 19:32 /dev/rad0s3 + */ + if (top_level && (S_ISBLK(ff_pkt->statp.st_mode) || S_ISCHR(ff_pkt->statp.st_mode))) { +#else if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) { +#endif ff_pkt->type = FT_RAW; /* raw partition */ } else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) && ff_pkt->flags & FO_READFIFO) { diff --git a/bacula/src/stored/job.c b/bacula/src/stored/job.c index 664e3f4909..8673fa4757 100644 --- a/bacula/src/stored/job.c +++ b/bacula/src/stored/job.c @@ -70,6 +70,7 @@ int job_cmd(JCR *jcr) struct timeval tv; struct timezone tz; struct timespec timeout; + JCR *ojcr; /* * Get JobId and permissions from Director @@ -95,6 +96,16 @@ int job_cmd(JCR *jcr) set_jcr_job_status(jcr, JS_ErrorTerminated); return 0; } + /* + * Since this job could be rescheduled, we + * check to see if we have it already. If so + * free the old jcr and use the new one. + */ + ojcr = get_jcr_by_full_name(job); + if (ojcr && !ojcr->authenticated) { + Dmsg2(000, "Found ojcr=0x%x Job %s\n", (unsigned)ojcr, job); + free_jcr(ojcr); + } jcr->JobId = JobId; jcr->VolSessionId = newVolSessionId(); jcr->VolSessionTime = VolSessionTime;