- Possibly up network buffers to 65K.
- Keep last 5 or 10 completed jobs and show them in a similar list.
- Make a Running Jobs: output similar to current Scheduled Jobs:
-- Optimize fsf not to read.
-- Use ioctl() fsf if it exists. Figure out where we are from
- the mt_status command. Use slow fsf only if other does not work.
-- Add flag to write only one EOF mark on the tape.
-- Implement autochanger testing in btape "test" command.
After 1.33:
+- Don't continue Restore if no files selected.
- Print warning message if FileId > 4 billion
- do a "messages" before the first prompt in Console
- Add a date and time stamp at the beginning of every line in the
/* find.c */
int db_find_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime);
int db_find_last_jobid(JCR *jcr, B_DB *mdb, char *Name, JOB_DBR *jr);
-int db_find_next_volume(JCR *jcr, B_DB *mdb, int index, MEDIA_DBR *mr);
+int db_find_next_volume(JCR *jcr, B_DB *mdb, int index, bool InChanger, MEDIA_DBR *mr);
/* get.c */
int db_get_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pdbr);
* numrows on success
*/
int
-db_find_next_volume(JCR *jcr, B_DB *mdb, int item, MEDIA_DBR *mr)
+db_find_next_volume(JCR *jcr, B_DB *mdb, int item, bool InChanger, MEDIA_DBR *mr)
{
SQL_ROW row;
int numrows;
item = 1;
} else {
/* Find next available volume */
- Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
- "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
- "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
- "FirstWritten,LastWritten,VolStatus "
- "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' "
- "ORDER BY LastWritten",
- mr->PoolId, mr->MediaType, mr->VolStatus);
+ if (InChanger) {
+ Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
+ "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+ "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
+ "FirstWritten,LastWritten,VolStatus "
+ "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' "
+ "AND InChanger=1 ORDER BY LastWritten,MediaId",
+ mr->PoolId, mr->MediaType, mr->VolStatus);
+ } else {
+ Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,VolJobs,VolFiles,VolBlocks,"
+ "VolBytes,VolMounts,VolErrors,VolWrites,MaxVolBytes,VolCapacityBytes,"
+ "VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,Recycle,Slot,"
+ "FirstWritten,LastWritten,VolStatus "
+ "FROM Media WHERE PoolId=%u AND MediaType='%s' AND VolStatus='%s' "
+ "ORDER BY LastWritten,MediaId",
+ mr->PoolId, mr->MediaType, mr->VolStatus);
+ }
}
if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
db_unlock(mdb);
* Returns: 0 on error or no Volumes found
* number of volumes on success
* Volumes are concatenated in VolumeNames
- * separated by a vertical bar (|).
+ * separated by a vertical bar (|) in the order
+ * that they were written.
*
* Returns: number of volumes on success
*/
db_lock(mdb);
Mmsg(&mdb->cmd,
-"SELECT VolumeName FROM JobMedia,Media WHERE JobMedia.JobId=%u "
-"AND JobMedia.MediaId=Media.MediaId GROUP BY VolumeName", JobId);
+ "SELECT VolumeName,JobMedia.VolIndex FROM JobMedia,Media WHERE "
+ "JobMedia.JobId=%u AND JobMedia.MediaId=Media.MediaId "
+ "GROUP BY VolumeName ORDER BY JobMedia.VolIndex", JobId);
Dmsg1(130, "VolNam=%s\n", mdb->cmd);
*VolumeNames[0] = 0;
{
int retry = 0;
bool ok;
+ bool InChanger;
mr->PoolId = jcr->PoolId;
bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType));
Dmsg2(120, "CatReq FindMedia: Id=%d, MediaType=%s\n", mr->PoolId, mr->MediaType);
+ /*
+ * If we are using an Autochanger, restrict Volume
+ * search to the Autochanger on the first pass
+ */
+ InChanger = jcr->store->autochanger;
/*
* Find the Next Volume for Append
*/
/*
* 1. Look for volume with "Append" status.
*/
- ok = db_find_next_volume(jcr, jcr->db, 1, mr);
+ ok = db_find_next_volume(jcr, jcr->db, 1, InChanger, mr);
Dmsg2(100, "catreq after find_next_vol ok=%d FW=%d\n", ok, mr->FirstWritten);
if (!ok) {
/*
* 2. Try finding a recycled volume
*/
- ok = find_recycled_volume(jcr, mr);
+ ok = find_recycled_volume(jcr, InChanger, mr);
Dmsg2(100, "find_recycled_volume %d FW=%d\n", ok, mr->FirstWritten);
if (!ok) {
/*
* 3. Try pruning Volumes
*/
prune_volumes(jcr);
- ok = recycle_oldest_purged_volume(jcr, mr);
+ ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
+ if (InChanger) {
+ InChanger = false;
+ if (!ok) {
+ continue; /* retry again accepting any volume */
+ }
+ }
Dmsg2(200, "find_recycled_volume2 %d FW=%d\n", ok, mr->FirstWritten);
if (!ok && create) {
/*
Dmsg2(200, "No next volume found. PurgeOldest=%d\n RecyleOldest=%d",
jcr->pool->purge_oldest_volume, jcr->pool->recycle_oldest_volume);
/* Find oldest volume to recycle */
- ok = db_find_next_volume(jcr, jcr->db, -1, mr);
+ ok = db_find_next_volume(jcr, jcr->db, -1, InChanger, mr);
Dmsg1(400, "Find oldest=%d\n", ok);
if (ok) {
UAContext *ua;
extern int prune_volumes(JCR *jcr);
/* autorecycle.c */
-extern int recycle_oldest_purged_volume(JCR *jcr, MEDIA_DBR *mr);
+extern int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
extern int recycle_volume(JCR *jcr, MEDIA_DBR *mr);
-extern int find_recycled_volume(JCR *jcr, MEDIA_DBR *mr);
+extern int find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
/* backup.c */
extern int wait_for_job_termination(JCR *jcr);
/* fd_cmds.c */
extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int send_include_list(JCR *jcr);
extern int send_exclude_list(JCR *jcr);
extern int send_bootstrap_file(JCR *jcr);
extern int get_attributes_and_put_in_catalog(JCR *jcr);
extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
- char *link, char *attr, int stream);
+ char *link, char *attr, int stream);
extern void get_level_since_time(JCR *jcr, char *since, int since_len);
extern int send_run_before_and_after_commands(JCR *jcr);
/* msgchan.c */
extern int connect_to_storage_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
+ int max_retry_time, int verbose);
extern int start_storage_daemon_job(JCR *jcr);
extern int start_storage_daemon_message_thread(JCR *jcr);
extern int bget_dirmsg(BSOCK *bs);
void free_ua_context(UAContext *ua);
/* ua_select.c */
-STORE *select_storage_resource(UAContext *ua);
-JOB *select_job_resource(UAContext *ua);
-JOB *select_restore_job_resource(UAContext *ua);
-CLIENT *select_client_resource(UAContext *ua);
+STORE *select_storage_resource(UAContext *ua);
+JOB *select_job_resource(UAContext *ua);
+JOB *select_restore_job_resource(UAContext *ua);
+CLIENT *select_client_resource(UAContext *ua);
FILESET *select_fileset_resource(UAContext *ua);
-int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
-int select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-
-void start_prompt(UAContext *ua, char *msg);
-void add_prompt(UAContext *ua, char *prompt);
-int do_prompt(UAContext *ua, char *automsg, char *msg, char *prompt, int max_prompt);
-CAT *get_catalog_resource(UAContext *ua);
+int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
+int select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+
+void start_prompt(UAContext *ua, char *msg);
+void add_prompt(UAContext *ua, char *prompt);
+int do_prompt(UAContext *ua, char *automsg, char *msg, char *prompt, int max_prompt);
+CAT *get_catalog_resource(UAContext *ua);
STORE *get_storage_resource(UAContext *ua, int use_default);
-int get_media_type(UAContext *ua, char *MediaType, int max_media);
-int get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+int get_media_type(UAContext *ua, char *MediaType, int max_media);
+int get_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
POOL *get_pool_resource(UAContext *ua);
POOL *select_pool_resource(UAContext *ua);
CLIENT *get_client_resource(UAContext *ua);
-int get_job_dbr(UAContext *ua, JOB_DBR *jr);
+int get_job_dbr(UAContext *ua, JOB_DBR *jr);
int find_arg_keyword(UAContext *ua, char **list);
int find_arg(UAContext *ua, char *keyword);
/* Forward referenced functions */
-int find_recycled_volume(JCR *jcr, MEDIA_DBR *mr)
+int find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
{
- strcpy(mr->VolStatus, "Recycle");
- if (db_find_next_volume(jcr, jcr->db, 1, mr)) {
+ bstrncpy(mr->VolStatus, "Recycle", sizeof(mr->VolStatus));
+ if (db_find_next_volume(jcr, jcr->db, 1, InChanger, mr)) {
jcr->MediaId = mr->MediaId;
Dmsg1(20, "Find_next_vol MediaId=%d\n", jcr->MediaId);
pm_strcpy(&jcr->VolumeName, mr->VolumeName);
/*
* Look for oldest Purged volume
*/
-int recycle_oldest_purged_volume(JCR *jcr, MEDIA_DBR *mr)
+int recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
{
struct s_oldest_ctx oldest;
POOLMEM *query = get_pool_memory(PM_EMSG);
- char *select =
- "SELECT MediaId, LastWritten FROM Media "
+ char *select1 =
+ "SELECT MediaId,LastWritten FROM Media "
+ "WHERE PoolId=%u AND Recycle=1 AND VolStatus=\"Purged\" "
+ "AND MediaType=\"%s\" AND InChanger=1";
+ char *select2 =
+ "SELECT MediaId,LastWritten FROM Media "
"WHERE PoolId=%u AND Recycle=1 AND VolStatus=\"Purged\" "
"AND MediaType=\"%s\"";
+
Dmsg0(100, "Enter recycle_oldest_purged_volume\n");
oldest.MediaId = 0;
bstrncpy(oldest.LastWritten, "9999-99-99 99:99:99", sizeof(oldest.LastWritten));
- Mmsg(&query, select, mr->PoolId, mr->MediaType);
+ if (InChanger) {
+ Mmsg(&query, select1, mr->PoolId, mr->MediaType);
+ } else {
+ Mmsg(&query, select2, mr->PoolId, mr->MediaType);
+ }
+
if (!db_sql_query(jcr->db, query, oldest_handler, (void *)&oldest)) {
Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
Dmsg0(100, "Exit 0 recycle_oldest_purged_volume query\n");
{ N_("estimate"), estimate_cmd, _("performs FileSet estimate, listing gives full listing")},
{ N_("exit"), quit_cmd, _("exit = quit")},
{ N_("help"), help_cmd, _("print this command")},
- { N_("list"), list_cmd, _("list [pools | jobs | jobtotals | media <pool> | files job=<nn>]; from catalog")},
+ { N_("list"), list_cmd, _("list [pools | jobs | jobtotals | media <pool> | files jobid=<nn>]; from catalog")},
{ N_("label"), label_cmd, _("label a tape")},
{ N_("llist"), llist_cmd, _("full or long list like list command")},
{ N_("messages"), messagescmd, _("messages")},
#undef VERSION
#define VERSION "1.33"
#define VSTRING "1"
-#define BDATE "18 Nov 2003"
-#define LSMDATE "18Nov03"
+#define BDATE "20 Nov 2003"
+#define LSMDATE "20Nov03"
/* Debug flags */
#undef DEBUG