/* * Create a Job Control Record and link it into JCR chain * Returns newly allocated JCR * Note, since each daemon has a different JCR, he passes * us the size. */ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr) { JCR *jcr; MQUEUE_ITEM *item = NULL; struct sigaction sigtimer; int status; Dmsg0(dbglvl, "Enter new_jcr\n"); status = pthread_once(&key_once, create_jcr_key); if (status != 0) { berrno be; Jmsg1(NULL, M_ABORT, 0, _("pthread_once failed. ERR=%s\n"), be.bstrerror(status)); } jcr = (JCR *)malloc(size); memset(jcr, 0, size); jcr->my_thread_id = pthread_self(); jcr->msg_queue = New(dlist(item, &item->link)); jcr->job_end_push.init(1, false); jcr->sched_time = time(NULL); jcr->daemon_free_jcr = daemon_free_jcr; /* plug daemon free routine */ jcr->init_mutex(); jcr->inc_use_count(); jcr->VolumeName = get_pool_memory(PM_FNAME); jcr->VolumeName[0] = 0; jcr->errmsg = get_pool_memory(PM_MESSAGE); jcr->errmsg[0] = 0; /* Setup some dummy values */ bstrncpy(jcr->Job, "*System*", sizeof(jcr->Job)); jcr->JobId = 0; jcr->set_JobType(JT_SYSTEM); /* internal job until defined */ jcr->set_JobLevel(L_NONE); set_jcr_job_status(jcr, JS_Created); /* ready to run */ set_jcr_in_tsd(jcr); sigtimer.sa_flags = 0; sigtimer.sa_handler = timeout_handler; sigfillset(&sigtimer.sa_mask); sigaction(TIMEOUT_SIGNAL, &sigtimer, NULL); /* * Locking jobs is a global lock that is needed * so that the Director can stop new jobs from being * added to the jcr chain while it processes a new * conf file and does the job_end_push(). */ lock_jobs(); lock_jcr_chain(); if (!jcrs) { jcrs = New(dlist(jcr, &jcr->link)); } jcrs->append(jcr); unlock_jcr_chain(); unlock_jobs(); return jcr; }
/* * Called here at the end of every job that was * hooked decrementing the active job_count. When * it goes to zero, no one is using the associated * resource table, so free it. */ static void reload_job_end_cb(JCR *jcr, void *ctx) { int reload_id = (int)((intptr_t)ctx); Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId, reload_id, reload_table[reload_id].job_count); lock_jobs(); LockRes(); if (--reload_table[reload_id].job_count <= 0) { free_saved_resources(reload_id); } UnlockRes(); unlock_jobs(); }
void reload_config(int sig) { static bool already_here = false; #if !defined(HAVE_WIN32) sigset_t set; #endif JCR *jcr; int njobs = 0; /* number of running jobs */ int table, rtable; bool ok; if (already_here) { abort(); /* Oops, recursion -> die */ } already_here = true; #if !defined(HAVE_WIN32) sigemptyset(&set); sigaddset(&set, SIGHUP); sigprocmask(SIG_BLOCK, &set, NULL); #endif lock_jobs(); LockRes(); table = find_free_reload_table_entry(); if (table < 0) { Jmsg(NULL, M_ERROR, 0, _("Too many open reload requests. Request ignored.\n")); goto bail_out; } /** * Flush the sql connection pools. */ db_sql_pool_flush(); Dmsg1(100, "Reload_config njobs=%d\n", njobs); reload_table[table].res_table = my_config->save_resources(); Dmsg1(100, "Saved old config in table %d\n", table); ok = parse_dir_config(my_config, configfile, M_ERROR); Dmsg0(100, "Reloaded config file\n"); if (!ok || !check_resources() || !check_catalog(UPDATE_CATALOG) || !initialize_sql_pooling()) { rtable = find_free_reload_table_entry(); /* save new, bad table */ if (rtable < 0) { Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile); Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n")); goto bail_out; } else { Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile); Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n")); } reload_table[rtable].res_table = my_config->save_resources(); /* Now restore old resource values */ int num = my_config->m_r_last - my_config->m_r_first + 1; RES **res_tab = reload_table[table].res_table; for (int i=0; i<num; i++) { my_config->m_res_head[i] = res_tab[i]; } table = rtable; /* release new, bad, saved table below */ } else { invalidate_schedules(); /* * Hook all active jobs so that they release this table */ foreach_jcr(jcr) { if (jcr->getJobType() != JT_SYSTEM) { reload_table[table].job_count++; job_end_push(jcr, reload_job_end_cb, (void *)((long int)table)); njobs++; } } endeach_jcr(jcr); } /* Reset globals */ set_working_directory(me->working_directory); Dmsg0(10, "Director's configuration file reread.\n"); /* Now release saved resources, if no jobs using the resources */ if (njobs == 0) { free_saved_resources(table); } bail_out: UnlockRes(); unlock_jobs(); #if !defined(HAVE_WIN32) sigprocmask(SIG_UNBLOCK, &set, NULL); signal(SIGHUP, reload_config); #endif already_here = false; }