X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffiled%2Fjob.c;h=e41d7f270b73ce730874edf309d56cd11807c99c;hb=19ca7b5d5dc95153dca7691a67196bf3537209ef;hp=c85e5ad0b0e5dcc665b0497ae54209219733e2dd;hpb=05b561ae0416abac31cd1f3b65d3617df2723659;p=bacula%2Fbacula diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index c85e5ad0b0..e41d7f270b 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -44,6 +44,22 @@ static pthread_mutex_t vss_mutex = PTHREAD_MUTEX_INITIALIZER; static int enable_vss = 0; #endif +/* + * As Windows saves ACLs as part of the standard backup stream + * we just pretend here that is has implicit acl support. + */ +#if defined(HAVE_ACL) || defined(HAVE_WIN32) +const bool have_acl = true; +#else +const bool have_acl = false; +#endif + +#if defined(HAVE_XATTR) +const bool have_xattr = true; +#else +const bool have_xattr = false; +#endif + extern CLIENT *me; /* our client resource */ /* Imported functions */ @@ -63,6 +79,7 @@ static int fileset_cmd(JCR *jcr); static int level_cmd(JCR *jcr); static int verify_cmd(JCR *jcr); static int restore_cmd(JCR *jcr); +static int end_restore_cmd(JCR *jcr); static int storage_cmd(JCR *jcr); static int session_cmd(JCR *jcr); static int response(JCR *jcr, BSOCK *sd, char *resp, const char *cmd); @@ -74,7 +91,7 @@ static int runbefore_cmd(JCR *jcr); static int runafter_cmd(JCR *jcr); static int runbeforenow_cmd(JCR *jcr); static void set_options(findFOPTS *fo, const char *opts); - +static void set_storage_auth_key(JCR *jcr, char *key); /* Exported functions */ @@ -97,6 +114,7 @@ static struct s_cmds cmds[] = { {"JobId=", job_cmd, 0}, {"level = ", level_cmd, 0}, {"restore", restore_cmd, 0}, + {"endrestore", end_restore_cmd, 0}, {"session", session_cmd, 0}, {"status", status_cmd, 1}, {".status", qstatus_cmd, 1}, @@ -113,7 +131,8 @@ static struct s_cmds cmds[] = { /* Commands received from director that need scanning */ static char jobcmd[] = "JobId=%d Job=%127s SDid=%d SDtime=%d Authorization=%100s"; -static char storaddr[] = "storage address=%s port=%d ssl=%d"; +static char storaddr[] = "storage address=%s port=%d ssl=%d Authorization=%100s"; +static char storaddr_v1[] = "storage address=%s port=%d ssl=%d"; static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n"; static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n"; static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n"; @@ -137,6 +156,7 @@ static char OKverify[] = "2000 OK verify\n"; static char OKrestore[] = "2000 OK restore\n"; static char OKsession[] = "2000 OK session\n"; static char OKstore[] = "2000 OK storage\n"; +static char OKstoreend[] = "2000 OK storage end\n"; static char OKjob[] = "2000 OK Job %s (%s) %s,%s,%s"; static char OKsetdebug[] = "2000 OK setdebug=%d\n"; static char BADjob[] = "2901 Bad Job\n"; @@ -196,7 +216,7 @@ static char read_close[] = "read close session %d\n"; * 5. FD gets/runs ClientRunBeforeJob and sends ClientRunAfterJob * 6. Dir sends include/exclude * 7. FD sends data to SD - * 8. SD/FD disconnects while SD despools data and attributes (optionnal) + * 8. SD/FD disconnects while SD despools data and attributes (optional) * 9. FD runs ClientRunAfterJob */ @@ -457,20 +477,18 @@ static int estimate_cmd(JCR *jcr) static int job_cmd(JCR *jcr) { BSOCK *dir = jcr->dir_bsock; - POOLMEM *sd_auth_key; + POOL_MEM sd_auth_key(PM_MESSAGE); + sd_auth_key.check_size(dir->msglen); - sd_auth_key = get_memory(dir->msglen); if (sscanf(dir->msg, jobcmd, &jcr->JobId, jcr->Job, - &jcr->VolSessionId, &jcr->VolSessionTime, - sd_auth_key) != 5) { + &jcr->VolSessionId, &jcr->VolSessionTime, + sd_auth_key.c_str()) != 5) { pm_strcpy(jcr->errmsg, dir->msg); Jmsg(jcr, M_FATAL, 0, _("Bad Job Command: %s"), jcr->errmsg); dir->fsend(BADjob); - free_pool_memory(sd_auth_key); return 0; } - jcr->sd_auth_key = bstrdup(sd_auth_key); - free_pool_memory(sd_auth_key); + set_storage_auth_key(jcr, sd_auth_key.c_str()); Dmsg2(120, "JobId=%d Auth=%s\n", jcr->JobId, jcr->sd_auth_key); Mmsg(jcr->errmsg, "JobId=%d Job=%s", jcr->JobId, jcr->Job); new_plugins(jcr); /* instantiate plugins for this jcr */ @@ -1238,6 +1256,8 @@ static int level_cmd(JCR *jcr) level = get_memory(dir->msglen+1); Dmsg1(100, "level_cmd: %s", dir->msg); + + /* keep compatibility with older directors */ if (strstr(dir->msg, "accurate")) { jcr->accurate = true; } @@ -1362,6 +1382,36 @@ static int session_cmd(JCR *jcr) return dir->fsend(OKsession); } +static void set_storage_auth_key(JCR *jcr, char *key) +{ + /* if no key don't update anything */ + if (!*key) { + return; + } + + /* We can be contacting multiple storage daemons. + * So, make sure that any old jcr->store_bsock is cleaned up. + */ + if (jcr->store_bsock) { + jcr->store_bsock->destroy(); + jcr->store_bsock = NULL; + } + + /* We can be contacting multiple storage daemons. + * So, make sure that any old jcr->sd_auth_key is cleaned up. + */ + if (jcr->sd_auth_key) { + /* If we already have a Authorization key, director can do multi + * storage restore + */ + Dmsg0(5, "set multi_restore=true\n"); + jcr->multi_restore = true; + bfree(jcr->sd_auth_key); + } + + jcr->sd_auth_key = bstrdup(key); +} + /* * Get address of storage daemon from Director * @@ -1370,20 +1420,39 @@ static int storage_cmd(JCR *jcr) { int stored_port; /* storage daemon port */ int enable_ssl; /* enable ssl to sd */ + POOL_MEM sd_auth_key(PM_MESSAGE); BSOCK *dir = jcr->dir_bsock; - BSOCK *sd; /* storage daemon bsock */ + BSOCK *sd = new_bsock(); /* storage daemon bsock */ + Dmsg1(100, "StorageCmd: %s", dir->msg); - if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port, &enable_ssl) != 3) { - pm_strcpy(jcr->errmsg, dir->msg); - Jmsg(jcr, M_FATAL, 0, _("Bad storage command: %s"), jcr->errmsg); - goto bail_out; + sd_auth_key.check_size(dir->msglen); + if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port, + &enable_ssl, sd_auth_key.c_str()) != 4) + { + if (sscanf(dir->msg, storaddr_v1, &jcr->stored_addr, + &stored_port, &enable_ssl) != 3) + { + pm_strcpy(jcr->errmsg, dir->msg); + Jmsg(jcr, M_FATAL, 0, _("Bad storage command: %s"), jcr->errmsg); + goto bail_out; + } } - Dmsg3(110, "Open storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port, enable_ssl); + + set_storage_auth_key(jcr, sd_auth_key.c_str()); + + Dmsg3(110, "Open storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port, + enable_ssl); /* Open command communications with Storage daemon */ /* Try to connect for 1 hour at 10 second intervals */ - sd = bnet_connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval, - _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1); + + sd->set_source_address(me->FDsrc_addr); + if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval, + _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1)) { + sd->destroy(); + sd = NULL; + } + if (sd == NULL) { Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"), jcr->stored_addr, stored_port); @@ -1406,8 +1475,8 @@ static int storage_cmd(JCR *jcr) return dir->fsend(OKstore); bail_out: - dir->fsend(BADcmd, "storage"); - return 0; + dir->fsend(BADcmd, "storage"); + return 0; } @@ -1433,6 +1502,19 @@ static int backup_cmd(JCR *jcr) } #endif + /* + * Validate some options given to the backup make sense for the compiled in + * options of this filed. + */ + if (jcr->ff->flags & FO_ACL && !have_acl) { + Jmsg(jcr, M_FATAL, 0, _("ACL support not configured for your machine.\n")); + goto cleanup; + } + if (jcr->ff->flags & FO_XATTR && !have_xattr) { + Jmsg(jcr, M_FATAL, 0, _("XATTR support not configured for your machine.\n")); + goto cleanup; + } + set_jcr_job_status(jcr, JS_Blocked); jcr->set_JobType(JT_BACKUP); Dmsg1(100, "begin backup ff=%p\n", jcr->ff); @@ -1772,12 +1854,29 @@ static int restore_cmd(JCR *jcr) sd->signal(BNET_TERMINATE); bail_out: + bfree_and_null(jcr->where); if (jcr->JobErrors) { set_jcr_job_status(jcr, JS_ErrorTerminated); } Dmsg0(130, "Done in job.c\n"); + + int ret; + if (jcr->multi_restore) { + dir->fsend(OKstoreend); + ret = 1; /* we continue the loop, waiting for next part */ + } else { + end_restore_cmd(jcr); + ret = 0; /* we stop here */ + } + + return ret; +} + +static int end_restore_cmd(JCR *jcr) +{ + Dmsg0(5, "end_restore_cmd\n"); generate_plugin_event(jcr, bEventEndRestoreJob); return 0; /* return and terminate command loop */ }