/* * After receiving a connection (in dircmd.c) if it is * from the Storage daemon, this routine is called. */ void *handle_stored_connection(BSOCK *sd, char *job_name) { JCR *jcr; /* * With the following bmicrosleep on, running the * SD under the debugger fails. */ // bmicrosleep(0, 50000); /* wait 50 millisecs */ if (!(jcr = get_jcr_by_full_name(job_name))) { Jmsg1(NULL, M_FATAL, 0, _("SD connect failed: Job name not found: %s\n"), job_name); Dmsg1(3, "**** Job \"%s\" not found.\n", job_name); sd->close(); delete sd; return NULL; } Dmsg1(50, "Found Job %s\n", job_name); if (jcr->authenticated) { Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"), (uint32_t)jcr->JobId, jcr->Job); Dmsg2(50, "Hey!!!! JobId %u Job %s already authenticated.\n", (uint32_t)jcr->JobId, jcr->Job); sd->close(); delete sd; free_jcr(jcr); return NULL; } jcr->store_bsock = sd; jcr->store_bsock->set_jcr(jcr); /* * Authenticate the Storage daemon */ if (jcr->authenticated || !authenticate_storagedaemon(jcr)) { Dmsg1(50, "Authentication failed Job %s\n", jcr->Job); Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate Storage daemon\n")); } else { jcr->authenticated = true; Dmsg2(50, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job); } if (!jcr->authenticated) { jcr->setJobStatus(JS_ErrorTerminated); } pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */ free_jcr(jcr); return NULL; }
/* * After receiving a connection (in dircmd.c) if it is * from the File daemon, this routine is called. */ void handle_filed_connection(BSOCK *fd, char *job_name, int fd_version, int sd_version) { JCR *jcr; if (!(jcr=get_jcr_by_full_name(job_name))) { Jmsg1(NULL, M_FATAL, 0, _("FD connect failed: Job name not found: %s\n"), job_name); Dmsg1(3, "**** Job \"%s\" not found.\n", job_name); fd->destroy(); return; } Dmsg1(100, "Found Filed Job %s\n", job_name); if (jcr->authenticated) { Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"), (uint32_t)jcr->JobId, jcr->Job); Dmsg2(050, "Hey!!!! JobId %u Job %s already authenticated.\n", (uint32_t)jcr->JobId, jcr->Job); fd->destroy(); free_jcr(jcr); return; } jcr->file_bsock = fd; jcr->file_bsock->set_jcr(jcr); jcr->FDVersion = fd_version; jcr->SDVersion = sd_version; Dmsg2(050, "fd_version=%d sd_version=%d\n", fd_version, sd_version); /* * Authenticate the File daemon */ if (jcr->authenticated || !authenticate_filed(jcr)) { Dmsg1(50, "Authentication failed Job %s\n", jcr->Job); Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n")); } else { jcr->authenticated = true; Dmsg2(050, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job); } if (!jcr->authenticated) { jcr->setJobStatus(JS_ErrorTerminated); } Dmsg3(050, "=== Auth OK, unblock Job %s jid=%d sd_ver=%d\n", job_name, jcr->JobId, sd_version); if (sd_version > 0) { jcr->sd_client = true; } pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */ free_jcr(jcr); return; }
/* * Director requests us to start a job * Basic tasks done here: * - We pickup the JobId to be run from the Director. * - We pickup the device, media, and pool from the Director * - Wait for a connection from the File Daemon (FD) * - Accept commands from the FD (i.e. run the job) * - Return when the connection is terminated or * there is an error. */ bool job_cmd(JCR *jcr) { int32_t JobId; char auth_key[MAX_NAME_LENGTH]; char seed[MAX_NAME_LENGTH]; char spool_size[MAX_NAME_LENGTH]; BSOCK *dir = jcr->dir_bsock; POOL_MEM job_name, client_name, job, fileset_name, fileset_md5, backup_format; int32_t JobType, level, spool_attributes, no_attributes, spool_data; int32_t PreferMountedVols, rerunning, protocol, dumplevel; int status; uint64_t quota = 0; JCR *ojcr; /* * Get JobId and permissions from Director */ Dmsg1(100, "<dird: %s", dir->msg); bstrncpy(spool_size, "0", sizeof(spool_size)); status = sscanf(dir->msg, jobcmd, &JobId, job.c_str(), job_name.c_str(), client_name.c_str(), &JobType, &level, fileset_name.c_str(), &no_attributes, &spool_attributes, fileset_md5.c_str(), &spool_data, &PreferMountedVols, spool_size, &rerunning, &jcr->VolSessionId, &jcr->VolSessionTime, "a, &protocol, backup_format.c_str(), &dumplevel); if (status != 20) { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(BAD_job, status, jcr->errmsg); Dmsg1(100, ">dird: %s", dir->msg); jcr->setJobStatus(JS_ErrorTerminated); return false; } jcr->rerunning = (rerunning) ? true : false; jcr->setJobProtocol(protocol); Dmsg4(100, "rerunning=%d VolSesId=%d VolSesTime=%d Protocol=%d\n", jcr->rerunning, jcr->VolSessionId, jcr->VolSessionTime, jcr->getJobProtocol()); /* * Since this job could be rescheduled, we * check to see if we have it already. If so * free the old jcr and use the new one. */ ojcr = get_jcr_by_full_name(job.c_str()); if (ojcr && !ojcr->authenticated) { Dmsg2(100, "Found ojcr=0x%x Job %s\n", (unsigned)(intptr_t)ojcr, job.c_str()); free_jcr(ojcr); } jcr->JobId = JobId; Dmsg2(800, "Start JobId=%d %p\n", JobId, jcr); /* * If job rescheduled because previous was incomplete, * the Resched flag is set and VolSessionId and VolSessionTime * are given to us (same as restarted job). */ if (!jcr->rerunning) { jcr->VolSessionId = newVolSessionId(); jcr->VolSessionTime = VolSessionTime; } bstrncpy(jcr->Job, job, sizeof(jcr->Job)); unbash_spaces(job_name); jcr->job_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->job_name, job_name); unbash_spaces(client_name); jcr->client_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->client_name, client_name); unbash_spaces(fileset_name); jcr->fileset_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->fileset_name, fileset_name); jcr->setJobType(JobType); jcr->setJobLevel(level); jcr->no_attributes = no_attributes; jcr->spool_attributes = spool_attributes; jcr->spool_data = spool_data; jcr->spool_size = str_to_int64(spool_size); jcr->fileset_md5 = get_pool_memory(PM_NAME); pm_strcpy(jcr->fileset_md5, fileset_md5); jcr->PreferMountedVols = PreferMountedVols; jcr->RemainingQuota = quota; unbash_spaces(backup_format); jcr->backup_format = get_pool_memory(PM_NAME); pm_strcpy(jcr->backup_format, backup_format); jcr->DumpLevel = dumplevel; jcr->authenticated = false; Dmsg1(50, "Quota set as %llu\n", quota); /* * Pass back an authorization key for the File daemon */ bsnprintf(seed, sizeof(seed), "%p%d", jcr, JobId); make_session_key(auth_key, seed, 1); dir->fsend(OK_job, jcr->VolSessionId, jcr->VolSessionTime, auth_key); Dmsg2(50, ">dird jid=%u: %s", (uint32_t)jcr->JobId, dir->msg); jcr->sd_auth_key = bstrdup(auth_key); memset(auth_key, 0, sizeof(auth_key)); dispatch_new_plugin_options(jcr); generate_plugin_event(jcr, bsdEventJobStart, (void *)"JobStart"); return true; }
void *handle_stored_connection(BSOCK *sd) { JCR *jcr; char job_name[MAX_NAME_LENGTH]; /* * Do a sanity check on the message received */ if (sd->msglen < 25 || sd->msglen > 256) { Dmsg1(000, "<filed: %s", sd->msg); Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), sd->who(), sd->msglen); bmicrosleep(5, 0); /* make user wait 5 seconds */ sd->close(); return NULL; } if (sscanf(sd->msg, "Hello Storage calling Start Job %127s", job_name) != 1) { char addr[64]; char *who = bnet_get_peer(sd, addr, sizeof(addr)) ? sd->who() : addr; sd->msg[100] = 0; Dmsg2(dbglvl, "Bad Hello command from Director at %s: %s\n", sd->who(), sd->msg); Jmsg2(NULL, M_FATAL, 0, _("Bad Hello command from Director at %s: %s\n"), who, sd->msg); sd->close(); return NULL; } if (!(jcr = get_jcr_by_full_name(job_name))) { Jmsg1(NULL, M_FATAL, 0, _("SD connect failed: Job name not found: %s\n"), job_name); Dmsg1(3, "**** Job \"%s\" not found.\n", job_name); sd->close(); return NULL; } Dmsg1(50, "Found Job %s\n", job_name); jcr->store_bsock = sd; jcr->store_bsock->set_jcr(jcr); /* * Authenticate the Storage Daemon. */ if (!authenticate_storagedaemon(jcr)) { Dmsg1(50, "Authentication failed Job %s\n", jcr->Job); Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n")); jcr->setJobStatus(JS_ErrorTerminated); } else { Dmsg2(50, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job); } if (!jcr->max_bandwidth) { if (jcr->director->max_bandwidth_per_job) { jcr->max_bandwidth = jcr->director->max_bandwidth_per_job; } else if (me->max_bandwidth_per_job) { jcr->max_bandwidth = me->max_bandwidth_per_job; } } sd->set_bwlimit(jcr->max_bandwidth); if (me->allow_bw_bursting) { sd->set_bwlimit_bursting(); } free_jcr(jcr); return NULL; }
/* * Director requests us to start a job * Basic tasks done here: * - We pickup the JobId to be run from the Director. * - We pickup the device, media, and pool from the Director * - Wait for a connection from the File Daemon (FD) * - Accept commands from the FD (i.e. run the job) * - Return when the connection is terminated or * there is an error. */ bool job_cmd(JCR *jcr) { int32_t JobId; char sd_auth_key[200]; char spool_size[30]; char seed[100]; BSOCK *dir = jcr->dir_bsock; POOL_MEM job_name, client_name, job, fileset_name, fileset_md5; int32_t JobType, level, spool_attributes, no_attributes, spool_data; int32_t write_part_after_job, PreferMountedVols; int32_t rerunning; int32_t is_client; int stat; JCR *ojcr; /* * Get JobId and permissions from Director */ Dmsg1(100, "<dird: %s", dir->msg); bstrncpy(spool_size, "0", sizeof(spool_size)); stat = sscanf(dir->msg, jobcmd, &JobId, job.c_str(), job_name.c_str(), client_name.c_str(), &JobType, &level, fileset_name.c_str(), &no_attributes, &spool_attributes, fileset_md5.c_str(), &spool_data, &write_part_after_job, &PreferMountedVols, spool_size, &rerunning, &jcr->VolSessionId, &jcr->VolSessionTime, &is_client, &sd_auth_key); if (stat != 19) { pm_strcpy(jcr->errmsg, dir->msg); dir->fsend(BAD_job, stat, jcr->errmsg); Dmsg1(100, ">dird: %s", dir->msg); jcr->setJobStatus(JS_ErrorTerminated); return false; } jcr->rerunning = rerunning; jcr->sd_client = is_client; if (is_client) { jcr->sd_auth_key = bstrdup(sd_auth_key); } Dmsg3(100, "rerunning=%d VolSesId=%d VolSesTime=%d\n", jcr->rerunning, jcr->VolSessionId, jcr->VolSessionTime); /* * Since this job could be rescheduled, we * check to see if we have it already. If so * free the old jcr and use the new one. */ ojcr = get_jcr_by_full_name(job.c_str()); if (ojcr && !ojcr->authenticated) { Dmsg2(100, "Found ojcr=0x%x Job %s\n", (unsigned)(intptr_t)ojcr, job.c_str()); free_jcr(ojcr); } jcr->JobId = JobId; Dmsg2(800, "Start JobId=%d %p\n", JobId, jcr); set_jcr_in_tsd(jcr); /* * If job rescheduled because previous was incomplete, * the Resched flag is set and VolSessionId and VolSessionTime * are given to us (same as restarted job). */ if (!jcr->rerunning) { jcr->VolSessionId = newVolSessionId(); jcr->VolSessionTime = VolSessionTime; } bstrncpy(jcr->Job, job, sizeof(jcr->Job)); unbash_spaces(job_name); jcr->job_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->job_name, job_name); unbash_spaces(client_name); jcr->client_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->client_name, client_name); unbash_spaces(fileset_name); jcr->fileset_name = get_pool_memory(PM_NAME); pm_strcpy(jcr->fileset_name, fileset_name); jcr->setJobType(JobType); jcr->setJobLevel(level); jcr->no_attributes = no_attributes; jcr->spool_attributes = spool_attributes; jcr->spool_data = spool_data; jcr->spool_size = str_to_int64(spool_size); jcr->write_part_after_job = write_part_after_job; jcr->fileset_md5 = get_pool_memory(PM_NAME); pm_strcpy(jcr->fileset_md5, fileset_md5); jcr->PreferMountedVols = PreferMountedVols; jcr->authenticated = false; /* * Pass back an authorization key for the File daemon */ if (jcr->sd_client) { bstrncpy(sd_auth_key, "xxx", 3); } else { bsnprintf(seed, sizeof(seed), "%p%d", jcr, JobId); make_session_key(sd_auth_key, seed, 1); } dir->fsend(OKjob, jcr->VolSessionId, jcr->VolSessionTime, sd_auth_key); Dmsg2(150, ">dird jid=%u: %s", (uint32_t)jcr->JobId, dir->msg); /* If not client, set key, otherwise it is already set */ if (!jcr->sd_client) { jcr->sd_auth_key = bstrdup(sd_auth_key); memset(sd_auth_key, 0, sizeof(sd_auth_key)); } new_plugins(jcr); /* instantiate the plugins */ generate_daemon_event(jcr, "JobStart"); generate_plugin_event(jcr, bsdEventJobStart, (void *)"JobStart"); return true; }