which the restore will be sent. The client keyword specifies
the backup client. The restoreclient keyword is optional if it is
not specified, the backup client will also be the restore client.
+- The disk file size is now checked to ensure that it agrees with the
+ catalog value before Bacula will append to the disk (same as tape
+ and DVD).
- Detect state change of system (verify)
Priority:
+- Mention Eric and Marc's work + Marc's doc.
- Add TLS to bat
- When Pool specifies Storage command override does not work.
- Implement wait_for_sysop() message display in wait_for_device(), which
Projects:
+- Average tape size from Eric
+ SELECT COALESCE(media_avg_size.volavg,0) * count(Media.MediaId) AS volmax, GROUP BY Media.MediaType, Media.PoolId, media_avg_size.volavg
+ count(Media.MediaId) AS volnum,
+ sum(Media.VolBytes) AS voltotal,
+ Media.PoolId AS PoolId,
+ Media.MediaType AS MediaType
+ FROM Media
+ LEFT JOIN (SELECT avg(Media.VolBytes) AS volavg,
+ Media.MediaType AS MediaType
+ FROM Media
+ WHERE Media.VolStatus = 'Full'
+ GROUP BY Media.MediaType
+ ) AS media_avg_size ON (Media.MediaType = media_avg_size.MediaType)
+ GROUP BY Media.MediaType, Media.PoolId, media_avg_size.volavg
- GUI
- Admin
- Management reports
bail_out:
set_jcr_job_status(jcr, JS_ErrorTerminated);
Dmsg1(400, "wait for sd. use=%d\n", jcr->use_count());
+ /* Cancel SD */
+ if (jcr->store_bsock) {
+ jcr->store_bsock->fsend("cancel Job=%s\n", jcr->Job);
+ }
wait_for_storage_daemon_termination(jcr);
Dmsg1(400, "after wait for sd. use=%d\n", jcr->use_count());
return false;
const char *sql_smallest_vol =
- "SELECT MediaId FROM Media,Pool WHERE"
- " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
+ "SELECT Media.MediaId FROM Media,Pool,JobMedia WHERE"
+ " Media.MediaId in (SELECT DISTINCT MediaId from JobMedia) AND"
+ " Media.VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
" Media.PoolId=Pool.PoolId AND Pool.Name='%s'"
" ORDER BY VolBytes ASC LIMIT 1";
const char *sql_oldest_vol =
- "SELECT MediaId FROM Media,Pool WHERE"
- " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
+ "SELECT Media.MediaId FROM Media,Pool,JobMedia WHERE"
+ " Media.MediaId in (SELECT DISTINCT MediaId from JobMedia) AND"
+ " Media.VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
" Media.PoolId=Pool.PoolId AND Pool.Name='%s'"
" ORDER BY LastWritten ASC LIMIT 1";
goto ok_out;
}
pool_bytes = ctx.value;
- Dmsg2(dbglevel, "highbytes=%d pool=%d\n", (int)jcr->rpool->MigrationHighBytes,
- (int)pool_bytes);
+ Dmsg2(dbglevel, "highbytes=%lld pool=%lld\n", jcr->rpool->MigrationHighBytes,
+ pool_bytes);
if (pool_bytes < (int64_t)jcr->rpool->MigrationHighBytes) {
Jmsg(jcr, M_INFO, 0, _("No Volumes found to migrate.\n"));
goto ok_out;
edit_uint64(jcr->MigrateJobId, ed1));
Dmsg1(dbglevel, "=============== Migration cmd=%s\n", ua->cmd);
parse_ua_args(ua); /* parse command */
- int stat = run_cmd(ua, ua->cmd);
- if (stat == 0) {
+ int jobid = run_cmd(ua, ua->cmd);
+ if (jobid == 0) {
Jmsg(jcr, M_ERROR, 0, _("Could not start migration job.\n"));
} else {
- Jmsg(jcr, M_INFO, 0, _("Migration JobId %d started.\n"), stat);
+ Jmsg(jcr, M_INFO, 0, _("Migration JobId %d started.\n"), jobid);
}
free_ua_context(ua);
}
goto bail_out;
}
if (ids->count == 0) {
- Jmsg(jcr, M_INFO, 0, _("No %ss found to migrate.\n"), type);
+ Jmsg(jcr, M_INFO, 0, _("No %s found to migrate.\n"), type);
ok = true; /* Not an error */
goto bail_out;
} else if (ids->count != 1) {
ids->count);
goto bail_out;
}
- Dmsg1(dbglevel, "Smallest Vol Jobids=%s\n", ids->list);
+ Dmsg2(dbglevel, "%s MediaIds=%s\n", type, ids->list);
ok = find_jobids_from_mediaid_list(jcr, ids, type);
*/
bool DEVICE::fsf(int num)
{
- int32_t os_file;
+ int32_t os_file = 0;
struct mtop mt_com;
int stat = 0;
* forward space past the end of the medium.
*/
if (has_cap(CAP_FSF) && has_cap(CAP_MTIOCGET) && has_cap(CAP_FASTFSF)) {
- int errno_save;
+ int my_errno = 0;
mt_com.mt_op = MTFSF;
mt_com.mt_count = num;
stat = tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com);
- errno_save = errno;
- if (stat < 0 || (os_file=get_os_tape_file()) < 0) {
- if (os_file >= 0) { /* get_os_tape_file reset errno */
- errno = errno_save;
- }
+ if (stat < 0) {
+ my_errno = errno; /* save errno */
+ } else if ((os_file=get_os_tape_file()) < 0) {
+ my_errno = errno; /* save errno */
+ }
+ if (my_errno != 0) {
berrno be;
set_eot();
Dmsg0(200, "Set ST_EOT\n");
clrerror(MTFSF);
Mmsg2(errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"),
- print_name(), be.bstrerror());
+ print_name(), be.bstrerror(my_errno));
Dmsg1(200, "%s", errmsg);
return false;
}
+
Dmsg1(200, "fsf file=%d\n", os_file);
set_ateof();
file = os_file;
jcr->unlock();
if (jcr->file_bsock) {
bnet_sig(jcr->file_bsock, BNET_TERMINATE);
+ } else {
+ /* Still waiting for FD to connect, release it */
+ pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
}
/* If thread waiting on mount, wake him */
if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
#undef VERSION
#define VERSION "2.1.8"
-#define BDATE "08 May 2007"
-#define LSMDATE "08May07"
+#define BDATE "09 May 2007"
+#define LSMDATE "09May07"
#define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
#define BYEAR "2007" /* year for copyright messages in progs */
Technical notes on version 2.1
General:
+09May07
+kes When backup fails, cancel SD before waiting for sd termination.
+kes If SD is waiting for FD to connect during cancel, wake up the
+ thread.
+kes Fix fsf code so that errno is correctly reported.
+kes Apply migration patch (with changes) from Sergey Svishchev <svs@ropnet.ru>
08May07
kes Make lack of Pool directive in Job an ERROR_TERM rather than FATAL
so that Bacula doesn't later stumble into a seg fault.