Пример #1
0
/* Modify the RecyclePool of a Volume */
void update_vol_recyclepool(UAContext *ua, char *val, MEDIA_DBR *mr)
{
   POOL_DBR pr;
   POOL_MEM query(PM_MESSAGE);
   char ed1[50], ed2[50], *poolname;

   if(val && *val) { /* update volume recyclepool="Scratch" */
     /* If a pool name is given, look up the PoolId */
     memset(&pr, 0, sizeof(pr));
     bstrncpy(pr.Name, val, sizeof(pr.Name));
     if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) {
        return;
     }
     /* pool = select_pool_resource(ua);  */
     mr->RecyclePoolId = pr.PoolId;            /* get the PoolId */
     poolname = pr.Name;

  } else { /* update volume recyclepool="" */
    /* If no pool name is given, set the PoolId to 0 (the default) */
     mr->RecyclePoolId = 0;
     poolname = _("*None*");
  }

   db_lock(ua->db);
   Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s",
      edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2));
   if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
      ua->error_msg("%s", db_strerror(ua->db));
   } else {
      ua->info_msg(_("New RecyclePool is: %s\n"), poolname);
   }
   db_unlock(ua->db);
}
Пример #2
0
static int send_volume_info_to_storage_daemon(JCR *jcr, BSOCK *sd, MEDIA_DBR *mr)
{
   int status;
   char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50];

   jcr->MediaId = mr->MediaId;
   pm_strcpy(jcr->VolumeName, mr->VolumeName);
   bash_spaces(mr->VolumeName);
   status = sd->fsend(OK_media, mr->VolumeName, mr->VolJobs,
      mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
      mr->VolMounts, mr->VolErrors, mr->VolWrites,
      edit_uint64(mr->MaxVolBytes, ed2),
      edit_uint64(mr->VolCapacityBytes, ed3),
      mr->VolStatus, mr->Slot, mr->MaxVolJobs, mr->MaxVolFiles,
      mr->InChanger,
      edit_int64(mr->VolReadTime, ed4),
      edit_int64(mr->VolWriteTime, ed5),
      mr->EndFile, mr->EndBlock,
      mr->LabelType,
      edit_uint64(mr->MediaId, ed6),
      mr->EncrKey, mr->MinBlocksize, mr->MaxBlocksize);
   unbash_spaces(mr->VolumeName);
   Dmsg2(100, "Vol Info for %s: %s", jcr->Job, sd->msg);
   return status;
}
Пример #3
0
/*
 * This routine will purge (delete) all records
 * associated with a particular Volume. It will
 * not delete the media record itself.
 * TODO: This function is broken and it doesn't purge
 *       File, BaseFiles, Log, ...
 *       We call it from relabel and delete volume=, both ensure
 *       that the volume is properly purged.
 */
static int do_media_purge(B_DB *mdb, MEDIA_DBR *mr)
{
   POOLMEM *query = get_pool_memory(PM_MESSAGE);
   struct s_del_ctx del;
   char ed1[50];
   int i;

   del.num_ids = 0;
   del.tot_ids = 0;
   del.num_del = 0;
   del.max_ids = 0;
   Mmsg(mdb->cmd, "SELECT JobId from JobMedia WHERE MediaId=%d", mr->MediaId);
   del.max_ids = mr->VolJobs;
   if (del.max_ids < 100) {
      del.max_ids = 100;
   } else if (del.max_ids > MAX_DEL_LIST_LEN) {
      del.max_ids = MAX_DEL_LIST_LEN;
   }
   del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
   db_sql_query(mdb, mdb->cmd, delete_handler, (void *)&del);

   for (i=0; i < del.num_ids; i++) {
      Dmsg1(400, "Delete JobId=%d\n", del.JobId[i]);
      Mmsg(query, "DELETE FROM Job WHERE JobId=%s", edit_int64(del.JobId[i], ed1));
      db_sql_query(mdb, query);
      Mmsg(query, "DELETE FROM File WHERE JobId=%s", edit_int64(del.JobId[i], ed1));
      db_sql_query(mdb, query);
      Mmsg(query, "DELETE FROM JobMedia WHERE JobId=%s", edit_int64(del.JobId[i], ed1));
      db_sql_query(mdb, query);
   }
   free(del.JobId);
   free_pool_memory(query);
   return 1;
}
Пример #4
0
/* Modify the Pool in which this Volume is located */
void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
{
   POOL_DBR pr;
   POOL_MEM query(PM_MESSAGE);
   char ed1[50], ed2[50];

   memset(&pr, 0, sizeof(pr));
   bstrncpy(pr.Name, val, sizeof(pr.Name));
   if (!get_pool_dbr(ua, &pr)) {
      return;
   }
   mr->PoolId = pr.PoolId;            /* set new PoolId */
   /*
    */
   db_lock(ua->db);
   Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s",
      edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2));
   if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
      ua->error_msg("%s", db_strerror(ua->db));
   } else {
      ua->info_msg(_("New Pool is: %s\n"), pr.Name);
      opr->NumVols--;
      if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
         ua->error_msg("%s", db_strerror(ua->db));
      }
      pr.NumVols++;
      if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
         ua->error_msg("%s", db_strerror(ua->db));
      }
   }
   db_unlock(ua->db);
}
Пример #5
0
/*
 * Find last failed job since given start-time
 *   it must be either Full or Diff.
 *
 * Returns: false on failure
 *          true  on success, jr is unchanged and stime unchanged
 *                level returned in JobLevel
 */
bool BDB::bdb_find_failed_job_since(JCR *jcr, JOB_DBR *jr, POOLMEM *stime, int &JobLevel)
{
   SQL_ROW row;
   char ed1[50], ed2[50];
   char esc_name[MAX_ESCAPE_NAME_LENGTH];

   bdb_lock();
   bdb_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));

   /* Differential is since last Full backup */
   Mmsg(cmd,
   "SELECT Level FROM Job WHERE JobStatus IN ('%c','%c', '%c', '%c') AND "
      "Type='%c' AND Level IN ('%c','%c') AND Name='%s' AND ClientId=%s "
      "AND FileSetId=%s AND StartTime>'%s' "
      "ORDER BY StartTime DESC LIMIT 1",
         JS_Canceled, JS_ErrorTerminated, JS_Error, JS_FatalError,
         jr->JobType, L_FULL, L_DIFFERENTIAL, esc_name,
         edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2),
         stime);
   if (!QueryDB(jcr, cmd)) {
      bdb_unlock();
      return false;
   }

   if ((row = sql_fetch_row()) == NULL) {
      sql_free_result();
      bdb_unlock();
      return false;
   }
   JobLevel = (int)*row[0];
   sql_free_result();

   bdb_unlock();
   return true;
}
Пример #6
0
/*
 * If we have a non-zero InChanger, ensure that no other Media
 *  record has InChanger set on the same Slot.
 *
 * This routine assumes the database is already locked.
 */
void
db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
{
    char ed1[50], ed2[50];
    char esc[MAX_ESCAPE_NAME_LENGTH];
    if (mr->InChanger != 0 && mr->Slot != 0 && mr->StorageId != 0) {

        if (mr->MediaId != 0) {
            Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0, Slot=0 WHERE "
                 "Slot=%d AND StorageId=%s AND MediaId!=%s",
                 mr->Slot,
                 edit_int64(mr->StorageId, ed1), edit_int64(mr->MediaId, ed2));

        } else if (*mr->VolumeName) {
            mdb->db_escape_string(jcr, esc,mr->VolumeName,strlen(mr->VolumeName));
            Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0, Slot=0 WHERE "
                 "Slot=%d AND StorageId=%s AND VolumeName!='%s'",
                 mr->Slot,
                 edit_int64(mr->StorageId, ed1), esc);

        } else {  /* used by ua_label to reset all volume with this slot */
            Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0, Slot=0 WHERE "
                 "Slot=%d AND StorageId=%s",
                 mr->Slot,
                 edit_int64(mr->StorageId, ed1), mr->VolumeName);
        }
        Dmsg1(100, "%s\n", mdb->cmd);
        UPDATE_DB_NO_AFR(jcr, mdb, mdb->cmd);
    }
}
Пример #7
0
bool db_update_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
{
   bool retval;
   char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50];
   char esc[MAX_ESCAPE_NAME_LENGTH];

   db_lock(mdb);
   mdb->db_escape_string(jcr, esc, pr->LabelFormat, strlen(pr->LabelFormat));

   Mmsg(mdb->cmd, "SELECT count(*) from Media WHERE PoolId=%s",
      edit_int64(pr->PoolId, ed4));
   pr->NumVols = get_sql_record_max(jcr, mdb);
   Dmsg1(400, "NumVols=%d\n", pr->NumVols);

   Mmsg(mdb->cmd,
"UPDATE Pool SET NumVols=%u,MaxVols=%u,UseOnce=%d,UseCatalog=%d,"
"AcceptAnyVolume=%d,VolRetention='%s',VolUseDuration='%s',"
"MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,Recycle=%d,"
"AutoPrune=%d,LabelType=%d,LabelFormat='%s',RecyclePoolId=%s,"
"ScratchPoolId=%s,ActionOnPurge=%d WHERE PoolId=%s",
      pr->NumVols, pr->MaxVols, pr->UseOnce, pr->UseCatalog,
      pr->AcceptAnyVolume, edit_uint64(pr->VolRetention, ed1),
      edit_uint64(pr->VolUseDuration, ed2),
      pr->MaxVolJobs, pr->MaxVolFiles,
      edit_uint64(pr->MaxVolBytes, ed3),
      pr->Recycle, pr->AutoPrune, pr->LabelType,
      esc, edit_int64(pr->RecyclePoolId,ed5),
      edit_int64(pr->ScratchPoolId,ed6),
      pr->ActionOnPurge,
      ed4);
   retval = UPDATE_DB(jcr, mdb, mdb->cmd);
   db_unlock(mdb);
   return retval;
}
Пример #8
0
/*
 * Get prune list for a volume
 */
int get_prune_list_for_volume(UAContext *ua, MEDIA_DBR *mr, del_ctx *del)
{
   POOL_MEM query(PM_MESSAGE);
   int count = 0;
   utime_t now, period;
   char ed1[50], ed2[50];

   if (mr->Enabled == 2) {
      return 0;                    /* cannot prune Archived volumes */
   }

   /*
    * Now add to the  list of JobIds for Jobs written to this Volume
    */
   edit_int64(mr->MediaId, ed1); 
   period = mr->VolRetention;
   now = (utime_t)time(NULL);
   edit_int64(now-period, ed2);
   Mmsg(query, sel_JobMedia, ed1, ed2);
   Dmsg3(250, "Now=%d period=%d now-period=%s\n", (int)now, (int)period,
      ed2);

   Dmsg1(050, "Query=%s\n", query.c_str());
   if (!db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)del)) {
      if (ua->verbose) {
         ua->error_msg("%s", db_strerror(ua->db));
      }
      Dmsg0(050, "Count failed\n");
      goto bail_out;
   }
   count = exclude_running_jobs_from_list(del);
   
bail_out:
   return count;
}
Пример #9
0
/*
 * Find last failed job since given start-time
 *   it must be either Full or Diff.
 *
 * Returns: false on failure
 *          true  on success, jr is unchanged and stime unchanged
 *                level returned in JobLevel
 */
bool
db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel)
{
   SQL_ROW row;
   char ed1[50], ed2[50];

   db_lock(mdb);
   /* Differential is since last Full backup */
   Mmsg(mdb->cmd,
"SELECT Level FROM Job WHERE JobStatus!='T' AND Type='%c' AND "
"Level IN ('%c','%c') AND Name='%s' AND ClientId=%s "
"AND FileSetId=%s AND StartTime>'%s' "
"ORDER BY StartTime DESC LIMIT 1",
         jr->JobType, L_FULL, L_DIFFERENTIAL, jr->Name,
         edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2),
         stime);

   if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
      db_unlock(mdb);
      return false;
   }

   if ((row = sql_fetch_row(mdb)) == NULL) {
      sql_free_result(mdb);
      db_unlock(mdb);
      return false;
   }
   JobLevel = (int)*row[0];
   sql_free_result(mdb);

   db_unlock(mdb);
   return true;
}
Пример #10
0
/*
 * Update the Job record at start of Job
 *
 * Returns: false on failure
 *          true  on success
 */
bool db_update_job_start_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
{
    char dt[MAX_TIME_LENGTH];
    time_t stime;
    struct tm tm;
    btime_t JobTDate;
    bool retval;
    char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50];

    stime = jr->StartTime;
    (void)localtime_r(&stime, &tm);
    strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
    JobTDate = (btime_t)stime;

    db_lock(mdb);
    Mmsg(mdb->cmd, "UPDATE Job SET JobStatus='%c',Level='%c',StartTime='%s',"
         "ClientId=%s,JobTDate=%s,PoolId=%s,FileSetId=%s WHERE JobId=%s",
         (char)(jcr->JobStatus),
         (char)(jr->JobLevel), dt,
         edit_int64(jr->ClientId, ed1),
         edit_uint64(JobTDate, ed2),
         edit_int64(jr->PoolId, ed3),
         edit_int64(jr->FileSetId, ed4),
         edit_int64(jr->JobId, ed5));

    retval = UPDATE_DB(jcr, mdb, mdb->cmd);
    mdb->changes = 0;
    db_unlock(mdb);
    return retval;
}
Пример #11
0
/*
 * Find last failed job since given start-time
 *   it must be either Full or Diff.
 *
 * Returns: false on failure
 *          true  on success, jr is unchanged and stime unchanged
 *                level returned in JobLevel
 */
bool db_find_failed_job_since(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *stime, int &JobLevel)
{
   bool retval = false;
   SQL_ROW row;
   char ed1[50], ed2[50];
   char esc_name[MAX_ESCAPE_NAME_LENGTH];

   db_lock(mdb);
   mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));

   /* Differential is since last Full backup */
   Mmsg(mdb->cmd,
"SELECT Level FROM Job WHERE JobStatus NOT IN ('T','W') AND "
"Type='%c' AND Level IN ('%c','%c') AND Name='%s' AND ClientId=%s "
"AND FileSetId=%s AND StartTime>'%s' "
"ORDER BY StartTime DESC LIMIT 1",
         jr->JobType, L_FULL, L_DIFFERENTIAL, esc_name,
         edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2),
         stime);
   if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
      goto bail_out;
   }

   if ((row = sql_fetch_row(mdb)) == NULL) {
      sql_free_result(mdb);
      goto bail_out;
   }
   JobLevel = (int)*row[0];
   sql_free_result(mdb);
   retval = true;

bail_out:
   db_unlock(mdb);
   return retval;
}
Пример #12
0
/*
 * Find JobId of last job that ran.  E.g. for
 *   VERIFY_CATALOG we want the JobId of the last INIT.
 *   For VERIFY_VOLUME_TO_CATALOG, we want the JobId of the last Job.
 *
 * Returns: true  on success
 *          false on failure
 */
bool
db_find_last_jobid(JCR *jcr, B_DB *mdb, const char *Name, JOB_DBR *jr)
{
   SQL_ROW row;
   char ed1[50];

   /* Find last full */
   db_lock(mdb);
   Dmsg2(100, "JobLevel=%d JobType=%d\n", jr->JobLevel, jr->JobType);
   if (jr->JobLevel == L_VERIFY_CATALOG) {
      Mmsg(mdb->cmd,
"SELECT JobId FROM Job WHERE Type='V' AND Level='%c' AND "
" JobStatus IN ('T','W') AND Name='%s' AND "
"ClientId=%s ORDER BY StartTime DESC LIMIT 1",
           L_VERIFY_INIT, jr->Name, 
           edit_int64(jr->ClientId, ed1));
   } else if (jr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ||
              jr->JobLevel == L_VERIFY_DISK_TO_CATALOG ||
              jr->JobType == JT_BACKUP) {
      if (Name) {
         Mmsg(mdb->cmd,
"SELECT JobId FROM Job WHERE Type='B' AND JobStatus IN ('T','W') AND "
"Name='%s' ORDER BY StartTime DESC LIMIT 1", Name);
      } else {
         Mmsg(mdb->cmd,
"SELECT JobId FROM Job WHERE Type='B' AND JobStatus IN ('T','W') AND "
"ClientId=%s ORDER BY StartTime DESC LIMIT 1", 
           edit_int64(jr->ClientId, ed1));
      }
   } else {
      Mmsg1(&mdb->errmsg, _("Unknown Job level=%d\n"), jr->JobLevel);
      db_unlock(mdb);
      return false;
   }
   Dmsg1(100, "Query: %s\n", mdb->cmd);
   if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
      db_unlock(mdb);
      return false;
   }
   if ((row = sql_fetch_row(mdb)) == NULL) {
      Mmsg1(&mdb->errmsg, _("No Job found for: %s.\n"), mdb->cmd);
      sql_free_result(mdb);
      db_unlock(mdb);
      return false;
   }

   jr->JobId = str_to_int64(row[0]);
   sql_free_result(mdb);

   Dmsg1(100, "db_get_last_jobid: got JobId=%d\n", jr->JobId);
   if (jr->JobId <= 0) {
      Mmsg1(&mdb->errmsg, _("No Job found for: %s\n"), mdb->cmd);
      db_unlock(mdb);
      return false;
   }

   db_unlock(mdb);
   return true;
}
Пример #13
0
/*
 * If VolumeName is non-zero, list the record for that Volume
 *   otherwise, list the Volumes in the Pool specified by PoolId
 */
void db_list_media_records(JCR *jcr, B_DB *mdb, MEDIA_DBR *mdbr,
                           OUTPUT_FORMATTER *sendit, e_list_type type)
{
   char ed1[50];
   char esc[MAX_ESCAPE_NAME_LENGTH];

   db_lock(mdb);
   mdb->db_escape_string(jcr, esc, mdbr->VolumeName, strlen(mdbr->VolumeName));

   if (type == VERT_LIST) {
      if (mdbr->VolumeName[0] != 0) {
         Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId,"
            "MediaType,FirstWritten,LastWritten,LabelDate,VolJobs,"
            "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
            "VolCapacityBytes,VolStatus,Enabled,Recycle,VolRetention,"
            "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
            "EndFile,EndBlock,LabelType,StorageId,DeviceId,"
            "LocationId,RecycleCount,InitialWrite,ScratchPoolId,RecyclePoolId, "
            "Comment"
            " FROM Media WHERE Media.VolumeName='%s'", esc);
      } else {
         Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,Slot,PoolId,"
            "MediaType,FirstWritten,LastWritten,LabelDate,VolJobs,"
            "VolFiles,VolBlocks,VolMounts,VolBytes,VolErrors,VolWrites,"
            "VolCapacityBytes,VolStatus,Enabled,Recycle,VolRetention,"
            "VolUseDuration,MaxVolJobs,MaxVolFiles,MaxVolBytes,InChanger,"
            "EndFile,EndBlock,LabelType,StorageId,DeviceId,"
            "LocationId,RecycleCount,InitialWrite,ScratchPoolId,RecyclePoolId, "
            "Comment"
            " FROM Media WHERE Media.PoolId=%s ORDER BY MediaId",
            edit_int64(mdbr->PoolId, ed1));
      }
   } else {
      if (mdbr->VolumeName[0] != 0) {
         Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,Enabled,"
            "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten "
            "FROM Media WHERE Media.VolumeName='%s'", esc);
      } else {
         Mmsg(mdb->cmd, "SELECT MediaId,VolumeName,VolStatus,Enabled,"
            "VolBytes,VolFiles,VolRetention,Recycle,Slot,InChanger,MediaType,LastWritten "
            "FROM Media WHERE Media.PoolId=%s ORDER BY MediaId",
            edit_int64(mdbr->PoolId, ed1));
      }
   }

   if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
      goto bail_out;
   }

   sendit->object_start("media");
   list_result(jcr, mdb, sendit, type);
   sendit->object_end("media");

   sql_free_result(mdb);

bail_out:
   db_unlock(mdb);
}
Пример #14
0
/* Mark the file record as being visited during database
 * verify compare. Stuff JobId into the MarkId field
 */
bool db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId)
{
    bool retval;
    char ed1[50], ed2[50];

    db_lock(mdb);
    Mmsg(mdb->cmd, "UPDATE File SET MarkId=%s WHERE FileId=%s",
         edit_int64(JobId, ed1), edit_int64(FileId, ed2));
    retval = UPDATE_DB(jcr, mdb, mdb->cmd);
    db_unlock(mdb);
    return retval;
}
Пример #15
0
/*
 * Update the Job record at end of Job
 *
 *  Returns: 0 on failure
 *           1 on success
 */
int
db_update_job_end_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
{
   char dt[MAX_TIME_LENGTH];
   char rdt[MAX_TIME_LENGTH];
   time_t ttime;
   struct tm tm;
   int stat;
   char ed1[30], ed2[30], ed3[50], ed4[50];
   btime_t JobTDate;
   char PriorJobId[50];

   if (jr->PriorJobId) {
      bstrncpy(PriorJobId, edit_int64(jr->PriorJobId, ed1), sizeof(PriorJobId));
   } else {
      bstrncpy(PriorJobId, "0", sizeof(PriorJobId));
   }

   ttime = jr->EndTime;
   (void)localtime_r(&ttime, &tm);
   strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);

   if (jr->RealEndTime == 0) {
      jr->RealEndTime = jr->EndTime;
   }
   ttime = jr->RealEndTime;
   (void)localtime_r(&ttime, &tm);
   strftime(rdt, sizeof(rdt), "%Y-%m-%d %H:%M:%S", &tm);

   JobTDate = ttime;

   db_lock(mdb);
   Mmsg(mdb->cmd,
      "UPDATE Job SET JobStatus='%c',EndTime='%s',"
"ClientId=%u,JobBytes=%s,ReadBytes=%s,JobFiles=%u,JobErrors=%u,VolSessionId=%u,"
"VolSessionTime=%u,PoolId=%u,FileSetId=%u,JobTDate=%s,"
"RealEndTime='%s',PriorJobId=%s,HasBase=%u,PurgedFiles=%u WHERE JobId=%s",
      (char)(jr->JobStatus), dt, jr->ClientId, edit_uint64(jr->JobBytes, ed1),
      edit_uint64(jr->ReadBytes, ed4),
      jr->JobFiles, jr->JobErrors, jr->VolSessionId, jr->VolSessionTime,
      jr->PoolId, jr->FileSetId, edit_uint64(JobTDate, ed2), 
      rdt, PriorJobId, jr->HasBase, jr->PurgedFiles,
      edit_int64(jr->JobId, ed3));

   stat = UPDATE_DB(jcr, mdb, mdb->cmd);

   db_unlock(mdb);
   return stat;
}
Пример #16
0
/*
 * Update pool record -- pull info from current POOL resource
 */
static bool update_pool(UAContext *ua)
{
   POOL_DBR  pr;
   int id;
   POOL *pool;
   POOLMEM *query;
   char ed1[50];

   pool = get_pool_resource(ua);
   if (!pool) {
      return false;
   }

   memset(&pr, 0, sizeof(pr));
   bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
   if (!get_pool_dbr(ua, &pr)) {
      return false;
   }

   set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
   set_pooldbr_references(ua->jcr, ua->db, &pr, pool);

   id = db_update_pool_record(ua->jcr, ua->db, &pr);
   if (id <= 0) {
      ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"),
         id, db_strerror(ua->db));
   }
   query = get_pool_memory(PM_MESSAGE);
   Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
   db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
   free_pool_memory(query);
   ua->info_msg(_("Pool DB record updated from resource.\n"));
   return true;
}
Пример #17
0
/*
 * Delete jobs (all records) from the catalog in groups of 1000
 *  at a time.
 */
void purge_job_list_from_catalog(UAContext *ua, del_ctx &del)
{
   POOL_MEM jobids(PM_MESSAGE);
   char ed1[50];

   for (int i=0; del.num_ids; ) {
      Dmsg1(150, "num_ids=%d\n", del.num_ids);
      pm_strcat(jobids, "");
      for (int j=0; j<1000 && del.num_ids>0; j++) {
         del.num_ids--;
         if (del.JobId[i] == 0 || ua->jcr->JobId == del.JobId[i]) {
            Dmsg2(150, "skip JobId[%d]=%d\n", i, (int)del.JobId[i]);
            i++;
            continue;
         }
         if (*jobids.c_str() != 0) {
            pm_strcat(jobids, ",");
         }
         pm_strcat(jobids, edit_int64(del.JobId[i++], ed1));
         Dmsg1(150, "Add id=%s\n", ed1);
         del.num_del++;
      }
      Dmsg1(150, "num_ids=%d\n", del.num_ids);
      purge_jobs_from_catalog(ua, jobids.c_str());
   }
}
Пример #18
0
/*
 * Prune Job stat records from the database.
 */
static bool prune_stats(UAContext *ua, utime_t retention)
{
   char ed1[50];
   char dt[MAX_TIME_LENGTH];
   POOL_MEM query(PM_MESSAGE);
   utime_t now = (utime_t)time(NULL);

   db_lock(ua->db);
   Mmsg(query, "DELETE FROM JobHisto WHERE JobTDate < %s",
        edit_int64(now - retention, ed1));
   db_sql_query(ua->db, query.c_str());
   db_unlock(ua->db);

   ua->info_msg(_("Pruned Jobs from JobHisto in catalog.\n"));

   bstrutime(dt, sizeof(dt), now - retention);

   db_lock(ua->db);
   Mmsg(query, "DELETE FROM DeviceStats WHERE SampleTime < '%s'", dt);
   db_sql_query(ua->db, query.c_str());
   db_unlock(ua->db);

   ua->info_msg(_("Pruned Statistics from DeviceStats in catalog.\n"));

   db_lock(ua->db);
   Mmsg(query, "DELETE FROM JobStats WHERE SampleTime < '%s'", dt);
   db_sql_query(ua->db, query.c_str());
   db_unlock(ua->db);

   ua->info_msg(_("Pruned Statistics from JobStats in catalog.\n"));

   return true;
}
Пример #19
0
/*
 * Delete files from a list of jobs in groups of 1000
 *  at a time.
 */
void purge_files_from_job_list(UAContext *ua, del_ctx &del)
{
   POOL_MEM jobids(PM_MESSAGE);
   char ed1[50];
   /*
    * OK, now we have the list of JobId's to be pruned, send them
    *   off to be deleted batched 1000 at a time.
    */
   for (int i=0; del.num_ids; ) {
      pm_strcat(jobids, "");
      for (int j=0; j<1000 && del.num_ids>0; j++) {
         del.num_ids--;
         if (del.JobId[i] == 0 || ua->jcr->JobId == del.JobId[i]) {
            Dmsg2(150, "skip JobId[%d]=%d\n", i, (int)del.JobId[i]);
            i++;
            continue;
         }
         if (*jobids.c_str() != 0) {
            pm_strcat(jobids, ",");
         }
         pm_strcat(jobids, edit_int64(del.JobId[i++], ed1));
         Dmsg1(150, "Add id=%s\n", ed1);
         del.num_del++;
      }
      purge_files_from_jobs(ua, jobids.c_str());
   }
}
Пример #20
0
static bool build_directory_tree(UAContext *ua, RESTORE_CTX *rx)
{
   TREE_CTX tree;
   JobId_t JobId, last_JobId;
   char *p;
   bool OK = true;
   char ed1[50];

   memset(&tree, 0, sizeof(TREE_CTX));
   /*
    * Build the directory tree containing JobIds user selected
    */
   tree.root = new_tree(rx->TotalFiles);
   tree.ua = ua;
   tree.all = rx->all;
   last_JobId = 0;
   /*
    * For display purposes, the same JobId, with different volumes may
    * appear more than once, however, we only insert it once.
    */
   p = rx->JobIds;
   tree.FileEstimate = 0;
   if (get_next_jobid_from_list(&p, &JobId) > 0) {
      /* Use first JobId as estimate of the number of files to restore */
      Mmsg(rx->query, uar_count_files, edit_int64(JobId, ed1));
      if (!db_sql_query(ua->db, rx->query, restore_count_handler, (void *)rx)) {
         ua->error_msg("%s\n", db_strerror(ua->db));
      }
      if (rx->found) {
         /* Add about 25% more than this job for over estimate */
         tree.FileEstimate = rx->JobId + (rx->JobId >> 2);
         tree.DeltaCount = rx->JobId/50; /* print 50 ticks */
      }
Пример #21
0
/*
 * Use pool and client specified by user to select jobs to prune
 * returns add_from string to add in FROM clause
 *         add_where string to add in WHERE clause
 */
bool prune_set_filter(UAContext *ua, CLIENTRES *client, POOLRES *pool, utime_t period,
                      POOL_MEM *add_from, POOL_MEM *add_where)
{
   utime_t now;
   char ed1[50], ed2[MAX_ESCAPE_NAME_LENGTH];
   POOL_MEM tmp(PM_MESSAGE);

   now = (utime_t)time(NULL);
   edit_int64(now - period, ed1);
   Dmsg3(150, "now=%lld period=%lld JobTDate=%s\n", now, period, ed1);
   Mmsg(tmp, " AND JobTDate < %s ", ed1);
   pm_strcat(*add_where, tmp.c_str());

   db_lock(ua->db);
   if (client) {
      db_escape_string(ua->jcr, ua->db, ed2,
                       client->name(), strlen(client->name()));
      Mmsg(tmp, " AND Client.Name = '%s' ", ed2);
      pm_strcat(*add_where, tmp.c_str());
      pm_strcat(*add_from, " JOIN Client USING (ClientId) ");
   }

   if (pool) {
      db_escape_string(ua->jcr, ua->db, ed2,
                       pool->name(), strlen(pool->name()));
      Mmsg(tmp, " AND Pool.Name = '%s' ", ed2);
      pm_strcat(*add_where, tmp.c_str());
      /* Use ON() instead of USING for some old SQLite */
      pm_strcat(*add_from, " JOIN Pool ON (Job.PoolId = Pool.PoolId) ");
   }
   Dmsg2(150, "f=%s w=%s\n", add_from->c_str(), add_where->c_str());
   db_unlock(ua->db);
   return true;
}
Пример #22
0
void db_list_files_for_job(JCR *jcr, B_DB *mdb, JobId_t jobid, OUTPUT_FORMATTER *sendit)
{
   char ed1[50];
   LIST_CTX lctx(jcr, mdb, sendit, NF_LIST);

   db_lock(mdb);

   /*
    * Stupid MySQL is NON-STANDARD !
    */
   if (db_get_type_index(mdb) == SQL_TYPE_MYSQL) {
      Mmsg(mdb->cmd, "SELECT CONCAT(Path.Path,Filename.Name) AS Filename "
           "FROM (SELECT PathId, FilenameId FROM File WHERE JobId=%s "
                  "UNION ALL "
                 "SELECT PathId, FilenameId "
                   "FROM BaseFiles JOIN File "
                         "ON (BaseFiles.FileId = File.FileId) "
                  "WHERE BaseFiles.JobId = %s"
           ") AS F, Filename,Path "
           "WHERE Filename.FilenameId=F.FilenameId "
           "AND Path.PathId=F.PathId",
           edit_int64(jobid, ed1), ed1);
   } else {
      Mmsg(mdb->cmd, "SELECT Path.Path||Filename.Name AS Filename "
           "FROM (SELECT PathId, FilenameId FROM File WHERE JobId=%s "
                  "UNION ALL "
                 "SELECT PathId, FilenameId "
                   "FROM BaseFiles JOIN File "
                         "ON (BaseFiles.FileId = File.FileId) "
                  "WHERE BaseFiles.JobId = %s"
           ") AS F, Filename,Path "
           "WHERE Filename.FilenameId=F.FilenameId "
           "AND Path.PathId=F.PathId",
           edit_int64(jobid, ed1), ed1);
   }

   sendit->array_start("filenames");
   if (!db_big_sql_query(mdb, mdb->cmd, list_result, &lctx)) {
       goto bail_out;
   }
   sendit->array_end("filenames");

   sql_free_result(mdb);

bail_out:
   db_unlock(mdb);
}
Пример #23
0
/*
 * Update the Media Record Default values from Pool
 *
 * Returns: false on failure
 *          true on success
 */
bool db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
{
    bool retval;
    char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50];
    char esc[MAX_ESCAPE_NAME_LENGTH];

    db_lock(mdb);
    if (mr->VolumeName[0]) {
        mdb->db_escape_string(jcr, esc, mr->VolumeName, strlen(mr->VolumeName));
        Mmsg(mdb->cmd, "UPDATE Media SET "
             "ActionOnPurge=%d,Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
             "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,RecyclePoolId=%s,"
             "MinBlocksize=%d,MaxBlocksize=%d"
             " WHERE VolumeName='%s'",
             mr->ActionOnPurge, mr->Recycle,edit_uint64(mr->VolRetention, ed1),
             edit_uint64(mr->VolUseDuration, ed2),
             mr->MaxVolJobs, mr->MaxVolFiles,
             edit_uint64(mr->MaxVolBytes, ed3),
             edit_uint64(mr->RecyclePoolId, ed4),
             mr->MinBlocksize,
             mr->MaxBlocksize,
             esc);
    } else {
        Mmsg(mdb->cmd, "UPDATE Media SET "
             "ActionOnPurge=%d,Recycle=%d,VolRetention=%s,VolUseDuration=%s,"
             "MaxVolJobs=%u,MaxVolFiles=%u,MaxVolBytes=%s,RecyclePoolId=%s,"
             "MinBlocksize=%d,MaxBlocksize=%d"
             " WHERE PoolId=%s",
             mr->ActionOnPurge, mr->Recycle,edit_uint64(mr->VolRetention, ed1),
             edit_uint64(mr->VolUseDuration, ed2),
             mr->MaxVolJobs, mr->MaxVolFiles,
             edit_uint64(mr->MaxVolBytes, ed3),
             edit_int64(mr->RecyclePoolId, ed4),
             mr->MinBlocksize,
             mr->MaxBlocksize,
             edit_int64(mr->PoolId, ed5));
    }

    Dmsg1(400, "%s\n", mdb->cmd);

    retval = UPDATE_DB(jcr, mdb, mdb->cmd);

    db_unlock(mdb);
    return retval;
}
Пример #24
0
/*
 * List fileset
 */
void db_list_filesets(JCR *jcr, B_DB *mdb, JOB_DBR *jr, const char *range,
                      OUTPUT_FORMATTER *sendit, e_list_type type)
{
   char esc[MAX_ESCAPE_NAME_LENGTH];

   db_lock(mdb);
   if (jr->Name[0] != 0) {
      mdb->db_escape_string(jcr, esc, jr->Name, strlen(jr->Name));
      Mmsg(mdb->cmd, "SELECT DISTINCT FileSet.FileSetId AS FileSetId, FileSet, MD5, CreateTime, FileSetText "
           "FROM Job, FileSet "
           "WHERE Job.FileSetId = FileSet.FileSetId "
           "AND Job.Name='%s'%s", esc, range);
   } else if (jr->Job[0] != 0) {
      mdb->db_escape_string(jcr, esc, jr->Job, strlen(jr->Job));
      Mmsg(mdb->cmd, "SELECT DISTINCT FileSet.FileSetId AS FileSetId, FileSet, MD5, CreateTime, FileSetText "
           "FROM Job, FileSet "
           "WHERE Job.FileSetId = FileSet.FileSetId "
           "AND Job.Name='%s'%s", esc, range);
   } else if (jr->JobId != 0) {
      Mmsg(mdb->cmd, "SELECT DISTINCT FileSet.FileSetId AS FileSetId, FileSet, MD5, CreateTime, FileSetText "
           "FROM Job, FileSet "
           "WHERE Job.FileSetId = FileSet.FileSetId "
           "AND Job.JobId='%s'%s", edit_int64(jr->JobId, esc), range);
   } else if (jr->FileSetId != 0) {
      Mmsg(mdb->cmd, "SELECT FileSetId, FileSet, MD5, CreateTime, FileSetText "
           "FROM FileSet "
           "WHERE  FileSetId=%s", edit_int64(jr->FileSetId, esc));
   } else {                           /* all records */
      Mmsg(mdb->cmd, "SELECT DISTINCT FileSet.FileSetId AS FileSetId, FileSet, MD5, CreateTime, FileSetText "
           "FROM FileSet ORDER BY FileSetId ASC%s", range);
   }

   if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
      goto bail_out;
   }
   sendit->array_start("filesets");
   list_result(jcr, mdb, sendit, type);
   sendit->array_end("filesets");

   sql_free_result(mdb);

bail_out:
   db_unlock(mdb);
}
Пример #25
0
void db_list_jobmedia_records(JCR *jcr, B_DB *mdb, uint32_t JobId,
                              OUTPUT_FORMATTER *sendit, e_list_type type)
{
   char ed1[50];

   db_lock(mdb);
   if (type == VERT_LIST) {
      if (JobId > 0) {                   /* do by JobId */
         Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
              "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
              "JobMedia.EndBlock "
              "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId "
              "AND JobMedia.JobId=%s", edit_int64(JobId, ed1));
      } else {
         Mmsg(mdb->cmd, "SELECT JobMediaId,JobId,Media.MediaId,Media.VolumeName,"
              "FirstIndex,LastIndex,StartFile,JobMedia.EndFile,StartBlock,"
              "JobMedia.EndBlock "
              "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId");
      }

   } else {
      if (JobId > 0) {                   /* do by JobId */
         Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
              "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId "
              "AND JobMedia.JobId=%s", edit_int64(JobId, ed1));
      } else {
         Mmsg(mdb->cmd, "SELECT JobId,Media.VolumeName,FirstIndex,LastIndex "
              "FROM JobMedia,Media WHERE Media.MediaId=JobMedia.MediaId");
      }
   }
   if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
      goto bail_out;
   }

   sendit->array_start("jobmedia");
   list_result(jcr, mdb, sendit, type);
   sendit->array_end("jobmedia");

   sql_free_result(mdb);

bail_out:
   db_unlock(mdb);
}
Пример #26
0
/*
 * Find the most recent successful real end time for a job given.
 *
 *  RealEndTime is returned in etime
 *  Job name is returned in job (MAX_NAME_LENGTH)
 *
 * Returns: false on failure
 *          true  on success, jr is unchanged, but etime and job are set
 */
bool BDB::bdb_find_last_job_end_time(JCR *jcr, JOB_DBR *jr, POOLMEM **etime, 
          char *job)
{
   SQL_ROW row;
   char ed1[50], ed2[50];
   char esc_name[MAX_ESCAPE_NAME_LENGTH];

   bdb_lock();
   bdb_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));
   pm_strcpy(etime, "0000-00-00 00:00:00");   /* default */
   job[0] = 0;

   Mmsg(cmd,
        "SELECT RealEndTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
        "Level IN ('%c','%c','%c') AND Name='%s' AND ClientId=%s AND FileSetId=%s "
        "ORDER BY RealEndTime DESC LIMIT 1", jr->JobType, 
        L_FULL, L_DIFFERENTIAL, L_INCREMENTAL, esc_name, 
        edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2));

   if (!QueryDB(jcr, cmd)) {
      Mmsg2(&errmsg, _("Query error for end time request: ERR=%s\nCMD=%s\n"),
         sql_strerror(), cmd);
      goto bail_out;
   }
   if ((row = sql_fetch_row()) == NULL) {
      sql_free_result();
      Mmsg(errmsg, _("No prior backup Job record found.\n"));
      goto bail_out;
   }
   Dmsg1(100, "Got end time: %s\n", row[0]);
   pm_strcpy(etime, row[0]);
   bstrncpy(job, row[1], MAX_NAME_LENGTH);

   sql_free_result();
   bdb_unlock();
   return true;

bail_out:
   bdb_unlock();
   return false;
}
Пример #27
0
static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
{
   POOL_MEM query(PM_MESSAGE);
   char ed1[50];
   Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s",
      val, edit_int64(mr->MediaId, ed1));
   if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
      ua->error_msg("%s", db_strerror(ua->db));
   } else {
      ua->info_msg(_("New max files is: %s\n"), val);
   }
}
Пример #28
0
static void *do_batch(void *jcr)
{
   JCR *bjcr = (JCR *)jcr;
   char data[1024];
   int lineno = 0;
   struct ATTR_DBR ar;
   memset(&ar, 0, sizeof(ar));
   btime_t begin = get_current_btime();
   char *datafile = bjcr->where;

   FILE *fd = fopen(datafile, "r");
   if (!fd) {
      Emsg1(M_ERROR_TERM, 0, _("Error opening datafile %s\n"), datafile);
   }
   while (fgets(data, sizeof(data)-1, fd)) {
      strip_trailing_newline(data);
      lineno++;
      if (verbose && ((lineno % 5000) == 1)) {
         printf("\r%i", lineno);
      }
      fill_attr(&ar, data);
      if (!db_create_attributes_record(bjcr, bjcr->db, &ar)) {
         Emsg0(M_ERROR_TERM, 0, _("Error while inserting file\n"));
      }
   }
   fclose(fd);
   db_write_batch_file_records(bjcr);
   btime_t end = get_current_btime();

   P(mutex);
   char ed1[200], ed2[200];
   printf("\rbegin = %s, end = %s\n", edit_int64(begin, ed1),edit_int64(end, ed2));
   printf("Insert time = %sms\n", edit_int64((end - begin) / 10000, ed1));
   printf("Create %u files at %.2f/s\n", lineno,
          (lineno / ((float)((end - begin) / 1000000))));
   nb--;
   V(mutex);
   pthread_exit(NULL);
   return NULL;
}
Пример #29
0
/*
 * Find the last job start time for the specified JobLevel
 *
 *  StartTime is returned in stime
 *  Job name is returned in job (MAX_NAME_LENGTH)
 *
 * Returns: false on failure
 *          true  on success, jr is unchanged, but stime and job are set
 */
bool db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr,
                                 POOLMEM **stime, char *job, int JobLevel)
{
   bool retval = false;
   SQL_ROW row;
   char ed1[50], ed2[50];
   char esc_name[MAX_ESCAPE_NAME_LENGTH];

   db_lock(mdb);
   mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));
   pm_strcpy(stime, "0000-00-00 00:00:00");   /* default */
   job[0] = 0;

   Mmsg(mdb->cmd,
"SELECT StartTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
"Level='%c' AND Name='%s' AND ClientId=%s AND FileSetId=%s "
"ORDER BY StartTime DESC LIMIT 1",
      jr->JobType, JobLevel, esc_name,
      edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2));
   if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
      Mmsg2(&mdb->errmsg, _("Query error for start time request: ERR=%s\nCMD=%s\n"),
         sql_strerror(mdb), mdb->cmd);
      goto bail_out;
   }
   if ((row = sql_fetch_row(mdb)) == NULL) {
      sql_free_result(mdb);
      Mmsg(mdb->errmsg, _("No prior Full backup Job record found.\n"));
      goto bail_out;
   }
   Dmsg1(100, "Got start time: %s\n", row[0]);
   pm_strcpy(stime, row[0]);
   bstrncpy(job, row[1], MAX_NAME_LENGTH);

   sql_free_result(mdb);
   retval = true;

bail_out:
   db_unlock(mdb);
   return retval;
}
Пример #30
0
bool db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
{
    bool retval;
    char ed1[50];

    db_lock(mdb);
    Mmsg(mdb->cmd, "UPDATE Storage SET AutoChanger=%d WHERE StorageId=%s",
         sr->AutoChanger, edit_int64(sr->StorageId, ed1));

    retval = UPDATE_DB(jcr, mdb, mdb->cmd);
    db_unlock(mdb);
    return retval;
}