/* * Remove work from a queue * wq is a queue that was created with workq_init * work_item is an element of work * * Note, it is "removed" by immediately calling a processing routine. * if you want to cancel it, you need to provide some external means * of doing so. */ int workq_remove(workq_t *wq, workq_ele_t *work_item) { int stat, found = 0; pthread_t id; workq_ele_t *item, *prev; Dmsg0(1400, "workq_remove\n"); if (wq->valid != WORKQ_VALID) { return EINVAL; } P(wq->mutex); for (prev=item=wq->first; item; item=item->next) { if (item == work_item) { found = 1; break; } prev = item; } if (!found) { return EINVAL; } /* Move item to be first on list */ if (wq->first != work_item) { prev->next = work_item->next; if (wq->last == work_item) { wq->last = prev; } work_item->next = wq->first; wq->first = work_item; } /* if any threads are idle, wake one */ if (wq->idle_workers > 0) { Dmsg0(1400, "Signal worker\n"); if ((stat = pthread_cond_broadcast(&wq->work)) != 0) { V(wq->mutex); return stat; } } else { Dmsg0(1400, "Create worker thread\n"); /* No idle threads so create a new one */ set_thread_concurrency(wq->max_workers + 1); if ((stat = pthread_create(&id, &wq->attr, workq_server, (void *)wq)) != 0) { V(wq->mutex); return stat; } wq->num_workers++; } V(wq->mutex); Dmsg0(1400, "Return workq_remove\n"); return stat; }
int main (int argc, char *argv[]) { int ch; bool no_signals = false; bool test_config = false; pthread_t thid; char *uid = NULL; char *gid = NULL; start_heap = sbrk(0); setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); my_name_is(argc, argv, "bareos-sd"); init_msg(NULL, NULL); daemon_start_time = time(NULL); /* Sanity checks */ if (TAPE_BSIZE % B_DEV_BSIZE != 0 || TAPE_BSIZE / B_DEV_BSIZE == 0) { Emsg2(M_ABORT, 0, _("Tape block size (%d) not multiple of system size (%d)\n"), TAPE_BSIZE, B_DEV_BSIZE); } if (TAPE_BSIZE != (1 << (ffs(TAPE_BSIZE)-1))) { Emsg1(M_ABORT, 0, _("Tape block size (%d) is not a power of 2\n"), TAPE_BSIZE); } while ((ch = getopt(argc, argv, "c:d:fg:mpstu:v?")) != -1) { switch (ch) { case 'c': /* configuration file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'd': /* debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } break; case 'f': /* run in foreground */ foreground = true; break; case 'g': /* set group id */ gid = optarg; break; case 'm': /* print kaboom output */ prt_kaboom = true; break; case 'p': /* proceed in spite of I/O errors */ forge_on = true; break; case 's': /* no signals */ no_signals = true; break; case 't': test_config = true; break; case 'u': /* set uid */ uid = optarg; break; case 'v': /* verbose */ verbose++; break; case '?': default: usage(); break; } } argc -= optind; argv += optind; if (argc) { if (configfile != NULL) { free(configfile); } configfile = bstrdup(*argv); argc--; argv++; } if (argc) usage(); /* * See if we want to drop privs. */ if (geteuid() == 0) { drop(uid, gid, false); } if (!no_signals) { init_signals(terminate_stored); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } my_config = new_config_parser(); parse_sd_config(my_config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n")); } if (!check_resources()) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); } init_reservations_lock(); if (test_config) { terminate_stored(0); } my_name_is(0, (char **)NULL, me->hdr.name); /* Set our real name */ if (!foreground) { daemon_start(); /* become daemon */ init_stack_dump(); /* pick up new pid */ } create_pid_file(me->pid_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); read_state_file(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); read_crypto_cache(me->working_directory, "bareos-sd", get_first_port_host_order(me->SDaddrs)); set_jcr_in_tsd(INVALID_JCR); /* * Make sure on Solaris we can run concurrent, watch dog + servers + misc */ set_thread_concurrency(me->max_concurrent_jobs * 2 + 4); lmgr_init_thread(); /* initialize the lockmanager stack */ load_sd_plugins(me->plugin_directory, me->plugin_names); cleanup_old_files(); /* Ensure that Volume Session Time and Id are both * set and are both non-zero. */ VolSessionTime = (uint32_t)daemon_start_time; if (VolSessionTime == 0) { /* paranoid */ Jmsg0(NULL, M_ABORT, 0, _("Volume Session Time is ZERO!\n")); } /* * Start the device allocation thread */ create_volume_lists(); /* do before device_init */ if (pthread_create(&thid, NULL, device_initialization, NULL) != 0) { berrno be; Emsg1(M_ABORT, 0, _("Unable to create thread. ERR=%s\n"), be.bstrerror()); } start_watchdog(); /* start watchdog thread */ if (me->jcr_watchdog_time) { init_jcr_subsystem(me->jcr_watchdog_time); /* start JCR watchdogs etc. */ } #if HAVE_NDMP /* Seperate thread that handles NDMP connections */ if (me->ndmp_enable) { start_ndmp_thread_server(me->NDMPaddrs, me->max_concurrent_jobs * 2 + 1, &ndmp_workq); } #endif /* Single server used for Director/Storage and File daemon */ sock_fds = New(alist(10, not_owned_by_alist)); bnet_thread_server_tcp(me->SDaddrs, me->max_concurrent_jobs * 2 + 1, sock_fds, &dird_workq, me->nokeepalive, handle_connection_request); exit(1); /* to keep compiler quiet */ }
int main (int argc, char *argv[]) { int ch; JCR *jcr; cat_op mode; bool no_signals = false; bool test_config = false; char *uid = NULL; char *gid = NULL; start_heap = sbrk(0); setlocale(LC_ALL, ""); bindtextdomain("bareos", LOCALEDIR); textdomain("bareos"); init_stack_dump(); my_name_is(argc, argv, "bareos-dir"); init_msg(NULL, NULL); /* initialize message handler */ init_reload(); daemon_start_time = time(NULL); console_command = run_console_command; while ((ch = getopt(argc, argv, "c:d:fg:mr:stu:v?")) != -1) { switch (ch) { case 'c': /* specify config file */ if (configfile != NULL) { free(configfile); } configfile = bstrdup(optarg); break; case 'd': /* set debug level */ if (*optarg == 't') { dbg_timestamp = true; } else { debug_level = atoi(optarg); if (debug_level <= 0) { debug_level = 1; } } Dmsg1(10, "Debug level = %d\n", debug_level); break; case 'f': /* run in foreground */ background = false; break; case 'g': /* set group id */ gid = optarg; break; case 'm': /* print kaboom output */ prt_kaboom = true; break; case 'r': /* run job */ if (runjob != NULL) { free(runjob); } if (optarg) { runjob = bstrdup(optarg); } break; case 's': /* turn off signals */ no_signals = true; break; case 't': /* test config */ test_config = true; break; case 'u': /* set uid */ uid = optarg; break; case 'v': /* verbose */ verbose++; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (!no_signals) { init_signals(terminate_dird); } if (argc) { if (configfile != NULL) { free(configfile); } configfile = bstrdup(*argv); argc--; argv++; } if (argc) { usage(); } if (configfile == NULL) { configfile = bstrdup(CONFIG_FILE); } /* * See if we want to drop privs. */ if (geteuid() == 0) { drop(uid, gid, false); /* reduce privileges if requested */ } my_config = new_config_parser(); parse_dir_config(my_config, configfile, M_ERROR_TERM); if (init_crypto() != 0) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Cryptography library initialization failed.\n")); goto bail_out; } if (!check_resources()) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); goto bail_out; } if (!test_config) { /* we don't need to do this block in test mode */ if (background) { daemon_start(); init_stack_dump(); /* grab new pid */ } /* Create pid must come after we are a daemon -- so we have our final pid */ create_pid_file(me->pid_directory, "bareos-dir", get_first_port_host_order(me->DIRaddrs)); read_state_file(me->working_directory, "bareos-dir", get_first_port_host_order(me->DIRaddrs)); } set_jcr_in_tsd(INVALID_JCR); set_thread_concurrency(me->MaxConcurrentJobs * 2 + 4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */); lmgr_init_thread(); /* initialize the lockmanager stack */ load_dir_plugins(me->plugin_directory, me->plugin_names); /* * If we are in testing mode, we don't try to fix the catalog */ mode = (test_config) ? CHECK_CONNECTION : UPDATE_AND_FIX; if (!check_catalog(mode)) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); goto bail_out; } if (test_config) { terminate_dird(0); } if (!initialize_sql_pooling()) { Jmsg((JCR *)NULL, M_ERROR_TERM, 0, _("Please correct configuration file: %s\n"), configfile); goto bail_out; } my_name_is(0, NULL, me->name()); /* set user defined name */ cleanup_old_files(); p_db_log_insert = (db_log_insert_func)dir_db_log_insert; #if !defined(HAVE_WIN32) signal(SIGHUP, reload_config); #endif init_console_msg(working_directory); Dmsg0(200, "Start UA server\n"); start_UA_server(me->DIRaddrs); start_watchdog(); /* start network watchdog thread */ if (me->jcr_watchdog_time) { init_jcr_subsystem(me->jcr_watchdog_time); /* start JCR watchdogs etc. */ } init_job_server(me->MaxConcurrentJobs); dbg_jcr_add_hook(db_debug_print); /* used to debug B_DB connexion after fatal signal */ // init_device_resources(); Dmsg0(200, "wait for next job\n"); /* Main loop -- call scheduler to get next job to run */ while ( (jcr = wait_for_next_job(runjob)) ) { run_job(jcr); /* run job */ free_jcr(jcr); /* release jcr */ set_jcr_in_tsd(INVALID_JCR); if (runjob) { /* command line, run a single job? */ break; /* yes, terminate */ } } terminate_dird(0); bail_out: return 0; }
/* * Add work to a queue * wq is a queue that was created with workq_init * element is a user unique item that will be passed to the * processing routine * work_item will get internal work queue item -- if it is not NULL * priority if non-zero will cause the item to be placed on the * head of the list instead of the tail. */ int workq_add(workq_t *wq, void *element, workq_ele_t **work_item, int priority) { int stat=0; workq_ele_t *item; pthread_t id; Dmsg0(1400, "workq_add\n"); if (wq->valid != WORKQ_VALID) { return EINVAL; } if ((item = (workq_ele_t *)malloc(sizeof(workq_ele_t))) == NULL) { return ENOMEM; } item->data = element; item->next = NULL; P(wq->mutex); Dmsg0(1400, "add item to queue\n"); if (priority) { /* Add to head of queue */ if (wq->first == NULL) { wq->first = item; wq->last = item; } else { item->next = wq->first; wq->first = item; } } else { /* Add to end of queue */ if (wq->first == NULL) { wq->first = item; } else { wq->last->next = item; } wq->last = item; } /* if any threads are idle, wake one */ if (wq->idle_workers > 0) { Dmsg0(1400, "Signal worker\n"); if ((stat = pthread_cond_broadcast(&wq->work)) != 0) { V(wq->mutex); return stat; } } else if (wq->num_workers < wq->max_workers) { Dmsg0(1400, "Create worker thread\n"); /* No idle threads so create a new one */ set_thread_concurrency(wq->max_workers + 1); if ((stat = pthread_create(&id, &wq->attr, workq_server, (void *)wq)) != 0) { V(wq->mutex); return stat; } wq->num_workers++; } V(wq->mutex); Dmsg0(1400, "Return workq_add\n"); /* Return work_item if requested */ if (work_item) { *work_item = item; } return stat; }