X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fua_run.c;h=334fe079c1e733a85c27d9b174e4a201267e9e16;hb=4f7896c56213a88d17777db9041a9643ae541c5f;hp=05113cc2b9e032107629467015017ee7451c915d;hpb=b199f720596dd5cfe1be63a39f87614218ab04f3;p=bacula%2Fbacula diff --git a/bacula/src/dird/ua_run.c b/bacula/src/dird/ua_run.c index 05113cc2b9..334fe079c1 100644 --- a/bacula/src/dird/ua_run.c +++ b/bacula/src/dird/ua_run.c @@ -6,24 +6,18 @@ * * Version $Id$ */ - /* - Copyright (C) 2001-2003 Kern Sibbald and John Walker + Copyright (C) 2001-2006 Kern Sibbald This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License + version 2 as amended with additional clauses defined in the + file LICENSE in the main source directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -33,7 +27,6 @@ /* Imported subroutines */ /* Imported variables */ -extern struct s_jl joblevels[]; extern struct s_kw ReplaceOptions[]; /* @@ -41,41 +34,56 @@ extern struct s_kw ReplaceOptions[]; * run [job=] level= * * For Restore Jobs - * run jobid=nn + * run + * + * Returns: 0 on error + * JobId if OK * */ -int run_cmd(UAContext *ua, char *cmd) +int run_cmd(UAContext *ua, const char *cmd) { JCR *jcr; char *job_name, *level_name, *jid, *store_name, *pool_name; - char *where, *fileset_name, *client_name, *bootstrap, *replace; - char *when, *verify_job_name; + char *where, *fileset_name, *client_name, *bootstrap; + const char *replace; + char *when, *verify_job_name, *catalog_name; + char *previous_job_name; + char *since = NULL; + char *verify_list; + bool cloned = false; int Priority = 0; - int i, j, opt; - bool found; + int i, j, opt, files = 0; + bool kw_ok; JOB *job = NULL; JOB *verify_job = NULL; + JOB *previous_job = NULL; STORE *store = NULL; CLIENT *client = NULL; FILESET *fileset = NULL; POOL *pool = NULL; - static char *kw[] = { /* command line arguments */ - N_("job"), /* Used in a switch() */ - N_("jobid"), /* 1 */ - N_("client"), /* 2 */ - N_("fd"), - N_("fileset"), /* 4 */ - N_("level"), /* 5 */ - N_("storage"), /* 6 */ - N_("sd"), /* 7 */ - N_("pool"), /* 8 */ - N_("where"), /* 9 */ - N_("bootstrap"), /* 10 */ - N_("replace"), /* 11 */ - N_("when"), /* 12 */ - N_("priority"), /* 13 */ - N_("yes"), /* 14 -- if you change this change YES_POS too */ - N_("verifyjob"), /* 16 */ + static const char *kw[] = { /* command line arguments */ + "job", /* Used in a switch() */ + "jobid", /* 1 */ + "client", /* 2 */ + "fd", + "fileset", /* 4 */ + "level", /* 5 */ + "storage", /* 6 */ + "sd", /* 7 */ + "pool", /* 8 */ + "where", /* 9 */ + "bootstrap", /* 10 */ + "replace", /* 11 */ + "when", /* 12 */ + "priority", /* 13 */ + "yes", /* 14 -- if you change this change YES_POS too */ + "verifyjob", /* 15 */ + "files", /* 16 number of files to restore */ + "catalog", /* 17 override catalog */ + "since", /* 18 since */ + "cloned", /* 19 cloned */ + "verifylist", /* 20 verify output list */ + "migrationjob", /* 21 migration job name */ NULL}; #define YES_POS 14 @@ -96,232 +104,327 @@ int run_cmd(UAContext *ua, char *cmd) bootstrap = NULL; replace = NULL; verify_job_name = NULL; + previous_job_name = NULL; + catalog_name = NULL; + verify_list = NULL; for (i=1; iargc; i++) { - found = false; - Dmsg2(200, "Doing arg %d = %s\n", i, ua->argk[i]); - for (j=0; !found && kw[j]; j++) { - if (strcasecmp(ua->argk[i], _(kw[j])) == 0) { - /* Note, yes and run have no value, so do not err */ - if (!ua->argv[i] && j != YES_POS /*yes*/) { + Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]); + kw_ok = false; + /* Keep looking until we find a good keyword */ + for (j=0; !kw_ok && kw[j]; j++) { + if (strcasecmp(ua->argk[i], kw[j]) == 0) { + /* Note, yes and run have no value, so do not fail */ + if (!ua->argv[i] && j != YES_POS /*yes*/) { bsendmsg(ua, _("Value missing for keyword %s\n"), ua->argk[i]); - return 1; - } - Dmsg1(200, "Got keyword=%s\n", kw[j]); - switch (j) { - case 0: /* job */ - if (job_name) { + return 1; + } + Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j])); + switch (j) { + case 0: /* job */ + if (job_name) { bsendmsg(ua, _("Job name specified twice.\n")); - return 1; - } - job_name = ua->argv[i]; - found = true; - break; - case 1: /* JobId */ - if (jid) { + return 0; + } + job_name = ua->argv[i]; + kw_ok = true; + break; + case 1: /* JobId */ + if (jid) { bsendmsg(ua, _("JobId specified twice.\n")); - return 1; - } - jid = ua->argv[i]; - found = true; - break; - case 2: /* client */ - case 3: /* fd */ - if (client_name) { + return 0; + } + jid = ua->argv[i]; + kw_ok = true; + break; + case 2: /* client */ + case 3: /* fd */ + if (client_name) { bsendmsg(ua, _("Client specified twice.\n")); - return 1; - } - client_name = ua->argv[i]; - found = true; - break; - case 4: /* fileset */ - if (fileset_name) { + return 0; + } + client_name = ua->argv[i]; + kw_ok = true; + break; + case 4: /* fileset */ + if (fileset_name) { bsendmsg(ua, _("FileSet specified twice.\n")); - return 1; - } - fileset_name = ua->argv[i]; - found = true; - break; - case 5: /* level */ - if (level_name) { + return 0; + } + fileset_name = ua->argv[i]; + kw_ok = true; + break; + case 5: /* level */ + if (level_name) { bsendmsg(ua, _("Level specified twice.\n")); - return 1; - } - level_name = ua->argv[i]; - found = true; - break; - case 6: /* storage */ - case 7: /* sd */ - if (store_name) { + return 0; + } + level_name = ua->argv[i]; + kw_ok = true; + break; + case 6: /* storage */ + case 7: /* sd */ + if (store_name) { bsendmsg(ua, _("Storage specified twice.\n")); - return 1; - } - store_name = ua->argv[i]; - found = true; - break; - case 8: /* pool */ - if (pool_name) { + return 0; + } + store_name = ua->argv[i]; + kw_ok = true; + break; + case 8: /* pool */ + if (pool_name) { bsendmsg(ua, _("Pool specified twice.\n")); - return 1; - } - pool_name = ua->argv[i]; - found = true; - break; - case 9: /* where */ - if (where) { + return 0; + } + pool_name = ua->argv[i]; + kw_ok = true; + break; + case 9: /* where */ + if (where) { bsendmsg(ua, _("Where specified twice.\n")); - return 1; - } - where = ua->argv[i]; - found = true; - break; - case 10: /* bootstrap */ - if (bootstrap) { + return 0; + } + where = ua->argv[i]; + kw_ok = true; + break; + case 10: /* bootstrap */ + if (bootstrap) { bsendmsg(ua, _("Bootstrap specified twice.\n")); - return 1; - } - bootstrap = ua->argv[i]; - found = true; - break; - case 11: /* replace */ - if (replace) { + return 0; + } + bootstrap = ua->argv[i]; + kw_ok = true; + break; + case 11: /* replace */ + if (replace) { bsendmsg(ua, _("Replace specified twice.\n")); - return 1; - } - replace = ua->argv[i]; - found = true; - break; - case 12: /* When */ - if (when) { + return 0; + } + replace = ua->argv[i]; + kw_ok = true; + break; + case 12: /* When */ + if (when) { bsendmsg(ua, _("When specified twice.\n")); - return 1; - } - when = ua->argv[i]; - found = true; - break; - case 13: /* Priority */ - if (Priority) { + return 0; + } + when = ua->argv[i]; + kw_ok = true; + break; + case 13: /* Priority */ + if (Priority) { bsendmsg(ua, _("Priority specified twice.\n")); - return 1; - } - Priority = atoi(ua->argv[i]); - if (Priority <= 0) { + return 0; + } + Priority = atoi(ua->argv[i]); + if (Priority <= 0) { bsendmsg(ua, _("Priority must be positive nonzero setting it to 10.\n")); - Priority = 10; - } - break; - case 14: /* yes */ - found = true; - break; - case 15: /* Verify Job */ - if (verify_job_name) { + Priority = 10; + } + kw_ok = true; + break; + case 14: /* yes */ + kw_ok = true; + break; + case 15: /* Verify Job */ + if (verify_job_name) { bsendmsg(ua, _("Verify Job specified twice.\n")); - return 1; - } - verify_job_name = ua->argv[i]; - found = true; - break; - - default: - break; - } - } /* end strcase compare */ + return 0; + } + verify_job_name = ua->argv[i]; + kw_ok = true; + break; + case 16: /* files */ + files = atoi(ua->argv[i]); + kw_ok = true; + break; + + case 17: /* catalog */ + catalog_name = ua->argv[i]; + kw_ok = true; + break; + + case 18: /* since */ + since = ua->argv[i]; + kw_ok = true; + break; + + case 19: /* cloned */ + cloned = true; + kw_ok = true; + break; + + case 20: /* write verify list output */ + verify_list = ua->argv[i]; + kw_ok = true; + break; + case 21: /* Migration Job */ + if (previous_job_name) { + bsendmsg(ua, _("Migration Job specified twice.\n")); + return 0; + } + previous_job_name = ua->argv[i]; + kw_ok = true; + break; + + + default: + break; + } + } /* end strcase compare */ } /* end keyword loop */ - if (!found) { - Dmsg1(200, "%s not found\n", ua->argk[i]); - /* - * Special case for Job Name, it can be the first - * keyword that has no value. - */ - if (!job_name && !ua->argv[i]) { - job_name = ua->argk[i]; /* use keyword as job name */ - Dmsg1(200, "Set jobname=%s\n", job_name); - } else { + /* + * End of keyword for loop -- if not found, we got a bogus keyword + */ + if (!kw_ok) { + Dmsg1(800, "%s not found\n", ua->argk[i]); + /* + * Special case for Job Name, it can be the first + * keyword that has no value. + */ + if (!job_name && !ua->argv[i]) { + job_name = ua->argk[i]; /* use keyword as job name */ + Dmsg1(800, "Set jobname=%s\n", job_name); + } else { bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]); - return 1; - } + return 0; + } } } /* end argc loop */ - - Dmsg0(200, "Done scan.\n"); + + Dmsg0(800, "Done scan.\n"); + + CAT *catalog = NULL; + if (catalog_name != NULL) { + catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name); + if (catalog == NULL) { + bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name); + return 0; + } + } + Dmsg1(800, "Using catalog=%s\n", NPRT(catalog_name)); if (job_name) { /* Find Job */ job = (JOB *)GetResWithName(R_JOB, job_name); if (!job) { - bsendmsg(ua, _("Job \"%s\" not found\n"), job_name); - job = select_job_resource(ua); + if (*job_name != 0) { + bsendmsg(ua, _("Job \"%s\" not found\n"), job_name); + } + job = select_job_resource(ua); } else { - Dmsg1(200, "Found job=%s\n", job_name); + Dmsg1(800, "Found job=%s\n", job_name); } } else { bsendmsg(ua, _("A job name must be specified.\n")); job = select_job_resource(ua); } if (!job) { - return 1; + return 0; + } else if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) { + bsendmsg(ua, _("No authorization. Job \"%s\".\n"), + job->hdr.name); + return 0; } if (store_name) { store = (STORE *)GetResWithName(R_STORAGE, store_name); if (!store) { - bsendmsg(ua, _("Storage \"%s\" not found.\n"), store_name); - store = select_storage_resource(ua); + if (*store_name != 0) { + bsendmsg(ua, _("Storage \"%s\" not found.\n"), store_name); + } + store = select_storage_resource(ua); } } else { - store = job->storage; /* use default */ + store = (STORE *)job->storage->first(); /* use default */ } if (!store) { return 1; + } else if (!acl_access_ok(ua, Storage_ACL, store->hdr.name)) { + bsendmsg(ua, _("No authorization. Storage \"%s\".\n"), + store->hdr.name); + return 0; } - + Dmsg1(800, "Using storage=%s\n", store->hdr.name); if (pool_name) { pool = (POOL *)GetResWithName(R_POOL, pool_name); if (!pool) { - bsendmsg(ua, _("Pool \"%s\" not found.\n"), pool_name); - pool = get_pool_resource(ua); + if (*pool_name != 0) { + bsendmsg(ua, _("Pool \"%s\" not found.\n"), pool_name); + } + pool = select_pool_resource(ua); } } else { - pool = job->pool; /* use default */ + pool = job->pool; /* use default */ + } + if (!pool) { + return 0; + } else if (!acl_access_ok(ua, Pool_ACL, pool->hdr.name)) { + bsendmsg(ua, _("No authorization. Pool \"%s\".\n"), + pool->hdr.name); + return 0; } + Dmsg1(800, "Using pool\n", pool->hdr.name); if (client_name) { client = (CLIENT *)GetResWithName(R_CLIENT, client_name); if (!client) { - bsendmsg(ua, _("Client \"%s\" not found.\n"), client_name); - client = select_client_resource(ua); + if (*client_name != 0) { + bsendmsg(ua, _("Client \"%s\" not found.\n"), client_name); + } + client = select_client_resource(ua); } } else { - client = job->client; /* use default */ + client = job->client; /* use default */ } if (!client) { - return 1; + return 0; + } else if (!acl_access_ok(ua, Client_ACL, client->hdr.name)) { + bsendmsg(ua, _("No authorization. Client \"%s\".\n"), + client->hdr.name); + return 0; } + Dmsg1(800, "Using client=%s\n", client->hdr.name); if (fileset_name) { fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name); if (!fileset) { bsendmsg(ua, _("FileSet \"%s\" not found.\n"), fileset_name); - fileset = select_fileset_resource(ua); + fileset = select_fileset_resource(ua); } } else { - fileset = job->fileset; /* use default */ + fileset = job->fileset; /* use default */ } if (!fileset) { - return 1; + return 0; + } else if (!acl_access_ok(ua, FileSet_ACL, fileset->hdr.name)) { + bsendmsg(ua, _("No authorization. FileSet \"%s\".\n"), + fileset->hdr.name); + return 0; } if (verify_job_name) { verify_job = (JOB *)GetResWithName(R_JOB, verify_job_name); if (!verify_job) { bsendmsg(ua, _("Verify Job \"%s\" not found.\n"), verify_job_name); - verify_job = select_job_resource(ua); + verify_job = select_job_resource(ua); } } else { verify_job = job->verify_job; } + if (previous_job_name) { + previous_job = (JOB *)GetResWithName(R_JOB, previous_job_name); + if (!previous_job) { + bsendmsg(ua, _("Migration Job \"%s\" not found.\n"), previous_job_name); + previous_job = select_job_resource(ua); + } + } else { + previous_job = job->verify_job; + } + + /* * Create JCR to run job. NOTE!!! after this point, free_jcr() * before returning. @@ -329,13 +432,19 @@ int run_cmd(UAContext *ua, char *cmd) jcr = new_jcr(sizeof(JCR), dird_free_jcr); set_jcr_defaults(jcr, job); - jcr->store = store; + jcr->verify_job = verify_job; + jcr->previous_job = previous_job; + set_storage(jcr, store); jcr->client = client; jcr->fileset = fileset; jcr->pool = pool; + jcr->ExpectedFiles = files; + if (catalog != NULL) { + jcr->catalog = catalog; + } if (where) { if (jcr->where) { - free(jcr->where); + free(jcr->where); } jcr->where = bstrdup(where); } @@ -344,13 +453,13 @@ int run_cmd(UAContext *ua, char *cmd) jcr->sched_time = str_to_utime(when); if (jcr->sched_time == 0) { bsendmsg(ua, _("Invalid time, using current time.\n")); - jcr->sched_time = time(NULL); + jcr->sched_time = time(NULL); } } - + if (bootstrap) { if (jcr->RestoreBootstrap) { - free(jcr->RestoreBootstrap); + free(jcr->RestoreBootstrap); } jcr->RestoreBootstrap = bstrdup(bootstrap); } @@ -358,13 +467,13 @@ int run_cmd(UAContext *ua, char *cmd) if (replace) { jcr->replace = 0; for (i=0; ReplaceOptions[i].name; i++) { - if (strcasecmp(replace, ReplaceOptions[i].name) == 0) { - jcr->replace = ReplaceOptions[i].token; - } + if (strcasecmp(replace, ReplaceOptions[i].name) == 0) { + jcr->replace = ReplaceOptions[i].token; + } } if (!jcr->replace) { bsendmsg(ua, _("Invalid replace option: %s\n"), replace); - goto bail_out; + goto bail_out; } } else if (job->replace) { jcr->replace = job->replace; @@ -376,190 +485,219 @@ int run_cmd(UAContext *ua, char *cmd) jcr->JobPriority = Priority; } + if (since) { + if (!jcr->stime) { + jcr->stime = get_pool_memory(PM_MESSAGE); + } + pm_strcpy(jcr->stime, since); + } + + jcr->cloned = cloned; + + if (find_arg(ua, NT_("fdcalled")) > 0) { + jcr->file_bsock = dup_bsock(ua->UA_sock); + ua->quit = true; + } + try_again: replace = ReplaceOptions[0].name; for (i=0; ReplaceOptions[i].name; i++) { if (ReplaceOptions[i].token == jcr->replace) { - replace = ReplaceOptions[i].name; + replace = ReplaceOptions[i].name; } } if (level_name) { - /* Look up level name and pull code */ - found = 0; - for (i=0; joblevels[i].level_name; i++) { - if (strcasecmp(level_name, _(joblevels[i].level_name)) == 0) { - jcr->JobLevel = joblevels[i].level; - found = 1; - break; - } - } - if (!found) { + if (!get_level_from_name(jcr, level_name)) { bsendmsg(ua, _("Level %s not valid.\n"), level_name); - goto bail_out; + goto bail_out; } } - level_name = NULL; if (jid) { - jcr->RestoreJobId = atoi(jid); + /* Note, this is also MigrateJobId */ + jcr->RestoreJobId = str_to_int64(jid); } /* Run without prompting? */ - if (find_arg(ua, _("yes")) > 0) { - Dmsg1(200, "Calling run_job job=%x\n", jcr->job); - run_job(jcr); - free_jcr(jcr); /* release jcr */ - bsendmsg(ua, _("Run command submitted.\n")); - return 1; + if (ua->batch || find_arg(ua, NT_("yes")) > 0) { + goto start_job; } - /* + /* * Prompt User to see if all run job parameters are correct, and - * allow him to modify them. + * allow him to modify them. */ - Dmsg1(20, "JobType=%c\n", jcr->JobType); + Dmsg1(800, "JobType=%c\n", jcr->JobType); switch (jcr->JobType) { char ec1[30]; char dt[MAX_TIME_LENGTH]; case JT_ADMIN: - bsendmsg(ua, _("Run %s job\n\ -JobName: %s\n\ -FileSet: %s\n\ -Client: %s\n\ -Storage: %s\n\ -When: %s\n\ -Priority: %d\n"), + bsendmsg(ua, _("Run %s job\n" +"JobName: %s\n" +"FileSet: %s\n" +"Client: %s\n" +"Storage: %s\n" +"When: %s\n" +"Priority: %d\n"), _("Admin"), - job->hdr.name, - jcr->fileset->hdr.name, - NPRT(jcr->client->hdr.name), - NPRT(jcr->store->hdr.name), - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->JobPriority); + job->hdr.name, + jcr->fileset->hdr.name, + NPRT(jcr->client->hdr.name), + NPRT(jcr->store->hdr.name), + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->JobPriority); jcr->JobLevel = L_FULL; break; case JT_BACKUP: case JT_VERIFY: if (jcr->JobType == JT_BACKUP) { - bsendmsg(ua, _("Run %s job\n\ -JobName: %s\n\ -FileSet: %s\n\ -Level: %s\n\ -Client: %s\n\ -Storage: %s\n\ -Pool: %s\n\ -When: %s\n\ -Priority: %d\n"), + bsendmsg(ua, _("Run %s job\n" +"JobName: %s\n" +"FileSet: %s\n" +"Level: %s\n" +"Client: %s\n" +"Storage: %s\n" +"Pool: %s\n" +"When: %s\n" +"Priority: %d\n"), _("Backup"), - job->hdr.name, - jcr->fileset->hdr.name, - level_to_str(jcr->JobLevel), - jcr->client->hdr.name, - jcr->store->hdr.name, - NPRT(jcr->pool->hdr.name), - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->JobPriority); - } else { /* JT_VERIFY */ - char *Name; - if (jcr->job->verify_job) { - Name = jcr->job->verify_job->hdr.name; - } else { + job->hdr.name, + jcr->fileset->hdr.name, + level_to_str(jcr->JobLevel), + jcr->client->hdr.name, + jcr->store->hdr.name, + NPRT(jcr->pool->hdr.name), + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->JobPriority); + } else { /* JT_VERIFY */ + const char *Name; + if (jcr->verify_job) { + Name = jcr->verify_job->hdr.name; + } else { Name = ""; - } - bsendmsg(ua, _("Run %s job\n\ -JobName: %s\n\ -FileSet: %s\n\ -Level: %s\n\ -Client: %s\n\ -Storage: %s\n\ -Pool: %s\n\ -Verify Job: %s\n\ -When: %s\n\ -Priority: %d\n"), + } + if (!verify_list) { + verify_list = job->WriteVerifyList; + } + if (!verify_list) { + verify_list = ""; + } + bsendmsg(ua, _("Run %s job\n" +"JobName: %s\n" +"FileSet: %s\n" +"Level: %s\n" +"Client: %s\n" +"Storage: %s\n" +"Pool: %s\n" +"Verify Job: %s\n" +"Verify List: %s\n" +"When: %s\n" +"Priority: %d\n"), _("Verify"), - job->hdr.name, - jcr->fileset->hdr.name, - level_to_str(jcr->JobLevel), - jcr->client->hdr.name, - jcr->store->hdr.name, - NPRT(jcr->pool->hdr.name), - Name, - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->JobPriority); + job->hdr.name, + jcr->fileset->hdr.name, + level_to_str(jcr->JobLevel), + jcr->client->hdr.name, + jcr->store->hdr.name, + NPRT(jcr->pool->hdr.name), + Name, + verify_list, + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->JobPriority); } break; case JT_RESTORE: if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) { - if (jid) { - jcr->RestoreJobId = atoi(jid); - } else { + if (jid) { + jcr->RestoreJobId = str_to_int64(jid); + } else { if (!get_pint(ua, _("Please enter a JobId for restore: "))) { - goto bail_out; - } - jcr->RestoreJobId = ua->pint32_val; - } + goto bail_out; + } + jcr->RestoreJobId = ua->int64_val; + } } - jcr->JobLevel = L_FULL; /* default level */ - Dmsg1(20, "JobId to restore=%d\n", jcr->RestoreJobId); + jcr->JobLevel = L_FULL; /* default level */ + Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId); if (jcr->RestoreJobId == 0) { - bsendmsg(ua, _("Run Restore job\n\ -JobName: %s\n\ -Bootstrap: %s\n\ -Where: %s\n\ -Replace: %s\n\ -FileSet: %s\n\ -Client: %s\n\ -Storage: %s\n\ -When: %s\n\ -Priority: %d\n"), - job->hdr.name, - NPRT(jcr->RestoreBootstrap), - jcr->where?jcr->where:NPRT(job->RestoreWhere), - replace, - jcr->fileset->hdr.name, - jcr->client->hdr.name, - jcr->store->hdr.name, - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->JobPriority); + bsendmsg(ua, _("Run Restore job\n" + "JobName: %s\n" + "Bootstrap: %s\n" + "Where: %s\n" + "Replace: %s\n" + "FileSet: %s\n" + "Client: %s\n" + "Storage: %s\n" + "When: %s\n" + "Catalog: %s\n" + "Priority: %d\n"), + job->hdr.name, + NPRT(jcr->RestoreBootstrap), + jcr->where?jcr->where:NPRT(job->RestoreWhere), + replace, + jcr->fileset->hdr.name, + jcr->client->hdr.name, + jcr->store->hdr.name, + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->catalog->hdr.name, + jcr->JobPriority); } else { - bsendmsg(ua, _("Run Restore job\n\ -JobName: %s\n\ -Bootstrap: %s\n\ -Where: %s\n\ -Replace: %s\n\ -FileSet: %s\n\ -Client: %s\n\ -Storage: %s\n\ -JobId: %s\n\ -When: %s\n\ -Priority: %d\n"), - job->hdr.name, - NPRT(jcr->RestoreBootstrap), - jcr->where?jcr->where:NPRT(job->RestoreWhere), - replace, - jcr->fileset->hdr.name, - jcr->client->hdr.name, - jcr->store->hdr.name, - jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1), - bstrutime(dt, sizeof(dt), jcr->sched_time), - jcr->JobPriority); + bsendmsg(ua, _("Run Restore job\n" + "JobName: %s\n" + "Bootstrap: %s\n" + "Where: %s\n" + "Replace: %s\n" + "Client: %s\n" + "Storage: %s\n" + "JobId: %s\n" + "When: %s\n" + "Catalog: %s\n" + "Priority: %d\n"), + job->hdr.name, + NPRT(jcr->RestoreBootstrap), + jcr->where?jcr->where:NPRT(job->RestoreWhere), + replace, + jcr->client->hdr.name, + jcr->store->hdr.name, + jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1), + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->catalog->hdr.name, + jcr->JobPriority); } break; + case JT_MIGRATE: + jcr->JobLevel = L_FULL; /* default level */ + bsendmsg(ua, _("Run Migration job\n" + "JobName: %s\n" + "Bootstrap: %s\n" + "FileSet: %s\n" + "Client: %s\n" + "Storage: %s\n" + "JobId: %s\n" + "When: %s\n" + "Catalog: %s\n" + "Priority: %d\n"), + job->hdr.name, + NPRT(jcr->RestoreBootstrap), + jcr->fileset->hdr.name, + jcr->client->hdr.name, + jcr->store->hdr.name, + jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1), + bstrutime(dt, sizeof(dt), jcr->sched_time), + jcr->catalog->hdr.name, + jcr->JobPriority); + break; default: bsendmsg(ua, _("Unknown Job Type=%d\n"), jcr->JobType); goto bail_out; } - if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) { goto bail_out; } /* * At user request modify parameters of job to be run. */ - if (ua->cmd[0] == 0) { - goto bail_out; - } - if (strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) { + if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) { FILE *fd; start_prompt(ua, _("Parameters to modify:\n")); @@ -571,11 +709,11 @@ Priority: %d\n"), add_prompt(ua, _("When")); /* 5 */ add_prompt(ua, _("Priority")); /* 6 */ if (jcr->JobType == JT_BACKUP || - jcr->JobType == JT_VERIFY) { + jcr->JobType == JT_VERIFY) { add_prompt(ua, _("Pool")); /* 7 */ - if (jcr->JobType == JT_VERIFY) { + if (jcr->JobType == JT_VERIFY) { add_prompt(ua, _("Verify Job")); /* 8 */ - } + } } else if (jcr->JobType == JT_RESTORE) { add_prompt(ua, _("Bootstrap")); /* 7 */ add_prompt(ua, _("Where")); /* 8 */ @@ -584,8 +722,8 @@ Priority: %d\n"), } switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) { case 0: - /* Level */ - if (jcr->JobType == JT_BACKUP) { + /* Level */ + if (jcr->JobType == JT_BACKUP) { start_prompt(ua, _("Levels:\n")); add_prompt(ua, _("Base")); add_prompt(ua, _("Full")); @@ -593,26 +731,26 @@ Priority: %d\n"), add_prompt(ua, _("Differential")); add_prompt(ua, _("Since")); switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { - case 0: - jcr->JobLevel = L_BASE; - break; - case 1: - jcr->JobLevel = L_FULL; - break; - case 2: - jcr->JobLevel = L_INCREMENTAL; - break; - case 3: - jcr->JobLevel = L_DIFFERENTIAL; - break; - case 4: - jcr->JobLevel = L_SINCE; - break; - default: - break; - } - goto try_again; - } else if (jcr->JobType == JT_VERIFY) { + case 0: + jcr->JobLevel = L_BASE; + break; + case 1: + jcr->JobLevel = L_FULL; + break; + case 2: + jcr->JobLevel = L_INCREMENTAL; + break; + case 3: + jcr->JobLevel = L_DIFFERENTIAL; + break; + case 4: + jcr->JobLevel = L_SINCE; + break; + default: + break; + } + goto try_again; + } else if (jcr->JobType == JT_VERIFY) { start_prompt(ua, _("Levels:\n")); add_prompt(ua, _("Initialize Catalog")); add_prompt(ua, _("Verify Catalog")); @@ -620,180 +758,193 @@ Priority: %d\n"), add_prompt(ua, _("Verify Disk to Catalog")); add_prompt(ua, _("Verify Volume Data (not yet implemented)")); switch (do_prompt(ua, "", _("Select level"), NULL, 0)) { - case 0: - jcr->JobLevel = L_VERIFY_INIT; - break; - case 1: - jcr->JobLevel = L_VERIFY_CATALOG; - break; - case 2: - jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG; - break; - case 3: - jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG; - break; - case 4: - jcr->JobLevel = L_VERIFY_DATA; - break; - default: - break; - } - goto try_again; - } else { + case 0: + jcr->JobLevel = L_VERIFY_INIT; + break; + case 1: + jcr->JobLevel = L_VERIFY_CATALOG; + break; + case 2: + jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG; + break; + case 3: + jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG; + break; + case 4: + jcr->JobLevel = L_VERIFY_DATA; + break; + default: + break; + } + goto try_again; + } else { bsendmsg(ua, _("Level not appropriate for this Job. Cannot be changed.\n")); - } - goto try_again; + } + goto try_again; case 1: - /* Storage */ - store = select_storage_resource(ua); - if (store) { - jcr->store = store; - goto try_again; - } - break; + /* Storage */ + store = select_storage_resource(ua); + if (store) { + set_storage(jcr, store); + goto try_again; + } + break; case 2: - /* Job */ - job = select_job_resource(ua); - if (job) { - jcr->job = job; - set_jcr_defaults(jcr, job); - goto try_again; - } - break; + /* Job */ + job = select_job_resource(ua); + if (job) { + jcr->job = job; + set_jcr_defaults(jcr, job); + goto try_again; + } + break; case 3: - /* FileSet */ - fileset = select_fileset_resource(ua); - if (fileset) { - jcr->fileset = fileset; - goto try_again; - } - break; + /* FileSet */ + fileset = select_fileset_resource(ua); + if (fileset) { + jcr->fileset = fileset; + goto try_again; + } + break; case 4: - /* Client */ - client = select_client_resource(ua); - if (client) { - jcr->client = client; - goto try_again; - } - break; + /* Client */ + client = select_client_resource(ua); + if (client) { + jcr->client = client; + goto try_again; + } + break; case 5: - /* When */ + /* When */ if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) { - break; - } - if (ua->cmd[0] == 0) { - jcr->sched_time = time(NULL); - } else { - jcr->sched_time = str_to_utime(ua->cmd); - if (jcr->sched_time == 0) { + break; + } + if (ua->cmd[0] == 0) { + jcr->sched_time = time(NULL); + } else { + jcr->sched_time = str_to_utime(ua->cmd); + if (jcr->sched_time == 0) { bsendmsg(ua, _("Invalid time, using current time.\n")); - jcr->sched_time = time(NULL); - } - } - goto try_again; + jcr->sched_time = time(NULL); + } + } + goto try_again; case 6: - /* Priority */ + /* Priority */ if (!get_pint(ua, _("Enter new Priority: "))) { - break; - } - if (ua->pint32_val == 0) { + break; + } + if (ua->pint32_val == 0) { bsendmsg(ua, _("Priority must be a positive integer.\n")); - } else { - jcr->JobPriority = ua->pint32_val; - } - goto try_again; + } else { + jcr->JobPriority = ua->pint32_val; + } + goto try_again; case 7: - /* Pool or Bootstrap depending on JobType */ - if (jcr->JobType == JT_BACKUP || - jcr->JobType == JT_VERIFY) { /* Pool */ - pool = select_pool_resource(ua); - if (pool) { - jcr->pool = pool; - goto try_again; - } - break; - } - - /* Bootstrap */ + /* Pool or Bootstrap depending on JobType */ + if (jcr->JobType == JT_BACKUP || + jcr->JobType == JT_VERIFY) { /* Pool */ + pool = select_pool_resource(ua); + if (pool) { + jcr->pool = pool; + goto try_again; + } + break; + } + + /* Bootstrap */ if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) { - break; - } - if (jcr->RestoreBootstrap) { - free(jcr->RestoreBootstrap); - jcr->RestoreBootstrap = NULL; - } - if (ua->cmd[0] != 0) { - jcr->RestoreBootstrap = bstrdup(ua->cmd); - fd = fopen(jcr->RestoreBootstrap, "r"); - if (!fd) { + break; + } + if (jcr->RestoreBootstrap) { + free(jcr->RestoreBootstrap); + jcr->RestoreBootstrap = NULL; + } + if (ua->cmd[0] != 0) { + jcr->RestoreBootstrap = bstrdup(ua->cmd); + fd = fopen(jcr->RestoreBootstrap, "rb"); + if (!fd) { bsendmsg(ua, _("Warning cannot open %s: ERR=%s\n"), - jcr->RestoreBootstrap, strerror(errno)); - free(jcr->RestoreBootstrap); - jcr->RestoreBootstrap = NULL; - } else { - fclose(fd); - } - } - goto try_again; + jcr->RestoreBootstrap, strerror(errno)); + free(jcr->RestoreBootstrap); + jcr->RestoreBootstrap = NULL; + } else { + fclose(fd); + } + } + goto try_again; case 8: - /* Verify Job */ - if (jcr->JobType == JT_VERIFY) { - JOB *job = select_job_resource(ua); - if (job) { - jcr->job->verify_job = job; - } else { - jcr->job->verify_job = NULL; - } - goto try_again; - } - /* Where */ + /* Verify Job */ + if (jcr->JobType == JT_VERIFY) { + verify_job = select_job_resource(ua); + if (verify_job) { + jcr->verify_job = verify_job; + } + goto try_again; + } + /* Where */ if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) { - break; - } - if (jcr->where) { - free(jcr->where); - jcr->where = NULL; - } + break; + } + if (jcr->where) { + free(jcr->where); + jcr->where = NULL; + } if (ua->cmd[0] == '/' && ua->cmd[1] == 0) { - ua->cmd[0] = 0; - } - jcr->where = bstrdup(ua->cmd); - goto try_again; + ua->cmd[0] = 0; + } + jcr->where = bstrdup(ua->cmd); + goto try_again; case 9: - /* Replace */ + /* Replace */ start_prompt(ua, _("Replace:\n")); - for (i=0; ReplaceOptions[i].name; i++) { - add_prompt(ua, ReplaceOptions[i].name); - } + for (i=0; ReplaceOptions[i].name; i++) { + add_prompt(ua, ReplaceOptions[i].name); + } opt = do_prompt(ua, "", _("Select replace option"), NULL, 0); - if (opt >= 0) { - jcr->replace = ReplaceOptions[opt].token; - } - goto try_again; + if (opt >= 0) { + jcr->replace = ReplaceOptions[opt].token; + } + goto try_again; case 10: - /* JobId */ - jid = NULL; /* force reprompt */ - jcr->RestoreJobId = 0; - if (jcr->RestoreBootstrap) { + /* JobId */ + jid = NULL; /* force reprompt */ + jcr->RestoreJobId = 0; + if (jcr->RestoreBootstrap) { bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n")); - } - goto try_again; - default: - goto try_again; + } + goto try_again; + case -1: /* error or cancel */ + goto bail_out; + default: + goto try_again; } goto bail_out; } - if (strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) { - Dmsg1(200, "Calling run_job job=%x\n", jcr->job); - run_job(jcr); - free_jcr(jcr); /* release jcr */ - bsendmsg(ua, _("Run command submitted.\n")); - return 1; + if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) { + JobId_t JobId; + Dmsg1(800, "Calling run_job job=%x\n", jcr->job); +start_job: + JobId = run_job(jcr); +#if 0 + bsendmsg(ua, "\n", + time(NULL), jcr->JobStatus, jcr->JobType, jcr->JobId, + jcr->Job, jcr->JobLevel, jcr->JobPriority); +#endif + free_jcr(jcr); /* release jcr */ + if (JobId == 0) { + bsendmsg(ua, _("Job failed.\n")); + } else { + char ed1[50]; + bsendmsg(ua, _("Job started. JobId=%s\n"), edit_int64(JobId,ed1)); + } + return JobId; } bail_out: bsendmsg(ua, _("Job not run.\n")); free_jcr(jcr); - return 0; /* do not run */ + return 0; /* do not run */ }