char cLastWritten[MAX_TIME_LENGTH]; /* LastWritten returned from DB */
char cLabelDate[MAX_TIME_LENGTH]; /* LabelData returned from DB */
char cInitialWrite[MAX_TIME_LENGTH]; /* InitialWrite returned from DB */
+ char *exclude_list; /* Optionnal exclude list for db_find_next_volume() */
bool set_first_written;
bool set_label_date;
};
} else {
POOL_MEM changer(PM_FNAME);
POOL_MEM voltype(PM_FNAME);
+ POOL_MEM exclude(PM_FNAME);
/* Find next available volume */
if (InChanger) {
Mmsg(changer, " AND InChanger=1 AND StorageId=%s ",
edit_int64(mr->StorageId, ed1));
}
+ /* Volumes will be automatically excluded from the query, we just take the
+ * first one of the list
+ */
+ if (mr->exclude_list && *mr->exclude_list) {
+ item = 1;
+ Mmsg(exclude, " AND MediaId NOT IN (%s) ", mr->exclude_list);
+ }
if (strcmp(mr->VolStatus, "Recycle") == 0 ||
strcmp(mr->VolStatus, "Purged") == 0) {
order = "AND Recycle=1 ORDER BY LastWritten ASC,MediaId"; /* take oldest that can be recycled */
"AND VolStatus='%s' "
"%s "
"%s "
+ "%s "
"%s LIMIT %d",
edit_int64(mr->PoolId, ed1), esc_type,
esc_status,
voltype.c_str(),
- changer.c_str(), order, item);
+ changer.c_str(), exclude.c_str(), order, item);
}
Dmsg1(100, "fnextvol=%s\n", cmd);
if (!QueryDB(jcr, cmd)) {
free_and_null_pool_memory(jcr->rpool_source);
free_and_null_pool_memory(jcr->wstore_source);
free_and_null_pool_memory(jcr->rstore_source);
+ free_and_null_pool_memory(jcr->next_vol_list);
/* Delete lists setup to hold storage pointers */
free_rwstorage(jcr);
jcr->setJobLevel(job->JobLevel);
break;
}
-
+ if (!jcr->next_vol_list) {
+ jcr->next_vol_list = get_pool_memory(PM_FNAME);
+ }
if (!jcr->fname) {
jcr->fname = get_pool_memory(PM_FNAME);
}
mr->StorageId = store->StorageId;
}
+static void add_volume_to_exclude_list(JCR *jcr, int index, MEDIA_DBR *mr)
+{
+ char ed1[50];
+ if (index == 1) {
+ *jcr->next_vol_list = 0;
+
+ } else if (*jcr->next_vol_list) {
+ pm_strcat(jcr->next_vol_list, ",");
+ }
+ pm_strcat(jcr->next_vol_list, edit_int64(mr->MediaId, ed1));
+
+ /* The list is valid only in find_next_volume_for_append() */
+ mr->exclude_list = NULL;
+}
+
+static void set_volume_to_exclude_list(JCR *jcr, int index, MEDIA_DBR *mr)
+{
+ if (index == 1) {
+ *jcr->next_vol_list = 0;
+ }
+ mr->exclude_list = jcr->next_vol_list;
+}
+
/*
* Items needed:
* mr.PoolId must be set
*/
InChanger = (store->autochanger)? true : false;
+ /* Make sure we don't send two times the same volume in the same session */
+ set_volume_to_exclude_list(jcr, index, mr);
+
/*
* Find the Next Volume for Append
*/
} /* end for loop */
db_unlock(jcr->db);
Dmsg1(dbglvl, "return ok=%d find_next_vol\n", ok);
+
+ /* We keep the record of all previous volumes requested */
+ if (ok) {
+ add_volume_to_exclude_list(jcr, index, mr);;
+ }
return ok;
}
POOLMEM *rstore_source; /* Where read storage came from */
POOLMEM *wstore_source; /* Where write storage came from */
POOLMEM *catalog_source; /* Where catalog came from */
+ POOLMEM *next_vol_list; /* Volumes previously requested */
uint32_t replace; /* Replace option */
int32_t NumVols; /* Number of Volume used in pool */
int32_t reschedule_count; /* Number of times rescheduled */