oval_probe_session_t *oval_probe_session_new(struct oval_syschar_model *model) { oval_probe_session_t *sess; void *handler_arg; register size_t i; sess = oscap_talloc(oval_probe_session_t); sess->ph = oval_phtbl_new(); sess->sys_model = model; sess->flg = 0; sess->pext = oval_pext_new(); sess->pext->model = &sess->sys_model; sess->pext->sess_ptr = sess; __init_once(); dD("__probe_meta_count = %zu", OSCAP_GSYM(__probe_meta_count)); for (i = 0; i < OSCAP_GSYM(__probe_meta_count); ++i) { handler_arg = NULL; if (OSCAP_GSYM(__probe_meta)[i].flags & OVAL_PROBEMETA_EXTERNAL) handler_arg = sess->pext; oval_probe_handler_set(sess->ph, OSCAP_GSYM(__probe_meta)[i].otype, OSCAP_GSYM(__probe_meta)[i].handler, handler_arg); } oval_probe_handler_set(sess->ph, OVAL_SUBTYPE_ALL, oval_probe_ext_handler, sess->pext); /* special case for reset */ return(sess); }
probe_rcache_t *probe_rcache_new(void) { probe_rcache_t *cache; cache = oscap_talloc(probe_rcache_t); cache->tree = rbt_str_new(); return (cache); }
probe_worker_t *probe_worker_new(void) { probe_worker_t *pth = oscap_talloc(probe_worker_t); pth->sid = 0; pth->tid = 0; pth->msg_handler = NULL; pth->msg = NULL; return (pth); }
/* * oval_pdtbl_ */ static oval_pdtbl_t *oval_pdtbl_new(void) { oval_pdtbl_t *p_tbl; p_tbl = oscap_talloc(oval_pdtbl_t); p_tbl->memb = NULL; p_tbl->count = 0; p_tbl->ctx = SEAP_CTX_new(); return (p_tbl); }
oval_agent_session_t * oval_agent_new_session(struct oval_definition_model *model, const char * name) { oval_agent_session_t *ag_sess; struct oval_sysinfo *sysinfo; struct oval_generator *generator; int ret; dI("Started new OVAL agent.", name); /* Optimalization */ oval_definition_model_optimize_by_filter_propagation(model); ag_sess = oscap_talloc(oval_agent_session_t); ag_sess->filename = oscap_strdup(name); ag_sess->def_model = model; ag_sess->cur_var_model = NULL; ag_sess->sys_model = oval_syschar_model_new(model); #if defined(OVAL_PROBES_ENABLED) ag_sess->psess = oval_probe_session_new(ag_sess->sys_model); #endif #if defined(OVAL_PROBES_ENABLED) /* probe sysinfo */ ret = oval_probe_query_sysinfo(ag_sess->psess, &sysinfo); if (ret != 0) { oval_probe_session_destroy(ag_sess->psess); oval_syschar_model_free(ag_sess->sys_model); oscap_free(ag_sess); return NULL; } #else /* TODO */ sysinfo = oval_sysinfo_new(ag_sess->sys_model); #endif /* OVAL_PROBES_ENABLED */ oval_syschar_model_set_sysinfo(ag_sess->sys_model, sysinfo); oval_sysinfo_free(sysinfo); /* one system only */ ag_sess->sys_models[0] = ag_sess->sys_model; ag_sess->sys_models[1] = NULL; #if defined(OVAL_PROBES_ENABLED) ag_sess->res_model = oval_results_model_new_with_probe_session( model, ag_sess->sys_models, ag_sess->psess); generator = oval_results_model_get_generator(ag_sess->res_model); oval_generator_set_product_version(generator, oscap_get_version()); #endif ag_sess->product_name = NULL; return ag_sess; }
probe_icache_t *probe_icache_new(void) { probe_icache_t *cache; cache = oscap_talloc(probe_icache_t); cache->tree = rbt_i64_new(); if (pthread_mutex_init(&cache->queue_mutex, NULL) != 0) { dE("Can't initialize icache mutex: %u, %s", errno, strerror(errno)); goto fail; } cache->queue_beg = 0; cache->queue_end = 0; cache->queue_cnt = 0; cache->queue_max = PROBE_IQUEUE_CAPACITY; if (pthread_cond_init(&cache->queue_notempty, NULL) != 0) { dE("Can't initialize icache queue condition variable (notempty): %u, %s", errno, strerror(errno)); goto fail; } if (pthread_cond_init(&cache->queue_notfull, NULL) != 0) { dE("Can't initialize icache queue condition variable (notfull): %u, %s", errno, strerror(errno)); goto fail; } if (pthread_create(&cache->thid, NULL, probe_icache_worker, (void *)cache) != 0) { dE("Can't start the icache worker: %u, %s", errno, strerror(errno)); goto fail; } return (cache); fail: if (cache->tree != NULL) rbt_i64_free(cache->tree); pthread_mutex_destroy(&cache->queue_mutex); pthread_cond_destroy(&cache->queue_notempty); oscap_free(cache); return (NULL); }
/* * oval_pext_ */ oval_pext_t *oval_pext_new(void) { oval_pext_t *pext; pext = oscap_talloc(oval_pext_t); pext->do_init = true; pthread_mutex_init(&pext->lock, NULL); #if defined(OVAL_PROBEDIR_ENV) pext->probe_dir = getenv("OVAL_PROBE_DIR"); #else pext->probe_dir = NULL; #endif if (pext->probe_dir == NULL) pext->probe_dir = OVAL_PROBE_DIR; pext->pdtbl = NULL; pext->pdsc = NULL; pext->pdsc_cnt = 0; return(pext); }
static int oval_pdtbl_add(oval_pdtbl_t *tbl, oval_subtype_t type, int sd, const char *uri) { oval_pd_t *pd; assume_d (tbl != NULL, -1); assume_d (uri != NULL, -1); pd = oscap_talloc(oval_pd_t); pd->subtype = type; pd->sd = sd; pd->uri = strdup(uri); tbl->memb = oscap_realloc(tbl->memb, sizeof(oval_pd_t *) * (++tbl->count)); assume_d(tbl->memb != NULL, -1); tbl->memb[tbl->count - 1] = pd; qsort(tbl->memb, tbl->count, sizeof(oval_pd_t *), (int (*)(const void *, const void *))oval_pdtbl_pdcmp); return (0); }
static void *probe_icache_worker(void *arg) { probe_icache_t *cache = (probe_icache_t *)(arg); probe_iqpair_t *pair, pair_mem; SEXP_ID_t item_ID; assume_d(cache != NULL, NULL); pthread_setname_np(pthread_self(), "icache_worker"); if (pthread_mutex_lock(&cache->queue_mutex) != 0) { dE("An error ocured while locking the queue mutex: %u, %s", errno, strerror(errno)); return (NULL); } pair = &pair_mem; dD("icache worker ready"); switch (errno = pthread_barrier_wait(&OSCAP_GSYM(th_barrier))) { case 0: case PTHREAD_BARRIER_SERIAL_THREAD: break; default: dE("pthread_barrier_wait: %d, %s.", errno, strerror(errno)); pthread_mutex_unlock(&cache->queue_mutex); return (NULL); } while(pthread_cond_wait(&cache->queue_notempty, &cache->queue_mutex) == 0) { assume_d(cache->queue_cnt > 0, NULL); next: dD("Extracting item from the cache queue: cnt=%"PRIu16", beg=%"PRIu16"", cache->queue_cnt, cache->queue_beg); /* * Extract an item from the queue and update queue beg, end & cnt */ pair_mem = cache->queue[cache->queue_beg]; #ifndef NDEBUG memset(cache->queue + cache->queue_beg, 0, sizeof(probe_iqpair_t)); #endif --cache->queue_cnt; ++cache->queue_beg; if (cache->queue_beg == cache->queue_max) cache->queue_beg = 0; assume_d(cache->queue_cnt == 0 ? cache->queue_end == cache->queue_beg : cache->queue_end != cache->queue_beg, NULL); /* * Release the mutex */ if (pthread_mutex_unlock(&cache->queue_mutex) != 0) { dE("An error ocured while unlocking the queue mutex: %u, %s", errno, strerror(errno)); abort(); } dD("Signaling `notfull'"); if (pthread_cond_signal(&cache->queue_notfull) != 0) { dE("An error ocured while signaling the `notfull' condition: %u, %s", errno, strerror(errno)); abort(); } if (pair->cobj == NULL) { /* * Handle NOP case (synchronization) */ assume_d(pair->p.cond != NULL, NULL); dD("Handling NOP"); if (pthread_cond_signal(pair->p.cond) != 0) { dE("An error ocured while signaling NOP condition: %u, %s", errno, strerror(errno)); abort(); } } else { probe_citem_t *cached = NULL; dD("Handling cache request"); /* * Compute item ID */ item_ID = SEXP_ID_v(pair->p.item); dD("item ID=%"PRIu64"", item_ID); /* * Perform cache lookup */ if (rbt_i64_get(cache->tree, (int64_t)item_ID, (void *)&cached) == 0) { register uint16_t i; SEXP_t rest1, rest2; /* * Maybe a cache HIT */ dD("cache HIT #1"); for (i = 0; i < cached->count; ++i) { if (SEXP_deepcmp(SEXP_list_rest_r(&rest1, pair->p.item), SEXP_list_rest_r(&rest2, cached->item[i]))) { SEXP_free_r(&rest1); SEXP_free_r(&rest2); break; } SEXP_free_r(&rest1); SEXP_free_r(&rest2); } if (i == cached->count) { /* * Cache MISS */ dD("cache MISS"); cached->item = oscap_realloc(cached->item, sizeof(SEXP_t *) * ++cached->count); cached->item[cached->count - 1] = pair->p.item; /* Assign an unique item ID */ probe_icache_item_setID(pair->p.item, item_ID); } else { /* * Cache HIT */ dD("cache HIT #2 -> real HIT"); SEXP_free(pair->p.item); pair->p.item = cached->item[i]; } } else { /* * Cache MISS */ dD("cache MISS"); cached = oscap_talloc(probe_citem_t); cached->item = oscap_talloc(SEXP_t *); cached->item[0] = pair->p.item; cached->count = 1; /* Assign an unique item ID */ probe_icache_item_setID(pair->p.item, item_ID); if (rbt_i64_add(cache->tree, (int64_t)item_ID, (void *)cached, NULL) != 0) { dE("Can't add item (k=%"PRIi64" to the cache (%p)", (int64_t)item_ID, cache->tree); oscap_free(cached->item); oscap_free(cached); /* now what? */ abort(); } } if (probe_cobj_add_item(pair->cobj, pair->p.item) != 0) { dW("An error ocured while adding the item to the collected object"); } } if (pthread_mutex_lock(&cache->queue_mutex) != 0) { dE("An error ocured while re-locking the queue mutex: %u, %s", errno, strerror(errno)); abort(); } if (cache->queue_cnt > 0) goto next; } return (NULL); }