+static void start_migration_job(JCR *jcr)
+{
+ UAContext *ua = new_ua_context(jcr);
+ char ed1[50];
+ ua->batch = true;
+ Mmsg(ua->cmd, "run %s jobid=%s", jcr->job->hdr.name,
+ edit_uint64(jcr->MigrateJobId, ed1));
+ Dmsg1(dbglevel, "=============== Migration cmd=%s\n", ua->cmd);
+ parse_ua_args(ua); /* parse command */
+ int stat = run_cmd(ua, ua->cmd);
+ if (stat == 0) {
+ Jmsg(jcr, M_ERROR, 0, _("Could not start migration job.\n"));
+ } else {
+ Jmsg(jcr, M_INFO, 0, _("Migration JobId %d started.\n"), stat);
+ }
+ free_ua_context(ua);
+}
+
+static bool find_mediaid_then_jobids(JCR *jcr, idpkt *ids, const char *query1,
+ const char *type)
+{
+ bool ok = false;
+ POOL_MEM query(PM_MESSAGE);
+
+ ids->count = 0;
+ /* Basic query for MediaId */
+ Mmsg(query, query1, jcr->pool->hdr.name);
+ if (!db_sql_query(jcr->db, query.c_str(), dbid_handler, (void *)ids)) {
+ Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db));
+ goto bail_out;
+ }
+ if (ids->count == 0) {
+ Jmsg(jcr, M_INFO, 0, _("No %ss found to migrate.\n"), type);
+ }
+ if (ids->count != 1) {
+ Jmsg(jcr, M_FATAL, 0, _("SQL logic error. Count should be 1 but is %d\n"),
+ ids->count);
+ goto bail_out;
+ }
+ Dmsg1(dbglevel, "Smallest Vol Jobids=%s\n", ids->list);
+
+ ok = find_jobids_from_mediaid_list(jcr, ids, type);
+
+bail_out:
+ return ok;
+}
+
+static bool find_jobids_from_mediaid_list(JCR *jcr, idpkt *ids, const char *type)
+{
+ bool ok = false;
+ POOL_MEM query(PM_MESSAGE);
+
+ Mmsg(query, sql_jobids_from_mediaid, ids->list);
+ ids->count = 0;
+ if (!db_sql_query(jcr->db, query.c_str(), dbid_handler, (void *)ids)) {
+ Jmsg(jcr, M_FATAL, 0, _("SQL failed. ERR=%s\n"), db_strerror(jcr->db));
+ goto bail_out;
+ }
+ if (ids->count == 0) {
+ Jmsg(jcr, M_INFO, 0, _("No %ss found to migrate.\n"), type);
+ }
+ ok = true;
+bail_out:
+ return ok;
+}
+
+static bool regex_find_jobids(JCR *jcr, idpkt *ids, const char *query1,
+ const char *query2, const char *type)
+{
+ dlist *item_chain;
+ uitem *item = NULL;
+ uitem *last_item = NULL;
+ regex_t preg;
+ char prbuf[500];
+ int rc;
+ bool ok = false;
+ POOL_MEM query(PM_MESSAGE);
+
+ item_chain = New(dlist(item, &item->link));
+ if (!jcr->job->selection_pattern) {
+ Jmsg(jcr, M_FATAL, 0, _("No Migration %s selection pattern specified.\n"),
+ type);
+ goto bail_out;
+ }
+ Dmsg1(dbglevel, "regex=%s\n", jcr->job->selection_pattern);
+ /* Compile regex expression */
+ rc = regcomp(&preg, jcr->job->selection_pattern, REG_EXTENDED);
+ if (rc != 0) {
+ regerror(rc, &preg, prbuf, sizeof(prbuf));
+ Jmsg(jcr, M_FATAL, 0, _("Could not compile regex pattern \"%s\" ERR=%s\n"),
+ jcr->job->selection_pattern, prbuf);
+ goto bail_out;
+ }
+ /* Basic query for names */
+ Mmsg(query, query1, jcr->pool->hdr.name);
+ Dmsg1(dbglevel, "query1=%s\n", query.c_str());
+ if (!db_sql_query(jcr->db, query.c_str(), unique_name_handler,
+ (void *)item_chain)) {
+ Jmsg(jcr, M_FATAL, 0,
+ _("SQL to get %s failed. ERR=%s\n"), type, db_strerror(jcr->db));
+ goto bail_out;
+ }
+ /* Now apply the regex to the names and remove any item not matched */
+ foreach_dlist(item, item_chain) {
+ const int nmatch = 30;
+ regmatch_t pmatch[nmatch];
+ if (last_item) {
+ Dmsg1(dbglevel, "Remove item %s\n", last_item->item);
+ free(last_item->item);
+ item_chain->remove(last_item);
+ }
+ Dmsg1(dbglevel, "Item=%s\n", item->item);
+ rc = regexec(&preg, item->item, nmatch, pmatch, 0);
+ if (rc == 0) {
+ last_item = NULL; /* keep this one */
+ } else {
+ last_item = item;
+ }
+ }
+ if (last_item) {
+ free(last_item->item);
+ Dmsg1(dbglevel, "Remove item %s\n", last_item->item);
+ item_chain->remove(last_item);
+ }
+ regfree(&preg);
+ /*
+ * At this point, we have a list of items in item_chain
+ * that have been matched by the regex, so now we need
+ * to look up their jobids.
+ */
+ ids->count = 0;
+ foreach_dlist(item, item_chain) {
+ Dmsg2(dbglevel, "Got %s: %s\n", type, item->item);
+ Mmsg(query, query2, item->item, jcr->pool->hdr.name);
+ Dmsg1(dbglevel, "query2=%s\n", query.c_str());
+ if (!db_sql_query(jcr->db, query.c_str(), dbid_handler, (void *)ids)) {
+ Jmsg(jcr, M_FATAL, 0,
+ _("SQL failed. ERR=%s\n"), db_strerror(jcr->db));
+ goto bail_out;
+ }
+ }
+ if (ids->count == 0) {
+ Jmsg(jcr, M_INFO, 0, _("No %ss found to migrate.\n"), type);
+ }
+ ok = true;
+bail_out:
+ Dmsg2(dbglevel, "Count=%d Jobids=%s\n", ids->count, ids->list);
+ delete item_chain;
+ Dmsg0(dbglevel, "After delete item_chain\n");
+ return ok;
+}
+