edit_int64(mr->PoolId, ed1), mr->MediaType);
item = 1;
} else {
- char changer[100];
+ POOL_MEM changer(PM_FNAME);
/* Find next available volume */
if (InChanger) {
- bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s",
- edit_int64(mr->StorageId, ed1));
- } else {
- changer[0] = 0;
+ Mmsg(changer, "AND InChanger=1 AND StorageId=%s",
+ edit_int64(mr->StorageId, ed1));
}
if (strcmp(mr->VolStatus, "Recycle") == 0 ||
strcmp(mr->VolStatus, "Purged") == 0) {
- order = "ORDER BY LastWritten ASC,MediaId"; /* take oldest */
+ order = "AND Recycle=1 ORDER BY LastWritten ASC,MediaId"; /* take oldest that can be recycled */
} else {
order = "ORDER BY LastWritten IS NULL,LastWritten DESC,MediaId"; /* take most recently written */
}
"%s "
"%s LIMIT %d",
edit_int64(mr->PoolId, ed1), mr->MediaType,
- mr->VolStatus, changer, order, item);
+ mr->VolStatus, changer.c_str(), order, item);
}
Dmsg1(050, "fnextvol=%s\n", mdb->cmd);
if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
*/
if (prune) {
Dmsg0(150, "Call prune_volumes\n");
- prune_volumes(jcr, InChanger, mr);
+ ok = prune_volumes(jcr, InChanger, mr);
}
- ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
- if (!ok && create) {
- Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n",
- ok, index, InChanger, mr->VolStatus);
- /*
- * 5. Try pulling a volume from the Scratch pool
- */
- ok = get_scratch_volume(jcr, InChanger, mr);
- }
- /*
- * If we are using an Autochanger and have not found
- * a volume, retry looking for any volume.
- */
- if (InChanger) {
- InChanger = false;
- if (!ok) {
- continue; /* retry again accepting any volume */
- }
- }
- }
+ if (!ok) {
+ ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
+ if (!ok && create) {
+ Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n",
+ ok, index, InChanger, mr->VolStatus);
+ /*
+ * 5. Try pulling a volume from the Scratch pool
+ */
+ ok = get_scratch_volume(jcr, InChanger, mr);
+ Dmsg4(050, "after get scratch volume ok=%d index=%d InChanger=%d Vstat=%s\n",
+ ok, index, InChanger, mr->VolStatus);
+ }
+ /*
+ * If we are using an Autochanger and have not found
+ * a volume, retry looking for any volume.
+ */
+ if (!ok && InChanger) {
+ InChanger = false;
+ continue; /* retry again accepting any volume */
+ }
+ }
+ }
}
#include "dird.h"
#include "ua.h"
-struct s_oldest_ctx {
- uint32_t MediaId;
- char LastWritten[30];
-};
-
-static int oldest_handler(void *ctx, int num_fields, char **row)
-{
- struct s_oldest_ctx *oldest = (struct s_oldest_ctx *)ctx;
-
- if (row[0]) {
- oldest->MediaId = str_to_int64(row[0]);
- bstrncpy(oldest->LastWritten, row[1]?row[1]:"", sizeof(oldest->LastWritten));
- Dmsg1(100, "New oldest %s\n", row[1]?row[1]:"");
- }
- return 1;
-}
-
/* Forward referenced functions */
bool find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
return false;
}
-
/*
* Look for oldest Purged volume
*/
bool recycle_oldest_purged_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr)
{
- struct s_oldest_ctx oldest;
- char ed1[50];
- POOLMEM *query = get_pool_memory(PM_EMSG);
- const char *select =
- "SELECT MediaId,LastWritten FROM Media "
- "WHERE PoolId=%s AND Recycle=1 AND VolStatus='Purged' "
- "AND Enabled=1 AND MediaType='%s' "
- "ORDER BY LastWritten ASC,MediaId LIMIT 1";
-
- Dmsg0(100, "Enter recycle_oldest_purged_volume\n");
- oldest.MediaId = 0;
- Mmsg(query, select, edit_int64(mr->PoolId, ed1), 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, "return 0 recycle_oldest_purged_volume query\n");
- free_pool_memory(query);
- return false;
- }
- free_pool_memory(query);
- Dmsg1(100, "Oldest mediaid=%d\n", oldest.MediaId);
- if (oldest.MediaId != 0) {
- mr->MediaId = oldest.MediaId;
- if (db_get_media_record(jcr, jcr->db, mr)) {
- if (recycle_volume(jcr, mr)) {
- Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\"\n"), mr->VolumeName);
- Dmsg1(100, "return 1 recycle_oldest_purged_volume Vol=%s\n", mr->VolumeName);
- return true;
- }
+ bstrncpy(mr->VolStatus, "Purged", sizeof(mr->VolStatus));
+ if (db_find_next_volume(jcr, jcr->db, 1, InChanger, mr)) {
+ if (recycle_volume(jcr, mr)) {
+ Jmsg(jcr, M_INFO, 0, _("Recycled volume \"%s\"\n"), mr->VolumeName);
+ Dmsg1(100, "return 1 recycle_oldest_purged_volume Vol=%s\n", mr->VolumeName);
+ return true;
}
- Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
}
Dmsg0(100, "return 0 recycle_oldest_purged_volume end\n");
return false;
General:
+25Jun08
+ebl Fix get_next_volume_for_append logic with autochanger
+ - use pruned volumes if found
+ - don't reset the inchanger flag after getting a recycled volume
+ or a scratch one
+ Fix recycle_oldest_purged_volume to take InChanger flag in account
23Jun08
ebl Add mmap/unmmap implementation for tokyodbm under win32
kes Make first step toward eliminating globals from config