static range* _expand_cluster(range_request* rr, const char* cluster, const char* section) { struct stat st; const char* res; libcrange* lr = range_request_lr(rr); set* cache = libcrange_get_cache(lr, "nodescf:cluster_keys"); apr_pool_t* req_pool = range_request_pool(rr); apr_pool_t* lr_pool = range_request_lr_pool(rr); const char* cluster_file; cache_entry* e; if (strcmp(section, "VIPS") == 0) return _cluster_vips(rr, cluster); if (strcmp(section, "VIPHOSTS") == 0) return _cluster_viphosts(rr, cluster); cluster_file = apr_psprintf(req_pool, "%s/%s/nodes.cf", nodescf_path, cluster); if (!cache) { cache = set_new(lr_pool, 0); libcrange_set_cache(lr, "nodescf:cluster_keys", cache); } if (stat(cluster_file, &st) == -1) { range_request_warn_type(rr, "NOCLUSTERDEF", cluster); return range_new(rr); } e = set_get_data(cache, cluster_file); if (!e) { e = apr_palloc(lr_pool, sizeof(struct cache_entry)); apr_pool_create(&e->pool, lr_pool); e->sections = _cluster_keys(rr, e->pool, cluster, cluster_file); e->mtime = st.st_mtime; set_add(cache, cluster_file, e); } else { time_t cached_mtime = e->mtime; if (cached_mtime != st.st_mtime) { apr_pool_clear(e->pool); e->sections = _cluster_keys(rr, e->pool, cluster, cluster_file); e->mtime = st.st_mtime; } } res = set_get_data(e->sections, section); if (!res) { char* cluster_section = apr_psprintf(req_pool, "%s:%s", cluster, section); range_request_warn_type(rr, "NOCLUSTER", cluster_section); return range_new(rr); } return do_range_expand(rr, res); }
range_request* range_expand(libcrange* lr, apr_pool_t* pool, const char* text) { range_request* rr; if (lr == NULL) lr = get_static_lr(); assert(lr); rr = range_request_new(lr, pool); do_range_expand(rr, text); return rr; }
range* rangefunc_group(range_request* rr, range** r) { range* ret; const char** members; int i, err; sqlite3* db; sqlite3_stmt* tag_stmt; sqlite3_stmt* all_nodes_stmt; apr_pool_t* pool = range_request_pool(rr); libcrange* lr = range_request_lr(rr); ret = range_new(rr); members = range_get_hostnames(pool, r[0]); if (!(db = libcrange_get_cache(lr, "sqlite:nodes"))) { const char* sqlite_db_path = libcrange_getcfg(lr, "sqlitedb"); if (!sqlite_db_path) sqlite_db_path = DEFAULT_SQLITE_DB; err = sqlite3_open(sqlite_db_path, &db); if (err != SQLITE_OK) { fprintf(stderr, "%s: %s\n", sqlite_db_path, sqlite3_errmsg(db)); return ret; } libcrange_set_cache(lr, "sqlite:nodes", db); } /* prepare our selects */ err = sqlite3_prepare(db, ALL_NODES_SQL, strlen(ALL_NODES_SQL), &all_nodes_stmt, NULL); if (err != SQLITE_OK) { fprintf(stderr, "%s: %s\n", ALL_NODES_SQL, sqlite3_errmsg(db)); abort(); } err = sqlite3_prepare(db, RANGE_FROM_TAGS, strlen(RANGE_FROM_TAGS), &tag_stmt, NULL); assert(err == SQLITE_OK); /* for each group */ for (i = 0; members[i]; ++i) { sqlite3_stmt* stmt; if (strcmp(members[i], "ALL") == 0) { stmt = all_nodes_stmt; } else { stmt = tag_stmt; /* bind the current group name */ sqlite3_bind_text(tag_stmt, 1, members[i], strlen(members[i]), SQLITE_STATIC); } while (sqlite3_step(stmt) == SQLITE_ROW) { range* this_group; const char* result = (const char*)sqlite3_column_text(stmt, 0); if (stmt == all_nodes_stmt) { range_add(ret, result); } else { this_group = do_range_expand(rr, result); set_union_inplace(ret->nodes, this_group->nodes); } } sqlite3_reset(stmt); } sqlite3_finalize(all_nodes_stmt); sqlite3_finalize(tag_stmt); return ret; }
range_request* range_expand_rr(range_request* rr, const char* text) { assert(rr); do_range_expand(rr, text); return rr; }