Repository: trafficserver Updated Branches: refs/heads/master 44c90698a -> 94f4083d0
HostDB HTTP UI: Add a listall endpoint. This closes #240 Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/94f4083d Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/94f4083d Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/94f4083d Branch: refs/heads/master Commit: 94f4083d02c545275177718a9a6c239de78ce978 Parents: 44c9069 Author: Brian Geffon <bri...@apache.org> Authored: Wed Jul 8 19:48:45 2015 -0700 Committer: Brian Geffon <bri...@apache.org> Committed: Tue Jul 14 22:45:39 2015 -0700 ---------------------------------------------------------------------- iocore/hostdb/HostDB.cc | 196 +++++++++++++++++++++++++++++++++ iocore/hostdb/I_HostDBProcessor.h | 2 + iocore/hostdb/P_HostDBProcessor.h | 4 +- 3 files changed, 201 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/94f4083d/iocore/hostdb/HostDB.cc ---------------------------------------------------------------------- diff --git a/iocore/hostdb/HostDB.cc b/iocore/hostdb/HostDB.cc index 9ccd08a..6abb7b0 100644 --- a/iocore/hostdb/HostDB.cc +++ b/iocore/hostdb/HostDB.cc @@ -1038,6 +1038,61 @@ HostDBProcessor::getbyname_imm(Continuation *cont, process_hostdb_info_pfn proce return &c->action; } +Action * +HostDBProcessor::getall(Continuation *cont) +{ + ink_assert(cont->mutex->thread_holding == this_ethread()); + EThread *thread = cont->mutex->thread_holding; + ProxyMutex *mutex = thread->mutex; + + HOSTDB_INCREMENT_DYN_STAT(hostdb_total_lookups_stat); + +Action * +HostDBProcessor::iterate(Continuation *cont) +{ + ink_assert(cont->mutex->thread_holding == this_ethread()); + EThread *thread = cont->mutex->thread_holding; + ProxyMutex *mutex = thread->mutex; + + HOSTDB_INCREMENT_DYN_STAT(hostdb_total_lookups_stat); + + + HostDBContinuation *c = hostDBContAllocator.alloc(); + HostDBContinuation::Options copt; + copt.cont = cont; + copt.force_dns = false; + copt.timeout = 0; + copt.host_res_style = HOST_RES_NONE; + c->init(HostDBMD5(), copt); + c->current_iterate_pos = 0; + SET_CONTINUATION_HANDLER(c, (HostDBContHandler)&HostDBContinuation::iterateEvent); + + if (thread->mutex == cont->mutex) { + thread->schedule_in(c, HOST_DB_RETRY_PERIOD); + } else { + dnsProcessor.thread->schedule_imm(c); + } + + return &c->action; +} + + HostDBContinuation *c = hostDBContAllocator.alloc(); + HostDBContinuation::Options copt; + copt.cont = cont; + copt.force_dns = false; + copt.timeout = 0; + copt.host_res_style = HOST_RES_NONE; + c->init(HostDBMD5(), copt); + SET_CONTINUATION_HANDLER(c, (HostDBContHandler)&HostDBContinuation::probeAllEvent); + + if (thread->mutex == cont->mutex) { + thread->schedule_in(c, HOST_DB_RETRY_PERIOD); + } else { + dnsProcessor.thread->schedule_imm(c); + } + + return &c->action; +} static void do_setby(HostDBInfo *r, HostDBApplicationInfo *app, const char *hostname, IpAddr const &ip, bool is_srv = false) @@ -1789,6 +1844,60 @@ HostDBContinuation::make_put_message(HostDBInfo *r, Continuation *c, char *buf, return len; } +int +HostDBContinuation::iterateEvent(int event, Event *e) +{ + Debug("hostdb", "iterateEvent event=%d eventp=%p", event, e); + ink_assert(!link.prev && !link.next); + EThread *t = e ? e->ethread : this_ethread(); + + MUTEX_TRY_LOCK_FOR(lock, action.mutex, t, action.continuation); + if (!lock.is_locked()) { + Debug("hostdb", "iterateEvent event=%d eventp=%p: reschedule due to not getting action mutex", event, e); + mutex->thread_holding->schedule_in(this, HOST_DB_RETRY_PERIOD); + return EVENT_CONT; + } + + if (action.cancelled) { + hostdb_cont_free(this); + return EVENT_DONE; + } + + // let's iterate through another record and then reschedule ourself. + if (current_iterate_pos < hostDB.buckets) { + // do 100 at a time + int end = min(current_iterate_pos + 100, hostDB.buckets); + for (; current_iterate_pos < end; ++current_iterate_pos) { + ProxyMutex *bucket_mutex = hostDB.lock_for_bucket(current_iterate_pos); + MUTEX_TRY_LOCK_FOR(lock_bucket, bucket_mutex, t, this); + if (!lock_bucket.is_locked()) { + // we couldn't get the bucket lock, let's just reschedule and try later. + Debug("hostdb", "iterateEvent event=%d eventp=%p: reschedule due to not getting bucket mutex", event, e); + mutex->thread_holding->schedule_in(this, HOST_DB_RETRY_PERIOD); + return EVENT_CONT; + } + + for (unsigned int l = 0; l < hostDB.levels; ++l) { + HostDBInfo *r = reinterpret_cast<HostDBInfo*>(hostDB.data + hostDB.level_offset[l] + hostDB.bucketsize[l] * current_iterate_pos); + if (!r->deleted && !r->failed()) { + action.continuation->handleEvent(EVENT_INTERVAL, static_cast<void*>(r)); + } + } + } + + // And reschedule ourselves to pickup the next bucket after HOST_DB_RETRY_PERIOD. + Debug("hostdb", "iterateEvent event=%d eventp=%p: completed current iteration %d of %d", event, e, current_iterate_pos, hostDB.buckets); + mutex->thread_holding->schedule_in(this, HOST_DB_ITERATE_PERIOD); + return EVENT_CONT; + } else { + Debug("hostdb", "iterateEvent event=%d eventp=%p: completed FINAL iteration %d", event, e, current_iterate_pos); + // if there are no more buckets, then we're done. + action.continuation->handleEvent(EVENT_DONE, NULL); + hostdb_cont_free(this); + } + + return EVENT_DONE; +} // // Build the put message and send it @@ -1807,6 +1916,39 @@ HostDBContinuation::do_put_response(ClusterMachine *m, HostDBInfo *r, Continuati clusterProcessor.invoke_remote(m->pop_ClusterHandler(), PUT_HOSTINFO_CLUSTER_FUNCTION, (char *)&msg, len); } +int +HostDBContinuation::probeAllEvent(int event, Event *e) +{ + Debug("hostdb", "probeAllEvent event=%d eventp=%p", event, e); + ink_assert(!link.prev && !link.next); + EThread *t = e ? e->ethread : this_ethread(); + + MUTEX_TRY_LOCK_FOR(lock, action.mutex, t, action.continuation); + if (!lock.is_locked()) { + mutex->thread_holding->schedule_in(this, HOST_DB_RETRY_PERIOD); + return EVENT_CONT; + } + + if (action.cancelled) { + hostdb_cont_free(this); + return EVENT_DONE; + } + + for (int i = 0; i < hostDB.buckets; ++i) { + ProxyMutex *bucket_mutex = hostDB.lock_for_bucket(i); + SCOPED_MUTEX_LOCK(lock, bucket_mutex, t); + for (unsigned int l = 0; l < hostDB.levels; ++l) { + HostDBInfo *r = reinterpret_cast<HostDBInfo*>(hostDB.data + hostDB.level_offset[l] + hostDB.bucketsize[l] * i); + if (!r->deleted && !r->failed()) { + action.continuation->handleEvent(EVENT_INTERVAL, static_cast<void*>(r)); + } + } + } + + action.continuation->handleEvent(EVENT_DONE, NULL); + hostdb_cont_free(this); + return EVENT_DONE; +} // // Probe state @@ -2300,6 +2442,7 @@ struct ShowHostDB : public ShowCont { showMain(int event, Event *e) { CHECK_SHOW(begin("HostDB")); + CHECK_SHOW(show("<a href=\"./showall\">Show all HostDB records<a/><hr>")); CHECK_SHOW(show("<form method = GET action = \"./name\">\n" "Lookup by name (e.g. trafficserver.apache.org):<br>\n" "<input type=text name=name size=64 maxlength=256>\n" @@ -2330,6 +2473,56 @@ struct ShowHostDB : public ShowCont { return EVENT_CONT; } + int + showAll(int event , Event *e) + { + CHECK_SHOW(begin("HostDB All Records")); + CHECK_SHOW(show("<hr>")); + SET_HANDLER(&ShowHostDB::showAllEvent); + hostDBProcessor.getall(this); + return EVENT_CONT; + } + + int + showAllEvent(int event, Event *e) + { + HostDBInfo *r = (HostDBInfo *)e; + if (event == EVENT_INTERVAL) { + HostDBInfo *r = reinterpret_cast<HostDBInfo *>(e); + return showOne(r,false,event,e); + } else if (event == EVENT_DONE) { + return complete(event, e); + } else { + ink_assert(!"unexpected event"); + } + return EVENT_CONT; + } + + int + showAll(int event , Event *e) + { + CHECK_SHOW(begin("HostDB All Records")); + CHECK_SHOW(show("<hr>")); + SET_HANDLER(&ShowHostDB::showAllEvent); + hostDBProcessor.iterate(this); + return EVENT_CONT; + } + + int + showAllEvent(int event, Event *e) + { + HostDBInfo *r = (HostDBInfo *)e; + if (event == EVENT_INTERVAL) { + HostDBInfo *r = reinterpret_cast<HostDBInfo *>(e); + return showOne(r,false,event,e); + } else if (event == EVENT_DONE) { + return complete(event, e); + } else { + ink_assert(!"unexpected event"); + } + return EVENT_CONT; + } + int showOne(HostDBInfo *r, bool rr, int event, Event *e) @@ -2443,6 +2636,9 @@ register_ShowHostDB(Continuation *c, HTTPHdr *h) } } SET_CONTINUATION_HANDLER(s, &ShowHostDB::showLookup); + } else if (STR_LEN_EQ_PREFIX(path, path_len, "showall")) { + Debug("hostdb", "dumping all hostdb records"); + SET_CONTINUATION_HANDLER(s, &ShowHostDB::showAll); } this_ethread()->schedule_imm(s); return &s->action; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/94f4083d/iocore/hostdb/I_HostDBProcessor.h ---------------------------------------------------------------------- diff --git a/iocore/hostdb/I_HostDBProcessor.h b/iocore/hostdb/I_HostDBProcessor.h index a3d0876..37719f6 100644 --- a/iocore/hostdb/I_HostDBProcessor.h +++ b/iocore/hostdb/I_HostDBProcessor.h @@ -418,6 +418,7 @@ struct HostDBCache; typedef void (Continuation::*process_hostdb_info_pfn)(HostDBInfo *r); typedef void (Continuation::*process_srv_info_pfn)(HostDBInfo *r); + Action *iterate(Continuation *cont); /** The Host Databse access interface. */ struct HostDBProcessor : public Processor { @@ -474,6 +475,7 @@ struct HostDBProcessor : public Processor { Action *getbyname_imm(Continuation *cont, process_hostdb_info_pfn process_hostdb_info, const char *hostname, int len, Options const &opt = DEFAULT_OPTIONS); + Action *getall(Continuation *cont); /** Lookup Hostinfo by addr */ Action * http://git-wip-us.apache.org/repos/asf/trafficserver/blob/94f4083d/iocore/hostdb/P_HostDBProcessor.h ---------------------------------------------------------------------- diff --git a/iocore/hostdb/P_HostDBProcessor.h b/iocore/hostdb/P_HostDBProcessor.h index 52617e4..2b491c4 100644 --- a/iocore/hostdb/P_HostDBProcessor.h +++ b/iocore/hostdb/P_HostDBProcessor.h @@ -138,6 +138,7 @@ HOSTDB_CLIENT_IP_HASH(sockaddr const *lhs, sockaddr const *rhs) // period to wait for a remote probe... #define HOST_DB_CLUSTER_TIMEOUT HRTIME_MSECONDS(5000) #define HOST_DB_RETRY_PERIOD HRTIME_MSECONDS(20) +#define HOST_DB_ITERATE_PERIOD HRTIME_MSECONDS(5) //#define TEST(_x) _x #define TEST(_x) @@ -482,6 +483,7 @@ struct HostDBContinuation : public Continuation { unsigned int round_robin : 1; int probeEvent(int event, Event *e); + int probeAllEvent(int event, Event *e); int clusterEvent(int event, Event *e); int clusterResponseEvent(int event, Event *e); int dnsEvent(int event, HostEnt *e); @@ -535,7 +537,7 @@ struct HostDBContinuation : public Continuation { HostDBContinuation() : Continuation(NULL), ttl(0), host_res_style(DEFAULT_OPTIONS.host_res_style), dns_lookup_timeout(DEFAULT_OPTIONS.timeout), - timeout(0), from(0), from_cont(0), probe_depth(0), missing(false), force_dns(DEFAULT_OPTIONS.force_dns), round_robin(false) + timeout(0), from(0), from_cont(0), probe_depth(0), current_iterate_pos(0), missing(false), force_dns(DEFAULT_OPTIONS.force_dns), round_robin(false) { ink_zero(md5_host_name_store); ink_zero(md5.hash);