int posix_dal_ctx_init(DAL_Context* ctx, struct DAL* dal, void* fh /* ? */) { ENTRY(); ctx->data.ptr = malloc(sizeof(PosixDal_Context)); POSIX_DAL_CONTEXT(ctx)->fd = -1; POSIX_DAL_CONTEXT(ctx)->fh = (MarFS_FileHandle*)fh; ctx->flags = 0; // create repo/namespace directory under the posix-repo from config. const MarFS_Repo *repo = POSIX_DAL_FH(ctx)->info.pre.repo; const MarFS_Namespace *ns = POSIX_DAL_FH(ctx)->info.pre.ns; struct stat st; char repo_path[MARFS_MAX_REPO_NAME + MARFS_MAX_HOST_SIZE + MARFS_MAX_NAMESPACE_NAME]; sprintf(repo_path, "%s/%s", repo->host, repo->name); // Check that the directory // <repo-host>/<repo-name>/<namespace-name> exists if(stat(repo_path, &st) == -1) { TRY0( mkdir(repo_path, 0755) ); // XXX: an arbitrary mode. } sprintf(repo_path, "%s/%s/%s", repo->host, repo->name, ns->name); if(stat(repo_path, &st) == -1) { TRY0( mkdir(repo_path, 0755) ); } memset(POSIX_DAL_PATH(ctx), '\0', MAX_OBJECT_PATH_LEN); EXIT(); return 0; }
int push_groups4(PerThreadContext* ctx, uid_t uid, gid_t gid) { TRY_DECLS(); // check for two pushes without a pop if (ctx->pushed_groups) { LOG(LOG_ERR, "double-push (groups) -> %u\n", uid); errno = EPERM; return -1; } // save the group-list for the current process ctx->group_ct = getgroups(sizeof ctx->groups / sizeof (gid_t), ctx->groups); if (ctx->group_ct < 0) { // ctx->group_ct = 0; // ? LOG(LOG_ERR, "getgroups() failed\n"); return -1; } // find user-name from uid struct passwd pwd; struct passwd* result; const size_t STR_BUF_LEN = 1024; // probably enough char str_buf[STR_BUF_LEN]; if (getpwuid_r(uid, &pwd, str_buf, STR_BUF_LEN, &result)) { LOG(LOG_ERR, "getpwuid_r() failed: %s\n", strerror(errno)); return -EINVAL; } else if (! result) { LOG(LOG_ERR, "No passwd entries found, for uid %u\n", uid); return -EINVAL; } LOG(LOG_INFO, "uid %u = user '%s'\n", uid, result->pw_name); // find group-membership of user, using user-name gid_t groups[NGROUPS_MAX +1]; int ngroups = NGROUPS_MAX +1; int group_ct = getgrouplist(result->pw_name, gid, groups, &ngroups); if (group_ct < 0) { LOG(LOG_ERR, "No passwd entries found, for user '%s'\n", result->pw_name); return -1; } // DEBUGGING int i; for (i=0; i<group_ct; ++i) { LOG(LOG_INFO, "group = %u\n", groups[i]); } // change group membership of process TRY0( setgroups(ngroups, groups) ); ctx->pushed_groups = 1; // so we can pop return 0; }
// See comments on stream_sync. When this returns, all I/O (ever) is // completed. No more I/O errors are possible. There should be no more // operations done on the stream at this point. int posix_dal_sync(DAL_Context* ctx) { TRY_DECLS(); // fsync will set errno = EBADF if the fd is not open. In order to // be consistent with stream_sync, we detect that case and fail // with EINVAL instead. if(! (POSIX_DAL_OS(ctx)->flags & OSF_OPEN)) { LOG(LOG_ERR, "%s isn't open\n", POSIX_DAL_OS(ctx)->url); errno = EINVAL; return -1; } TRY0( fsync(POSIX_DAL_FD(ctx)) ); // Since close might cause an error we do it here. TRY0( close_posix_object(ctx) ); return 0; }
static int close_posix_object(DAL_Context* ctx) { TRY_DECLS(); TRY0( close(POSIX_DAL_FD(ctx)) ); POSIX_DAL_OS(ctx)->flags &= ~OSF_OPEN; POSIX_DAL_OS(ctx)->flags |= OSF_CLOSED; // prevent future mistakes by clearing out the file descriptor. POSIX_DAL_FD(ctx) = -1; return 0; }
static void rdtypestat_dump(dns_rdatastatstype_t type, isc_uint64_t val, void *arg) { char typebuf[64]; const char *typestr; stats_dumparg_t *dumparg = arg; FILE *fp; #ifdef HAVE_LIBXML2 xmlTextWriterPtr writer; int xmlrc; #endif if ((DNS_RDATASTATSTYPE_ATTR(type) & DNS_RDATASTATSTYPE_ATTR_OTHERTYPE) == 0) { dns_rdatatype_format(DNS_RDATASTATSTYPE_BASE(type), typebuf, sizeof(typebuf)); typestr = typebuf; } else typestr = "Others"; switch (dumparg->type) { case statsformat_file: fp = dumparg->arg; fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, typestr); break; case statsformat_xml: #ifdef HAVE_LIBXML2 writer = dumparg->arg; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdtype")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR typestr)); TRY0(xmlTextWriterEndElement(writer)); /* name */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", val)); TRY0(xmlTextWriterEndElement(writer)); /* counter */ TRY0(xmlTextWriterEndElement(writer)); /* rdtype */ #endif break; } return; #ifdef HAVE_LIBXML2 error: dumparg->result = ISC_R_FAILURE; return; #endif }
int posix_dal_close(DAL_Context* ctx) { TRY_DECLS(); // the file may have already been closed by _sync if(! (POSIX_DAL_OS(ctx)->flags & OSF_OPEN)) { return 0; } TRY0( close_posix_object(ctx) ); return 0; }
int posix_dal_open(DAL_Context* ctx, int is_put, size_t chunk_offset, size_t content_length, uint8_t preserve_write_count, uint16_t timeout) { ENTRY(); // fail if the path has not been generated. This should never // happen and would be a logical error. if(! (ctx->flags & POSIX_DAL_PATH_GENERATED)) { LOG(LOG_ERR, "POSIX_DAL: no previous call to " "DAL->update_object_location"); return -1; } TRY0( stream_cleanup_for_reopen(POSIX_DAL_OS(ctx), preserve_write_count) ); char* object_path = POSIX_DAL_PATH(ctx); int object_flags; const mode_t mode = S_IRUSR|S_IWUSR; if(is_put) { POSIX_DAL_OS(ctx)->flags |= OSF_WRITING; object_flags = O_WRONLY|O_CREAT; } else { POSIX_DAL_OS(ctx)->flags |= OSF_READING; object_flags = O_RDONLY; } int fd = open(object_path, object_flags, mode); if(fd < 0) { LOG(LOG_ERR, "Failed to open file with posix_dal: %s\n", object_path); return -1; } if (chunk_offset) { off_t rc = lseek(fd, chunk_offset, SEEK_SET); if (rc == (off_t)-1) { LOG(LOG_ERR, "lseek(%ld) faild for posix_dal: %s\n", chunk_offset, object_path); return -1; } } POSIX_DAL_FD(ctx) = fd; POSIX_DAL_OS(ctx)->flags |= OSF_OPEN; EXIT(); return 0; }
static void opcodestat_dump(dns_opcode_t code, isc_uint64_t val, void *arg) { FILE *fp; isc_buffer_t b; char codebuf[64]; stats_dumparg_t *dumparg = arg; #ifdef HAVE_LIBXML2 xmlTextWriterPtr writer; int xmlrc; #endif isc_buffer_init(&b, codebuf, sizeof(codebuf) - 1); dns_opcode_totext(code, &b); codebuf[isc_buffer_usedlength(&b)] = '\0'; switch (dumparg->type) { case statsformat_file: fp = dumparg->arg; fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", val, codebuf); break; case statsformat_xml: #ifdef HAVE_LIBXML2 writer = dumparg->arg; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "opcode")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR codebuf)); TRY0(xmlTextWriterEndElement(writer)); /* name */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", val)); TRY0(xmlTextWriterEndElement(writer)); /* counter */ TRY0(xmlTextWriterEndElement(writer)); /* opcode */ #endif break; } return; #ifdef HAVE_LIBXML2 error: dumparg->result = ISC_R_FAILURE; return; #endif }
// restore the group-membership of the current process to what it was // before push_groups4() int pop_groups4(PerThreadContext* ctx) { TRY_DECLS(); // DEBUGGING int i; for (i=0; i<ctx->group_ct; ++i) { LOG(LOG_INFO, "group = %u\n", ctx->groups[i]); } TRY0( setgroups(ctx->group_ct, ctx->groups) ); ctx->pushed_groups = 0; return 0; }
// Open a multi-component object stream backed by a ne_handle. // // This used to defer opens, since that is now done in MarFS proper, // we no longer need to do it here. int mc_open(DAL_Context* ctx, int is_put, size_t chunk_offset, size_t content_length, uint8_t preserve_write_count, uint16_t timeout) { ENTRY(); ObjectStream* os = MC_OS(ctx); char* path_template = MC_CONTEXT(ctx)->path_template; unsigned int n = MC_CONFIG(ctx)->n; unsigned int e = MC_CONFIG(ctx)->e; // do the generic cleanup stuff like resetting flags. TRY0( stream_cleanup_for_reopen(os, preserve_write_count) ); int mode = is_put ? NE_WRONLY : NE_RDONLY; MC_HANDLE(ctx) = ne_open(path_template, mode, MC_CONTEXT(ctx)->start_block, n, e); if(! MC_HANDLE(ctx)) { LOG(LOG_ERR, "Failed to open MC Handle %s\n", path_template); return -1; } if(is_put) { os->flags |= OSF_WRITING; } else { os->flags |= OSF_READING; } os->flags |= OSF_OPEN; MC_CONTEXT(ctx)->chunk_offset = chunk_offset; EXIT(); return 0; }
static isc_result_t generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"]; char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"]; isc_time_t now; xmlTextWriterPtr writer = NULL; xmlDocPtr doc = NULL; int xmlrc; dns_view_t *view; stats_dumparg_t dumparg; dns_stats_t *cachestats; isc_uint64_t nsstat_values[dns_nsstatscounter_max]; isc_uint64_t resstat_values[dns_resstatscounter_max]; isc_uint64_t zonestat_values[dns_zonestatscounter_max]; isc_uint64_t sockstat_values[isc_sockstatscounter_max]; isc_result_t result; isc_time_now(&now); isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime); isc_time_formatISO8601(&now, nowstr, sizeof nowstr); writer = xmlNewTextWriterDoc(&doc, 0); if (writer == NULL) goto error; TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL)); TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet", ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\"")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "isc")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", ISC_XMLCHAR "1.0")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "bind")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", ISC_XMLCHAR "2.2")); /* Set common fields for statistics dump */ dumparg.type = statsformat_xml; dumparg.arg = writer; /* * Start by rendering the views we know of here. For each view we * know of, call its rendering function. */ view = ISC_LIST_HEAD(server->viewlist); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views")); while (view != NULL) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "view")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name)); TRY0(xmlTextWriterEndElement(writer)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones")); result = dns_zt_apply(view->zonetable, ISC_TRUE, zone_xmlrender, writer); if (result != ISC_R_SUCCESS) goto error; TRY0(xmlTextWriterEndElement(writer)); if (view->resquerystats != NULL) { dumparg.result = ISC_R_SUCCESS; dns_rdatatypestats_dump(view->resquerystats, rdtypestat_dump, &dumparg, 0); if (dumparg.result != ISC_R_SUCCESS) goto error; } if (view->resstats != NULL) { result = dump_counters(view->resstats, statsformat_xml, writer, "resstat", resstats_xmldesc, dns_resstatscounter_max, resstats_index, resstat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; } cachestats = dns_db_getrrsetstats(view->cachedb); if (cachestats != NULL) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "cache")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "name", ISC_XMLCHAR dns_cache_getname(view->cache))); dumparg.result = ISC_R_SUCCESS; dns_rdatasetstats_dump(cachestats, rdatasetstats_dump, &dumparg, 0); if (dumparg.result != ISC_R_SUCCESS) goto error; TRY0(xmlTextWriterEndElement(writer)); /* cache */ } TRY0(xmlTextWriterEndElement(writer)); /* view */ view = ISC_LIST_NEXT(view, link); } TRY0(xmlTextWriterEndElement(writer)); /* views */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socketmgr")); isc_socketmgr_renderxml(ns_g_socketmgr, writer); TRY0(xmlTextWriterEndElement(writer)); /* socketmgr */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "taskmgr")); isc_taskmgr_renderxml(ns_g_taskmgr, writer); TRY0(xmlTextWriterEndElement(writer)); /* taskmgr */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime)); TRY0(xmlTextWriterEndElement(writer)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr)); TRY0(xmlTextWriterEndElement(writer)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "requests")); dumparg.result = ISC_R_SUCCESS; dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg, 0); if (dumparg.result != ISC_R_SUCCESS) goto error; TRY0(xmlTextWriterEndElement(writer)); /* requests */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "queries-in")); dumparg.result = ISC_R_SUCCESS; dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump, &dumparg, 0); if (dumparg.result != ISC_R_SUCCESS) goto error; TRY0(xmlTextWriterEndElement(writer)); /* queries-in */ result = dump_counters(server->nsstats, statsformat_xml, writer, "nsstat", nsstats_xmldesc, dns_nsstatscounter_max, nsstats_index, nsstat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; result = dump_counters(server->zonestats, statsformat_xml, writer, "zonestat", zonestats_xmldesc, dns_zonestatscounter_max, zonestats_index, zonestat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; /* * Most of the common resolver statistics entries are 0, so we don't * use the verbose dump here. */ result = dump_counters(server->resolverstats, statsformat_xml, writer, "resstat", resstats_xmldesc, dns_resstatscounter_max, resstats_index, resstat_values, 0); if (result != ISC_R_SUCCESS) goto error; result = dump_counters(server->sockstats, statsformat_xml, writer, "sockstat", sockstats_xmldesc, isc_sockstatscounter_max, sockstats_index, sockstat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; TRY0(xmlTextWriterEndElement(writer)); /* server */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory")); isc_mem_renderxml(writer); TRY0(xmlTextWriterEndElement(writer)); /* memory */ TRY0(xmlTextWriterEndElement(writer)); /* statistics */ TRY0(xmlTextWriterEndElement(writer)); /* bind */ TRY0(xmlTextWriterEndElement(writer)); /* isc */ TRY0(xmlTextWriterEndDocument(writer)); xmlFreeTextWriter(writer); xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 1); xmlFreeDoc(doc); return (ISC_R_SUCCESS); error: if (writer != NULL) xmlFreeTextWriter(writer); if (doc != NULL) xmlFreeDoc(doc); return (ISC_R_FAILURE); }
static isc_result_t zone_xmlrender(dns_zone_t *zone, void *arg) { char buf[1024 + 32]; /* sufficiently large for zone name and class */ dns_rdataclass_t rdclass; isc_uint32_t serial; xmlTextWriterPtr writer = arg; isc_stats_t *zonestats; isc_uint64_t nsstat_values[dns_nsstatscounter_max]; int xmlrc; isc_result_t result; TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zone")); dns_zone_name(zone, buf, sizeof(buf)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf)); TRY0(xmlTextWriterEndElement(writer)); rdclass = dns_zone_getclass(zone); dns_rdataclass_format(rdclass, buf, sizeof(buf)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "rdataclass")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR buf)); TRY0(xmlTextWriterEndElement(writer)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "serial")); if (dns_zone_getserial2(zone, &serial) == ISC_R_SUCCESS) TRY0(xmlTextWriterWriteFormatString(writer, "%u", serial)); else TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "-")); TRY0(xmlTextWriterEndElement(writer)); zonestats = dns_zone_getrequeststats(zone); if (zonestats != NULL) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); result = dump_counters(zonestats, statsformat_xml, writer, NULL, nsstats_xmldesc, dns_nsstatscounter_max, nsstats_index, nsstat_values, ISC_STATSDUMP_VERBOSE); if (result != ISC_R_SUCCESS) goto error; TRY0(xmlTextWriterEndElement(writer)); /* counters */ } TRY0(xmlTextWriterEndElement(writer)); /* zone */ return (ISC_R_SUCCESS); error: return (ISC_R_FAILURE); }
static isc_result_t dump_counters(isc_stats_t *stats, statsformat_t type, void *arg, const char *category, const char **desc, int ncounters, int *indices, isc_uint64_t *values, int options) { int i, index; isc_uint64_t value; stats_dumparg_t dumparg; FILE *fp; #ifdef HAVE_LIBXML2 xmlTextWriterPtr writer; int xmlrc; #endif #ifndef HAVE_LIBXML2 UNUSED(category); #endif dumparg.type = type; dumparg.ncounters = ncounters; dumparg.counterindices = indices; dumparg.countervalues = values; memset(values, 0, sizeof(values[0]) * ncounters); isc_stats_dump(stats, generalstat_dump, &dumparg, options); for (i = 0; i < ncounters; i++) { index = indices[i]; value = values[index]; switch (dumparg.type) { case statsformat_file: fp = arg; fprintf(fp, "%20" ISC_PRINT_QUADFORMAT "u %s\n", value, desc[index]); break; case statsformat_xml: #ifdef HAVE_LIBXML2 writer = arg; if (category != NULL) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR category)); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR desc[index])); TRY0(xmlTextWriterEndElement(writer)); /* name */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counter")); } else { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR desc[index])); } TRY0(xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u", value)); TRY0(xmlTextWriterEndElement(writer)); /* counter */ if (category != NULL) TRY0(xmlTextWriterEndElement(writer)); /* category */ #endif break; } } return (ISC_R_SUCCESS); #ifdef HAVE_LIBXML2 error: return (ISC_R_FAILURE); #endif }
int isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) { isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0; isc__task_t *task = NULL; int xmlrc; LOCK(&mgr->lock); /* * Write out the thread-model, and some details about each depending * on which type is enabled. */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model")); #ifdef ISC_PLATFORM_USETHREADS TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded")); TRY0(xmlTextWriterEndElement(writer)); /* type */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->workers)); TRY0(xmlTextWriterEndElement(writer)); /* worker-threads */ #else /* ISC_PLATFORM_USETHREADS */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type")); TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded")); TRY0(xmlTextWriterEndElement(writer)); /* type */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs)); TRY0(xmlTextWriterEndElement(writer)); /* references */ #endif /* ISC_PLATFORM_USETHREADS */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->default_quantum)); TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running)); TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */ TRY0(xmlTextWriterEndElement(writer)); /* thread-model */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks")); task = ISC_LIST_HEAD(mgr->tasks); while (task != NULL) { LOCK(&task->lock); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "task")); if (task->name[0] != 0) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", task->name)); TRY0(xmlTextWriterEndElement(writer)); /* name */ } TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", task->references)); TRY0(xmlTextWriterEndElement(writer)); /* references */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id")); TRY0(xmlTextWriterWriteFormatString(writer, "%p", task)); TRY0(xmlTextWriterEndElement(writer)); /* id */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "state")); TRY0(xmlTextWriterWriteFormatString(writer, "%s", statenames[task->state])); TRY0(xmlTextWriterEndElement(writer)); /* state */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum")); TRY0(xmlTextWriterWriteFormatString(writer, "%d", task->quantum)); TRY0(xmlTextWriterEndElement(writer)); /* quantum */ TRY0(xmlTextWriterEndElement(writer)); UNLOCK(&task->lock); task = ISC_LIST_NEXT(task, link); } TRY0(xmlTextWriterEndElement(writer)); /* tasks */ error: if (task != NULL) UNLOCK(&task->lock); UNLOCK(&mgr->lock); return (xmlrc); }
static void generatexml(ns_server_t *server, int *buflen, xmlChar **buf) { char boottime[sizeof "yyyy-mm-ddThh:mm:ssZ"]; char nowstr[sizeof "yyyy-mm-ddThh:mm:ssZ"]; isc_time_t now; xmlTextWriterPtr writer; xmlDocPtr doc; int xmlrc; dns_view_t *view; stats_dumparg_t dumparg; dns_stats_t *cachestats; isc_time_now(&now); isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime); isc_time_formatISO8601(&now, nowstr, sizeof nowstr); writer = xmlNewTextWriterDoc(&doc, 0); TRY0(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL)); TRY0(xmlTextWriterWritePI(writer, ISC_XMLCHAR "xml-stylesheet", ISC_XMLCHAR "type=\"text/xsl\" href=\"/bind9.xsl\"")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "isc")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", ISC_XMLCHAR "1.0")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "bind")); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics")); TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version", ISC_XMLCHAR "1.0")); /* Set common fields for statistics dump */ dumparg.type = statsformat_xml; dumparg.arg = writer; /* * Start by rendering the views we know of here. For each view we * know of, call its rendering function. */ view = ISC_LIST_HEAD(server->viewlist); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "views")); while (view != NULL) { xmlTextWriterStartElement(writer, ISC_XMLCHAR "view"); xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"); xmlTextWriterWriteString(writer, ISC_XMLCHAR view->name); xmlTextWriterEndElement(writer); xmlTextWriterStartElement(writer, ISC_XMLCHAR "zones"); dns_zt_apply(view->zonetable, ISC_FALSE, zone_xmlrender, writer); xmlTextWriterEndElement(writer); if (view->resquerystats != NULL) { dns_rdatatypestats_dump(view->resquerystats, rdtypestat_dump, &dumparg, 0); } if (view->resstats != NULL) { xmlTextWriterStartElement(writer, ISC_XMLCHAR "resstats"); dumparg.ncounters = dns_resstatscounter_max; dumparg.desc = resstats_xmldesc; /* auto-generated */ dns_generalstats_dump(view->resstats, generalstat_dump, &dumparg, DNS_STATSDUMP_VERBOSE); xmlTextWriterEndElement(writer); /* resstats */ } cachestats = dns_db_getrrsetstats(view->cachedb); if (cachestats != NULL) { xmlTextWriterStartElement(writer, ISC_XMLCHAR "cache"); dns_rdatasetstats_dump(cachestats, rdatasetstats_dump, &dumparg, 0); xmlTextWriterEndElement(writer); /* cache */ } xmlTextWriterEndElement(writer); /* view */ view = ISC_LIST_NEXT(view, link); } TRY0(xmlTextWriterEndElement(writer)); /* views */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socketmgr")); isc_socketmgr_renderxml(ns_g_socketmgr, writer); TRY0(xmlTextWriterEndElement(writer)); /* socketmgr */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "taskmgr")); isc_taskmgr_renderxml(ns_g_taskmgr, writer); TRY0(xmlTextWriterEndElement(writer)); /* taskmgr */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "server")); xmlTextWriterStartElement(writer, ISC_XMLCHAR "boot-time"); xmlTextWriterWriteString(writer, ISC_XMLCHAR boottime); xmlTextWriterEndElement(writer); xmlTextWriterStartElement(writer, ISC_XMLCHAR "current-time"); xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr); xmlTextWriterEndElement(writer); TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "requests")); dns_opcodestats_dump(server->opcodestats, opcodestat_dump, &dumparg, 0); xmlTextWriterEndElement(writer); /* requests */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "queries-in")); dns_rdatatypestats_dump(server->rcvquerystats, rdtypestat_dump, &dumparg, 0); xmlTextWriterEndElement(writer); /* queries-in */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "nsstats")); dumparg.desc = nsstats_xmldesc; /* auto-generated in bind9.xsl.h */ dumparg.ncounters = dns_nsstatscounter_max; dns_generalstats_dump(server->nsstats, generalstat_dump, &dumparg, DNS_STATSDUMP_VERBOSE); xmlTextWriterEndElement(writer); /* nsstats */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "zonestats")); dumparg.desc = zonestats_xmldesc; /* auto-generated in bind9.xsl.h */ dumparg.ncounters = dns_zonestatscounter_max; dns_generalstats_dump(server->zonestats, generalstat_dump, &dumparg, DNS_STATSDUMP_VERBOSE); xmlTextWriterEndElement(writer); /* zonestats */ xmlTextWriterStartElement(writer, ISC_XMLCHAR "resstats"); dumparg.ncounters = dns_resstatscounter_max; dumparg.desc = resstats_xmldesc; dns_generalstats_dump(server->resolverstats, generalstat_dump, &dumparg, DNS_STATSDUMP_VERBOSE); xmlTextWriterEndElement(writer); /* resstats */ xmlTextWriterEndElement(writer); /* server */ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "memory")); isc_mem_renderxml(writer); TRY0(xmlTextWriterEndElement(writer)); /* memory */ TRY0(xmlTextWriterEndElement(writer)); /* statistics */ TRY0(xmlTextWriterEndElement(writer)); /* bind */ TRY0(xmlTextWriterEndElement(writer)); /* isc */ TRY0(xmlTextWriterEndDocument(writer)); xmlFreeTextWriter(writer); xmlDocDumpFormatMemoryEnc(doc, buf, buflen, "UTF-8", 1); xmlFreeDoc(doc); }