From: Kern Sibbald Date: Mon, 26 Aug 2002 13:33:53 +0000 (+0000) Subject: Restore from multiple simultaneous backups X-Git-Tag: Release-1.25~21 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=a8d79e52a979863bd3d94436b9f8d220d51fba89;p=bacula%2Fbacula Restore from multiple simultaneous backups git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@122 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/Makefile.in b/bacula/Makefile.in index 6c3a64a7ac..9cc7c3b3c2 100755 --- a/bacula/Makefile.in +++ b/bacula/Makefile.in @@ -34,7 +34,7 @@ MKDIR = $(srcdir)/autoconf/mkinstalldirs all: Makefile @for I in ${subdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ - $(MAKE) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ + $(MAKE) $@ || (echo ""; echo ""; echo -e " \a\a ====== Error in `pwd` ======\a\a"; \ echo ""; echo "";)); \ done @@ -45,7 +45,7 @@ depend: bacula-fd: Makefile @for I in ${FDsubdirs}; \ do (cd $$I; echo "==>Entering directory `pwd`"; \ - $(MAKE) all || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \ + $(MAKE) all || (echo ""; echo ""; echo -e " \a\a ====== Error in `pwd` ======\a\a"; \ echo ""; echo "";)); \ done diff --git a/bacula/kernstodo b/bacula/kernstodo index df56c94e79..1556594d58 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -1,5 +1,5 @@ Kern's ToDo List - 20 August 2002 + 26 August 2002 Irix conversion notes: - no uuencode @@ -28,13 +28,10 @@ From Chuck: --sd.conf password does not match dir.conf storage password ======= -- In restore job, print some summary information at end, such - as rate, ... job status, ... - After unmount, if restore job started, ask to mount. -- Fix db_update_fileset in cats/sql_get.c +- Fix db_get_fileset in cats/sql_get.c for multiple records. - Fix start/end blocks for File - Add new code to scheduler.c and run_conf.c -- Problem with len at 362 in tree.c - Volume Bytes shows bytes on last volume written in Job summary. - Fix catalog filename truncation in sql_get and sql_create. Use only a single filename split routine. @@ -451,3 +448,7 @@ Done: (see kernsdone for more) - Get correct block/file information in Catalog, pay attention to change of media. - Write better dump of Messages resource. - Authentication between SD and FD +- In restore job, print some summary information at end, such + as rate, ... job status, ... +- Problem with len at 362 in tree.c + diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index 8e7e6bac54..a32c524cec 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -100,7 +100,7 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr) */ fnl = p - l; if (fnl > 255) { - Emsg1(M_WARNING, 0, _("Filename truncated to 255 chars: %s\n"), l); + Jmsg1(mdb->jcr, M_WARNING, 0, _("Filename truncated to 255 chars: %s\n"), l); fnl = 255; } if (fnl > 0) { @@ -114,7 +114,7 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr) pnl = l - fname; if (pnl > 255) { - Emsg1(M_WARNING, 0, _("Path name truncated to 255 chars: %s\n"), fname); + Jmsg1(mdb->jcr, M_WARNING, 0, _("Path name truncated to 255 chars: %s\n"), fname); pnl = 255; } strncpy(spath, fname, pnl); @@ -122,7 +122,7 @@ int db_get_file_attributes_record(B_DB *mdb, char *fname, FILE_DBR *fdbr) if (pnl == 0) { Mmsg1(&mdb->errmsg, _("Path length is zero. File=%s\n"), fname); - Emsg0(M_ERROR, 0, mdb->errmsg); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); spath[0] = ' '; spath[1] = 0; pnl = 1; @@ -176,12 +176,13 @@ File.FilenameId=%d", fdbr->JobId, fdbr->PathId, fdbr->FilenameId); * filename if the file is linked. ???????? */ if (mdb->num_rows > 1) { - Emsg1(M_WARNING, 0, _("get_file_record want 1 got rows=%d\n"), mdb->num_rows); - Emsg1(M_ERROR, 0, "%s", mdb->cmd); + Jmsg1(mdb->jcr, M_WARNING, 0, _("get_file_record want 1 got rows=%d\n"), mdb->num_rows); + Jmsg1(mdb->jcr, M_ERROR, 0, "%s", mdb->cmd); } if (mdb->num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, "Error fetching row: %s\n", sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { fdbr->FileId = (FileId_t)strtod(row[0], NULL); strncpy(fdbr->LStat, row[1], sizeof(fdbr->LStat)); @@ -220,19 +221,18 @@ static int db_get_filename_record(B_DB *mdb, char *fname) if (mdb->num_rows > 1) { Mmsg1(&mdb->errmsg, _("More than one Filename!: %d\n"), (int)(mdb->num_rows)); - Emsg1(M_WARNING, 0, _("get_filename_record want 1 got rows=%d\n"), mdb->num_rows); - Emsg1(M_ERROR, 0, "%s", mdb->errmsg); + Jmsg(mdb->jcr, M_WARNING, 0, "%s", mdb->errmsg); } if (mdb->num_rows >= 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); - Emsg1(M_ERROR, 0, "%s", mdb->errmsg); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { FilenameId = atoi(row[0]); if (FilenameId <= 0) { Mmsg2(&mdb->errmsg, _("Get DB Filename record %s found bad record: %d\n"), mdb->cmd, FilenameId); - Emsg1(M_ERROR, 0, "%s", mdb->errmsg); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); FilenameId = 0; } } @@ -272,14 +272,17 @@ static int db_get_path_record(B_DB *mdb, char *path) if (mdb->num_rows > 1) { Mmsg1(&mdb->errmsg, _("More than one Path!: %s\n"), edit_uint64(mdb->num_rows, ed1)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { PathId = atoi(row[0]); if (PathId <= 0) { Mmsg2(&mdb->errmsg, _("Get DB path record %s found bad record: %d\n"), mdb->cmd, PathId); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); PathId = 0; } else { /* Cache path */ @@ -325,6 +328,7 @@ FROM Job WHERE JobId=%d", jr->JobId); } if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("No Job found for JobId %d\n"), jr->JobId); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); sql_free_result(mdb); db_unlock(mdb); return 0; /* failed */ @@ -371,12 +375,14 @@ AND JobMedia.MediaId=Media.MediaId", JobId); Dmsg1(130, "Num rows=%d\n", mdb->num_rows); if (mdb->num_rows <= 0) { Mmsg1(&mdb->errmsg, _("No volumes found for JobId=%d"), JobId); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); stat = 0; } else { stat = mdb->num_rows; for (i=0; i < stat; i++) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg2(&mdb->errmsg, _("Error fetching row %d: ERR=%s\n"), i, sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); stat = 0; break; } else { @@ -441,6 +447,7 @@ int db_get_pool_ids(B_DB *mdb, int *num_ids, uint32_t *ids[]) stat = 1; } else { Mmsg(&mdb->errmsg, _("Pool id select failed: ERR=%s\n"), sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); stat = 0; } db_unlock(mdb); @@ -479,9 +486,11 @@ PoolType, LabelFormat FROM Pool WHERE Pool.Name='%s'", pdbr->Name); char ed1[30]; Mmsg1(&mdb->errmsg, _("More than one Pool!: %s\n"), edit_uint64(mdb->num_rows, ed1)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { pdbr->PoolId = atoi(row[0]); strcpy(pdbr->Name, row[1]); @@ -538,9 +547,11 @@ int db_get_fileset_record(B_DB *mdb, FILESET_DBR *fsr) Mmsg1(&mdb->errmsg, _("Got %s FileSets expected only one!\n"), edit_uint64(mdb->num_rows, ed1)); sql_data_seek(mdb, mdb->num_rows-1); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } if ((row = sql_fetch_row(mdb)) == NULL) { - Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Mmsg1(&mdb->errmsg, _("Error fetching row get_fileset: %s\n"), sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { fsr->FileSetId = atoi(row[0]); strcpy(fsr->FileSet, row[1]); @@ -602,6 +613,7 @@ int db_get_media_ids(B_DB *mdb, int *num_ids, uint32_t *ids[]) stat = 1; } else { Mmsg(&mdb->errmsg, _("Media id select failed: ERR=%s\n"), sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); stat = 0; } db_unlock(mdb); @@ -644,9 +656,11 @@ FROM Media WHERE VolumeName='%s'", mr->VolumeName); char ed1[30]; Mmsg1(&mdb->errmsg, _("More than one Volume!: %s\n"), edit_uint64(mdb->num_rows, ed1)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else if (mdb->num_rows == 1) { if ((row = sql_fetch_row(mdb)) == NULL) { Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb)); + Jmsg(mdb->jcr, M_ERROR, 0, "%s", mdb->errmsg); } else { /* return values */ mr->MediaId = atoi(row[0]); diff --git a/bacula/src/filed/filed_conf.c b/bacula/src/filed/filed_conf.c index 6d2fcd2d9d..ff0ed75c57 100644 --- a/bacula/src/filed/filed_conf.c +++ b/bacula/src/filed/filed_conf.c @@ -77,6 +77,7 @@ static struct res_items cli_items[] = { {"workingdirectory", store_dir, ITEM(res_client.working_directory), 0, ITEM_REQUIRED, 0}, {"piddirectory", store_dir, ITEM(res_client.pid_directory), 0, ITEM_REQUIRED, 0}, {"subsysdirectory", store_dir, ITEM(res_client.subsys_directory), 0, ITEM_REQUIRED, 0}, + {"maximumconcurrentjobs", store_pint, ITEM(res_client.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1}, {"messages", store_res, ITEM(res_client.messages), R_MSGS, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; diff --git a/bacula/src/filed/filed_conf.h b/bacula/src/filed/filed_conf.h index 56a3ef9827..40c28ba361 100644 --- a/bacula/src/filed/filed_conf.h +++ b/bacula/src/filed/filed_conf.h @@ -28,38 +28,39 @@ /* * Resource codes -- they must be sequential for indexing */ -#define R_FIRST 1001 +#define R_FIRST 1001 -#define R_DIRECTOR 1001 -#define R_CLIENT 1002 -#define R_MSGS 1003 +#define R_DIRECTOR 1001 +#define R_CLIENT 1002 +#define R_MSGS 1003 -#define R_LAST R_MSGS +#define R_LAST R_MSGS /* * Some resource attributes */ -#define R_NAME 1020 -#define R_ADDRESS 1021 -#define R_PASSWORD 1022 -#define R_TYPE 1023 +#define R_NAME 1020 +#define R_ADDRESS 1021 +#define R_PASSWORD 1022 +#define R_TYPE 1023 /* Definition of the contents of each Resource */ struct s_res_dir { - RES hdr; - char *password; /* Director password */ - char *address; /* Director address or zero */ + RES hdr; + char *password; /* Director password */ + char *address; /* Director address or zero */ }; typedef struct s_res_dir DIRRES; struct s_res_client { - RES hdr; - int FDport; /* where we listen for Directors */ + RES hdr; + int FDport; /* where we listen for Directors */ char *working_directory; char *pid_directory; char *subsys_directory; struct s_res_msgs *messages; /* daemon message handler */ + int MaxConcurrentJobs; }; typedef struct s_res_client CLIENT; @@ -69,9 +70,9 @@ typedef struct s_res_client CLIENT; * resource structure definitions. */ union u_res { - struct s_res_dir res_dir; - struct s_res_client res_client; - struct s_res_msgs res_msgs; + struct s_res_dir res_dir; + struct s_res_client res_client; + struct s_res_msgs res_msgs; RES hdr; }; diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 67a3e8d6cc..46c73a7ced 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -143,16 +143,17 @@ void do_restore(JCR *jcr) * Link name (if file linked i.e. FT_LNK) * */ + Dmsg1(100, "Attr: %s\n", sd->msg); if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) { - Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg); - Dmsg0(0, "\nError scanning header\n"); + Jmsg(jcr, M_FATAL, 0, _("Error scanning attributes: %s\n"), sd->msg); + Dmsg1(000, "\nError scanning attributes. %s\n", sd->msg); goto bail_out; } - Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type); + Dmsg2(100, "Got Attr: FilInx=%d type=%d\n", record_file_index, type); if (record_file_index != file_index) { Jmsg(jcr, M_FATAL, 0, _("Record header file index %ld not equal record index %ld\n"), file_index, record_file_index); - Dmsg0(0, "File index error\n"); + Dmsg0(000, "File index error\n"); goto bail_out; } ap = sd->msg; diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 48aa1ee650..312edad2c7 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -661,7 +661,7 @@ term_bsock(BSOCK *bsock) free_pool_memory(bsock->msg); bsock->msg = NULL; } else { - ASSERT(1=0); /* double close */ + ASSERT(1==0); /* double close */ } if (bsock->errmsg) { free_pool_memory(bsock->errmsg); diff --git a/bacula/src/lib/mem_pool.c b/bacula/src/lib/mem_pool.c index 2af3a7b8b6..c5443ac354 100644 --- a/bacula/src/lib/mem_pool.c +++ b/bacula/src/lib/mem_pool.c @@ -195,10 +195,13 @@ void free_pool_memory(POOLMEM *obuf) if (pool == 0) { free((char *)buf); /* free nonpooled memory */ } else { /* otherwise link it to the free pool chain */ +#ifdef DEBUG struct abufhead *next; + /* Don't let him free the same buffer twice */ for (next=pool_ctl[pool].free_buf; next; next=next->next) { ASSERT(next != buf); /* attempt to free twice */ } +#endif buf->next = pool_ctl[pool].free_buf; pool_ctl[pool].free_buf = buf; } diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 63fef7f34c..aa12351914 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -511,10 +511,12 @@ Warning, this Volume is a continuation of Volume %s\n", record = 0; for (rec->state=0; !is_block_empty(rec); ) { if (!read_record_from_block(block, rec)) { - Dmsg2(30, "!read-break. stat=%s blk=%d\n", rec_state_to_str(rec), - block->BlockNumber); + Dmsg3(10, "!read-break. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), + block->BlockNumber, rec->remainder); break; } + Dmsg3(10, "read-OK. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), + block->BlockNumber, rec->remainder); /* * At this point, we have at least a record header. * Now decide if we want this record or not, but remember diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 7882e678b7..80c6315de2 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -144,10 +144,12 @@ init_dev(DEVICE *dev, char *dev_name) dev->errmsg = get_pool_memory(PM_EMSG); *dev->errmsg = 0; +#ifdef NEW_LOCK if ((errstat=rwl_init(&dev->lock)) != 0) { Mmsg1(&dev->errmsg, _("Unable to initialize dev lock. ERR=%s\n"), strerror(errstat)); Emsg0(M_FATAL, 0, dev->errmsg); } +#endif if ((errstat = pthread_mutex_init(&dev->mutex, NULL)) != 0) { dev->dev_errno = errstat; @@ -1073,7 +1075,9 @@ term_dev(DEVICE *dev) free_pool_memory(dev->errmsg); dev->errmsg = NULL; } +#ifdef NEW_LOCK rwl_destroy(&dev->lock); +#endif pthread_mutex_destroy(&dev->mutex); pthread_cond_destroy(&dev->wait); pthread_cond_destroy(&dev->wait_next_vol); diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index a6c263ab18..4173fafe3f 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -110,11 +110,19 @@ typedef struct s_volume_catalog_info { } VOLUME_CAT_INFO; +typedef struct s_steal_lock { + pthread_t no_wait_id; /* id of no wait thread */ + int dev_blocked; /* state */ +} bsteal_lock_t; + + /* Device structure definition */ typedef struct s_device { struct s_device *next; /* pointer to next open device */ void *attached_jcrs; /* attached JCR list */ +#ifdef NEW_LOCK brwlock_t lock; /* new device locking mechanism */ +#endif pthread_mutex_t mutex; /* access control */ pthread_cond_t wait; /* thread wait variable */ pthread_cond_t wait_next_vol; /* wait for tape to be mounted */ diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 24adab2ebe..9af8ce96f1 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -301,6 +301,33 @@ void unblock_device(DEVICE *dev) #endif } +void steal_device_lock(DEVICE *dev, bsteal_lock_t *hold, int state) +{ +#ifndef NEW_LOCK + hold->dev_blocked = dev->dev_blocked; + hold->no_wait_id = dev->no_wait_id; + dev->dev_blocked = state; + dev->no_wait_id = pthread_self(); + V(dev->mutex); +#endif +} + +void return_device_lock(DEVICE *dev, bsteal_lock_t *hold) +{ +#ifndef NEW_LOCK + P(dev->mutex); + dev->dev_blocked = hold->dev_blocked; + dev->no_wait_id = hold->no_wait_id; +#endif +} + + + +/* ================================================================== + * New device locking code. It is not currently used. + * ================================================================== + */ + /* * New device locking scheme */ @@ -344,7 +371,6 @@ void _unlock_device(char *file, int line, DEVICE *dev) void new_steal_device_lock(DEVICE *dev, brwsteal_t *hold, int state) { #ifdef NEW_LOCK - P(dev->lock.mutex); hold->state = dev->dev_blocked; hold->writer_id = dev->lock.writer_id; dev->dev_blocked = state; @@ -359,6 +385,5 @@ void new_return_device_lock(DEVICE *dev, brwsteal_t *hold) P(dev->lock.mutex); dev->dev_blocked = hold->state; dev->lock.writer_id = hold->writer_id; - V(dev->lock.mutex); #endif } diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 759dd2fa2a..45b1a5c4de 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -254,10 +254,48 @@ static int label_cmd(JCR *jcr) } UnlockRes(); if (found) { +#ifdef NEW_LOCK + int label_it = FALSE; + brwsteal_t hold; +#endif /******FIXME**** compare MediaTypes */ jcr->device = device; dev = device->dev; +#ifdef NEW_LOCK + P(dev->lock.mutex); + if (!(dev->state & ST_OPENED)) { + label_it = TRUE; + } else if (dev->dev_blocked && + dev->dev_blocked != BST_DOING_ACQUIRE) { /* device blocked? */ + label_it = TRUE; + } else if (dev->state & ST_READ || dev->num_writers) { + if (dev->state & ST_READ) { + bnet_fsend(dir, _("3901 Device %s is busy with 1 reader.\n"), + dev_name(dev)); + } else { + bnet_fsend(dir, _("3902 Device %s is busy with %d writer(s).\n"), + dev_name(dev), dev->num_writers); + } + } else { /* device not being used */ + label_it = TRUE; + } + if (label_it) { + new_steal_device_lock(dev, &hold, BST_WRITING_LABEL); + if (!(dev->state & ST_OPENED)) { + if (open_dev(dev, volname, READ_WRITE) < 0) { + bnet_fsend(dir, _("3994 Connot open device: %s\n"), strerror_dev(dev)); + } else { + label_volume_if_ok(jcr, dev, volname, poolname); + force_close_dev(dev); + } + } else { + label_volume_if_ok(jcr, dev, volname, poolname); + } + new_return_device_lock(dev, &hold); + } + V(dev->lock.mutex); +#else P(dev->mutex); if (!(dev->state & ST_OPENED)) { if (open_dev(dev, volname, READ_WRITE) < 0) { @@ -281,6 +319,7 @@ static int label_cmd(JCR *jcr) label_volume_if_ok(jcr, dev, volname, poolname); } V(dev->mutex); +#endif } else { bnet_fsend(dir, _("3999 Device %s not found\n"), dname); } @@ -307,19 +346,12 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolnam { BSOCK *dir = jcr->dir_bsock; DEV_BLOCK *block; - brwsteal_t hold; #ifndef NEW_LOCK - int blocked; - pthread_t no_wait_id; + bsteal_lock_t hold; - blocked = dev->dev_blocked; /* save any prev blocked state */ - dev->dev_blocked = BST_WRITING_LABEL; - no_wait_id = dev->no_wait_id; - dev->no_wait_id = pthread_self(); /* let us use the tape */ + steal_device_lock(dev, &hold, BST_WRITING_LABEL); #endif - new_steal_device_lock(dev, &hold, BST_WRITING_LABEL); - V(dev->mutex); strcpy(jcr->VolumeName, vname); block = new_block(dev); switch (read_dev_volume_label(jcr, dev, block)) { @@ -343,11 +375,8 @@ Unknown status %d from read_volume_label()\n"), jcr->label_status); break; } free_block(block); - P(dev->mutex); - new_return_device_lock(dev, &hold); #ifndef NEW_LOCK - dev->dev_blocked = blocked; /* reset blocked state */ - dev->no_wait_id = no_wait_id; /* reset blocking thread id */ + return_device_lock(dev, &hold); #endif } @@ -362,18 +391,11 @@ static int read_label(JCR *jcr, DEVICE *dev) int stat; BSOCK *dir = jcr->dir_bsock; DEV_BLOCK *block; - brwsteal_t hold; #ifndef NEW_LOCK - int blocked; - pthread_t no_wait_id; + bsteal_lock_t hold; - blocked = dev->dev_blocked; /* save any prev blocked state */ - no_wait_id = dev->no_wait_id; - dev->dev_blocked = BST_DOING_ACQUIRE; - dev->no_wait_id = pthread_self(); /* let us use the tape */ + steal_device_lock(dev, &hold, BST_DOING_ACQUIRE); #endif - new_steal_device_lock(dev, &hold, BST_DOING_ACQUIRE); - V(dev->mutex); /* release lock */ jcr->VolumeName[0] = 0; block = new_block(dev); @@ -390,11 +412,8 @@ static int read_label(JCR *jcr, DEVICE *dev) break; } free_block(block); - P(dev->mutex); - new_return_device_lock(dev, &hold); #ifndef NEW_LOCK - dev->dev_blocked = blocked; /* reset blocked state */ - dev->no_wait_id = no_wait_id; /* reset blocking thread id */ + return_device_lock(dev, &hold); #endif return stat; } diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index c43d312de5..495cdc4cea 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -28,80 +28,82 @@ uint32_t new_VolSessionId(); /* From acquire.c */ -int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); /* From askdir.c */ -int dir_get_volume_info(JCR *jcr); -int dir_find_next_appendable_volume(JCR *jcr); -int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel); -int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev); -int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev); -int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec); -int dir_send_job_status(JCR *jcr); -int dir_create_jobmedia_record(JCR *jcr); +int dir_get_volume_info(JCR *jcr); +int dir_find_next_appendable_volume(JCR *jcr); +int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel); +int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev); +int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev); +int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec); +int dir_send_job_status(JCR *jcr); +int dir_create_jobmedia_record(JCR *jcr); /* authenticate.c */ -int authenticate_director(JCR *jcr); -int authenticate_filed(JCR *jcr); +int authenticate_director(JCR *jcr); +int authenticate_filed(JCR *jcr); /* From block.c */ -void dump_block(DEV_BLOCK *b, char *msg); +void dump_block(DEV_BLOCK *b, char *msg); DEV_BLOCK *new_block(DEVICE *dev); -void init_block_write(DEV_BLOCK *block); -void empty_block(DEV_BLOCK *block); -void free_block(DEV_BLOCK *block); -int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block); -int read_block_from_device(DEVICE *dev, DEV_BLOCK *block); -int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block); +void init_block_write(DEV_BLOCK *block); +void empty_block(DEV_BLOCK *block); +void free_block(DEV_BLOCK *block); +int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block); +int read_block_from_device(DEVICE *dev, DEV_BLOCK *block); +int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block); /* From dev.c */ -DEVICE *init_dev(DEVICE *dev, char *device); -int open_dev(DEVICE *dev, char *VolName, int mode); -void close_dev(DEVICE *dev); -void force_close_dev(DEVICE *dev); -int truncate_dev(DEVICE *dev); -void term_dev(DEVICE *dev); -char * strerror_dev(DEVICE *dev); -void clrerror_dev(DEVICE *dev, int func); -int update_pos_dev(DEVICE *dev); -int rewind_dev(DEVICE *dev); -int load_dev(DEVICE *dev); -int offline_dev(DEVICE *dev); -int flush_dev(DEVICE *dev); -int weof_dev(DEVICE *dev, int num); -int write_block(DEVICE *dev); -int write_dev(DEVICE *dev, char *buf, size_t len); -int read_dev(DEVICE *dev, char *buf, size_t len); -int status_dev(DEVICE *dev, uint32_t *status); -int eod_dev(DEVICE *dev); -int fsf_dev(DEVICE *dev, int num); -int fsr_dev(DEVICE *dev, int num); -int bsf_dev(DEVICE *dev, int num); -int bsr_dev(DEVICE *dev, int num); -void attach_jcr_to_device(DEVICE *dev, JCR *jcr); -void detach_jcr_from_device(DEVICE *dev, JCR *jcr); -JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); +DEVICE *init_dev(DEVICE *dev, char *device); +int open_dev(DEVICE *dev, char *VolName, int mode); +void close_dev(DEVICE *dev); +void force_close_dev(DEVICE *dev); +int truncate_dev(DEVICE *dev); +void term_dev(DEVICE *dev); +char * strerror_dev(DEVICE *dev); +void clrerror_dev(DEVICE *dev, int func); +int update_pos_dev(DEVICE *dev); +int rewind_dev(DEVICE *dev); +int load_dev(DEVICE *dev); +int offline_dev(DEVICE *dev); +int flush_dev(DEVICE *dev); +int weof_dev(DEVICE *dev, int num); +int write_block(DEVICE *dev); +int write_dev(DEVICE *dev, char *buf, size_t len); +int read_dev(DEVICE *dev, char *buf, size_t len); +int status_dev(DEVICE *dev, uint32_t *status); +int eod_dev(DEVICE *dev); +int fsf_dev(DEVICE *dev, int num); +int fsr_dev(DEVICE *dev, int num); +int bsf_dev(DEVICE *dev, int num); +int bsr_dev(DEVICE *dev, int num); +void attach_jcr_to_device(DEVICE *dev, JCR *jcr); +void detach_jcr_from_device(DEVICE *dev, JCR *jcr); +JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); /* Get info about device */ -char * dev_name(DEVICE *dev); -char * dev_vol_name(DEVICE *dev); +char * dev_name(DEVICE *dev); +char * dev_vol_name(DEVICE *dev); uint32_t dev_block(DEVICE *dev); uint32_t dev_file(DEVICE *dev); -int dev_is_tape(DEVICE *dev); +int dev_is_tape(DEVICE *dev); /* From device.c */ -int open_device(DEVICE *dev); -void block_device(DEVICE *dev, int state); -void unblock_device(DEVICE *dev); -void lock_device(DEVICE *dev); -void unlock_device(DEVICE *dev); -int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int open_device(DEVICE *dev); +void block_device(DEVICE *dev, int state); +void unblock_device(DEVICE *dev); +void lock_device(DEVICE *dev); +void unlock_device(DEVICE *dev); +void steal_device_lock(DEVICE *dev, bsteal_lock_t *hold, int state); +void return_device_lock(DEVICE *dev, bsteal_lock_t *hold); +int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); void _lock_device(char *file, int line, DEVICE *dev); void _lock_device(char *file, int line, DEVICE *dev, int state); void _unlock_device(char *file, int line, DEVICE *dev); @@ -109,38 +111,38 @@ void new_steal_device_lock(DEVICE *dev, brwsteal_t *hold, int state); void new_return_device_lock(DEVICE *dev, brwsteal_t *hold); /* From dircmd.c */ -void connection_request(void *arg); +void connection_request(void *arg); /* From fd_cmds.c */ -void run_job(JCR *jcr); +void run_job(JCR *jcr); /* From fdmsg.c */ -int bget_msg(BSOCK *sock); +int bget_msg(BSOCK *sock); /* From job.c */ -void stored_free_jcr(JCR *jcr); -void connection_from_filed(void *arg); -void handle_filed_connection(BSOCK *fd, char *job_name); +void stored_free_jcr(JCR *jcr); +void connection_from_filed(void *arg); +void handle_filed_connection(BSOCK *fd, char *job_name); /* From label.c */ -int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -void create_session_label(JCR *jcr, DEV_RECORD *rec, int label); -int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName); -int write_session_label(JCR *jcr, DEV_BLOCK *block, int label); -int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -void dump_volume_label(DEVICE *dev); -void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose); -int unser_volume_label(DEVICE *dev, DEV_RECORD *rec); -int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec); +int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +void create_session_label(JCR *jcr, DEV_RECORD *rec, int label); +int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName); +int write_session_label(JCR *jcr, DEV_BLOCK *block, int label); +int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +void dump_volume_label(DEVICE *dev); +void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose); +int unser_volume_label(DEVICE *dev, DEV_RECORD *rec); +int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec); /* From match_bsr.c */ int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, - SESSION_LABEL *sesrec); + SESSION_LABEL *sesrec); /* From mount.c */ -int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release); -int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release); +int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); /* From parse_bsr.c */ @@ -155,8 +157,8 @@ extern void create_vol_list(JCR *jcr); /* From record.c */ char *FI_to_ascii(int fi); char *stream_to_ascii(int stream); -int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); -int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); -int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); +int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); +int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); +int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); DEV_RECORD *new_record(); -void free_record(DEV_RECORD *rec); +void free_record(DEV_RECORD *rec); diff --git a/bacula/src/stored/read.c b/bacula/src/stored/read.c index 59851434f0..35e2abe626 100644 --- a/bacula/src/stored/read.c +++ b/bacula/src/stored/read.c @@ -80,7 +80,6 @@ int do_read_data(JCR *jcr) block = new_block(dev); - create_vol_list(jcr); Dmsg1(20, "Found %d volumes names to restore.\n", jcr->NumVolumes); @@ -223,10 +222,13 @@ int do_read_data(JCR *jcr) ds->msglen = rec->data_len; Dmsg1(40, ">filed: send %d bytes data.\n", ds->msglen); if (!bnet_send(ds)) { - Dmsg0(0, "Error sending to FD\n"); + Dmsg1(000, "Error sending to FD. ERR=%s\n", bnet_strerror(ds)); + Dmsg1(100, "Hdr=%s\n", hdr); + Dmsg1(100, "data=%s\n", ds->msg); Jmsg1(jcr, M_FATAL, 0, _("Error sending to File daemon. ERR=%s\n"), bnet_strerror(ds)); ok = FALSE; + break; } } } diff --git a/bacula/src/stored/record.c b/bacula/src/stored/record.c index eebb5af25b..9ada74bda1 100644 --- a/bacula/src/stored/record.c +++ b/bacula/src/stored/record.c @@ -328,8 +328,16 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec) block->binbuf -= RECHDR_LENGTH; remlen -= RECHDR_LENGTH; - /* - * if Stream is negative, it means that this is a continuation + /* If we are looking for more (remainder!=0), we reject anything + * where the VolSessionId and VolSessionTime don't agree + */ + if (rec->remainder && (rec->VolSessionId != VolSessionId || + rec->VolSessionTime != VolSessionTime)) { + rec->state |= REC_NO_MATCH; + return 0; /* This is from some other Session */ + } + + /* if Stream is negative, it means that this is a continuation * of a previous partially written record. */ if (Stream < 0) { /* continuation record? */ @@ -338,9 +346,7 @@ int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec) rec->state |= REC_CONTINUATION; if (!rec->remainder) { /* if we didn't read previously */ rec->data_len = 0; /* return data as if no continuation */ - } else if (rec->VolSessionId != VolSessionId || - rec->VolSessionTime != VolSessionTime || - rec->Stream != -Stream) { + } else if (rec->Stream != -Stream) { rec->state |= REC_NO_MATCH; return 0; /* This is from some other Session */ } diff --git a/bacula/src/version.h b/bacula/src/version.h index 1c9b489b99..66e77a2ca8 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.25" #define VSTRING "1" -#define DATE "24 August 2002" -#define LSMDATE "24Aug02" +#define DATE "26 August 2002" +#define LSMDATE "26Aug02" /* Debug flags */ #define DEBUG 1