if (jr->JobId == 0) {
Mmsg(mdb->cmd, "SELECT VolSessionId,VolSessionTime,"
"PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus,"
-"Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId "
+"Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId "
"FROM Job WHERE Job='%s'", jr->Job);
} else {
Mmsg(mdb->cmd, "SELECT VolSessionId,VolSessionTime,"
"PoolId,StartTime,EndTime,JobFiles,JobBytes,JobTDate,Job,JobStatus,"
-"Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId "
+"Type,Level,ClientId,Name,PriorJobId,RealEndTime,JobId,FileSetId "
"FROM Job WHERE JobId=%s",
edit_int64(jr->JobId, ed1));
}
if (jr->JobId == 0) {
jr->JobId = str_to_int64(row[16]);
}
+ jr->FileSetId = str_to_int64(row[17]);
sql_free_result(mdb);
db_unlock(mdb);
return false;
}
+ jcr->spool_data = job->spool_data; /* turn on spooling if requested in job */
+
/* Create a migation jcr */
mig_jcr = jcr->mig_jcr = new_jcr(sizeof(JCR), dird_free_jcr);
memcpy(&mig_jcr->previous_jr, &jcr->previous_jr, sizeof(mig_jcr->previous_jr));
/* Now reset the job record from the previous job */
memcpy(&mig_jcr->jr, &jcr->previous_jr, sizeof(mig_jcr->jr));
- /* Update the jr to reflect the new values of PoolId, FileSetId, and JobId. */
+ /* Update the jr to reflect the new values of PoolId and JobId. */
mig_jcr->jr.PoolId = jcr->jr.PoolId;
- mig_jcr->jr.FileSetId = jcr->jr.FileSetId;
mig_jcr->jr.JobId = mig_jcr->JobId;
Dmsg4(dbglevel, "mig_jcr: Name=%s JobId=%d Type=%c Level=%c\n",
Dmsg1(dbglvl, "Close lex file: %s\n", lf->fname);
of = lf->next;
- fclose(lf->fd);
+ if (lf->bpipe) {
+ close_bpipe(lf->bpipe);
+ lf->bpipe = NULL;
+ } else {
+ fclose(lf->fd);
+ }
Dmsg1(dbglvl, "Close cfg file %s\n", lf->fname);
free(lf->fname);
if (of) {
{
LEX *nf;
FILE *fd;
+ BPIPE *bpipe = NULL;
char *fname = bstrdup(filename);
- if ((fd = fopen(fname, "rb")) == NULL) {
+ if (fname[0] == '|') {
+ if ((bpipe = open_bpipe(fname, 0, "rb")) == NULL) {
+ free(fname);
+ return NULL;
+ }
+ fd = bpipe->rfd;
+ } else if ((fd = fopen(fname, "rb")) == NULL) {
+ free(fname);
return NULL;
}
Dmsg1(400, "Open config file: %s\n", fname);
lex_set_default_error_handler(lf);
}
lf->fd = fd;
+ lf->bpipe = bpipe;
lf->fname = fname;
lf->state = lex_none;
lf->ch = L_EOL;
-/*
- * lex.h
- *
- * Lexical scanning of configuration files, used by parsers.
- *
- * Kern Sibbald, MM
- *
- * Version $Id$
- *
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2007 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
+/*
+ * lex.h
+ *
+ * Lexical scanning of configuration files, used by parsers.
+ *
+ * Kern Sibbald, MM
+ *
+ * Version $Id$
+ *
+ */
#ifndef _LEX_H
#define _LEX_H
#define LOPT_NO_IDENT 0x1 /* No Identifiers -- use string */
#define LOPT_STRING 0x2 /* Force scan for string */
+class BPIPE; /* forward reference */
+
/* Lexical context */
typedef struct s_lex_context {
struct s_lex_context *next; /* pointer to next lexical context */
void (*scan_error)(const char *file, int line, struct s_lex_context *lc, const char *msg, ...);
int err_type; /* message level for scan_error (M_..) */
void *caller_ctx; /* caller private data */
+ BPIPE *bpipe; /* set if we are piping */
} LEX;
typedef void (LEX_ERROR_HANDLER)(const char *file, int line, LEX *lc, const char *msg, ...);
Dmsg2(200, "===== After acquire pos %u:%u\n", jcr->dcr->dev->file, jcr->dcr->dev->block_num);
-
set_jcr_job_status(jcr, JS_Running);
dir_send_job_status(jcr);
+ begin_data_spool(jcr->dcr);
+ begin_attribute_spool(jcr);
+
jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
jcr->run_time = time(NULL);
Dmsg2(200, "Flush block to device pos %u:%u\n", dev->file, dev->block_num);
}
+ if (!ok) {
+ discard_data_spool(jcr->dcr);
+ } else {
+ /* Note: if commit is OK, the device will remain locked */
+ commit_data_spool(jcr->dcr);
+ }
if (ok && dev->is_dvd()) {
ok = dvd_close_job(jcr->dcr); /* do DVD cleanup if any */
}
/* Release the device -- and send final Vol info to DIR */
release_device(jcr->dcr);
+
+ if (!ok || job_canceled(jcr)) {
+ discard_attribute_spool(jcr);
+ } else {
+ commit_attribute_spool(jcr);
+ }
}
if (jcr->read_dcr) {
free_restore_volume_list(jcr);
-
- if (!ok || job_canceled(jcr)) {
- discard_attribute_spool(jcr);
- } else {
- commit_attribute_spool(jcr);
- }
-
dir_send_job_status(jcr); /* update director */
Technical notes on version 2.1
General:
+08May07
+kes Merge patch from Sergey Svishchev <svs@ropnet.ru> that preserves
+ the original jobb's FileSetId.
+kes Merge patch from Sergey Svishchev <svs@ropnet.ru> that implements
+ spooling in migration jobs. Not yet tested.
+kes Merge patch from Jorj Bauer <jorj@seas.upenn.edu> that implements
+ reading conf file from a pipe. However, do it with open_bpipe()
+ rather than popen. Not yet tested.
07May07
kes Fix an ugly bug where the VolCatBytes were getting updated
during a restore.