Kern's ToDo List
- 06 June 2003
+ 10 June 2003
Documentation to do: (any release a little bit at a time)
- Document running a test version.
- Add next Volume to be used to status output.
- Add a recycle command.
- Make bootstrap filename unique.
-- Implement FileSet VolIndex -- done, but must update old records.
- Sort JobIds entered into recover tree.
- The bsr for Dan's job has file indexes covering the whole range rather
than only the range contained on the volume.
- Implement Release Storage=xxx
- Fix restore on Win95/98
- Remove the Jmsg() in sql_find.c:102 or only print on hard error.
+- Implement FileSet VolIndex -- done, but must update old records.
#define Mmsg15(buf,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) m_msg(__FILE__,__LINE__,buf,msg,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15)
/* Edit message into Pool Memory buffer -- no __FILE__ and __LINE__ */
-int Mmsg(char **msgbuf, char *fmt,...);
+int Mmsg(POOLMEM **msgbuf, char *fmt,...);
struct JCR;
void p_msg(char *file, int line, int level, char *fmt,...);
void e_msg(char *file, int line, int type, int level, char *fmt,...);
void j_msg(char *file, int line, JCR *jcr, int type, int level, char *fmt,...);
-int m_msg(char *file, int line, char **msgbuf, char *fmt,...);
+int m_msg(char *file, int line, POOLMEM **msgbuf, char *fmt,...);
/* Use our strdup with smartalloc */
* includes before these.
*/
#include "version.h"
-#include "baconfig.h"
#include "bc_types.h"
+#include "baconfig.h"
#include "lib/lib.h"
#ifndef HAVE_ZLIB_H
#ifndef __bc_types_INCLUDED
#define __bc_types_INCLUDED
-typedef char POOLMEM;
+typedef char POOLMEM;
+#define mp_chr(x) x
+#ifdef xxxxx
+#define mp_chr(x) ((char*)(x))
+struct POOLMEM { };
+#endif
/* Types */
"WHERE FileSetId=%u", fsr->FileSetId);
} else { /* find by name */
Mmsg(&mdb->cmd,
- "SELECT FileSetId,FileSet,CreateTime MD5,FROM FileSet "
+ "SELECT FileSetId,FileSet,CreateTime,MD5 FROM FileSet "
"WHERE FileSet='%s'", fsr->FileSet);
}
Dmsg7(200, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n",
attr->file_index, attr->type, attr->fname, attr->attr, attr->lname,
attr->attrEx, attr->data_stream);
- *attr->ofname = 0;
- *attr->olname = 0;
+ *mp_chr(attr->ofname) = 0;
+ *mp_chr(attr->olname) = 0;
return 1;
}
pm_strcpy(&attr->olname, jcr->where);
add_link = true;
} else {
- attr->olname[0] = 0;
+ mp_chr(attr->olname)[0] = 0;
add_link = false;
}
if (win32_client && attr->lname[1] == ':') {
p = encode_time(attr->statp.st_ctime, p);
*p++ = ' ';
*p++ = ' ';
- for (f=attr->ofname; *f && (p-buf) < (int)sizeof(buf)-10; ) {
+ for (f=mp_chr(attr->ofname); *f && (p-buf) < (int)sizeof(buf)-10; ) {
*p++ = *f++;
}
if (attr->type == FT_LNK) {
*p++ = '>';
*p++ = ' ';
/* Copy link name */
- for (f=attr->olname; *f && (p-buf) < (int)sizeof(buf)-10; ) {
+ for (f=mp_chr(attr->olname); *f && (p-buf) < (int)sizeof(buf)-10; ) {
*p++ = *f++;
}
}
int32_t nbytes;
int32_t pktsiz;
- bsock->msg[0] = 0;
+ mp_chr(bsock->msg)[0] = 0;
if (bsock->errors || bsock->terminated) {
return BNET_HARDEOF;
}
bsock->timer_start = watchdog_time; /* set start wait time */
bsock->timed_out = 0;
/* now read the actual data */
- if ((nbytes = read_nbytes(bsock, bsock->msg, pktsiz)) <= 0) {
+ if ((nbytes = read_nbytes(bsock, mp_chr(bsock->msg), pktsiz)) <= 0) {
bsock->timer_start = 0; /* clear timer */
if (errno == 0) {
bsock->b_errno = ENODATA;
* string that was send to us. Note, we ensured above that the
* buffer is at least one byte longer than the message length.
*/
- bsock->msg[nbytes] = 0; /* terminate in case it is a string */
+ mp_chr(bsock->msg)[nbytes] = 0; /* terminate in case it is a string */
sm_check(__FILE__, __LINE__, False);
return nbytes; /* return actual length of message */
}
/* send data packet */
bsock->timer_start = watchdog_time; /* start timer */
bsock->timed_out = 0;
- rc = write_nbytes(bsock, bsock->msg, bsock->msglen);
+ rc = write_nbytes(bsock, mp_chr(bsock->msg), bsock->msglen);
bsock->timer_start = 0; /* clear timer */
if (rc != bsock->msglen) {
bsock->errors++;
again:
maxlen = sizeof_pool_memory(bs->msg) - 1;
va_start(arg_ptr, fmt);
- bs->msglen = bvsnprintf(bs->msg, maxlen, fmt, arg_ptr);
+ bs->msglen = bvsnprintf(mp_chr(bs->msg), maxlen, fmt, arg_ptr);
va_end(arg_ptr);
if (bs->msglen < 0 || bs->msglen >= maxlen) {
bs->msg = realloc_pool_memory(bs->msg, maxlen + 200);
/* Build arguments for running program. */
tprog = get_pool_memory(PM_FNAME);
pm_strcpy(&tprog, prog);
- build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
+ build_argc_argv(mp_chr(tprog), &bargc, bargv, MAX_ARGV);
#ifdef xxxxxx
printf("argc=%d\n", bargc);
int i;
return 0;
}
if (results) {
- results[0] = 0;
- stat1 = fgets(results, sizeof_pool_memory(results), bpipe->rfd) == NULL;
+ mp_chr(results)[0] = 0;
+ stat1 = fgets(mp_chr(results), sizeof_pool_memory(results), bpipe->rfd) == NULL;
} else {
stat1 = 0;
}
struct stat statp;
Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
- if (stat(fname, &statp) == 0) {
+ if (stat(mp_chr(fname), &statp) == 0) {
/* File exists, see what we have */
*pidbuf = 0;
- if ((pidfd = open(fname, O_RDONLY)) < 0 ||
+ if ((pidfd = open(mp_chr(fname), O_RDONLY)) < 0 ||
read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
sscanf(pidbuf, "%d", &oldpid) != 1) {
Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, strerror(errno));
progname, oldpid, fname);
}
/* He is not alive, so take over file ownership */
- unlink(fname); /* remove stale pid file */
+ unlink(mp_chr(fname)); /* remove stale pid file */
}
/* Create new pid file */
- if ((pidfd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0644)) >= 0) {
+ if ((pidfd = open(mp_chr(fname), O_CREAT | O_TRUNC | O_WRONLY, 0644)) >= 0) {
len = sprintf(pidbuf, "%d\n", (int)getpid());
write(pidfd, pidbuf, len);
close(pidfd);
}
del_pid_file_ok = FALSE;
Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
- unlink(fname);
+ unlink(mp_chr(fname));
free_pool_memory(fname);
#endif
return 1;
}
hmac_md5((uint8_t *)chal, strlen(chal), (uint8_t *)password, strlen(password), hmac);
bin_to_base64(host, (char *)hmac, 16);
- ok = strcmp(bs->msg, host) == 0;
+ ok = strcmp(mp_chr(bs->msg), host) == 0;
Dmsg3(99, "Authenticate %s: wanted %s, got %s\n",
ok ? "OK" : "NOT OK", host, bs->msg);
if (ok) {
bmicrosleep(5, 0);
return 0;
}
- if (sscanf(bs->msg, "auth cram-md5 %s ssl=%d\n", chal, &ssl_has) != 2) {
+ if (sscanf(mp_chr(bs->msg), "auth cram-md5 %s ssl=%d\n", chal, &ssl_has) != 2) {
ssl_has = BNET_SSL_NONE;
- if (sscanf(bs->msg, "auth cram-md5 %s\n", chal) != 1) {
+ if (sscanf(mp_chr(bs->msg), "auth cram-md5 %s\n", chal) != 1) {
bmicrosleep(5, 0);
return 0;
}
}
hmac_md5((uint8_t *)chal, strlen(chal), (uint8_t *)password, strlen(password), hmac);
- bs->msglen = bin_to_base64(bs->msg, (char *)hmac, 16) + 1;
+ bs->msglen = bin_to_base64(mp_chr(bs->msg), (char *)hmac, 16) + 1;
if (!bnet_send(bs)) {
return 0;
}
bmicrosleep(5, 0);
return 0;
}
- if (strcmp(bs->msg, "1000 OK auth\n") == 0) {
+ if (strcmp(mp_chr(bs->msg), "1000 OK auth\n") == 0) {
return 1;
}
bmicrosleep(5, 0);
pthread_mutex_init(&(jcr->mutex), NULL);
jcr->JobStatus = JS_Created; /* ready to run */
jcr->VolumeName = get_pool_memory(PM_FNAME);
- jcr->VolumeName[0] = 0;
+ mp_chr(jcr->VolumeName)[0] = 0;
jcr->errmsg = get_pool_memory(PM_MESSAGE);
- jcr->errmsg[0] = 0;
+ mp_chr(jcr->errmsg)[0] = 0;
strcpy(jcr->Job, "*Console*"); /* default */
sigtimer.sa_flags = 0;
POOLMEM *name = get_pool_memory(PM_MESSAGE);
make_unique_spool_filename(jcr, &name, bs->fd);
- bs->spool_fd = fopen(name, "w+");
+ bs->spool_fd = fopen(mp_chr(name), "w+");
if (!bs->spool_fd) {
Jmsg(jcr, M_ERROR, 0, "fopen spool file %s failed: ERR=%s\n", name, strerror(errno));
free_pool_memory(name);
make_unique_spool_filename(jcr, &name, bs->fd);
fclose(bs->spool_fd);
- unlink(name);
+ unlink(mp_chr(name));
free_pool_memory(name);
bs->spool_fd = NULL;
bs->spool = 0;
fflush(stdout);
if (!(bpipe = open_bpipe(*cmd, 120, "rw"))) {
- Jmsg(jcr, M_ERROR, 0, "open mail pipe %s failed: ERR=%s\n", *cmd, strerror(errno));
+ Jmsg(jcr, M_ERROR, 0, "open mail pipe %s failed: ERR=%s\n",
+ *cmd, strerror(errno));
}
return bpipe;
}
len = d->max_len+10;
line = get_memory(len);
rewind(d->fd);
- while (fgets(line, len, d->fd)) {
+ while (fgets(mp_chr(line), len, d->fd)) {
fputs(line, bpipe->wfd);
}
if (!close_wpipe(bpipe)) { /* close write pipe sending mail */
*/
if (msgs != daemon_msgs) {
/* read what mail prog returned -- should be nothing */
- while (fgets(line, len, bpipe->rfd)) {
+ while (fgets(mp_chr(line), len, bpipe->rfd)) {
Jmsg1(jcr, M_INFO, 0, _("Mail prog: %s"), line);
}
}
rem_temp_file:
/* Remove temp file */
fclose(d->fd);
- unlink(d->mail_filename);
+ unlink(mp_chr(d->mail_filename));
free_pool_memory(d->mail_filename);
d->mail_filename = NULL;
Dmsg0(150, "end mail or mail on error\n");
case MD_MAIL_ON_ERROR:
Dmsg1(800, "MAIL for following msg: %s", msg);
if (!d->fd) {
- POOLMEM *name = get_pool_memory(PM_MESSAGE);
- make_unique_mail_filename(jcr, &name, d);
- d->fd = fopen(name, "w+");
+ POOLMEM *name = get_pool_memory(PM_MESSAGE);
+ make_unique_mail_filename(jcr, &mp_chr(name), d);
+ d->fd = fopen(mp_chr(name), "w+");
if (!d->fd) {
d->fd = stdout;
Emsg2(M_ERROR, 0, "fopen %s failed: ERR=%s\n", name, strerror(errno));
if (jcr && jcr->JobId == 0 && jcr->dir_bsock) {
BSOCK *dir = jcr->dir_bsock;
va_start(arg_ptr, fmt);
- dir->msglen = bvsnprintf(dir->msg, sizeof_pool_memory(dir->msg), fmt, arg_ptr);
+ dir->msglen = bvsnprintf(mp_chr(dir->msg), sizeof_pool_memory(dir->msg),
+ fmt, arg_ptr);
va_end(arg_ptr);
bnet_send(jcr->dir_bsock);
return;
va_list arg_ptr;
int i, len, maxlen;
- i = sprintf(*pool_buf, "%s:%d ", file, line);
+ i = sprintf(mp_chr(*pool_buf), "%s:%d ", file, line);
again:
maxlen = sizeof_pool_memory(*pool_buf) - i - 1;
" -r list records\n"
" -s synchronize or store in database\n"
" -v verbose\n"
-" -V specify Volume names (separated by |)\n"
+" -V specify Volume names (separated by |)\n"
" -w dir specify working directory (default from conf file)\n"
" -? print this message\n\n"));
exit(1);
init_msg(NULL, NULL);
- while ((ch = getopt(argc, argv, "b:c:d:mn:p:rsu:vw:?")) != -1) {
+ while ((ch = getopt(argc, argv, "b:c:d:mn:p:rsu:vVw:?")) != -1) {
switch (ch) {
case 'b':
bsr = parse_bsr(NULL, optarg);
return 0;
}
+/*
+ * We are at the end of reading a tape. Now, we simulate handling
+ * the end of writing a tape by wiffling through the attached
+ * jcrs creating jobmedia records.
+ */
+static int bscan_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
+{
+ Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
+ for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
+ if (verbose) {
+ Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job);
+ }
+ if (dev->state & ST_TAPE) {
+ mjcr->EndBlock = dev->EndBlock;
+ mjcr->EndFile = dev->EndFile;
+ } else {
+ mjcr->EndBlock = (uint32_t)dev->file_addr;
+ mjcr->StartBlock = (uint32_t)(dev->file_addr >> 32);
+ }
+ if (!create_jobmedia_record(db, mjcr)) {
+ Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
+ dev->VolCatInfo.VolCatName, mjcr->Job);
+ }
+ }
+ /* Now let common read routine get up next tape. Note,
+ * we call mount_next... with bscan's jcr because that is where we
+ * have the Volume list, but we get attached.
+ */
+ int stat = mount_next_read_volume(jcr, dev, block);
+ /* we must once more detach ourselves (attached by mount_next ...) */
+ detach_jcr_from_device(dev, jcr); /* detach bscan jcr */
+ return stat;
+}
static void do_scan()
{
memset(&fsr, 0, sizeof(fsr));
memset(&fr, 0, sizeof(fr));
+ /* Detach bscan's jcr as we are not a real Job on the tape */
detach_jcr_from_device(dev, bjcr);
- read_records(bjcr, dev, record_cb, mount_next_read_volume);
+ read_records(bjcr, dev, record_cb, bscan_mount_next_read_volume);
release_device(bjcr, dev);
free_attr(attr);
Pmsg0(000, _("Volume is prelabeled. This tape cannot be scanned.\n"));
return;
break;
+
case VOL_LABEL:
unser_volume_label(dev, rec);
/* Check Pool info */
Pmsg1(000, _("VOL_LABEL: OK for Volume: %s\n"), mr.VolumeName);
break;
+
case SOS_LABEL:
mr.VolJobs++;
if (ignored_msgs > 0) {
return;
}
break;
+
case EOS_LABEL:
unser_session_label(&elabel, rec);
free_jcr(mjcr);
break;
+
case EOM_LABEL:
break;
+
case EOT_LABEL: /* end of all tapes */
/*
* Wiffle through all jobs still open and close
mr.VolBytes += mr.VolBlocks * WRITE_BLKHDR_LENGTH; /* approx. */
mr.VolMounts++;
update_media_record(db, &mr);
- Pmsg3(0, _("End of Volume. VolFiles=%u VolBlocks=%u VolBytes=%s\n"), mr.VolFiles,
+ Pmsg3(0, _("End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n"), mr.VolFiles,
mr.VolBlocks, edit_uint64_with_commas(mr.VolBytes, ec1));
break;
default:
int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev)
{
- /*
- * We are at the end of reading a tape. Now, we simulate handling
- * the end of writing a tape by wiffling through the attached
- * jcrs creating jobmedia records.
- */
- Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
- for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
- if (verbose) {
- Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job);
- }
- if (dev->state & ST_TAPE) {
- mjcr->EndBlock = dev->EndBlock;
- mjcr->EndFile = dev->EndFile;
- } else {
- mjcr->EndBlock = (uint32_t)dev->file_addr;
- mjcr->StartBlock = (uint32_t)(dev->file_addr >> 32);
- }
- if (!create_jobmedia_record(db, mjcr)) {
- Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
- dev->VolCatInfo.VolCatName, mjcr->Job);
- }
- }
-
fprintf(stderr, _("Mount Volume %s on device %s and press return when ready: "),
jcr->VolumeName, dev_name(dev));
getchar();
Dmsg3(100, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
block->BlockNumber, rec->remainder);
+ Jmsg(jcr, M_INFO, 0, "Got EOM at file %u on device %s, Volume \"%s\"\n",
+ dev->file, dev_name(dev), jcr->VolumeName);
if (!mount_cb(jcr, dev, block)) {
+ Jmsg(jcr, M_INFO, 0, "End of all volumes.\n");
Dmsg3(100, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
block->BlockNumber, rec->remainder);
ok = FALSE;
/* */
#define VERSION "1.31"
#define VSTRING "1"
-#define BDATE "04 Jun 2003"
-#define LSMDATE "04Jun03"
+#define BDATE "10 Jun 2003"
+#define LSMDATE "10Jun03"
/* Debug flags */
#define DEBUG 1