Пример #1
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;
}
Пример #2
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;
}
Пример #3
0
/*
 * Update Client record
 *   Returns: 0 on failure
 *            1 on success
 */
int
db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
{
   int stat;
   char ed1[50], ed2[50];
   char esc_name[MAX_ESCAPE_NAME_LENGTH];
   char esc_uname[MAX_ESCAPE_NAME_LENGTH];
   CLIENT_DBR tcr;

   db_lock(mdb);
   memcpy(&tcr, cr, sizeof(tcr));
   if (!db_create_client_record(jcr, mdb, &tcr)) {
      db_unlock(mdb);
      return 0;
   }

   mdb->db_escape_string(jcr, esc_name, cr->Name, strlen(cr->Name));
   mdb->db_escape_string(jcr, esc_uname, cr->Uname, strlen(cr->Uname));
   Mmsg(mdb->cmd,
"UPDATE Client SET AutoPrune=%d,FileRetention=%s,JobRetention=%s,"
"Uname='%s' WHERE Name='%s'",
      cr->AutoPrune,
      edit_uint64(cr->FileRetention, ed1),
      edit_uint64(cr->JobRetention, ed2),
      esc_uname, esc_name);

   stat = UPDATE_DB(jcr, mdb, mdb->cmd);
   db_unlock(mdb);
   return stat;
}
Пример #4
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;
}
Пример #5
0
bool
update_container_file(struct directory *directory,
                      const char *name,
                      const struct stat *st,
                      const struct decoder_plugin *plugin)
{
    if (plugin->container_scan == NULL)
        return false;

    db_lock();
    struct directory *contdir =
        make_directory_if_modified(directory, name, st);
    if (contdir == NULL) {
        /* not modified */
        db_unlock();
        return true;
    }

    contdir->device = DEVICE_CONTAINER;
    db_unlock();

    char *const pathname = map_directory_child_fs(directory, name);

    char *vtrack;
    unsigned int tnum = 0;
    while ((vtrack = plugin->container_scan(pathname, ++tnum)) != NULL) {
        struct song *song = song_file_new(vtrack, contdir);

        // shouldn't be necessary but it's there..
        song->mtime = st->st_mtime;

        char *child_path_fs = map_directory_child_fs(contdir, vtrack);

        song->tag = tag_new();
        decoder_plugin_scan_file(plugin, child_path_fs,
                                 &add_tag_handler, song->tag);
        g_free(child_path_fs);

        db_lock();
        directory_add_song(contdir, song);
        db_unlock();

        modified = true;

        g_message("added %s/%s",
                  directory_get_path(directory), vtrack);
        g_free(vtrack);
    }

    g_free(pathname);

    if (tnum == 1) {
        db_lock();
        delete_directory(contdir);
        db_unlock();
        return false;
    } else
        return true;
}
Пример #6
0
/*
 * Automatic Volume name creation using the LabelFormat
 *
 *  The media record must have the PoolId filled in when
 *   calling this routine.
 */
bool newVolume(JCR *jcr, MEDIA_DBR *mr)
{
   POOL_DBR pr;

   memset(&pr, 0, sizeof(pr));

   /* See if we can create a new Volume */
   db_lock(jcr->db);
   pr.PoolId = mr->PoolId;
   if (!db_get_pool_record(jcr, jcr->db, &pr)) {
      goto bail_out;
   }
   if (pr.MaxVols == 0 || pr.NumVols < pr.MaxVols) {
      memset(mr, 0, sizeof(MEDIA_DBR));
      set_pool_dbr_defaults_in_media_dbr(mr, &pr);
      jcr->VolumeName[0] = 0;
      bstrncpy(mr->MediaType, jcr->wstore->media_type, sizeof(mr->MediaType));
      generate_job_event(jcr, "NewVolume"); /* return bool */
      generate_plugin_event(jcr, bEventNewVolume); /* return void... */
      if (jcr->VolumeName[0] && is_volume_name_legal(NULL, jcr->VolumeName)) {
         bstrncpy(mr->VolumeName, jcr->VolumeName, sizeof(mr->VolumeName));
      /* Check for special characters */
      } else if (pr.LabelFormat[0] && pr.LabelFormat[0] != '*') {
         if (is_volume_name_legal(NULL, pr.LabelFormat)) {
            /* No special characters, so apply simple algorithm */
            if (!create_simple_name(jcr, mr, &pr)) {
               goto bail_out;
            }
         } else {  /* try full substitution */
            /* Found special characters, so try substitution */
            if (!perform_full_name_substitution(jcr, mr, &pr)) {
               goto bail_out;
            }
            if (!is_volume_name_legal(NULL, mr->VolumeName)) {
               Jmsg(jcr, M_ERROR, 0, _("Illegal character in Volume name \"%s\"\n"),
                  mr->VolumeName);
               goto bail_out;
            }
         }
      } else {                                       
         goto bail_out;
      }
      pr.NumVols++;
      mr->Enabled = 1;
      if (db_create_media_record(jcr, jcr->db, mr) &&
         db_update_pool_record(jcr, jcr->db, &pr)) {
         db_unlock(jcr->db);
         Jmsg(jcr, M_INFO, 0, _("Created new Volume \"%s\" in catalog.\n"), mr->VolumeName);
         Dmsg1(90, "Created new Volume=%s\n", mr->VolumeName);
         return true;
      } else {
         Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
      }
   }
bail_out:
   db_unlock(jcr->db);
   return false;
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
0
void db_list_client_records(JCR *jcr, B_DB *mdb, char *clientname, OUTPUT_FORMATTER *sendit, e_list_type type)
{
   db_lock(mdb);
   POOL_MEM clientfilter(PM_MESSAGE);

   if (clientname) {
      clientfilter.bsprintf("WHERE Name = '%s'", clientname);
   }
   if (type == VERT_LIST) {
      Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,"
           "JobRetention "
           "FROM Client %s ORDER BY ClientId ", clientfilter.c_str());
   } else {
      Mmsg(mdb->cmd, "SELECT ClientId,Name,FileRetention,JobRetention "
           "FROM Client %s ORDER BY ClientId", clientfilter.c_str());
   }

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

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

   sql_free_result(mdb);

bail_out:
   db_unlock(mdb);
}
Пример #10
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;
}
Пример #11
0
bool db_list_sql_query(JCR *jcr, B_DB *mdb, const char *query,
                       OUTPUT_FORMATTER *sendit, e_list_type type,
                       const char *description, bool verbose)
{
   bool retval = false;

   db_lock(mdb);
   if (!sql_query(mdb, query, QF_STORE_RESULT)) {
      Mmsg(mdb->errmsg, _("Query failed: %s\n"), sql_strerror(mdb));
      if (verbose) {
         sendit->decoration(mdb->errmsg);
      }
      goto bail_out;
   }

   sendit->array_start(description);
   list_result(jcr, mdb, sendit, type);
   sendit->array_end(description);
   sql_free_result(mdb);
   retval = true;

bail_out:
   db_unlock(mdb);
   return retval;
}
Пример #12
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);
}
Пример #13
0
void db_list_client_records(JCR *jcr, B_DB *mdb, OUTPUT_FORMATTER *sendit, e_list_type type)
{
   db_lock(mdb);
   if (type == VERT_LIST) {
      Mmsg(mdb->cmd, "SELECT ClientId,Name,Uname,AutoPrune,FileRetention,"
         "JobRetention "
         "FROM Client ORDER BY ClientId");
   } else {
      Mmsg(mdb->cmd, "SELECT ClientId,Name,FileRetention,JobRetention "
         "FROM Client ORDER BY ClientId");
   }

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

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

   sql_free_result(mdb);

bail_out:
   db_unlock(mdb);
}
Пример #14
0
/*
 * Prune a given Volume
 */
bool prune_volume(UAContext *ua, MEDIA_DBR *mr)
{
   POOL_MEM query(PM_MESSAGE);
   struct del_ctx del;
   bool ok = false;
   int count;

   if (mr->Enabled == 2) {
      return false;                   /* Cannot prune archived volumes */
   }

   memset(&del, 0, sizeof(del));
   del.max_ids = 10000;
   del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);

   db_lock(ua->db);

   /* Prune only Volumes with status "Full", or "Used" */
   if (strcmp(mr->VolStatus, "Full")   == 0 ||
       strcmp(mr->VolStatus, "Used")   == 0) {
      Dmsg2(050, "get prune list MediaId=%d Volume %s\n", (int)mr->MediaId, mr->VolumeName);
      count = get_prune_list_for_volume(ua, mr, &del);
      Dmsg1(050, "Num pruned = %d\n", count);
      if (count != 0) {
         purge_job_list_from_catalog(ua, del);
      }
      ok = is_volume_purged(ua, mr);
   }

   db_unlock(ua->db);
   if (del.JobId) {
      free(del.JobId);
   }
   return ok;
}
Пример #15
0
/*
 * List Job totals
 *
 */
void db_list_job_totals(JCR *jcr, B_DB *mdb, JOB_DBR *jr, OUTPUT_FORMATTER *sendit)
{
   db_lock(mdb);

   /* List by Job */
   Mmsg(mdb->cmd, "SELECT  count(*) AS Jobs,sum(JobFiles) "
      "AS Files,sum(JobBytes) AS Bytes,Name AS Job FROM Job GROUP BY Name");

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

   list_result(jcr, mdb, sendit, HORZ_LIST);

   sql_free_result(mdb);

   /* Do Grand Total */
   Mmsg(mdb->cmd, "SELECT count(*) AS Jobs,sum(JobFiles) "
        "AS Files,sum(JobBytes) As Bytes FROM Job");

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

   list_result(jcr, mdb, sendit, HORZ_LIST);

   sql_free_result(mdb);

bail_out:
   db_unlock(mdb);
}
Пример #16
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;
}
Пример #17
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);
}
Пример #18
0
/*
 * Set the inchanger flag to zero for each slot marked in
 * the given slot_list.
 *
 * The vol_list passed here needs to be from an "autochanger listall" cmd.
 */
void update_inchanger_for_export(UAContext *ua, STORERES *store, dlist *vol_list, char *slot_list)
{
   vol_list_t *vl;
   MEDIA_DBR mr;

   if (!open_client_db(ua)) {
      return;
   }

   /*
    * Walk through the list updating the media records
    */
   foreach_dlist(vl, vol_list) {
      /*
       * We are only interested in normal slots.
       */
      switch (vl->Type) {
      case slot_type_normal:
         break;
      default:
         continue;
      }

      /*
       * Only update entries of slots marked in the slot_list.
       */
      if (!bit_is_set(vl->Slot - 1, slot_list)) {
         continue;
      }

      /*
       * Set InChanger to zero for this Slot
       */
      memset(&mr, 0, sizeof(mr));
      mr.Slot = vl->Slot;
      mr.InChanger = 1;
      mr.MediaId = 0;                 /* Get by VolumeName */
      if (vl->VolName) {
         bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName));
      } else {
         mr.VolumeName[0] = 0;
      }
      set_storageid_in_mr(store, &mr);

      Dmsg4(100, "Before make unique: Vol=%s slot=%d inchanger=%d sid=%d\n",
            mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId);
      db_lock(ua->db);

      /*
       * Set InChanger to zero for this Slot
       */
      db_make_inchanger_unique(ua->jcr, ua->db, &mr);

      db_unlock(ua->db);
      Dmsg4(100, "After make unique: Vol=%s slot=%d inchanger=%d sid=%d\n",
            mr.VolumeName, mr.Slot, mr.InChanger, mr.StorageId);
   }
   return;
}
Пример #19
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);
}
Пример #20
0
/*
 * used for SELECT queries
 */
MYSQL_RES* db_select(char *query, ...)
{
	va_list arglist;
	va_start(arglist, query);

	db_lock();

	if (db_query_raw(query, arglist)) {
		va_end(arglist);
		db_unlock();
		return NULL;
	}

	va_end(arglist);

	MYSQL_RES* ret = mysql_store_result(conn);
	db_unlock();

	return ret;
}
Пример #21
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;
}
Пример #22
0
/*
 * Delete Pool record, must also delete all associated
 *  Media records.
 *
 *  Returns: false on error
 *           true on success
 *           PoolId = number of Pools deleted (should be 1)
 *           NumVols = number of Media records deleted
 */
bool db_delete_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
{
   bool retval = false;
   SQL_ROW row;
   int num_rows;
   char esc[MAX_ESCAPE_NAME_LENGTH];

   db_lock(mdb);
   mdb->db_escape_string(jcr, esc, pr->Name, strlen(pr->Name));
   Mmsg(mdb->cmd, "SELECT PoolId FROM Pool WHERE Name='%s'", esc);
   Dmsg1(10, "selectpool: %s\n", mdb->cmd);

   pr->PoolId = pr->NumVols = 0;

   if (QUERY_DB(jcr, mdb, mdb->cmd)) {

      num_rows = sql_num_rows(mdb);
      if (num_rows == 0) {
         Mmsg(mdb->errmsg, _("No pool record %s exists\n"), pr->Name);
         sql_free_result(mdb);
         goto bail_out;
      } else if (num_rows != 1) {
         Mmsg(mdb->errmsg, _("Expecting one pool record, got %d\n"), num_rows);
         sql_free_result(mdb);
         goto bail_out;
      }
      if ((row = sql_fetch_row(mdb)) == NULL) {
         Mmsg1(mdb->errmsg, _("Error fetching row %s\n"), sql_strerror(mdb));
         goto bail_out;
      }
      pr->PoolId = str_to_int64(row[0]);
      sql_free_result(mdb);
   }

   /* Delete Media owned by this pool */
   Mmsg(mdb->cmd,
"DELETE FROM Media WHERE Media.PoolId = %d", pr->PoolId);

   pr->NumVols = DELETE_DB(jcr, mdb, mdb->cmd);
   Dmsg1(200, "Deleted %d Media records\n", pr->NumVols);

   /* Delete Pool */
   Mmsg(mdb->cmd,
"DELETE FROM Pool WHERE Pool.PoolId = %d", pr->PoolId);
   pr->PoolId = DELETE_DB(jcr, mdb, mdb->cmd);
   Dmsg1(200, "Deleted %d Pool records\n", pr->PoolId);

   retval = true;

bail_out:
   db_unlock(mdb);
   return retval;
}
Пример #23
0
int log_get      (logbase_t * base, long long rec, logrec_t * data)
{  int rc;

   if (base->fasync == 0) rc = db_shlock(base->fd);
   else rc = 0;

   if (rc >= 0)
   {  rc = logi_get(base, rec, data);
      if (base->fasync == 0) db_unlock(base->fd);
   }
   else return IO_ERROR;  
   return rc;
}
Пример #24
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;
}
Пример #25
0
/*
 * used for insert and update queries
 * returns 0 for success
 */
int db_insert(char *query, ...)
{
	va_list arglist;
	va_start(arglist, query);

	db_lock();

	int res = db_query_raw(query, arglist);
	va_end(arglist);

	db_unlock();

	return res;
}
Пример #26
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;
}
Пример #27
0
int log_put      (logbase_t * base, long long rec, logrec_t * data)
{  int rc;

   syslog(LOG_ERR, "log_put() requested :)");

   if (base->fasync == 0) rc = db_exlock(base->fd);
   else rc = 0;

   if (rc >= 0)
   {  rc = logi_put(base, rec, data);
      if (base->fasync == 0) db_unlock(base->fd);
   }
   else return IO_ERROR;  
   return rc;
}
Пример #28
0
/*
 * Find the last job start time for the specified JobLevel
 *
 *  StartTime is returned in stime
 *
 * Returns: false on failure
 *          true  on success, jr is unchanged, but stime is set
 */
bool
db_find_last_job_start_time(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM **stime, int JobLevel)
{
   SQL_ROW row;
   char ed1[50], ed2[50];

   db_lock(mdb);

   pm_strcpy(stime, "0000-00-00 00:00:00");   /* default */

   Mmsg(mdb->cmd,
"SELECT StartTime 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, jr->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]);
   sql_free_result(mdb);
   db_unlock(mdb);
   return true;

bail_out:
   db_unlock(mdb);
   return false;
}
Пример #29
0
/*
 * Update Counters record
 *   Returns: 0 on failure
 *            1 on success
 */
int db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
{
   char esc[MAX_ESCAPE_NAME_LENGTH];
   db_lock(mdb);
   mdb->db_escape_string(jcr, esc, cr->Counter, strlen(cr->Counter));
   Mmsg(mdb->cmd,
"UPDATE Counters SET Counters.MinValue=%d,Counters.MaxValue=%d,CurrentValue=%d,"
"WrapCounter='%s' WHERE Counter='%s'",
      cr->MinValue, cr->MaxValue, cr->CurrentValue,
      cr->WrapCounter, esc);

   int stat = UPDATE_DB(jcr, mdb, mdb->cmd);
   db_unlock(mdb);
   return stat;
}
Пример #30
0
/* Prune Job stat records from the database.
 *
 */
int prune_stats(UAContext *ua, utime_t retention)
{
   char ed1[50];
   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 catalog.\n"));

   return true;
}