diff options
Diffstat (limited to 'TAO/utils')
24 files changed, 3120 insertions, 1293 deletions
diff --git a/TAO/utils/logWalker/GIOP_Buffer.cpp b/TAO/utils/logWalker/GIOP_Buffer.cpp new file mode 100644 index 00000000000..48f5df26530 --- /dev/null +++ b/TAO/utils/logWalker/GIOP_Buffer.cpp @@ -0,0 +1,597 @@ +// $Id$ + +#include "GIOP_Buffer.h" +#include "ace/OS_NS_string.h" + +static const char *size_leadin_1_5 = "GIOP v1."; //"x msg, "; +static size_t leadin_len_1_5 = 15; +static const char *size_leadin_1_6 = "GIOP message v1."; //2, "; +static size_t leadin_len_1_6 = 19; + + +const char *GIOP_Buffer::size_leadin = 0; +size_t GIOP_Buffer::leadin_len = 0; +const size_t GIOP_Buffer::giop_header_len = 12; + +void +GIOP_Buffer::init_leadin (int version) +{ + if (size_leadin == 0) + { + if (version == 150) + { + size_leadin = size_leadin_1_5; + leadin_len = leadin_len_1_5; + } + else + { + size_leadin = size_leadin_1_6; + leadin_len = leadin_len_1_6; + } + } +} + +// GIOP 1.2 header: 12 bytes +// Magic: 4 +// ver: 2 +// flags: 1 // bo +// type: 1 // req/repl/lf/excp +// len: 4 +// +// Request 1.2 header: +// req_id: 4 +// flags: 1 +// RESVD: 3 +// Address disposition: 4 +// target: <4 len, + len> [0-3 pad] +// opname: <4 len, + len> + +// GIOP 1.0 header: 12 bytes +// Magic: 4 +// ver: 2 +// byte_order: 1 +// type: 1 // req/repl/lf/excp +// len: 4 +// +// Request 1.0 header: +/* +struct RequestHeader_1_0 { // Renamed from RequestHeader + IOP::ServiceContextList service_context; + unsigned long request_id; + boolean response_expected; + sequence <octet> object_key; + string operation; + CORBA::OctetSeq requesting_principal; +}; +*/ +// service_context: 4(count)+contexts. +// context id: 4 +// content blob: 4(len) + len octets + (0-3)pad +// request_id: 4 +// respexp: 1 +// RESVD: 3 +// Address disposition: 4 +// target: <4 len, + len> [0-3 pad] +// opname: <4 len, + len> + +/* +struct ReplyHeader_1_0 { // Renamed from ReplyHeader + IOP::ServiceContextList service_context; + unsigned long request_id; + ReplyStatusType_1_0 reply_status; + }; + // GIOP 1.1 + typedef ReplyHeader_1_0 ReplyHeader_1_1; + // Same Header contents for 1.0 and 1.1 +#else + // GIOP 1.2, 1.3 + enum ReplyStatusType_1_2 { + NO_EXCEPTION, + USER_EXCEPTION, + SYSTEM_EXCEPTION, + LOCATION_FORWARD, + LOCATION_FORWARD_PERM,// new value for 1.2 + NEEDS_ADDRESSING_MODE // new value for 1.2 + }; + struct ReplyHeader_1_2 { + unsigned long request_id; + ReplyStatusType_1_2 reply_status; + IOP::ServiceContextList service_context; + }; + + */ + + + +static const size_t target_offset_12 = GIOP_Buffer::giop_header_len + 12; + +// 12 = req_id + flags + RESVD + addr disp. + +GIOP_Buffer::GIOP_Buffer(void) + : cdr_ (0), + preamble_(), + log_offset_(0), + thr_(0), + time_(0), + expected_req_id_(0), + expected_size_(0), + expected_type_(0), + buffer_size_(0), + wr_pos_ (0), + octets_ (0), + owner_ (0), + buffer_lost_ (false), + sending_(false), + oid_ (0), + oid_len_ (0), + opname_ (0), + req_id_ (0), + resp_exp_ (0), + reply_status_ (0), + ver_minor_ (0), + msg_size_ (0), + num_contexts_ (0), + header_parsed_ (false), + payload_start_ (0) +{ +} + +GIOP_Buffer::GIOP_Buffer(const char *text, + size_t offset, + Thread *thread, + Invocation *owner) + : cdr_ (0), + preamble_(text), + log_offset_(offset), + thr_(thread), + time_(0), + expected_req_id_(0), + expected_size_(0), + expected_type_(0), + buffer_size_(0), + wr_pos_ (0), + octets_ (0), + owner_ (owner), + buffer_lost_ (false), + sending_(false), + oid_ (0), + oid_len_ (0), + opname_ (0), + req_id_ (0), + resp_exp_ (0), + reply_status_ (0), + ver_minor_ (0), + msg_size_ (0), + num_contexts_ (0), + header_parsed_ (false), + payload_start_ (0) +{ + const char *size_str = ACE_OS::strstr(text, size_leadin) + leadin_len; + const char *id = size_str == 0 ? 0 : ACE_OS::strchr(size_str, '[') + 1; + this->sending_ = ACE_OS::strstr(text,"send") ? 0 : 1; + this->expected_type_ = ACE_OS::strstr(text,"Request") ? 0 : 1; + this->expected_size_ = ACE_OS::strtol(size_str, 0,10); + this->expected_req_id_ = ACE_OS::strtol(id, 0, 10); + const char *time_tok = ACE_OS::strchr (text,'@'); + if (time_tok != 0) + { + char timebuf[30]; + ACE_OS::strncpy(timebuf, text, (time_tok - text)); + timebuf[time_tok - text] = 0; + char *hms = ACE_OS::strchr (timebuf,' '); + if (hms != 0) + { + int hr, min, sec, msec; + ::sscanf (hms+1,"%d:%d:%d.%d", &hr, &min, &sec, &msec); + this->time_ = (hr * 3600 + min *60 + sec) * 1000 + msec; + } + } +} + +void +GIOP_Buffer::owner (Invocation *owner) +{ + this->owner_ = owner; +} + +Invocation * +GIOP_Buffer::owner (void) +{ + return this->owner_; +} + +void +GIOP_Buffer::init_buf (const char *text, size_t offset) +{ + // GIOP message - HEXDUMP + this->log_offset_ = offset; + const char * size_str = ACE_OS::strstr (text,"HEXDUMP ") + 8; + this->buffer_size_ = ACE_OS::strtol (size_str, 0, 10); + size_str = ACE_OS::strstr (text,"showing first "); + if (size_str != 0) + { + size_str += 14; + this->buffer_size_ = ACE_OS::strtol (size_str, 0, 10); + } + if (this->octets_ != 0) + { + delete [] this->octets_; + } + this->octets_ = new char [this->buffer_size_]; + ACE_OS::memset (this->octets_, 0, this->buffer_size_); + this->wr_pos_ = this->octets_; +} + +GIOP_Buffer::~GIOP_Buffer(void) +{ + delete [] this->octets_; +} + +int +GIOP_Buffer::add_octets (const char *text, size_t offset) +{ + if (this->octets_ == 0) + { + this->init_buf(text, offset); + return 0; + } + + const char *c = text; + char *err; + for (int count = 0; + count < 16 && this->cur_size() < this->buffer_size_; + count++) + { + if (count == 8) + ++c; + int o = ::strtol(c, &err, 16); + if (err == c || *err == 0) + return -1; + *this->wr_pos_++ = o; + c = err+1; + } + size_t cs = this->cur_size(); + int rtn = 0; + if (!this->header_parsed_) + { + this->header_parsed_ = this->parse_header(); + if (this->header_parsed_ ) + rtn = 1; + } + if (cs == this->buffer_size_) + { + char vmaj = this->octets_[4]; + char order = this->octets_[6]; + + delete this->cdr_; + this->cdr_ = new ACE_InputCDR (this->octets_, + this->cur_size(), + order, vmaj, this->ver_minor_); + this->cdr_->skip_bytes (this->payload_start_ - this->octets_); + rtn = -1; + } + return rtn; +} + +bool +GIOP_Buffer::sending (void) const +{ + return this->sending_; +} + +bool +GIOP_Buffer::is_full (void) const +{ + return this->buffer_size_ > 0 && this->cur_size() == this->buffer_size_; +} + +char +GIOP_Buffer::type (void) const +{ + if (this->octets_ == 0) + return 127; + return this->octets_[7]; +} + +char +GIOP_Buffer::expected_type (void) const +{ + return this->expected_type_; +} + +char +GIOP_Buffer::minor_version (void) const +{ + return this->ver_minor_; +} + +size_t +GIOP_Buffer::reply_status (void) const +{ + return this->reply_status_; +} + +size_t +GIOP_Buffer::num_contexts (void) const +{ + return this->num_contexts_; +} + +bool +GIOP_Buffer::is_oneway (void) +{ + if (this->octets_ == 0) + { + return false; + } + + if (!this->header_parsed_) + this->header_parsed_ = this->parse_header(); + + return (resp_exp_ &1) == 0; +} + +size_t +GIOP_Buffer::log_posn (void) const +{ + return this->log_offset_; +} + +Thread * +GIOP_Buffer::thread (void) +{ + return this->thr_; +} + +time_t +GIOP_Buffer::time (void) const +{ + return this->time_; +} + +const ACE_CString & +GIOP_Buffer::preamble (void) const +{ + return this->preamble_; +} + +size_t +GIOP_Buffer::expected_size (void) const +{ + return this->expected_size_; +} + +size_t +GIOP_Buffer::msg_size (void) +{ + if (this->cur_size() < 12) + return 0; + if (!this->header_parsed_) + this->header_parsed_ = this->parse_header(); + return this->msg_size_; +} + +size_t +GIOP_Buffer::expected_req_id (void) const +{ + return this->expected_req_id_; +} + +size_t +GIOP_Buffer::actual_req_id (void) +{ + if (this->octets_ == 0) + return 0; + + if (!this->header_parsed_) + this->header_parsed_ = this->parse_header(); + + return this->req_id_; +} + +size_t +GIOP_Buffer::cur_size (void) const +{ + return this->wr_pos_ - this->octets_; +} + +bool +GIOP_Buffer::parse_svc_contexts (void) +{ + ACE_CDR::ULong temp; + ACE_CDR::ULong num_svc_cont; + if ( !(*this->cdr_ >> num_svc_cont)) + return false; + this->num_contexts_ = static_cast<size_t>(num_svc_cont); + while (num_svc_cont > 0) + { + if (!(*this->cdr_ >> temp)) // tag really + return false; + if (!(*this->cdr_ >> temp)) + return false; + if (!this->cdr_->skip_bytes(temp)) + return false; + --num_svc_cont; + } + return true; +} + +bool +GIOP_Buffer::parse_header (void) +{ + if (this->octets_ == 0 || this->cur_size() < 12) + { + return false; + } + + char vmaj = this->octets_[4]; + this->ver_minor_ = this->octets_[5]; + char order = this->octets_[6]; + + char mtype = this->octets_[7]; + if (mtype > 1) // not a request or reply + return false; + + delete this->cdr_; + this->cdr_ = new ACE_InputCDR (this->octets_, + this->cur_size(), + order, vmaj, this->ver_minor_); + this->cdr_->skip_bytes (8); + this->payload_start_ = this->cdr_->rd_ptr(); + ACE_CDR::ULong len_ulong; + if (!(*this->cdr_ >> len_ulong)) + return false; + this->msg_size_ = len_ulong; + + if (this->ver_minor_ < 2) + { + if (!this->parse_svc_contexts()) + return false; + } + + if (!(*this->cdr_ >> len_ulong)) + return false; + this->req_id_ = static_cast<size_t>(len_ulong); + + switch (mtype) { + case 0: //Request + if (!(*this->cdr_ >> this->resp_exp_)) + return false; + if (this->ver_minor_ > 1 && + !(*this->cdr_ >> len_ulong)) // address disposition + return false; + if (!(*this->cdr_ >> len_ulong)) + return false; + this->oid_len_ = static_cast<size_t>(len_ulong); + this->oid_ = this->cdr_->rd_ptr(); + if (!this->cdr_->skip_bytes(len_ulong)) + return false; + + if (!(*this->cdr_ >> len_ulong)) + return false; + this->opname_ = this->cdr_->rd_ptr(); + if (!this->cdr_->skip_bytes(len_ulong)) + return false; + break; + case 1: //Reply + if (!(*this->cdr_ >> len_ulong)) + return false; + this->reply_status_ = static_cast<size_t>(len_ulong); + break; + default: + return true; + } + if (this->ver_minor_ > 1) + { + if (!this->parse_svc_contexts()) + return false; + } + this->cdr_->align_read_ptr (8); + this->payload_start_ = this->cdr_->rd_ptr(); + return true; +} + +const char * +GIOP_Buffer::target_oid (size_t &len) +{ + if (this->octets_ == 0) + { + return 0; + } + + if (!this->header_parsed_) + this->header_parsed_ = this->parse_header(); + + if (this->oid_ == 0) + return 0; + + len = this->oid_len_; + return this->oid_; +} + +const char * +GIOP_Buffer::operation (void) +{ + if (octets_ == 0) + return 0; + + if (!this->header_parsed_) + this->header_parsed_ = this->parse_header(); + + return this->opname_; +} + +ACE_InputCDR & +GIOP_Buffer::payload (void) +{ + if (octets_ != 0 && !this->header_parsed_) + this->header_parsed_ = this->parse_header(); + return *this->cdr_; +} + +bool +GIOP_Buffer::has_octets (void) const +{ + return (octets_ != 0); +} + +bool +GIOP_Buffer::validate (void) +{ + return + this->expected_req_id_ == this->actual_req_id() && + this->expected_type_ == this->type() && + this->expected_size_ == this->msg_size(); +} + +bool +GIOP_Buffer::matches (GIOP_Buffer *other) const +{ + if (other->header_parsed_) + return this->expected_req_id_ == other->actual_req_id() && + this->expected_type_ == other->type() && + this->expected_size_ == other->msg_size(); + else + return this->expected_req_id_ == other->expected_req_id() && + this->expected_type_ == other->expected_type() && + this->sending_ == other->sending() && + this->expected_size_ == other->expected_size(); +} + +void +GIOP_Buffer::reset (void) +{ + this->octets_ = 0; + this->wr_pos_ = 0; + this->buffer_size_ = 0; + this->buffer_lost_ = true; + this->header_parsed_ = false; + this->opname_ = 0; +} + +void +GIOP_Buffer::transfer_from (GIOP_Buffer *other) +{ + delete this->octets_; + this->octets_ = other->octets_; + this->wr_pos_ = other->wr_pos_; + this->buffer_size_ = other->buffer_size_; + this->header_parsed_ = false; + other->reset(); +} + +void +GIOP_Buffer::swap (GIOP_Buffer *other) +{ + char *tmp_octets = this->octets_; + char *tmp_wr_pos = this->wr_pos_; + size_t tmp_size = this->buffer_size_; + + this->octets_ = other->octets_; + this->wr_pos_ = other->wr_pos_; + this->buffer_size_ = other->buffer_size_; + + other->octets_ = tmp_octets; + other->wr_pos_ = tmp_wr_pos; + other->buffer_size_ = tmp_size; +} diff --git a/TAO/utils/logWalker/GIOP_Buffer.h b/TAO/utils/logWalker/GIOP_Buffer.h new file mode 100644 index 00000000000..1e1386374c5 --- /dev/null +++ b/TAO/utils/logWalker/GIOP_Buffer.h @@ -0,0 +1,117 @@ +// -*- C++ -*- + +// $Id$ +// + +#ifndef LOG_WALKER_GIOP_BUFFER_H +#define LOG_WALKER_GIOP_BUFFER_H + +#include "ace/SString.h" +#include "ace/CDR_Stream.h" + +class Invocation; +class Thread; + +// Invocation holds the buffer contents for a request/response pair. +// This could be originating in this process, or in the peer process. +// +// The trigger for finding a new outgoing invocation is "Muxed_TMS[%d]" +// following that the process/thread will perform a dump_msg. +// +// The trigger for finding a new incoming invocation is +// "Transport[%d]::process_parsed_messages, entering (missing data == 0)" +// which could indicate a new request or reply, depending on the context +// in which the peer connection is made. +// +// It is possible that two or more threads may call dump_msg +// concurrently and thus have the preamble and body printed out of +// order. The HEXDUMP always reports a buffer size including the 12 +// byte GIOP header. Also, the first line of the text contains header +// data which can be compared to the expected request ID. + +class GIOP_Buffer +{ +public: + + static const char *size_leadin; + static size_t leadin_len; + static const size_t giop_header_len; + static void init_leadin (int version); + + GIOP_Buffer (const char *text, + size_t offset, + Thread *thread, + Invocation *owner = 0); + GIOP_Buffer (void); + ~GIOP_Buffer (void); + + void owner (Invocation *); + Invocation *owner (void); + + void init_buf (const char *text, size_t offset); + int add_octets(const char *text, size_t offset); + char type (void) const; + char expected_type (void) const; + bool sending (void) const; + char minor_version (void) const; + size_t reply_status (void) const; + size_t num_contexts (void) const; + bool is_oneway (void); + bool is_full (void) const; + size_t log_posn (void) const; + Thread *thread (void); + time_t time (void) const; + + const ACE_CString &preamble(void) const; + size_t expected_req_id(void) const; + size_t actual_req_id(void); + + size_t expected_size (void) const; + size_t buf_size (void) const; + size_t cur_size(void) const; + size_t msg_size (void); + + const char * target_oid (size_t &len); + const char * operation (void); + ACE_InputCDR &payload (void); + + bool has_octets (void) const; + bool validate (void); + bool matches (GIOP_Buffer *other) const; + + void reset (void); + void transfer_from (GIOP_Buffer *other); + void swap (GIOP_Buffer *other); + +private: + bool parse_svc_contexts (void); + bool parse_header (void); + + ACE_InputCDR *cdr_; + ACE_CString preamble_; + size_t log_offset_; + Thread *thr_; + time_t time_; + size_t expected_req_id_; + size_t expected_size_; + char expected_type_; + size_t buffer_size_; + char * wr_pos_; + char * octets_; + Invocation *owner_; + bool buffer_lost_; + bool sending_; + char * oid_; + size_t oid_len_; + char * opname_; + size_t req_id_; + char resp_exp_; + size_t reply_status_; + char ver_minor_; + size_t msg_size_; + size_t num_contexts_; + bool header_parsed_; + char * payload_start_; +}; + +#endif // LOG_WALKER_GIOP_BUFFER_H diff --git a/TAO/utils/logWalker/HostProcess.cpp b/TAO/utils/logWalker/HostProcess.cpp index d68d518bfd8..6f9988c163b 100644 --- a/TAO/utils/logWalker/HostProcess.cpp +++ b/TAO/utils/logWalker/HostProcess.cpp @@ -9,16 +9,10 @@ PeerNode::PeerNode (long h, PeerProcess *p) :handle_ (h), - peer_ (p), - closed_ (false) + peer_ (p) { } -PeerNode::~PeerNode (void) -{ - delete peer_; -} - HostProcess::HostProcess (const ACE_CString &src, long pid) : pid_(pid), logfile_name_(src) @@ -39,24 +33,15 @@ HostProcess::~HostProcess (void) { delete reinterpret_cast<Thread *>(i.next()->item_); } - - for (PeerArray::ITERATOR i(this->by_handle_); !i.done(); i++) +#if 0 + for (PeerProcs::ITERATOR i = by_addr_.begin(); i != servers_.end(); i++) { - ACE_DLList_Node *entry; + PeerProcs::ENTRY *entry; if (i.next(entry) == 0) break; - //i.remove (); - - PeerNode *node = reinterpret_cast<PeerNode*>(entry->item_); - PeerProcess *pp = node->peer_; - const ACE_CString &addr = pp->is_server() ? - pp->server_addr() : pp->last_client_addr(); - this->by_addr_.unbind (addr); - delete node; + delete entry->item(); } - - this->by_addr_.close(); - +#endif } void @@ -72,7 +57,7 @@ HostProcess::proc_name (void) const } Thread * -HostProcess::find_thread (long tid) +HostProcess::find_thread (long tid, size_t offset) { Thread *thr = 0; for (ACE_DLList_Iterator<Thread> i(threads_); @@ -86,12 +71,31 @@ HostProcess::find_thread (long tid) char alias[20]; ACE_OS::sprintf (alias,"Thread[" ACE_SIZE_T_FORMAT_SPECIFIER_ASCII "]", this->threads_.size() + 1); - thr = new Thread (tid, alias); + thr = new Thread (tid, alias, offset); threads_.insert_tail (thr); return thr; } Thread * +HostProcess::find_thread_for_peer (const ACE_CString &addr, Session &session) +{ + Thread *thr = 0; + for (ACE_DLList_Iterator<Thread> i(threads_); + !i.done(); + i.advance()) + { + i.next(thr); + PeerProcess *pp = thr->pending_peer(); + if (pp == 0) + continue; + + if (pp->match_server_addr(addr, session)) + return thr; + } + return 0; +} + +Thread * HostProcess::find_thread_for_handle (long h) { Thread *thr = 0; @@ -115,8 +119,8 @@ HostProcess::find_peer (const ACE_CString &addr) return pp; } -PeerNode * -HostProcess::find_peer_i (long h) +PeerProcess * +HostProcess::find_peer (long h) { if (this->by_handle_.size() == 0) return 0; @@ -126,19 +130,8 @@ HostProcess::find_peer_i (long h) { PeerNode *node = reinterpret_cast<PeerNode *>(i.next()->item_); if (node->handle_ == h) - return node; + return node->peer_; } - - return 0; -} - - -PeerProcess * -HostProcess::find_peer (long h, bool ignore_closed) -{ - PeerNode *node = this->find_peer_i (h); - if (node != 0 && !(ignore_closed && node->closed_) ) - return node->peer_; return 0; } @@ -181,8 +174,8 @@ void HostProcess::add_peer(long handle, PeerProcess *peer) { peer->set_owner (this); - PeerNode *node = this->find_peer_i(handle); - if (node != 0 && !node->closed_ ) + PeerProcess *existing = this->find_peer(handle); + if (existing != 0) { ACE_DEBUG ((LM_DEBUG, "add_peer, found existing for %d\n", @@ -190,29 +183,16 @@ HostProcess::add_peer(long handle, PeerProcess *peer) } const ACE_CString &addr = peer->is_server() ? peer->server_addr() : peer->last_client_addr(); - errno = 0; - int result = this->by_addr_.bind (addr,peer); - if (result == -1) - { - ACE_ERROR ((LM_ERROR,"add_peer, cannot bind handle %d to addr %s %p\n", - handle, addr.c_str(), "by_addr_.bind")); - } + if (result < 0) + ACE_ERROR ((LM_ERROR,"add_peer, cannot bind to addr %s result = %d, %p\n", addr.c_str(), result, "by_addr_.bind")); - if (node == 0) - { - node = new PeerNode (handle,peer); - this->by_handle_.insert_tail(node); - } - else - { - node->closed_ = false; - node->peer_ = peer; - } + PeerNode *node = new PeerNode (handle,peer); + this->by_handle_.insert_tail(node); } void -HostProcess::close_peer(long h) +HostProcess::remove_peer(long h) { if (this->by_handle_.size() == 0) return; @@ -223,7 +203,7 @@ HostProcess::close_peer(long h) PeerNode *node = reinterpret_cast<PeerNode *>(i.next()->item_); if (node->handle_ == h) { - node->closed_ = true; + this->by_handle_.remove(i.next()); return; } } @@ -273,7 +253,11 @@ HostProcess::dump_ident (ostream &strm, const char *message) void HostProcess::dump_thread_detail (ostream &strm) { - this->dump_ident (strm, " thread details:"); + this->dump_ident (strm, "thread details:"); + long total_sent = 0; + long total_recv = 0; + size_t total_bytes_sent = 0; + size_t total_bytes_recv = 0; for (ACE_DLList_Iterator <Thread> t_iter (this->threads_); !t_iter.done(); t_iter.advance()) @@ -281,13 +265,16 @@ HostProcess::dump_thread_detail (ostream &strm) Thread *thr = 0; t_iter.next(thr); thr->dump_detail (strm); + thr->get_summary (total_recv, total_sent, total_bytes_recv, total_bytes_sent); } + strm << "Total requests sent: " << total_sent << " received: " << total_recv << endl; + strm << "Total requests bytes sent: " << total_bytes_sent << " received: " << total_bytes_recv << endl; } void HostProcess::dump_thread_invocations (ostream &strm) { - this->dump_ident (strm, " invocations by thread:"); + this->dump_ident (strm, "invocations by thread:"); for (ACE_DLList_Iterator <Thread> t_iter (this->threads_); !t_iter.done(); t_iter.advance()) @@ -345,7 +332,7 @@ HostProcess::iterate_peers (int group, void HostProcess::dump_peer_detail (ostream &strm) { - this->dump_ident (strm, " peer processes:"); + this->dump_ident (strm, "peer processes:"); size_t num_servers = 0; size_t num_clients = 0; strm << " total peers: " << this->by_addr_.current_size() << endl; @@ -372,16 +359,16 @@ HostProcess::dump_peer_detail (ostream &strm) void HostProcess::dump_object_detail (ostream &strm) { - this->dump_ident (strm, " peer objects: "); + this->dump_ident (strm, "peer objects: "); this->iterate_peers (3, 1, &strm); } void HostProcess::dump_invocation_detail(ostream &strm) { - this->dump_ident (strm, " invocations: "); + this->dump_ident (strm, "invocations: "); this->iterate_peers (3, 2, &strm); - this->dump_ident (strm, " end invocation report"); + this->dump_ident (strm, "end invocation report"); } void diff --git a/TAO/utils/logWalker/HostProcess.h b/TAO/utils/logWalker/HostProcess.h index d92e9dd2630..5cd9f65b8a4 100644 --- a/TAO/utils/logWalker/HostProcess.h +++ b/TAO/utils/logWalker/HostProcess.h @@ -27,10 +27,8 @@ class Thread; struct PeerNode { PeerNode (long h, PeerProcess *p); - ~PeerNode (void); long handle_; PeerProcess *peer_; - bool closed_; }; typedef ACE_DLList<Thread> ThreadList; @@ -57,7 +55,10 @@ public: // Returns a thread instance based on thread id. Will create an instance // as needed. - Thread * find_thread (long tid); + Thread * find_thread (long tid, size_t offset); + + // Returns a thread that has a pending peer with the supplied address + Thread * find_thread_for_peer (const ACE_CString& addr, Session &session); // Returns a thread that had previously worked with handle h. May return // a null pointer. @@ -85,9 +86,12 @@ public: // locate a peer process by handle or address PeerProcess *find_peer (const ACE_CString& addr); - PeerProcess *find_peer (long handle, bool ignore_closed); + PeerProcess *find_peer (long handle); + + void remove_peer (long handle); - void close_peer (long handle); + // remove a peer by handle, noting the line. + void close_peer (long handle, size_t offset); // various output methods void dump_ident (ostream &strm, const char *extra); @@ -103,8 +107,6 @@ public: void reconcile_peers (Session *session); private: - PeerNode *find_peer_i (long handle); - void iterate_peers (int group, int operation, ostream *strm = 0, diff --git a/TAO/utils/logWalker/Invocation.cpp b/TAO/utils/logWalker/Invocation.cpp index 7e8dc980154..27ed20d7da8 100644 --- a/TAO/utils/logWalker/Invocation.cpp +++ b/TAO/utils/logWalker/Invocation.cpp @@ -1,6 +1,7 @@ // $Id$ #include "Invocation.h" +#include "GIOP_Buffer.h" #include "PeerProcess.h" #include "PeerObject.h" #include "Session.h" @@ -8,518 +9,19 @@ #include "Thread.h" #include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" #include "ace/Log_Msg.h" -#include <stdio.h> - -static const char *size_leadin_1_5 = "GIOP v1."; //"x msg, "; -static size_t leadin_len_1_5 = 15; -static const char *size_leadin_1_6 = "GIOP message v1."; //2, "; -static size_t leadin_len_1_6 = 19; - - -static const char *size_leadin = 0; -static size_t leadin_len = 0; -static const size_t giop_header_len = 12; - -static const int date_format = 2; - -// GIOP 1.2 header: 12 bytes -// Magic: 4 -// ver: 2 -// flags: 1 // bo -// type: 1 // req/repl/lf/excp -// len: 4 -// -// Request 1.2 header: -// req_id: 4 -// flags: 1 -// RESVD: 3 -// Address disposition: 4 -// target: <4 len, + len> [0-3 pad] -// opname: <4 len, + len> - -// GIOP 1.0 header: 12 bytes -// Magic: 4 -// ver: 2 -// byte_order: 1 -// type: 1 // req/repl/lf/excp -// len: 4 -// -// Request 1.0 header: -/* -struct RequestHeader_1_0 { // Renamed from RequestHeader - IOP::ServiceContextList service_context; - unsigned long request_id; - boolean response_expected; - sequence <octet> object_key; - string operation; - CORBA::OctetSeq requesting_principal; -}; -*/ -// service_context: 4(count)+contexts. -// context id: 4 -// content blob: 4(len) + len octets + (0-3)pad -// request_id: 4 -// respexp: 1 -// RESVD: 3 -// Address disposition: 4 -// target: <4 len, + len> [0-3 pad] -// opname: <4 len, + len> - -/* -struct ReplyHeader_1_0 { // Renamed from ReplyHeader - IOP::ServiceContextList service_context; - unsigned long request_id; - ReplyStatusType_1_0 reply_status; - }; - // GIOP 1.1 - typedef ReplyHeader_1_0 ReplyHeader_1_1; - // Same Header contents for 1.0 and 1.1 -#else - // GIOP 1.2, 1.3 - enum ReplyStatusType_1_2 { - NO_EXCEPTION, - USER_EXCEPTION, - SYSTEM_EXCEPTION, - LOCATION_FORWARD, - LOCATION_FORWARD_PERM,// new value for 1.2 - NEEDS_ADDRESSING_MODE // new value for 1.2 - }; - struct ReplyHeader_1_2 { - unsigned long request_id; - ReplyStatusType_1_2 reply_status; - IOP::ServiceContextList service_context; - }; - - */ - - - -static const size_t target_offset_12 = giop_header_len + 12; - -// 12 = req_id + flags + RESVD + addr disp. - -Invocation::GIOP_Buffer::GIOP_Buffer(const char *text, - size_t offset, - Thread *thread, - Invocation *owner) - : preamble_(text), - log_offset_(offset), - thr_(thread), - time_(0), - expected_req_id_(0), - expected_size_(0), - expected_type_(0), - size_(0), - wr_pos_ (0), - octets_ (0), - owner_ (owner), - buffer_lost_ (false), - sending_(false), - oid_ (0), - oid_len_ (0), - opname_ (0), - req_id_ (0), - resp_exp_ (0), - reply_status_ (0), - ver_minor_ (0), - num_contexts_ (0), - header_parsed_ (false) -{ - const char *size_str = ACE_OS::strstr(text, size_leadin) + leadin_len; - const char *id = size_str == 0 ? 0 : ACE_OS::strchr(size_str, '[') + 1; - this->sending_ = ACE_OS::strstr(text,"send") ? 0 : 1; - this->expected_type_ = ACE_OS::strstr(text,"Request") ? 0 : 1; - this->expected_size_ = ACE_OS::strtol(size_str, 0,10) + giop_header_len; - this->expected_req_id_ = ACE_OS::strtol(id, 0, 10); - const char *time_tok = ACE_OS::strchr (text,'@'); - if (time_tok != 0) - { - char timebuf[30]; - ACE_OS::strncpy(timebuf, text, (time_tok - text)); - timebuf[time_tok - text] = 0; - char *hms = ACE_OS::strchr (timebuf,' '); - if (Session::date_format() == 2) // MMM DD hh:mm:ss.msec YYYY - { - if (hms != 0) - hms = ACE_OS::strchr (hms+1,' '); - } - - if (hms != 0) - { - int hr, min, sec, msec; - ::sscanf (hms+1,"%d:%d:%d.%d", &hr, &min, &sec, &msec); - this->time_ = (hr * 3600 + min *60 + sec) * 1000 + msec; - } - } -} - -void -Invocation::GIOP_Buffer::owner (Invocation *owner) -{ - this->owner_ = owner; -} - -Invocation * -Invocation::GIOP_Buffer::owner (void) -{ - return this->owner_; -} - -void -Invocation::GIOP_Buffer::init_buf (const char *text) -{ - // GIOP message - HEXDUMP - const char * size_str = ACE_OS::strstr(text,"HEXDUMP ") + 8; - this->size_ = ACE_OS::strtol(size_str, 0,10); - size_str = ACE_OS::strstr(text,"showing first "); - if (size_str != 0) - { - size_str += 14; - this->size_ = ACE_OS::strtol(size_str, 0, 10); - } - this->octets_ = new char [this->size_]; - ACE_OS::memset(this->octets_,0,this->size_); - this->wr_pos_ = this->octets_; -} - -Invocation::GIOP_Buffer::~GIOP_Buffer(void) -{ - delete [] this->octets_; -} - -int -Invocation::GIOP_Buffer::add_octets(const char *text) -{ - if (this->octets_ == 0) - { - this->init_buf(text); - return 0; - } - - const char *c = text; - char *err; - for (int count = 0; count < 16 && this->cur_size() < this->size_; count++) - { - if (count == 8) - ++c; - int o = ::strtol(c, &err, 16); - if (err == c || *err == 0) - return -1; - *this->wr_pos_++ = o; - c = err+1; - } - size_t cs = this->cur_size(); - if (cs == this->size_) - return -1; - else - if (!this->header_parsed_) - { - this->header_parsed_ = this->parse_header(); - if (this->header_parsed_ ) - return 1; - } - return 0; -} - -bool -Invocation::GIOP_Buffer::sending (void) const -{ - return this->sending_; -} - -bool -Invocation::GIOP_Buffer::is_full(void) const -{ - return this->size_ > 0 && this->cur_size() == this->size_; -} - -char -Invocation::GIOP_Buffer::type (void) const -{ - if (this->octets_ == 0) - return 127; - return this->octets_[7]; -} - -char -Invocation::GIOP_Buffer::expected_type (void) const -{ - return this->expected_type_; -} - -char -Invocation::GIOP_Buffer::minor_version (void) const -{ - return this->ver_minor_; -} - -char -Invocation::GIOP_Buffer::reply_status (void) const -{ - return this->reply_status_; -} - -size_t -Invocation::GIOP_Buffer::num_contexts (void) const -{ - return this->num_contexts_; -} - -bool -Invocation::GIOP_Buffer::is_oneway(void) -{ - if (this->octets_ == 0) - { - return false; - } - - if (!this->header_parsed_) - this->header_parsed_ = this->parse_header(); - - return (resp_exp_ &1) == 0; -} - -size_t -Invocation::GIOP_Buffer::log_posn (void) const -{ - return this->log_offset_; -} - -Thread * -Invocation::GIOP_Buffer::thread (void) -{ - return this->thr_; -} - -time_t -Invocation::GIOP_Buffer::time (void) const -{ - return this->time_; -} - -const ACE_CString & -Invocation::GIOP_Buffer::preamble(void) const -{ - return this->preamble_; -} - -size_t -Invocation::GIOP_Buffer::expected_size (void) const -{ - return this->expected_size_; -} - -size_t -Invocation::GIOP_Buffer::size(void) const -{ - return this->size_; -} - -size_t -Invocation::GIOP_Buffer::expected_req_id(void) const -{ - return this->expected_req_id_; -} - -size_t -Invocation::GIOP_Buffer::actual_req_id(void) -{ - if (this->octets_ == 0) - return 0; - - if (!this->header_parsed_) - this->header_parsed_ = this->parse_header(); - - return this->req_id_; -} - -size_t -Invocation::GIOP_Buffer::cur_size(void) const -{ - return this->wr_pos_ - this->octets_; -} - -bool -Invocation::GIOP_Buffer::parse_svc_contexts (ACE_InputCDR &cdr) -{ - ACE_CDR::ULong temp; - ACE_CDR::ULong num_svc_cont; - if ( !(cdr >> num_svc_cont)) - return false; - this->num_contexts_ = static_cast<size_t>(num_svc_cont); - while (num_svc_cont > 0) - { - if (!(cdr >> temp)) // tag really - return false; - if (!(cdr >> temp)) - return false; - if (!cdr.skip_bytes(temp)) - return false; - --num_svc_cont; - } - return true; -} - -bool -Invocation::GIOP_Buffer::parse_header (void) -{ - if (this->octets_ == 0) - { - return false; - } - - char vmaj = this->octets_[4]; - this->ver_minor_ = this->octets_[5]; - char bo = this->octets_[6]; - - char mtype = this->octets_[7]; - if (mtype > 1) // not a request or reply - return false; - - ACE_InputCDR cdr(this->octets_ + giop_header_len, - this->cur_size() - giop_header_len, - bo, vmaj, this->ver_minor_); - - ACE_CDR::ULong len_ulong; - - if (this->ver_minor_ < 2) - { - if (!this->parse_svc_contexts(cdr)) - return false; - } - - if (!(cdr >> len_ulong)) - return false; - this->req_id_ = static_cast<size_t>(len_ulong); - - switch (mtype) { - case 0: //Request - if (!(cdr >> this->resp_exp_)) - return false; - if (this->ver_minor_ > 1 && - !(cdr >> len_ulong)) // address disposition - return false; - if (!(cdr >> len_ulong)) - return false; - this->oid_len_ = static_cast<size_t>(len_ulong); - this->oid_ = cdr.rd_ptr(); - if (!cdr.skip_bytes(len_ulong)) - return false; - - if (!(cdr >> len_ulong)) - return false; - this->opname_ = cdr.rd_ptr(); - if (!cdr.skip_bytes(len_ulong)) - return false; - break; - case 1: //Reply - if (!(cdr >> len_ulong)) - return false; - this->reply_status_ = static_cast<size_t>(len_ulong); - break; - default: - return false; - } - if (this->ver_minor_ > 1) - { - if (!this->parse_svc_contexts(cdr)) - return false; - } - - return true; -} - -const char * -Invocation::GIOP_Buffer::target_oid(size_t &len) -{ - if (this->octets_ == 0) - { - return 0; - } - - if (!this->header_parsed_) - this->header_parsed_ = this->parse_header(); - - if (this->oid_ == 0) - return 0; - - len = this->oid_len_; - return this->oid_; -} - -const char * -Invocation::GIOP_Buffer::operation(void) -{ - if (octets_ == 0) - return 0; - - if (!this->header_parsed_) - this->header_parsed_ = this->parse_header(); - - return this->opname_; -} - -bool -Invocation::GIOP_Buffer::validate (void) -{ - return this->expected_req_id_ == this->actual_req_id() && - this->expected_type_ == this->type(); -} - -bool -Invocation::GIOP_Buffer::matches (Invocation::GIOP_Buffer *other) const -{ - return this->expected_req_id_ == other->actual_req_id() && - this->expected_type_ == other->type() && - this->expected_size_ == other->size(); -} - -void -Invocation::GIOP_Buffer::reset (void) -{ - this->octets_ = 0; - this->wr_pos_ = 0; - this->size_ = 0; - this->buffer_lost_ = true; -} - -void -Invocation::GIOP_Buffer::transfer_from (GIOP_Buffer *other) -{ - delete this->octets_; - this->octets_ = other->octets_; - this->wr_pos_ = other->wr_pos_; - this->size_ = other->size_; - other->reset(); -} - - -//---------------------------------------------------------------------------- - - -Invocation::Invocation (PeerProcess *peer, long handle, size_t rid) +Invocation::Invocation (PeerProcess *peer, Thread *thr, size_t rid) :req_octets_(0), repl_octets_(0), + waiter_ (thr), + notify_incidents_ (), peer_(peer), req_id_(rid), target_(0), - handle_(handle) + handle_(thr->active_handle()) { - if (size_leadin == 0) - { - if (Session::tao_version() == 150) - { - size_leadin = size_leadin_1_5; - leadin_len = leadin_len_1_5; - } - else - { - size_leadin = size_leadin_1_6; - leadin_len = leadin_len_1_6; - } - } } Invocation::~Invocation (void) @@ -531,7 +33,9 @@ Invocation::~Invocation (void) bool Invocation::init (const char * text, size_t offset, Thread *thread) { - const char *size_str = ACE_OS::strstr(text, size_leadin); + if (GIOP_Buffer::size_leadin == 0) + GIOP_Buffer::init_leadin (Session::tao_version()); + const char *size_str = ACE_OS::strstr(text, GIOP_Buffer::size_leadin); const char *id = size_str == 0 ? 0 : ACE_OS::strchr(size_str, '['); if (size_str == 0 || id == 0) { @@ -549,6 +53,12 @@ Invocation::init (const char * text, size_t offset, Thread *thread) return true; } +void +Invocation::add_notify_incident (const ACE_CString &text, size_t /* offset */) +{ + this->notify_incidents_.enqueue_tail (text); +} + bool Invocation::is_oneway(void) const { @@ -584,13 +94,13 @@ Invocation::message_complete (void) return true; } -Invocation::GIOP_Buffer * +GIOP_Buffer * Invocation::octets (bool request) { return request ? this->req_octets_ : this->repl_octets_ ; } -Invocation::GIOP_Buffer * +GIOP_Buffer * Invocation::give_octets (bool request) { GIOP_Buffer *result = request ? this->req_octets_ : this->repl_octets_ ; @@ -624,6 +134,16 @@ Invocation::set_octets (bool request, GIOP_Buffer *octets) octets->owner(this); } +bool +Invocation::sent_request (void) const +{ + if (this->req_octets_) + return this->req_octets_->sending(); + if (this->repl_octets_) + return !this->repl_octets_->sending(); + return false; +} + size_t Invocation::request_id (void) const { @@ -638,6 +158,18 @@ Invocation::expected_size (void) const return req_octets_->expected_size(); } +size_t +Invocation::request_bytes (void) const +{ + return req_octets_ != 0 ? req_octets_->expected_size() : 0; +} + +Thread * +Invocation::waiter (void) const +{ + return this->waiter_; +} + long Invocation::handle (void) const { @@ -661,10 +193,13 @@ Invocation::req_line (void) } void -Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_handle) +Invocation::dump_detail (ostream &strm, + int indent, + Dump_Mode mode, + bool show_handle) { const char *opname = ""; - const char *dir_1 = "to "; + const char *dir_1 = "sent to "; const char *dir_2 = " in "; if (this->req_octets_ != 0) @@ -672,7 +207,7 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha opname = this->req_octets_->operation(); if (this->req_octets_->sending()) { - dir_1 = "for "; + dir_1 = "recv for "; dir_2 = " from "; } } @@ -697,14 +232,15 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha strm << " [" << opname << "]\t"; time_t req_time = 0; time_t rep_time = 0; - long delta = 0; + size_t delta = 0; if (!this->is_oneway() && this->req_octets_ != 0) { req_time = this->req_octets_->time(); if (this->repl_octets_ != 0) { rep_time = this->repl_octets_->time(); - delta = this->repl_octets_->log_posn() - this->req_octets_->log_posn(); + delta = this->repl_octets_->log_posn() - + this->req_octets_->log_posn(); } } if (req_time != 0 && rep_time != 0) @@ -715,6 +251,7 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha strm << " Request, "; if (this->req_octets_->num_contexts() > 0) strm << "with " << this->req_octets_->num_contexts() << " contexts, "; + strm << "size " << this->req_octets_->expected_size() << " "; strm << "line " << this->req_octets_->log_posn(); if (mode == Dump_Thread || mode == Dump_Both) strm << " " << this->req_octets_->thread()->alias(); @@ -729,27 +266,21 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha { strm << " Reply, "; if (this->repl_octets_->num_contexts() > 0) - strm << "with " << this->repl_octets_->num_contexts() << " contexts, "; + strm << "with " << this->repl_octets_->num_contexts() + << " contexts, "; + strm << "size " << this->repl_octets_->expected_size() << " "; strm << "line " << this->repl_octets_->log_posn(); #if defined (SHOW_THREAD_ID) strm << " " << this->repl_octets_->thread()->alias(); #endif char rstat = this->repl_octets_->reply_status(); - switch (rstat) + if (rstat == 1 || rstat == 2) + { + strm << (rstat == 1 ? " User" : " System") << " Exception"; + } + else if (rstat == 3) { - case 0: - break; - case 1: - strm << " User Exception"; - break; - case 2: - strm << " System Exception"; - break; - case 3: strm << " Location Forward"; - break; - default: - strm << " status = " << static_cast<short>(rstat); } } else @@ -757,5 +288,143 @@ Invocation::dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_ha } if (delta > 0) strm << " log span = " << delta; + if (this->req_octets_ != 0 && this->req_octets_->has_octets() && + this->repl_octets_ != 0 && this->repl_octets_->has_octets()) + this->dump_special_details (strm, opname); strm << endl; + if (this->notify_incidents_.size() > 0) + { + for (NotifyIncidents::ITERATOR i = this->notify_incidents_.begin(); + !(i.done()); i.advance()) + { + ACE_CString *note; + i.next(note); + strm << " " << *note << endl; + } + } +} + +void +Invocation::dump_special_details (ostream &strm, const char *opname) +{ + char rstat = this->repl_octets_->reply_status(); + int opid = 0; + if (ACE_OS::strcmp (opname, "_is_a") == 0) + { + opid = 1; + ACE_InputCDR &giop_cdr = this->req_octets_->payload(); + ACE_InputCDR cdr (giop_cdr.rd_ptr(), + giop_cdr.length(), + giop_cdr.byte_order()); + ACE_CDR::ULong len; + if (cdr >> len) + strm << "\n expected type ( len = " << len << ") " + << cdr.rd_ptr(); + } + else if (ACE_OS::strcmp (opname, "_get_MyID") == 0) + { + opid = 2; + } + else if (ACE_OS::strcmp (opname, "resolve_str") == 0) + { + opid = 3; + ACE_InputCDR &giop_cdr = this->req_octets_->payload(); + ACE_InputCDR cdr (giop_cdr.rd_ptr(), + giop_cdr.length(), + giop_cdr.byte_order()); + ACE_CDR::ULong len; + if (cdr >> len) + strm << "\n name len = " << len << ") " << cdr.rd_ptr(); + } + else if (ACE_OS::strcmp (opname, "resolve") == 0 || + ACE_OS::strcmp (opname, "bind") == 0 || + ACE_OS::strcmp (opname, "rebind") == 0 || + ACE_OS::strcmp (opname, "bind_new_context") == 0 + ) + { + opid = 3; + ACE_InputCDR &giop_cdr = this->req_octets_->payload(); + ACE_InputCDR cdr (giop_cdr.rd_ptr(), + giop_cdr.length(), + giop_cdr.byte_order()); + ACE_CDR::ULong count; + if (cdr >> count) + { + strm << "\n name_seq.lengh = " << count << " "; + while (count-- > 0) + { + ACE_CDR::ULong len; + if (!(cdr >> len)) + break; + strm << cdr.rd_ptr(); + if (!cdr.skip_bytes (len)) + break; + if (!(cdr >> len)) + break; + if (len > 1) + { + strm << "." << cdr.rd_ptr(); + } + if (!cdr.skip_bytes (len)) + break; + if (count > 0) + { + strm << "/"; + } + } + if (static_cast<ACE_CDR::Long>(count) > 0) + { + strm << " [name truncated]"; + } + } + } + + + ACE_InputCDR &giop_cdr = this->repl_octets_->payload(); + ACE_InputCDR cdr (giop_cdr.rd_ptr(), + giop_cdr.length(), + giop_cdr.byte_order()); + + if (rstat == 0) + { + switch (opid) + { + case 1: + { + ACE_CDR::Boolean x; + if (cdr >> ACE_InputCDR::to_boolean (x)) + strm << " reply: " << (x ? "yes" : "no"); + break; + } + case 2: + { + ACE_CDR::Long x; + if (cdr >> x) + strm << " \n MyID reply: " << x; + break; + } + default:; + } + } + else + { + if (opid == 0) + { + strm << "\n "; + } + if (rstat == 1 || rstat == 2) + { + strm << " Exception "; + } + else + { + strm << " Redirect to "; + } + ACE_CDR::ULong len; + if (cdr >> len) + { + strm << cdr.rd_ptr(); + } + } + } diff --git a/TAO/utils/logWalker/Invocation.h b/TAO/utils/logWalker/Invocation.h index 0594a79665f..107a513652d 100644 --- a/TAO/utils/logWalker/Invocation.h +++ b/TAO/utils/logWalker/Invocation.h @@ -8,10 +8,14 @@ #include "ace/SString.h" #include "ace/CDR_Stream.h" +#include "ace/Unbounded_Queue.h" class PeerProcess; class PeerObject; class Thread; +class GIOP_Buffer; + +typedef ACE_Unbounded_Queue<ACE_CString> NotifyIncidents; // Invocation holds the buffer contents for a request/response pair. // This could be originating in this process, or in the peer process. @@ -33,68 +37,6 @@ class Thread; class Invocation { public: - class GIOP_Buffer - { - public: - GIOP_Buffer (const char *text, size_t offset, Thread *thread, Invocation *owner = 0); - ~GIOP_Buffer (void); - void owner (Invocation *); - Invocation *owner (void); - void init_buf (const char *text); - int add_octets(const char *text); - char type (void) const; - char expected_type (void) const; - bool sending (void) const; - char minor_version (void) const; - char reply_status (void) const; - size_t num_contexts (void) const; - bool is_oneway (void); - bool is_full (void) const; - size_t log_posn (void) const; - Thread *thread (void); - time_t time (void) const; - - const ACE_CString &preamble(void) const; - size_t expected_req_id(void) const; - size_t actual_req_id(void); - size_t expected_size (void) const; - size_t size (void) const; - size_t cur_size(void) const; - const char * target_oid (size_t &len); - const char * operation (void); - bool validate (void); - bool matches (GIOP_Buffer *other) const; - void reset (void); - void transfer_from (GIOP_Buffer *other); - - private: - bool parse_svc_contexts (ACE_InputCDR& cdr); - bool parse_header (void); - - ACE_CString preamble_; - size_t log_offset_; - Thread *thr_; - time_t time_; - size_t expected_req_id_; - size_t expected_size_; - char expected_type_; - size_t size_; - char * wr_pos_; - char * octets_; - Invocation *owner_; - bool buffer_lost_; - bool sending_; - char * oid_; - size_t oid_len_; - char * opname_; - size_t req_id_; - char resp_exp_; - size_t reply_status_; - char ver_minor_; - size_t num_contexts_; - bool header_parsed_; - }; - enum Dump_Mode { Dump_Proc, Dump_Thread, @@ -102,15 +44,13 @@ public: }; // initialize a new instance, with the initial request text line and offeset - Invocation (PeerProcess *peer, long handle, size_t req_id = 0); + Invocation (PeerProcess *peer, Thread *thr, size_t req_id = 0); bool init ( const char * text, size_t offset, Thread *thr); ~Invocation (void); // return true if the invocation was a oneway bool is_oneway(void) const; - void set_target (const char *oid, size_t oid_len); - // return true if the request is a oneway and has all its octets, or // if it also has all its reply octets. The side-effect of this call // is to obtain the target reference from the request buffer and associate @@ -119,10 +59,17 @@ public: size_t request_id (void) const; + // returns true if this request was sent by the host process. + bool sent_request (void) const; + // returns the size parsed from either the request or reply preamble // which can be used to match a HEXDUMP b size_t expected_size (void) const; + size_t request_bytes (void) const; + + void set_target (const char *oid, size_t oid_len); + void set_octets (bool request, GIOP_Buffer *octets); GIOP_Buffer *octets (bool request); GIOP_Buffer *give_octets (bool request); @@ -130,14 +77,19 @@ public: bool contains (size_t line); size_t req_line (void); + void add_notify_incident (const ACE_CString &text, size_t offset); + Thread *waiter (void) const; long handle (void) const; void dump_detail (ostream &strm, int indent, Dump_Mode mode, bool show_handle); + void dump_special_details (ostream &strm, const char *opname); private: GIOP_Buffer *req_octets_; GIOP_Buffer *repl_octets_; + Thread *waiter_; + NotifyIncidents notify_incidents_; PeerProcess *peer_; size_t req_id_; PeerObject *target_; diff --git a/TAO/utils/logWalker/Log.cpp b/TAO/utils/logWalker/Log.cpp index 0f2ebfa7889..b54e4e22301 100644 --- a/TAO/utils/logWalker/Log.cpp +++ b/TAO/utils/logWalker/Log.cpp @@ -11,8 +11,15 @@ #include "ace/Mem_Map.h" Log::Log (Session &session) - : session_(session), - dump_target_(0) + : session_ (session), + dump_target_ (0), + history_ (), + timestamp_ (), + line_ (0), + info_ (0), + offset_ (0), + hostproc_ (0), + thr_ (0) { } @@ -21,7 +28,7 @@ Log::~Log (void) } bool -Log::init (const ACE_TCHAR *filename, const char *alias) +Log::process_file (const ACE_TCHAR *filename, const char *alias) { ACE_DEBUG ((LM_DEBUG,"Processing log file %C\n", filename)); @@ -43,13 +50,13 @@ Log::init (const ACE_TCHAR *filename, const char *alias) size_t remainder = mapsize; size_t linelen = 0; - char *line; + char *text; size_t maxline = 1000; char *buffer = new char[maxline]; - size_t line_pos = 1; - while ((line = ACE_OS::strchr(base,'\n')) != 0) + this->offset_ = 1; + while ((text = ACE_OS::strchr(base,'\n')) != 0) { - linelen = line - base; + linelen = text - base; if (linelen >= maxline) { delete [] buffer; @@ -59,9 +66,11 @@ Log::init (const ACE_TCHAR *filename, const char *alias) } ACE_OS::strncpy(buffer,base,linelen); buffer[linelen] = 0; - this->parse_line (buffer, line_pos); - base = line+1; - ++line_pos; + this->line_ = buffer; + if (linelen > 0) + this->parse_line (); + base = text+1; + ++this->offset_; remainder -= linelen; if (remainder < 1) break; @@ -74,115 +83,116 @@ Log::init (const ACE_TCHAR *filename, const char *alias) return true; } -bool -Log::get_pid_tid (long &pid, long &tid, char *line) +void +Log::get_preamble () { - const char * p = ACE_OS::strstr (line, "TAO ("); + char * p = ACE_OS::strstr (this->line_, "("); char * t = 0; + + this->info_ = this->line_; + if (p == 0) - return false; + return; - pid = ACE_OS::strtol(p+5,&t,10); - tid = ACE_OS::strtol(t+1,0,10); - return true; -} + if (p != this->line_) + { + char * x = ACE_OS::strstr (this->line_, "TAO ("); + if (x+4 != p) + { + x = ACE_OS::strstr (this->line_, "@("); + if (x + 1 != p) + return; + } + } -HostProcess * -Log::get_host (long pid) -{ - HostProcess *hp = 0; + + long pid = ACE_OS::strtol(p + 1, &t, 10); if (pid == 0) - return 0; + return; + + long tid = 0; + if ( *t == '|' ) + tid = ACE_OS::strtol(t + 1, 0, 10); + else if ( *t != ')') + return; // not either (pid) or (pid|tid) + + this->info_ = ACE_OS::strstr (p, ")") + 1; + this->hostproc_ = 0; for (ACE_DLList_Iterator<HostProcess> i (this->procs_); !i.done(); i.advance()) { - i.next(hp); - if (hp->pid() == pid) - return hp; + i.next(this->hostproc_); + if (this->hostproc_->pid() == pid) + { + break; + } + this->hostproc_ = 0; } - hp = this->session_.find_process(pid); - if (hp != 0) - return hp; - size_t numprocs = this->procs_.size(); - hp = new HostProcess (this->origin_,pid); - this->procs_.insert_tail(hp); - ACE_CString &procname = this->alias_.length() > 0 ? - this->alias_ : this->origin_; - switch (numprocs) + if (this->hostproc_ == 0) + this->hostproc_ = this->session_.find_process(pid); + + if (this->hostproc_ == 0) { - case 0: - hp->proc_name(procname); - break; - case 1: - { - ACE_CString a2 = procname + "_1"; - HostProcess *first; - if (this->procs_.get(first) == 0) - first->proc_name(a2); - } - //fallthru - default: - { - char ext[10]; - ACE_OS::sprintf(ext,"_" ACE_SIZE_T_FORMAT_SPECIFIER_ASCII,numprocs+1); - ACE_CString a2 = procname + ext; - hp->proc_name(a2); - } - } - - this->session_.add_process(hp); - return hp; + size_t numprocs = this->procs_.size(); + this->hostproc_ = new HostProcess (this->origin_,pid); + this->procs_.insert_tail(this->hostproc_); + ACE_CString &procname = this->alias_.length() > 0 ? + this->alias_ : this->origin_; + switch (numprocs) + { + case 0: + this->hostproc_->proc_name(procname); + break; + case 1: + { + ACE_CString a2 = procname + "_1"; + HostProcess *first; + if (this->procs_.get(first) == 0) + first->proc_name(a2); + } + //fallthru + default: + { + char ext[10]; + ACE_OS::sprintf(ext,"_" ACE_SIZE_T_FORMAT_SPECIFIER_ASCII,numprocs+1); + ACE_CString a2 = procname + ext; + this->hostproc_->proc_name(a2); + } + } + + this->session_.add_process(this->hostproc_); + } + this->thr_ = this->hostproc_->find_thread (tid, this->offset_); + return; } void -Log::handle_msg_dump (char *line, size_t offset) +Log::handle_msg_octets () { - int pos = this->dump_target_->add_octets(line); - if (pos > 0) // need to validate target + int pos = this->dump_target_->add_octets(this->line_, this->offset_); + if (this->dump_target_ == &this->unknown_msg_) { - if (!this->dump_target_->validate()) - { - for (ACE_DLList_Iterator<Thread> t_iter(this->giop_waiters_); - !t_iter.done(); - t_iter.advance()) - { - Thread *th = 0; - t_iter.next(th); - Invocation::GIOP_Buffer *new_target = th->giop_target(); - if (new_target == 0 || new_target == this->dump_target_) - continue; - if (new_target->matches (this->dump_target_)) - { - Thread *tmp_thr = this->dump_target_->thread(); - new_target->transfer_from (this->dump_target_); - this->dump_target_ = new_target; - t_iter.remove(); - this->giop_waiters_.insert_tail (tmp_thr); - break; - } - } - } - else + for (ACE_DLList_Iterator<Thread> t_iter(this->giop_waiters_); + !t_iter.done(); + t_iter.advance()) { - for (ACE_DLList_Iterator<Thread> t_iter(this->giop_waiters_); - !t_iter.done(); - t_iter.advance()) + Thread *th = 0; + t_iter.next(th); + GIOP_Buffer *waiter = th->giop_target(); + if (waiter == 0) + continue; + if (waiter->matches (this->dump_target_)) { - Thread *th = 0; - t_iter.next(th); - if (this->dump_target_ == th->giop_target()) - { - PeerProcess *pp = th->incoming(); - th->exit_wait(pp, offset); - t_iter.remove(); - break; - } + waiter->transfer_from (this->dump_target_); + this->dump_target_ = waiter; + t_iter.remove(); + break; } } } - else if (pos == -1) // done + if (pos == -1) // done { Invocation *inv = this->dump_target_->owner(); if (inv != 0) @@ -192,338 +202,289 @@ Log::handle_msg_dump (char *line, size_t offset) if (oid != 0) inv->set_target (oid, len); } + else + { + if (this->dump_target_ == &this->unknown_msg_) + ACE_ERROR ((LM_ERROR, "%d dump ended with no target owner\n", this->offset_)); + } this->dump_target_ = 0; + this->unknown_msg_.reset(); } } void -Log::parse_HEXDUMP (Log *this_, char *line, size_t offset) +Log::parse_HEXDUMP_i (void) { - Thread *thr = 0; - - char *pos = ACE_OS::strstr (line,"HEXDUMP"); + char *pos = ACE_OS::strstr (this->line_,"HEXDUMP"); pos += 8; - size_t len = ACE_OS::strtol (pos, 0, 10); - for (ACE_DLList_Reverse_Iterator<Thread> t_iter(this_->giop_waiters_); - !t_iter.done(); - t_iter.advance()) - { - t_iter.next(thr); - Invocation::GIOP_Buffer *target = thr->giop_target(); - if (target == 0 || target->expected_size() != len || target->size() > 0) - continue; - this_->dump_target_ = target; - t_iter.remove(); - break; - } - if (this_->dump_target_ == 0) + + if (this->dump_target_ != 0) { ACE_ERROR ((LM_ERROR, - "%d: Could not find a giop waiter for size %d\n", - offset, len)); + "%d: Parse HEXDUMP in the middle of an existing dump\n", + this->offset_)); } else - this_->dump_target_->init_buf (line); + { + this->unknown_msg_.init_buf (this->line_, this->offset_); + this->dump_target_ = &this->unknown_msg_; + } } void -Log::parse_dump_msg (Log *this_, char *line, size_t offset) +Log::parse_dump_giop_msg_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); + int sending = ACE_OS::strstr (this->info_,"send") != 0 ? 0 : 1; + int type = ACE_OS::strstr (this->info_,"Request") != 0 ? 0 : 1; + int mode = sending + type * 2; - int mode = ACE_OS::strstr (line,"send") != 0 ? 0 : 1; - mode += ACE_OS::strstr (line,"Request") != 0 ? 0 : 2; - char *pos = strrchr (line,'['); + char *pos = strrchr (this->info_,'['); long rid = ACE_OS::strtol(pos+1, 0, 10); - PeerProcess *pp = thr->incoming(); + PeerProcess *pp = this->thr_->incoming(); if (pp == 0) { ACE_ERROR((LM_ERROR, "%d: dump_msg, could not find pp for incoming, text = %s\n", - offset, line)); + this->offset_, this->info_)); return; } - Invocation::GIOP_Buffer *target = 0; + GIOP_Buffer *target = 0; switch (mode) { case 1: { // receiving request - thr->handle_request(); - Invocation *inv = pp->new_invocation (rid,thr); + this->thr_->handle_request(); + Invocation *inv = pp->new_invocation (rid, this->thr_); if (inv == 0) { ACE_ERROR ((LM_ERROR, "%d: process %s already has invocation %d\n", - offset, pp->id(), rid)); + this->offset_, pp->id(), rid)); break; } - inv->init (line, offset, thr); + inv->init (this->line_, this->offset_, this->thr_); + this->thr_->push_invocation (inv); target = inv->octets(true); + if (target == 0) + { + ACE_DEBUG ((LM_DEBUG, "%d: no target octets for new recv reqeust, id = %d\n", + this->offset_, rid)); + return; + } break; } case 0: // sending request - thr->enter_wait(pp); + this->thr_->enter_wait(pp); + this->thr_->push_invocation (0); // fall through. case 3: { // receiving reply - Invocation *inv = pp->find_invocation(rid, thr->active_handle()); + Invocation *inv = pp->find_invocation(rid, this->thr_->active_handle()); if (inv == 0) { ACE_ERROR ((LM_ERROR, "%d: could not find existing invocation for req_id %d\n", - offset, rid)); - inv = pp->new_invocation (rid,thr); + this->offset_, rid)); + inv = pp->new_invocation (rid,this->thr_); } - inv->init (line, offset, thr); + inv->init (this->line_, this->offset_, this->thr_); target = inv->octets(mode == 0); if (target == 0 && mode == 3) { ACE_ERROR ((LM_ERROR, "%d: could not map invocation to target for req_id %d\n", - offset, rid)); + this->offset_, rid)); return; } // if (mode == 3) -// thr->exit_wait(pp, offset); +// this->thr_->exit_wait(pp, this->offset_); break; } case 2: { // sending reply - target = new Invocation::GIOP_Buffer(line,offset, thr); + target = new GIOP_Buffer(this->line_, this->offset_, this->thr_); + this->thr_->pop_invocation (); break; } default:; } - thr->set_giop_target (target); - this_->giop_waiters_.insert_tail(thr); - if (this_->giop_waiters_.size() > 1 && (mode == 1 || mode == 3)) + this->thr_->set_giop_target (target); + if (this->giop_waiters_.size() > 0) { - size_t prev_size = 0; - for (ACE_DLList_Reverse_Iterator<Thread> t_iter(this_->giop_waiters_); + Thread *other_thr = 0; + for (ACE_DLList_Iterator<Thread> t_iter(this->giop_waiters_); !t_iter.done(); t_iter.advance()) { - if (prev_size == 0) - prev_size = target->expected_size(); + t_iter.next(other_thr); + GIOP_Buffer *tgt = other_thr->giop_target(); + if (target == 0) + { + ACE_DEBUG ((LM_DEBUG, "%d: parse_dump_giop_msg_i, target is null, mode = %d, reqid = %d\n", + this->offset_, mode, rid)); + return; + } + if (tgt != 0 && this->thr_ != other_thr && target->matches (tgt)) + { + this->thr_->set_dup (other_thr, true); + } } } + this->giop_waiters_.insert_tail(this->thr_); } void -Log::parse_open_listener (Log *this_, char *line, size_t ) +Log::parse_open_listener_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - char *addr = ACE_OS::strchr(line,'<') +1; + char *addr = ACE_OS::strchr(this->info_,'<') +1; char *c = ACE_OS::strchr(addr,'>'); *c = '\0'; ACE_CString server_addr(addr); - hp->add_listen_endpoint(server_addr); + this->hostproc_->add_listen_endpoint(server_addr); } void -Log::parse_got_existing (Log *this_, char *line, size_t offset) +Log::parse_got_existing_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - char *hpos = ACE_OS::strchr(line,'['); + char *hpos = ACE_OS::strchr(this->info_,'['); long handle = ACE_OS::strtol(hpos+1,0,10); - PeerProcess *pp = hp->find_peer(handle, true); + PeerProcess *pp = this->hostproc_->find_peer(handle); if (pp == 0) { ACE_ERROR ((LM_ERROR, "%d: Error parsing %C, can't find peer " "for handle %d, text = %s\n", - offset, this_->origin_.c_str(), handle, line)); + this->offset_, this->origin_.c_str(), handle, this->info_)); return; } - thr->active_handle (handle); + this->thr_->active_handle (handle); } void -Log::parse_muxed_tms (Log *this_, char *line, size_t offset) +Log::parse_muxed_tms_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - char *hpos = ACE_OS::strchr(line,'['); + char *hpos = ACE_OS::strchr(this->info_,'['); long handle = ACE_OS::strtol(hpos+1,0,10); hpos = ACE_OS::strchr(hpos, '<'); long req_id = ACE_OS::strtol(hpos+1,0,10); - PeerProcess *pp = hp->find_peer(handle, true); + PeerProcess *pp = this->hostproc_->find_peer(handle); if (pp == 0) { ACE_ERROR ((LM_ERROR, "%d: Error parsing %C, can't find peer " "for handle %d, text = %s\n", - offset, this_->origin_.c_str(), handle, line)); + this->offset_, this->origin_.c_str(), handle, this->info_)); return; } - thr->active_handle (handle); + this->thr_->active_handle (handle); - Invocation *inv = pp->new_invocation(req_id, thr); + Invocation *inv = pp->new_invocation(req_id, this->thr_); if (inv == 0) ACE_DEBUG ((LM_DEBUG,"%d: peer %s already has invocation id %d\n", - offset, pp->id(), req_id)); - thr->incoming_from (pp); + this->offset_, pp->id(), req_id)); + this->thr_->incoming_from (pp); } void -Log::parse_exclusive_tms (Log *this_, char *line, size_t offset) +Log::parse_exclusive_tms_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - long handle = thr->active_handle(); - PeerProcess *pp = hp->find_peer(handle, true); + long handle = this->thr_->active_handle(); + PeerProcess *pp = this->hostproc_->find_peer(handle); if (pp == 0) { ACE_ERROR ((LM_ERROR, "%d: Error parsing %C, can't find peer " "for handle %d, text = %s\n", - offset, this_->origin_.c_str(), handle, line)); + this->offset_, this->origin_.c_str(), handle, this->info_)); return; } - char *rpos = ACE_OS::strchr(line, '<'); + char *rpos = ACE_OS::strchr(this->info_, '<'); long req_id = ACE_OS::strtol(rpos+1,0,10); - Invocation *inv = pp->new_invocation(req_id, thr); + Invocation *inv = pp->new_invocation(req_id, this->thr_); if (inv == 0) ACE_DEBUG ((LM_DEBUG,"%d: peer %s already has invocation id %d\n", - offset, pp->id(), req_id)); - thr->incoming_from (pp); + this->offset_, pp->id(), req_id)); + this->thr_->incoming_from (pp); } void -Log::parse_process_parsed_msgs (Log *this_, char *line, size_t offset) +Log::parse_process_parsed_msgs_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - char *hpos = ACE_OS::strchr(line,'['); - long handle = ACE_OS::strtol(hpos+1,0,10); + char *hpos = ACE_OS::strchr(this->info_, '['); + long handle = ACE_OS::strtol(hpos+1, 0, 10); - PeerProcess *pp = hp->find_peer(handle, true); + PeerProcess *pp = this->hostproc_->find_peer(handle); if (pp == 0) { ACE_ERROR ((LM_ERROR, "%d: Error parsing %C, can't find peer " "for handle %d, text = %s\n", - offset, this_->origin_.c_str(), handle, line)); - pp = new PeerProcess (offset,true); - Transport *t = new Transport ("<unknown>",false, offset); + this->offset_, this->origin_.c_str(), handle, this->info_)); + pp = new PeerProcess (this->offset_, true); + Transport *t = new Transport ("<unknown>", false, this->offset_); t->handle_ = handle; pp->add_transport(t); - hp->add_peer (handle,pp); + this->hostproc_->add_peer (handle,pp); return; } - thr->active_handle(handle); - thr->incoming_from (pp); + this->thr_->active_handle(handle); + this->thr_->incoming_from (pp); } void -Log::parse_wait_for_event (Log *this_, char *line, size_t offset) +Log::parse_wait_for_event_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); +// char *pos = ACE_OS::strchr (this->info_,'['); +// long rid = ACE_OS::strtol(pos+1, 0, 10); - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); + bool done = (ACE_OS::strstr (this->info_,"done (follower)") != 0) || + (ACE_OS::strstr(this->info_,"(leader) exit") != 0); - PeerProcess *pp = thr->incoming(); + PeerProcess *pp = this->thr_->incoming(); if (pp == 0) + pp = this->thr_->pending_peer(); + if (pp != 0 && done) { - ACE_ERROR((LM_ERROR, - "%d: wait_for_event, could not find peer process for incoming, text = %s\n", - offset, line)); - return; + this->thr_->exit_wait(pp, this->offset_); } - - bool done = (ACE_OS::strstr (line,"done (follower)") != 0) || - (ACE_OS::strstr(line,"(leader) exit") != 0); - - - if (done) - thr->exit_wait(pp, offset); -// else -// thr->enter_wait(pp); } void -Log::parse_wait_on_read (Log *this_, char *line, size_t offset) +Log::parse_wait_on_read_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - PeerProcess *pp = thr->incoming(); - - thr->exit_wait (pp, offset); + PeerProcess *pp = this->thr_->incoming(); + this->thr_->exit_wait (pp, this->offset_); } void -Log::parse_cleanup_queue (Log *this_, char *line, size_t offset) +Log::parse_cleanup_queue_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - char *hpos = ACE_OS::strchr(line,'['); + char *hpos = ACE_OS::strchr(this->info_,'['); long handle = ACE_OS::strtol(hpos+1,0,10); - PeerProcess *pp = hp->find_peer(handle, false); - if (pp == 0) - { - ACE_ERROR ((LM_ERROR, - "%d: cleanup queue, could not find peer for handle %d\n", - offset, handle)); - return; - } + PeerProcess *pp = this->hostproc_->find_peer(handle); - Thread *original_thr = thr; - Invocation::GIOP_Buffer *target = original_thr->giop_target(); + Thread *original_thr = this->thr_; + GIOP_Buffer *target = original_thr->giop_target(); if (target == 0 || target->owner() != 0) { - original_thr = hp->find_thread_for_handle (handle); + original_thr = this->hostproc_->find_thread_for_handle (handle); if (original_thr == 0) { ACE_ERROR ((LM_ERROR, "%d: cleanup queue, no original " "thread found, handle %d\n", - offset, handle)); + this->offset_, handle)); return; } target = original_thr->giop_target(); } + if (target != 0 && target->cur_size() == 0 && original_thr->has_dup()) + { + ACE_ERROR ((LM_ERROR, "%d: cleanup queue, swapping targets for thread %d\n", + this->offset_, original_thr->id())); + original_thr->swap_target(); + } original_thr->set_giop_target(0); original_thr->active_handle (0); @@ -536,18 +497,18 @@ Log::parse_cleanup_queue (Log *this_, char *line, size_t offset) { ACE_ERROR ((LM_ERROR, "%d: Cleanup queue detected, " - "could not find invocation for rid = %d\n", - offset, rid)); + "could not find invocation for rid = %d on thread %d\n", + this->offset_, rid, original_thr->id())); rid = target->expected_req_id(); inv = pp->find_invocation (rid, handle); if (inv == 0) { ACE_ERROR ((LM_ERROR, - "%d, Cleanup queue still failed to find rid %d\n", - offset, rid)); + "%d, Cleanup queue still failed to find rid %d, on thread %d\n", + this->offset_, rid, original_thr->id())); return; } - original_thr->exit_wait(pp, offset); + original_thr->exit_wait(pp, this->offset_); mtype = target->expected_type(); } inv->set_octets (mtype == 0, target); @@ -560,48 +521,76 @@ Log::parse_cleanup_queue (Log *this_, char *line, size_t offset) } void -Log::parse_close_connection (Log *this_, char *line, size_t offset) +Log::parse_close_connection_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - - char *hpos = ACE_OS::strchr(line,'['); + char *hpos = ACE_OS::strchr(this->info_,'['); long handle = ACE_OS::strtol(hpos+1,0,10); - PeerProcess *pp = hp->find_peer(handle, false); + PeerProcess *pp = this->hostproc_->find_peer(handle); if (pp != 0) { Transport *t = pp->find_transport (handle); if (t != 0) - t->close_offset_ = offset; + t->close_offset_ = this->offset_; } - hp->close_peer(handle); + this->hostproc_->remove_peer(handle); } void -Log::parse_handler_open (Log *this_, char *line, size_t offset) +Log::parse_handler_open_i (bool is_ssl) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - char *addr = ACE_OS::strchr(line,'<') +1; + char *addr = ACE_OS::strrchr(this->info_,'<') +1; char *c = ACE_OS::strchr(addr,'>'); *c = '\0'; c = ACE_OS::strstr(c+1,"on "); - long handle = ACE_OS::strtol(c + 3,0,10); - PeerProcess *pp = thr->pending_peer(); + c += 3; + if (*c == '[') + c++; + long handle = ACE_OS::strtol(c,0,10); + PeerProcess *pp = 0; + if (this->conn_waiters_.size() > 0) + { + for (ACE_DLList_Iterator<PeerProcess> c_iter (this->conn_waiters_); + !c_iter.done(); + c_iter.advance()) + { + PeerProcess *waiter = 0; + c_iter.next(waiter); + if (waiter != 0 && waiter->match_server_addr (addr, session_)) + { + pp = waiter; + c_iter.remove(); + break; + } + } + } + else + { + pp = this->thr_->pending_peer(); + } if (pp == 0) + { + ACE_ERROR ((LM_ERROR,"%d: no pending peer for addr %s\n", + this->offset_, addr)); + return; + } + + pp->ssl (is_ssl); + + const ACE_CString &local_addr = this->thr_->pending_local_addr(); + if (local_addr.length() > 0 ) { - ACE_ERROR ((LM_ERROR,"%d: no pending peer for file %s\n", - offset, this_->origin_.c_str())); - return; + if (pp->is_server()) + { + Transport *t = new Transport (addr, true, this->offset_); + pp->add_transport (t); + this->hostproc_->add_client_endpoint (t->client_endpoint_); + } + else + { + pp->set_server_addr (local_addr); + } + this->thr_->pending_local_addr (""); } Transport *trans = 0; @@ -613,209 +602,378 @@ Log::parse_handler_open (Log *this_, char *line, size_t offset) ACE_ERROR ((LM_ERROR, "%d: Pending peer exists, but no last transport " "set, file %s\n", - offset, this_->origin_.c_str())); + this->offset_, this->origin_.c_str())); return; } // trans->client_endpoint_ = addr; } else { - trans = new Transport (addr,false,offset); + trans = new Transport (addr, false, this->offset_); pp->add_transport(trans); } trans->handle_ = handle; - thr->pending_peer(0); - hp->add_peer(handle,pp); + this->thr_->pending_peer(0); + this->hostproc_->add_peer (handle,pp); } void -Log::parse_SSLIOP_from_client (Log *this_, char *line, size_t offset) +Log::parse_begin_connection_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - char *addr = ACE_OS::strchr(line,'<') +1; + char *addr = ACE_OS::strchr(this->info_,'<') +1; char *c = ACE_OS::strchr(addr,'>'); *c = '\0'; - c = ACE_OS::strstr(c+1,"on ["); - - PeerProcess *pp = thr->pending_peer(); + PeerProcess *pp = this->hostproc_->find_peer(addr); if (pp == 0) { - pp = new PeerProcess (offset, false); - thr->pending_peer (pp); + pp = new PeerProcess(this->offset_, true); + pp->set_server_addr (addr); } - - pp->set_server_addr(addr); + this->conn_waiters_.insert_tail (pp); + this->thr_->pending_peer (pp); } + void -Log::parse_SSLIOP_from_server (Log *this_, char *line, size_t offset) +Log::parse_local_addr_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - char *addr = ACE_OS::strchr(line,'<') +1; + char *addr = ACE_OS::strchr(this->info_,'<') +1; char *c = ACE_OS::strchr(addr,'>'); *c = '\0'; - c = ACE_OS::strstr(c+1,"on ["); - long handle = ACE_OS::strtol(c + 4,0,10); - PeerProcess *pp = thr->pending_peer(); - if (pp == 0) + + PeerProcess *peer = this->thr_->pending_peer(); + if (peer == 0) { - ACE_ERROR ((LM_ERROR,"%d: no pending peer for file %s\n", - offset, this_->origin_.c_str())); - return; + this->thr_->pending_local_addr (addr); + return; } - Transport *trans = new Transport (addr,false,offset); - pp->add_transport(trans); - trans->handle_ = handle; - thr->pending_peer(0); - hp->add_peer(handle,pp); + if (peer->is_server()) + { + Transport *t = new Transport (addr, true, this->offset_); + peer->add_transport (t); + this->hostproc_->add_client_endpoint (t->client_endpoint_); + } + else + { + peer->set_server_addr (addr); + } } void -Log::parse_begin_connection (Log *this_, char *line, size_t offset) +Log::parse_connection_not_complete_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); + this->thr_->pending_peer (0); +} - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); +void +Log::parse_open_as_server_i (void) +{ + this->thr_->pending_peer (new PeerProcess(this->offset_, false)); +} - char *addr = ACE_OS::strchr(line,'<') +1; - char *c = ACE_OS::strchr(addr,'>'); - *c = '\0'; - PeerProcess *pp = hp->find_peer(addr); +void +Log::parse_iiop_connection_handler_ctor_i (void) +{ + PeerProcess *pp = this->thr_->pending_peer(); if (pp == 0) { - pp = new PeerProcess(offset,true); - pp->set_server_addr (addr); + ACE_ERROR ((LM_ERROR, "%d: parse_iiop_connection_handler_ctor_i: no pending peer on thread\n", this->offset_)); + return; } - thr->pending_peer (pp); + +#if 0 + char *pos = ACE_OS::strchr (this->info_,'[') + 1; + long tmp_handle = ACE_OS::strtol (pos, 0, 10); + // pp->set_handle (tmp_handle); +#endif } void -Log::parse_SSLIOP_begin_connection (Log *this_, char *line, size_t offset) +Log::parse_wait_for_connection_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); + ACE_ERROR ((LM_ERROR,"%d: parse_wait_for_connection, line = %s\n", this->offset_, this->line_)); + if (ACE_OS::strstr (this->info_,"Connection not complete") == 0) + { + return; + } + else if (ACE_OS::strstr (this->info_,"wait done result =") == 0) + { + char *pos = ACE_OS::strchr (this->info_, '=') + 2; + int result = ACE_OS::strtol (pos, 0, 10); + if (result == 1) + return; + pos = ACE_OS::strchr (this->info_, '[') + 1; + long handle = ACE_OS::strtol (pos, 0, 10); + PeerProcess *pp = 0; + + ACE_DEBUG ((LM_DEBUG, "%d: parse_wait_for_connection: wait done, result = %d, purging handle = %d\n", this->offset_, result, handle)); + + if (this->conn_waiters_.size() > 0) + { + for (ACE_DLList_Iterator<PeerProcess> c_iter (this->conn_waiters_); + !c_iter.done(); + c_iter.advance()) + { + PeerProcess *waiter = 0; + c_iter.next(waiter); + if (waiter != 0) + { + Transport *t = waiter->find_transport (handle); + if (t != 0) + { + pp = waiter; + c_iter.remove(); + break; + } + } + } + } + else + { + pp = this->thr_->pending_peer(); + Transport *t = pp->find_transport (handle); + if (t == 0) + { + pp = 0; + } + else + { + this->thr_->pending_peer (0); + } + } + if (pp == 0) + { + ACE_ERROR ((LM_ERROR,"%d: no pending peer for handle %s\n", + this->offset_, handle)); + return; + } + delete pp; - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); + } +} - PeerProcess *pp = new PeerProcess(offset,true); - thr->pending_peer (pp); +void +Log::parse_post_open_i (void) +{ + // ACE_ERROR ((LM_ERROR,"%d: parse_post_open, line = %s\n", this->offset_, this->line_)); } void -Log::parse_local_addr (Log *this_, char *line, size_t offset) +Log::parse_notify_poa_helper_i (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); + Invocation *inv = this->thr_->current_invocation (); + if (inv == 0) + { + ACE_ERROR ((LM_ERROR,"%d: parse_notify_poa_helper line = %s, no current invocation on thread\n", this->offset_, this->info_)); + return; + } + bool activate = ACE_OS::strstr (this->info_, "Activating") != 0; + char *idpos = ACE_OS::strstr (this->info_, "id = "); + long objid = ACE_OS::strtol (idpos + 5, 0, 10); + idpos = ACE_OS::strstr (idpos + 5, "in POA : "); + long poaid = ACE_OS::strtol (idpos + 10, 0, 10); - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); + char buffer[100]; + ACE_OS::sprintf (buffer,"Notify object %s, object id %ld, POA %ld on line %ld", + (activate ? "activation" : "deactivation"), objid, poaid, + (unsigned long)this->offset_); + ACE_CString text (buffer); - PeerProcess *peer = thr->pending_peer(); - if (peer == 0) + inv->add_notify_incident (text, this->offset_); +} + +void +Log::parse_notify_object_i (void) +{ + Invocation *inv = this->thr_->current_invocation (); + if (inv == 0) { - ACE_ERROR((LM_ERROR, "%d: file %s, no pending client or server\n", - offset, this_->origin_.c_str())); - return; + // ACE_ERROR ((LM_ERROR,"%d: parse_notify_object line = %s, no current invocation on thread\n", this->offset_, this->info_)); } - char *addr = ACE_OS::strchr(line,'<') +1; - char *c = ACE_OS::strchr(addr,'>'); - *c = '\0'; - if (peer->is_server()) + char *ptr = ACE_OS::strstr (this->info_, "object:") + 7; + u_long objid = ACE_OS::strtol (ptr, &ptr, 16); + char note[100]; + note[0] = 0; + if (ACE_OS::strstr (ptr, "created") != 0) { - Transport *t = new Transport (addr, true, offset); - peer->add_transport (t); - hp->add_client_endpoint (t->client_endpoint_); + ::sprintf (note, "Created notify object %lx",objid); +#if 0 + NotifyObject notobj = new NotifyObject (objid, this->offset_, this->timestamp_); + this->hostproc_->add_notify_obj (notobj); +#endif } - else + else if (ACE_OS::strstr (ptr, "destroyed") != 0) { - peer->set_server_addr (addr); + ::sprintf (note, "Destroyed notify object %lx",objid); +#if 0 + NotifyObject notobj = this->hostproc_->find_notify_obj (objid); + if (notobj == 0) + { + ACE_ERROR ((LM_ERROR, "%d: could not find notify object %lx\n", this->offset_, objid)); + } + else + { + notobj->destroyed (this->offset_, this->timestamp_); + } +#endif + } + else if (ACE_OS::strstr (ptr, "incr ") != 0) + { + ptr = ACE_OS::strchr (ptr, '='); + int count = ACE_OS::strtol (ptr + 2, 0, 10); + ::sprintf (note, "increment reference notify object %lx, count now %d",objid, count); +#if 0 + NotifyObject notobj = this->hostproc_->find_notify_obj (objid); + if (notobj == 0) + { + notobj = new NotifyObject (objid, this->offset_, this->timestamp_); + this->hostproc_->add_notify_obj (notobj); + } + notobj->incr (this->offset_, this->timestamp_); +#endif + } + else if (ACE_OS::strstr (ptr, "decr ") != 0) + { + ptr = ACE_OS::strchr (ptr, '='); + int count = ACE_OS::strtol (ptr + 2, 0, 10); + ::sprintf (note, "decrement reference notify object %lx, count now %d",objid, count); +#if 0 + NotifyObject notobj = this->hostproc_->find_notify_obj (objid); + if (notobj == 0) + { + ACE_ERROR ((LM_ERROR, "%d: could not find notify object %x\n", this->offset_, objid)); + } + else + { + notobj->decr (this->offset_, this->timestamp_); + } +#endif } + + ACE_CString text (note); + if (inv) + inv->add_notify_incident (text, this->offset_); } void -Log::parse_open_as_server (Log *this_, char *line, size_t offset) +Log::get_timestamp (void) { - long pid = 0; - long tid = 0; - this_->get_pid_tid(pid,tid,line); - - HostProcess *hp = this_->get_host(pid); - Thread *thr = hp == 0 ? 0 : hp->find_thread (tid); - - thr->pending_peer (new PeerProcess(offset, false)); - + const char *time_tok = ACE_OS::strchr (this->line_,'@'); + size_t len = (size_t)(time_tok - this->line_); + if (time_tok != 0 && len < 30) + { + this->timestamp_ = ACE_CString (this->line_, len); +#if 0 + int year, mon, day; + int hr, min, sec, msec; + ::sscanf (hms+1,"%d-%d-%d %d:%d:%d.%d", &year, &mon, &day, &hr, &min, &sec, &msec); + time = (hr * 3600 + min *60 + sec) * 1000 + msec; + if (this->time_ > time) + time += 24 * 3600 * 1000; +#endif + } } void -Log::parse_line (char *line, size_t offset) +Log::parse_line (void) { - // first, is it a client connection to a new peer? - // next is it a server connection to a new peer? - // is it a new request or reply? - // a GIOP hex dump? - - static parse_key exprs[] = - { - { "Handler::open, IIOP connection to peer", parse_handler_open }, - { "GIOP_Message_Base::dump_msg,", parse_dump_msg }, - { "GIOP message - HEXDUMP", parse_HEXDUMP }, - { "open_i, listening on:", parse_open_listener }, - { "open_i - listening on:", parse_open_listener }, - { "Muxed_TMS[", parse_muxed_tms }, - { "Exclusive_TMS::request_id", parse_exclusive_tms }, - { "process_parsed_messages", parse_process_parsed_msgs }, - { "wait_for_event", parse_wait_for_event }, - { "Wait_On_Read", parse_wait_on_read }, - { "::cleanup_queue, byte_count", parse_cleanup_queue }, - { "close_connection_eh", parse_close_connection }, - { "ssliop_connect, making a new ", parse_SSLIOP_begin_connection }, - { "SSLIOP connection from client", parse_SSLIOP_from_client }, - { "SSLIOP connection accepted from server", parse_SSLIOP_from_server }, - { "IIOP_Connector::begin_connection, to ", parse_begin_connection }, - { "IIOP_Connection_Handler::open, The local addr is", parse_local_addr }, - { "opened as TAO_SERVER_ROLE", parse_open_as_server }, - { "Transport_Connector::connect, got an existing connected", parse_got_existing }, - { 0,0 } - }; - if (this->dump_target_ != 0) { - this->handle_msg_dump (line, offset); + this->handle_msg_octets (); return; } - for (int i = 0; exprs[i].text != 0; i++) + this->get_preamble(); + this->get_timestamp(); + + if (ACE_OS::strstr (this->info_, "Handler::open, IIOP connection to peer") != 0) { - if (ACE_OS::strstr(line, exprs[i].text) != 0) - { - (*exprs[i].op)(this, line, offset); - return; - } + this->parse_handler_open_i(false); + } + else if (ACE_OS::strstr (this->info_, "GIOP_Message_Base::dump_msg,") != 0) + { + this->parse_dump_giop_msg_i(); + } + else if (ACE_OS::strstr (this->info_, "GIOP message - HEXDUMP") != 0) + { + this->parse_HEXDUMP_i(); + } + else if (ACE_OS::strstr (this->info_, "open_i, listening on:") != 0) + { + this->parse_open_listener_i(); + } + else if (ACE_OS::strstr (this->info_, "Muxed_TMS[") != 0) + { + this->parse_muxed_tms_i(); + } + else if (ACE_OS::strstr (this->info_, "Exclusive_TMS::request_id") != 0) + { + this->parse_exclusive_tms_i(); + } + else if (ACE_OS::strstr (this->info_, "process_parsed_messages") != 0) + { + this->parse_process_parsed_msgs_i(); + } + else if (ACE_OS::strstr (this->info_, "wait_for_event") != 0) + { + this->parse_wait_for_event_i(); + } + else if (ACE_OS::strstr (this->info_, "Wait_On_Read") != 0) + { + this->parse_wait_on_read_i(); + } + else if (ACE_OS::strstr (this->info_, "::cleanup_queue, byte_count") != 0) + { + this->parse_cleanup_queue_i(); + } + else if (ACE_OS::strstr (this->info_, "close_connection_eh") != 0) + { + this->parse_close_connection_i(); + } + else if (ACE_OS::strstr (this->info_, "IIOP_Connector::begin_connection, to ") != 0) + { + this->parse_begin_connection_i(); + } + else if (ACE_OS::strstr (this->info_, "IIOP_Connection_Handler::open, The local addr is") != 0) + { + this->parse_local_addr_i(); + } + else if (ACE_OS::strstr (this->info_, "Connection not complete.") != 0) + { + this->parse_connection_not_complete_i(); + } + else if (ACE_OS::strstr (this->info_, "opened as TAO_SERVER_ROLE") != 0) + { + this->parse_open_as_server_i(); + } + else if (ACE_OS::strstr (this->info_, "Transport_Connector::connect, got an existing connected") != 0) + { + this->parse_got_existing_i(); + } + else if (ACE_OS::strstr (this->info_, "Transport_Connector::wait_for_connection_competion") != 0) + { + this->parse_wait_for_connection_i(); + } + else if (ACE_OS::strstr (this->info_, "Transport::post_open, tport") != 0) + { + this->parse_post_open_i(); + } + else if (ACE_OS::strstr (this->info_, "SSLIOP connection from client") != 0) + { + this->parse_handler_open_i(true); + } + else if (ACE_OS::strstr (this->info_, "SSLIOP connection accepted from server") != 0) + { + this->parse_local_addr_i(); + } + else if (ACE_OS::strstr (this->info_, "POA_Helper") != 0) + { + this->parse_notify_poa_helper_i(); + } + else if (ACE_OS::strstr (this->info_, "object:") != 0) + { + this->parse_notify_object_i (); } return; } - -void -Log::summarize (void) -{ - // todo -} diff --git a/TAO/utils/logWalker/Log.h b/TAO/utils/logWalker/Log.h index 3aaffa8853d..682f7a21bb6 100644 --- a/TAO/utils/logWalker/Log.h +++ b/TAO/utils/logWalker/Log.h @@ -9,68 +9,87 @@ #include "ace/Containers.h" #include "ace/Synch.h" #include "ace/SString.h" +#include "ace/Time_Value.h" #include "PeerProcess.h" #include "HostProcess.h" +#include "GIOP_Buffer.h" class Session; class HostProcess; +class Invocation; typedef ACE_DLList<HostProcess> HostProcesses; +class Incident +{ +public: + ACE_CString timestamp_; + size_t offset_; + int thread_; + ACE_CString annotation_; + Invocation *invocation_; +}; + +typedef ACE_Unbounded_Queue<Incident> IncidentList; + + class Log { public: Log (Session &s); - ~Log(); - - bool init (const ACE_TCHAR *filename, const char *alias = ""); - - void summarize(void); - - void dump (ostream &strm); - -private: - typedef void (* parser_func)(Log *this_, char *line, size_t offset); - - struct parse_key - { - const char *text; - parser_func op; - }; - - bool get_pid_tid (long &pid, long &tid, char *line); - HostProcess *get_host (long pid); - void handle_msg_dump (char *line, size_t offset); - void parse_line (char* line, size_t offset); - - static void parse_handler_open (Log *this_, char *line, size_t offset); - static void parse_SSLIOP_handler_open (Log *this_, char *line, size_t offset); - static void parse_dump_msg (Log *this_, char *line, size_t offset); - static void parse_HEXDUMP (Log *this_, char *line, size_t offset); - static void parse_open_listener (Log *this_, char *line, size_t offset); - static void parse_got_existing (Log *this_, char *line, size_t offset); - static void parse_muxed_tms (Log *this_, char *line, size_t offset); - static void parse_exclusive_tms (Log *this_, char *line, size_t offset); - static void parse_process_parsed_msgs (Log *this_, char *line, size_t offset); - static void parse_wait_for_event (Log *this_, char *line, size_t offset); - static void parse_wait_on_read (Log *this_, char *line, size_t offset); - static void parse_cleanup_queue (Log *this_, char *line, size_t offset); - static void parse_close_connection (Log *this_, char *line, size_t offset); - static void parse_begin_connection (Log *this_, char *line, size_t offset); - static void parse_SSLIOP_begin_connection (Log *this_, char *line, size_t offset); - static void parse_SSLIOP_from_client (Log *this_, char *line, size_t offset); - static void parse_SSLIOP_from_server (Log *this_, char *line, size_t offset); - static void parse_local_addr (Log *this_, char *line, size_t offset); - static void parse_open_as_server (Log *this_, char *line, size_t offset); + virtual ~Log(void); + + bool process_file (const ACE_TCHAR *filename, const char *alias = ""); + +protected: + + virtual void parse_line (void); + + void get_preamble (void); + void get_timestamp (void); + void handle_msg_octets (void); + bool match_target(void); + + void parse_handler_open_i (bool is_ssl); + void parse_dump_giop_msg_i (void); + void parse_HEXDUMP_i (void); + void parse_open_listener_i (void); + void parse_got_existing_i (void); + void parse_muxed_tms_i (void); + void parse_exclusive_tms_i (void); + void parse_process_parsed_msgs_i (void); + void parse_wait_for_event_i (void); + void parse_wait_on_read_i (void); + void parse_cleanup_queue_i (void); + void parse_close_connection_i (void); + void parse_begin_connection_i (void); + void parse_local_addr_i (void); + void parse_connection_not_complete_i (void); + void parse_open_as_server_i (void); + void parse_iiop_connection_handler_ctor_i (void); + void parse_wait_for_connection_i (void); + void parse_post_open_i (void); + void parse_notify_poa_helper_i (void); + void parse_notify_object_i (void); ACE_CString origin_; ACE_CString alias_; Session &session_; HostProcesses procs_; - Invocation::GIOP_Buffer* dump_target_; + GIOP_Buffer unknown_msg_; + GIOP_Buffer* dump_target_; ThreadList giop_waiters_; - + ACE_DLList<PeerProcess> conn_waiters_; + IncidentList history_; + + // parsed for every line + ACE_CString timestamp_; + char *line_; + char *info_; + size_t offset_; + HostProcess *hostproc_; + Thread *thr_; }; #endif // LOG_WALKER_LOG_H diff --git a/TAO/utils/logWalker/PeerObject.cpp b/TAO/utils/logWalker/PeerObject.cpp index 3cf504bcb5e..00ec6e7f9c9 100644 --- a/TAO/utils/logWalker/PeerObject.cpp +++ b/TAO/utils/logWalker/PeerObject.cpp @@ -41,7 +41,10 @@ PeerObject::num_invocations (void) void PeerObject::dump_detail (ostream &strm) { - strm << this->ident_ << " has " - << this->invocations_.size() << " invocations" << endl; + size_t s = this->invocations_.size(); + strm << " " << this->name_ << " has " + << s << " invocation" + << (s > 1 ? "s" : "") + << endl; } diff --git a/TAO/utils/logWalker/PeerProcess.cpp b/TAO/utils/logWalker/PeerProcess.cpp index 10669845dda..00e51c68d77 100644 --- a/TAO/utils/logWalker/PeerProcess.cpp +++ b/TAO/utils/logWalker/PeerProcess.cpp @@ -3,6 +3,7 @@ #include "PeerProcess.h" #include "PeerObject.h" #include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" #include "ace/ACE.h" #include "Invocation.h" #include "HostProcess.h" @@ -20,23 +21,27 @@ Transport::Transport (const char *addr, bool is_client, size_t offset) } char * -PeerProcess::nextIdent(void) +PeerProcess::nextIdent(bool is_server) { static int count = 0; char *ident = new char[15]; - ACE_OS::sprintf (ident,"proc_%d", count++); + ACE_OS::sprintf (ident,"%s_%d", (is_server ? "server" : "client"), count++); return ident; } PeerProcess::PeerProcess (size_t offset, bool is_server) : owner_ (0), remote_ (0), - server_addr_(), + server_port_(), + server_host_(), server_(is_server), + ssl_(false), + localhost_(false), origin_offset_ (offset), - objects_ () + objects_ (), + object_by_index_ () { - this->ident_ = PeerProcess::nextIdent(); + this->ident_ = PeerProcess::nextIdent(is_server); } PeerProcess::~PeerProcess (void) @@ -54,26 +59,43 @@ PeerProcess::~PeerProcess (void) break; delete entry->item(); } - for (TransportList::ITERATOR i(this->transports_); !i.done(); i++) - { - ACE_DLList_Node *entry; - if (i.next(entry) == 0) - break; - //i.remove (); - delete reinterpret_cast<Transport*>(entry->item_); - } } void -PeerProcess::set_server_addr (const char *addr) +PeerProcess::set_server_addr (const ACE_CString &addr) { - this->server_addr_ = addr; + size_t p = addr.rfind (':'); + this->server_port_ = addr.substring(p); + this->server_host_ = addr.substring(0,p); + + this->localhost_ = this->server_host_ == "localhost" || + this->server_host_ == "127.0.0.1" || this->server_host_ == "[::1]"; } -const ACE_CString& +bool +PeerProcess::match_server_addr (const ACE_CString &addr, Session &session) const +{ + size_t p = addr.rfind (':'); + ACE_CString port = addr.substring (p); + ACE_CString host = addr.substring (0,p); + if (port != this->server_port_) + return false; + + if (this->localhost_) + { + return host == "localhost" || host == "127.0.0.1" || host == "[::1]"; + } + + if (this->server_host_ == host) + return true; + + return session.is_equivalent (this->server_host_, host); +} + +ACE_CString PeerProcess::server_addr (void) const { - return this->server_addr_; + return this->server_host_ + this->server_port_; } const ACE_CString& @@ -89,6 +111,12 @@ PeerProcess::is_server (void) const } void +PeerProcess::ssl (bool is_ssl) +{ + this->ssl_ = is_ssl; +} + +void PeerProcess::add_transport (Transport *t) { this->last_transport_ = t; @@ -118,7 +146,6 @@ PeerProcess::find_transport (long handle) return 0; } - void PeerProcess::match_hosts (Session *session) { @@ -127,7 +154,7 @@ PeerProcess::match_hosts (Session *session) // then this wants to find the remote based on the Transport // instance if (this->server_) - this->remote_ = session->find_host(this->server_addr_, true); + this->remote_ = session->find_host(this->server_host_, true); else { Transport *t = 0; @@ -161,8 +188,9 @@ PeerProcess::object_for (const char *oid, size_t len) long index = static_cast<long>(objects_.current_size()); char alias[20]; ACE_OS::sprintf (alias, "obj_%ld", index); - po = new PeerObject(index,alias, this); + po = new PeerObject(index, alias, this); objects_.bind(key, po); + object_by_index_.bind (index, po); } return po; } @@ -172,7 +200,7 @@ PeerProcess::new_invocation (size_t req_id, Thread *thr) { if (this->find_invocation (req_id, thr->active_handle()) != 0) return 0; - Invocation *inv = new Invocation (this, thr->active_handle(), req_id); + Invocation *inv = new Invocation (this, thr, req_id); this->invocations_.insert_tail(inv); thr->add_invocation (inv); return inv; @@ -236,11 +264,13 @@ PeerProcess::dump_summary (ostream &strm) else strm << " peer process " << this->ident_; strm << " is a "; + if (this->ssl_) + strm << "secure "; if (this->server_) strm << "server at "; else strm << "client to "; - strm << this->server_addr_; + strm << this->server_host_ << this->server_port_; strm << " with " << num_transports << " connections, "; strm << " referenced " << this->objects_.current_size() << " objects in " << this->invocations_.size() << " invocations"; @@ -252,7 +282,7 @@ PeerProcess::dump_summary (ostream &strm) Transport *tran = 0; i.next(tran); strm << " connection[" << tran->handle_ << "] "; - strm << (tran->local_is_client_ ? "from " : "to "); + strm << (tran->local_is_client_ ? "to " : "from "); strm << tran->client_endpoint_; strm << " created line " << tran->open_offset_; if (tran->close_offset_) @@ -265,18 +295,22 @@ void PeerProcess::dump_object_detail (ostream &strm) { strm << this->objects_.current_size() - << " Objects referenced in "; + << " Objects referenced"; + if (this->server_) + strm << " in "; + else + strm << " by "; if (this->remote_) strm << remote_->proc_name(); else - strm << " peer process " << this->ident_; + strm << "peer process " << this->ident_; strm << ":" << endl; size_t count_inv = 0; - for (PeerObjectTable::ITERATOR i = this->objects_.begin(); - i != this->objects_.end(); - i++) + for (ObjectByIndex::ITERATOR i = this->object_by_index_.begin(); + !i.done(); + i.advance()) { - PeerObjectTable::ENTRY *entry = 0; + ObjectByIndex::ENTRY *entry = 0; i.next (entry); PeerObject *obj = entry->item(); obj->dump_detail (strm); @@ -288,7 +322,8 @@ PeerProcess::dump_object_detail (ostream &strm) void PeerProcess::dump_invocation_detail (ostream &strm) { - strm << "\n " << this->invocations_.size() << " Invocations with "; + strm << "\n " << this->invocations_.size() << " Invocations "; + strm << (this->server_ ? "to " : "from "); if (this->remote_) strm << remote_->proc_name(); else diff --git a/TAO/utils/logWalker/PeerProcess.h b/TAO/utils/logWalker/PeerProcess.h index 76205ba19ad..59ebacbcd64 100644 --- a/TAO/utils/logWalker/PeerProcess.h +++ b/TAO/utils/logWalker/PeerProcess.h @@ -32,13 +32,14 @@ public: typedef ACE_RB_Tree<u_long, PeerObject*, ACE_Less_Than<u_long>, ACE_Null_Mutex> PeerObjectTable; +typedef ACE_RB_Tree<long, PeerObject*, ACE_Less_Than<long>, ACE_Null_Mutex> ObjectByIndex; typedef ACE_DLList<Invocation> InvocationList; typedef ACE_DLList<Transport> TransportList; class PeerProcess { public: - static char *nextIdent(void); + static char *nextIdent(bool is_server); PeerProcess (size_t offset, bool is_server); virtual ~PeerProcess (void); @@ -49,16 +50,18 @@ public: HostProcess *owner (void); void match_hosts (Session *session); - void set_server_addr (const char *addr); - const ACE_CString &server_addr (void) const; + void set_server_addr (const ACE_CString &addr); + ACE_CString server_addr (void) const; const ACE_CString &last_client_addr (void) const; bool is_server (void) const; + void ssl (bool is_ssl); void add_transport (Transport *t); Transport *last_transport (void); Transport *find_transport (long handle); bool match_local (const char *addr) const; + bool match_server_addr (const ACE_CString &addr, Session &session) const; Invocation *new_invocation (size_t req_id, Thread *thr); Invocation *find_invocation (size_t req_id, long handle); @@ -72,15 +75,20 @@ public: private: char *ident_; + char *origin_; HostProcess *owner_; HostProcess *remote_; - ACE_CString server_addr_; + ACE_CString server_port_; + ACE_CString server_host_; TransportList transports_; Transport *last_transport_; bool server_; + bool ssl_; + bool localhost_; size_t origin_offset_; PeerObjectTable objects_; InvocationList invocations_; + ObjectByIndex object_by_index_; }; diff --git a/TAO/utils/logWalker/Session.cpp b/TAO/utils/logWalker/Session.cpp index ad497703eb9..8f194415417 100644 --- a/TAO/utils/logWalker/Session.cpp +++ b/TAO/utils/logWalker/Session.cpp @@ -9,8 +9,6 @@ long Session::tao_version_ = 200; -int -Session::date_format_ = 1; Session::Session (void) { @@ -53,24 +51,6 @@ Session::tao_version (void) return tao_version_; } -bool -Session::set_date_format (ACE_TCHAR *str) -{ - if (ACE_OS::strncmp(str, ACE_TEXT("1"), 1)== 0) - date_format_ = 1; - else if (ACE_OS::strncmp (str, ACE_TEXT("2"), 1) == 0) - date_format_ = 2; - else - return false; - return true; -} - -int -Session::date_format (void) -{ - return date_format_; -} - void Session::add_process (HostProcess *proc) { @@ -95,6 +75,19 @@ Session::alternate_address (const char *addrspec) this->alt_addrs_.bind(name,value); } +bool +Session::is_equivalent (const ACE_CString &primary, + const ACE_CString &alternate) +{ + ACE_CString test(primary); + ACE_CString alt; + if (this->alt_addrs_.find(test,alt) == 0) + { + return alt == alternate; + } + return false; +} + void Session::default_service (const char *addrspec) { diff --git a/TAO/utils/logWalker/Session.h b/TAO/utils/logWalker/Session.h index 7e944fc5701..2f4bfb0c85d 100644 --- a/TAO/utils/logWalker/Session.h +++ b/TAO/utils/logWalker/Session.h @@ -17,7 +17,7 @@ class HostProcess; typedef ACE_RB_Tree<long, HostProcess *, ACE_Less_Than<long>, ACE_Null_Mutex> Processes; typedef ACE_RB_Tree<ACE_CString, HostProcess *, ACE_Less_Than<ACE_CString>, ACE_Null_Mutex> Procs_By_Name; -typedef ACE_Hash_Map_Manager<ACE_CString, ACE_CString, ACE_Null_Mutex> AltAddresses; +typedef ACE_Hash_Map_Manager<const ACE_CString, ACE_CString, ACE_Null_Mutex> AltAddresses; class Session { @@ -33,10 +33,9 @@ public: static bool set_tao_version (ACE_TCHAR *str); static long tao_version (void); - static int date_format (void); - static bool set_date_format (ACE_TCHAR *ser); - void alternate_address (const char *string); + bool is_equivalent (const ACE_CString &primary, + const ACE_CString &alternate); void default_service (const char *string); void make_dir (const char * ); @@ -56,7 +55,6 @@ private: ACE_CString base_dir_; ACE_CString outfile_; static long tao_version_; - static int date_format_; }; #endif // LOG_WALKER_SESSION_H diff --git a/TAO/utils/logWalker/Thread.cpp b/TAO/utils/logWalker/Thread.cpp index 57345a22447..a9e2f2394cb 100644 --- a/TAO/utils/logWalker/Thread.cpp +++ b/TAO/utils/logWalker/Thread.cpp @@ -3,21 +3,25 @@ #include "Thread.h" #include "Invocation.h" #include "PeerProcess.h" +#include "GIOP_Buffer.h" #include "ace/OS_NS_stdio.h" - #include <stack> -Thread::Thread (long tid, const char *alias) +Thread::Thread (long tid, const char *alias, size_t offset) : id_(tid), alias_ (alias), max_depth_ (0), - encounters_ (0), + client_encounters_ (0), + server_encounters_ (0), nested_ (0), pending_(), incoming_(0), new_connection_(0), giop_target_(0), - active_handle_ (0) + target_dup_(0), + current_invocation_ (), + active_handle_ (0), + first_line_ (offset) { } @@ -34,9 +38,21 @@ Thread::pending_peer (void) const } void +Thread::pending_local_addr (const ACE_CString &addr) +{ + this->pending_local_addr_ = addr; +} + +const ACE_CString & +Thread::pending_local_addr (void) const +{ + return this->pending_local_addr_; +} + +void Thread::handle_request (void) { - this->encounters_++; + this->server_encounters_++; if (this->pending_.size() > 1) this->nested_++; } @@ -45,7 +61,7 @@ void Thread::enter_wait (PeerProcess *pp) { this->pending_.push (pp); - this->encounters_++; + this->client_encounters_++; if (this->pending_.size() > this->max_depth_) this->max_depth_ = this->pending_.size(); if (this->pending_.size() > 1) @@ -72,13 +88,7 @@ Thread::exit_wait (PeerProcess *pp, size_t linenum) long Thread::max_depth (void) const { - return this->max_depth_; -} - -long -Thread::encounters (void) const -{ - return this->encounters_; + return static_cast<long> (this->max_depth_); } long @@ -117,16 +127,61 @@ Thread::active_handle (void) const return this->active_handle_; } -Invocation::GIOP_Buffer * +void +Thread::set_dup (Thread *other, bool set_other) +{ + this->target_dup_ = other; + if (set_other) + { + other->set_dup (this, false); + } +} + +void +Thread::clear_dup (void) +{ + this->target_dup_ = 0; +} + +bool +Thread::has_dup (void) +{ + return this->target_dup_ != 0; +} + +void +Thread::swap_target (void) +{ + if (target_dup_ != 0 && target_dup_->giop_target() != 0) + { + this->giop_target_->swap (target_dup_->giop_target()); + this->target_dup_->clear_dup (); + this->target_dup_ = 0; + } + else + { + if (target_dup_ == 0) + ACE_ERROR ((LM_ERROR, "Thread::swap_target, target_dup_ == 0\n")); + else + ACE_ERROR ((LM_ERROR, "Thread::swap_target, target_dup_.id = %d, giop_target == 0\n", target_dup_->id())); + } +} + +GIOP_Buffer * Thread::giop_target (void) { return this->giop_target_; } void -Thread::set_giop_target (Invocation::GIOP_Buffer *buffer) +Thread::set_giop_target (GIOP_Buffer *buffer) { this->giop_target_ = buffer; + if (this->target_dup_ != 0) + { + this->target_dup_->clear_dup(); + this->target_dup_ = 0; + } } void @@ -136,10 +191,34 @@ Thread::add_invocation (Invocation *inv) } void -Thread::dump_detail (ostream &strm) +Thread::push_invocation (Invocation *inv) +{ + this->current_invocation_.push(inv); +} + +void +Thread::pop_invocation (void) { - strm << " " << this->alias_ << " tid = " << this->id_ - << "\t" << this->encounters_ << " encounters"; + Invocation *inv; + this->current_invocation_.pop (inv); +} + +Invocation * +Thread::current_invocation (void) const +{ + Invocation *inv = 0; + if (this->current_invocation_.size() > 0) + this->current_invocation_.top(inv); + return inv; +} + +void +Thread::dump_detail (ostream &strm) const +{ + strm << " " << this->alias_ << " tid = 0x" << hex << this->id_ + << "\tfirst line " << dec << this->first_line_ << "\t" + << this->server_encounters_ << " requests sent " + << this->client_encounters_ << " requests received"; if (nested_ > 0) strm <<", with " << this->nested_ << " nested upcalls, max depth " << this->max_depth_; @@ -147,21 +226,48 @@ Thread::dump_detail (ostream &strm) } void +Thread::get_summary (long &sent_reqs, + long &recv_reqs, + size_t &sent_size, + size_t &recv_size) +{ + for (ACE_DLList_Iterator <Invocation> i(this->invocations_); + !i.done(); + i.advance()) + { + Invocation *inv; + i.next(inv); + if (inv->sent_request()) + { + ++sent_reqs; + sent_size += inv->request_bytes(); + } + else + { + ++recv_reqs; + recv_size += inv->request_bytes(); + } + } +} + +void Thread::dump_invocations (ostream &strm) { - strm << " " << this->alias_ << " handled " << this->invocations_.size() << " invocations" << endl; + size_t total_request_bytes = 0; + strm << " " << this->alias_ << " handled " << this->invocations_.size() + << " invocations" << endl; std::stack<Invocation *> nested; - for (ACE_DLList_Iterator <Invocation> i(this->invocations_); + for (ACE_DLList_Iterator <Invocation> i (this->invocations_); !i.done(); i.advance()) { Invocation *inv; i.next(inv); - int level = 0; - while (!nested.empty()) + size_t level = 0; + while (!nested.empty ()) { - if (nested.top()->contains(inv->req_line())) + if (nested.top()->contains (inv->req_line ())) { level = nested.size(); break; @@ -171,5 +277,7 @@ Thread::dump_invocations (ostream &strm) nested.push(inv); inv->dump_detail (strm, level, Invocation::Dump_Proc, false); + total_request_bytes += inv->request_bytes(); } + strm << "total request octet count: " << total_request_bytes; } diff --git a/TAO/utils/logWalker/Thread.h b/TAO/utils/logWalker/Thread.h index 4660d34a0c1..d6bf5f5d7b1 100644 --- a/TAO/utils/logWalker/Thread.h +++ b/TAO/utils/logWalker/Thread.h @@ -14,44 +14,60 @@ #include "PeerProcess.h" typedef ACE_Unbounded_Stack<PeerProcess *> UpcallStack; +typedef ACE_Unbounded_Stack<Invocation *> InvocationStack; class Thread { public: - Thread (long tid, const char *alias); + Thread (long tid, const char *alias, size_t offset); long max_depth (void) const; - long encounters (void) const; + long client_encounters (void) const; + long server_encounters (void) const; long id (void) const; const ACE_CString &alias (void) const; void incoming_from (PeerProcess *); void add_invocation (Invocation *); + void push_invocation (Invocation *); + void pop_invocation (void); + Invocation *current_invocation (void) const; PeerProcess *incoming (void) const; void handle_request (void); void enter_wait (PeerProcess *); void exit_wait (PeerProcess *, size_t linenum); - Invocation::GIOP_Buffer *giop_target (void); - void set_giop_target (Invocation::GIOP_Buffer *buffer); - void dump_detail (ostream &strm); + GIOP_Buffer *giop_target (void); + void set_giop_target (GIOP_Buffer *buffer); + void dump_detail (ostream &strm) const; void dump_invocations (ostream &strm); + void get_summary (long &sent_reqs, long &recv_reqs, size_t &sent_size, size_t &recv_size); PeerProcess *pending_peer (void) const; void pending_peer (PeerProcess *pp); - + void pending_local_addr (const ACE_CString &addr); + const ACE_CString& pending_local_addr (void) const; void active_handle (long handle); long active_handle (void) const; + void set_dup (Thread *other, bool set_other); + void clear_dup (void); + void swap_target (void); + bool has_dup (void); private: long id_; ACE_CString alias_; size_t max_depth_; - long encounters_; + long client_encounters_; + long server_encounters_; long nested_; UpcallStack pending_; PeerProcess *incoming_; PeerProcess *new_connection_; - Invocation::GIOP_Buffer *giop_target_; + ACE_CString pending_local_addr_; + GIOP_Buffer *giop_target_; + Thread *target_dup_; InvocationList invocations_; + InvocationStack current_invocation_; long active_handle_; + size_t first_line_; }; #endif // LOG_WALKER_THREAD_H diff --git a/TAO/utils/logWalker/logWalker.cpp b/TAO/utils/logWalker/logWalker.cpp index cbd0c7375c3..b669c89c1d3 100644 --- a/TAO/utils/logWalker/logWalker.cpp +++ b/TAO/utils/logWalker/logWalker.cpp @@ -30,7 +30,7 @@ parse_filename (Session &session, char * buffer) Log log(session); if (ACE_OS::strchr(buffer,'=') == 0) { - log.init(ACE_TEXT_CHAR_TO_TCHAR(buffer)); + log.process_file (ACE_TEXT_CHAR_TO_TCHAR(buffer)); } else { @@ -38,7 +38,7 @@ parse_filename (Session &session, char * buffer) tokens.delimiter_replace('=', 0); char *alias = tokens.next(); ACE_TString filename = ACE_TEXT_CHAR_TO_TCHAR(tokens.next()); - log.init(filename.c_str(), alias); + log.process_file (filename.c_str(), alias); } } @@ -111,13 +111,12 @@ void print_help (void) { ACE_DEBUG ((LM_DEBUG, "tao_logWalker recongizes the following arguments\n")); - ACE_DEBUG ((LM_DEBUG, "-outfile <filename> - write all output to specified file\n")); - ACE_DEBUG ((LM_DEBUG, "-dir <directory> - create separate output files, one per log, and put them in specified directory.\n Either -outfile or -dir may be set but not both. Default output to stdout.\n")); - ACE_DEBUG ((LM_DEBUG, "-manifest <manifest> - Take inputs from named manifest file\n")); - ACE_DEBUG ((LM_DEBUG, "-tao <1.5 .. 2.0> - set source TAO version, default 2.0\n")); - ACE_DEBUG ((LM_DEBUG, "-date <1|2> - interpret dates as 1) YYYY-MM-DD hh:mm:ss.sss, or 2) MMM DD hh:mm:ss.sss YYYY\n")); - ACE_DEBUG ((LM_DEBUG, "-alias <name=address> - bind an alias to a host address.\n Repeat as many times as necessary.\n")); - ACE_DEBUG ((LM_DEBUG, "-proc <service=address> - bind a service such as Naming to a specific endpoint address\n")); + ACE_DEBUG ((LM_DEBUG, "-o <filename> - write all output to specified file\n")); + ACE_DEBUG ((LM_DEBUG, "-d <directory> - create separate output files, one per log, and put them in specified directory.\n Either -o or -d may be set but not both. Default output to stdout.\n")); + ACE_DEBUG ((LM_DEBUG, "-m <manifest> - Take inputs from named manifest file\n")); + ACE_DEBUG ((LM_DEBUG, "-t <1.5 .. 2.0> - set source TAO version, default 2.0\n")); + ACE_DEBUG ((LM_DEBUG, "-a <name=address> - bind an alias to a host address.\n Repeat as many times as necessary.\n")); + ACE_DEBUG ((LM_DEBUG, "-p <service=address> - bind a service such as Naming to a specific endpoint address\n")); } int @@ -132,8 +131,7 @@ ACE_TMAIN (int argc, ACE_TCHAR **argv) Session session; for (int i = 1; i < argc; i++) { - if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-outfile")) == 0 || - ACE_OS::strcasecmp (argv[i], ACE_TEXT("-o")) == 0) + if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-o")) == 0) { if (session.has_dir()) ACE_ERROR_RETURN ((LM_ERROR, @@ -142,8 +140,7 @@ ACE_TMAIN (int argc, ACE_TCHAR **argv) session.outfile(ACE_TEXT_ALWAYS_CHAR(argv[++i])); continue; } - if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-dir")) == 0 || - ACE_OS::strcasecmp (argv[i], ACE_TEXT("-d")) == 0) + if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-d")) == 0) { if (session.has_outfile()) ACE_ERROR_RETURN ((LM_ERROR, @@ -152,14 +149,12 @@ ACE_TMAIN (int argc, ACE_TCHAR **argv) session.make_dir (ACE_TEXT_ALWAYS_CHAR(argv[++i])); continue; } - if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-manifest")) == 0 || - ACE_OS::strcasecmp (argv[i], ACE_TEXT("-m")) == 0) + if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-m")) == 0) { parse_manifest (session, argv[++i]); continue; } - if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-tao")) == 0 || - ACE_OS::strcasecmp (argv[i], ACE_TEXT("-t")) == 0) + if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-t")) == 0) { if (Session::set_tao_version (argv[++i])) continue; @@ -167,23 +162,12 @@ ACE_TMAIN (int argc, ACE_TCHAR **argv) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT("TAO version must be 1.5, 1.6, 1.7, 1.8, or 2.0 \n")), 0); } - if (ACE_OS::strcasecmp (argv[i], ACE_TEXT ("-date")) == 0) - { - if (Session::set_date_format (argv[++i])) - continue; - else - ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT("Date format option must be 1 or 2\n")), 0); - } - - if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-alias")) == 0 || - ACE_OS::strcasecmp (argv[i], ACE_TEXT("-a")) == 0) + if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-a")) == 0) { session.alternate_address (ACE_TEXT_ALWAYS_CHAR (argv[++i])); continue; } - if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-proc")) == 0 || - ACE_OS::strcasecmp (argv[i], ACE_TEXT("-p")) == 0) + if (ACE_OS::strcasecmp (argv[i], ACE_TEXT("-p")) == 0) { session.default_service (ACE_TEXT_ALWAYS_CHAR (argv[++i])); continue; diff --git a/TAO/utils/nsgroup/README.nsgroup b/TAO/utils/nsgroup/README.nsgroup new file mode 100644 index 00000000000..4dc243dbad1 --- /dev/null +++ b/TAO/utils/nsgroup/README.nsgroup @@ -0,0 +1,156 @@ +$Id$ + +This utility provides a command line interface for the tao_ft_naming service. +tao_ft_naming service supports the NameService and NamingManager interfaces. + +Here is a summary of the commands and options: + +tao_nsgroup group_create -group <group> -policy <round | rand | least> +tao_nsgroup group_remove -group <group> +tao_nsgroup group_bind -group <group> -name <name> +tao_nsgroup group_unbind -name <name> +tao_nsgroup group_modify -group <group> -policy <round | rand | least> +tao_nsgroup group_list +tao_nsgroup member_add -group <group> -location <location> -ior <ior> +tao_nsgroup member_remove -group <group> -location <location> +tao_nsgroup member_show -group <group> -location <location> +tao_nsgroup member_list -group <group> +tao_nsgroup -help + +tao_nsgroup group_create -group <group> -policy <round | rand | least> + + Adds the object group to to the load balancing naming manager service with the + specified selection policy. On Creation, an object group contains no member + objects. Returns error if <group> is not unique. + + Returns Success(0), Error(1) + + Example: + $ACE_ROOT/bin/tao_nsgroup group_create -group ieee -policy round \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + +tao_nsgroup group_remove -group <group> + + Removes the specified object group from the load balancing naming manager + service. + + Returns Success(0), Error(1) + + Example: + $ACE_ROOT/bin/tao_nsgroup group_remove -group ieee \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + + Note: If the object group is bound with group_bind, you must also unbind it + with group_unbind. + +tao_nsgroup group_bind -group <group> -name <name> + + Binds the specified object group to the specified stringified name in the + naming service. When clients resolve that name, they tranparently obtain a + member of the specified object group from the load balancing naming manager + service. + + Returns Success(0), Error(1) + + Example: + + $ACE_ROOT/bin/tao_nsgroup group_bind -group ieee -name iso/ieee \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + + Note: The iso context used in this example must be created before calling + group_bind. + +tao_nsgroup group_unbind -name <name> + + Unbinds the specified stringified name from the naming service, but does not + remove the object group. + + Returns Success(0), Error(1) + + Example: + + $ACE_ROOT/bin/tao_nsgroup group_unbind -name iso/ieee \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + +tao_nsgroup group_modify -group <group> -policy <round | rand | least> + + Changes the selection algorithm for the specified object group. An object + group's selection algorithm determines how the load balancing naming manager + service directs client requests to object group members. + + Returns Success(0), Error(1) + + Example: + $ACE_ROOT/bin/tao_nsgroup group_modify -group ieee -policy rand \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + +tao_nsgroup group_list + + Displays all object groups that currently exist in the load balancing naming + manager service by selection policy. + + Returns Success(0), Error(1) + + Example: + $ACE_ROOT/bin/tao_nsgroup group_list \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + + Round Robin Load Balancing Groups: + ieee + + Random Load Balancing Groups: + ieed + + Least Load Balancing Groups: + No Least Load Balancing Groups Registered + + +tao_nsgroup member_add -group <group> -location <location> -ior <ior> + + Adds an member object to the specified object group. After being added, the + member object is available for selection. Returns error if the ior is not + unique for the specified object group. + + Returns Success(0), Error(1) + + Example: + $ACE_ROOT/bin/tao_nsgroup member_add -group ieee -location 127.0.0.1 \ + -ior file://mo.ior -ORBInitRef NameService=file://ns.ior \ + -ORBInitRef NamingManager=file://nm.ior + +tao_nsgroup member_remove -group <group> -location <location> + + Removes the specified member object location from the specified object group. + + Returns Success(0), Error(1) + + Example: + $ACE_ROOT/bin/tao_nsgroup member_remove -group ieee -location 127.0.0.1 \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + +tao_nsgroup member_list -group <group> + + Lists the member locations of the specified object group. + + Returns Success(0), Error(1) + + Example: + $ACE_ROOT/bin/tao_nsgroup member_list -group ieee \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + 127.0.0.1 + + +tao_nsgroup member_show -group <group> -location <location> + + Displays the object reference that cooresponds to the specified member location + of an object group. + + Returns Success(0), Error(1) + + Example: + + $ACE_ROOT/bin/tao_nsgroup member_show -group ieee -location 127.0.0.1 \ + -ORBInitRef NameService=file://ns.ior -ORBInitRef NamingManager=file://nm.ior + IOR:010000002100000049444c3a6f6d672e6f72672f46542f4e616d696e674d616e616765723a312e300000000001000000000000006c000000010102000e00000031302e3230312e3230302e363400e1841b00000014010f005253541571a65076c60a000000000001000000010000000002000000000000000800000001000000004f41540100000018000000010000000100010001000000010001050901010000000000 + + diff --git a/TAO/utils/nsgroup/nsgroup.cpp b/TAO/utils/nsgroup/nsgroup.cpp new file mode 100644 index 00000000000..da59a31f561 --- /dev/null +++ b/TAO/utils/nsgroup/nsgroup.cpp @@ -0,0 +1,519 @@ +//========================================================================== +/** + * @file nsgroup.cpp + * + * $Id$ + * + * @author Phillip LaBanca <labancap@ociweb.com> + */ +//========================================================================== + + +#include "orbsvcs/Naming/FaultTolerant/nsgroup_svc.h" +#include "ace/Get_Opt.h" + +//============================================================================ +bool +show_help(int argc, ACE_TCHAR *argv[]) +{ + static const ACE_TCHAR options[] = ACE_TEXT("h"); + static const int skip_args = 1; + static const int report_errors = 0; + static const int ordering = ACE_Get_Opt::RETURN_IN_ORDER; + static const int long_only = 0; + + // Not enough arguments indicates help is required + if( argc < 2 ) + { + return true; + } + + // Did they ask for help ? + ACE_Get_Opt get_opts ( + argc, + argv, + options, + skip_args, + report_errors, + ordering, + long_only + ); + + if (get_opts.long_option (ACE_TEXT ("help"),'h') != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" Unable to add long option 'H'\n")), + true); + } + + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'h': // help + + return true; + break; + } + } + return false; +} + +/** + * @class nsgroup + * + * @brief Encapsulate the NS group command line operations in a class. + * + * + */ + +class NSGROUP +{ +public: + + enum NSGROUP_COMMAND { + NSGROUP_NONE, + NSGROUP_HELP, + NSGROUP_GROUP_CREATE, + NSGROUP_GROUP_BIND, + NSGROUP_GROUP_UNBIND, + NSGROUP_GROUP_MODIFY, + NSGROUP_GROUP_LIST, + NSGROUP_GROUP_REMOVE, + NSGROUP_MEMBER_LIST, + NSGROUP_MEMBER_ADD, + NSGROUP_MEMBER_REMOVE, + NSGROUP_MEMBER_SHOW + }; + + /// Constructor + NSGROUP (int argc, ACE_TCHAR **argv); + + /// start the ORB. + int start_orb (void); + + /// parse command line, validate arguments and run the command + int run_cmd (void); + + /// Display command line interface usage + int show_usage( void ); + + const char * group_arg(void) const { return group_arg_; } + const char * policy_arg(void) const { return policy_arg_; } + const char * location_arg(void) const { return location_arg_; } + const char * ior_arg(void) const { return ior_arg_; } + const char * namepath_arg(void) const { return namepath_arg_; } + +private: + + /// parse command line arguments + NSGROUP_COMMAND parse_command_line (void); + +private: + + NS_group_svc svc_; + + int argc_; + ACE_TCHAR **argv_; + + /// parsed command result + NSGROUP_COMMAND nsgroup_cmd_; + + /// parsed command line arguments + const char *group_arg_; + const char *policy_arg_; + const char *typeid_arg_; + const char *location_arg_; + const char *ior_arg_; + const char *namepath_arg_; +}; + + + NSGROUP::NSGROUP (int argc, ACE_TCHAR **argv) + : argc_ (argc), + argv_ (argv), + nsgroup_cmd_(NSGROUP::NSGROUP_NONE) +{ +} + +int +NSGROUP::start_orb (void) +{ + const int RC_SUCCESS = 0; + const int RC_ERROR = -1; + + try + { + +#if 0 + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("start_orb::argc(%u)\n"), this->argc_)); + for( int i = 0; i < this->argc_; ++i){ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("start_orb::argv(%u:%s)\n"), + i, + this->argv_[i])); + } +#endif // + + // Initialise the ORB. + + CORBA::ORB_var orb_ = CORBA::ORB_init (this->argc_, this->argv_); + + if (RC_SUCCESS != svc_.set_orb (orb_)) + { + + ACE_ERROR_RETURN (( LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the ORB.\n")), + RC_ERROR); + } + + ////////////////////////////////////////////////////////////////////////// + // + ////////////////////////////////////////////////////////////////////////// + CORBA::Object_var naming_manager_object = + orb_->resolve_initial_references (ACE_TEXT_ALWAYS_CHAR ("NamingManager")); + + FT_Naming::NamingManager_var naming_manager_ = + FT_Naming::NamingManager::_narrow (naming_manager_object.in ()); + + if (RC_SUCCESS != svc_.set_naming_manager (naming_manager_)) + { + ACE_ERROR_RETURN (( LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to get Naming ") + ACE_TEXT ("Manager Reference\n")), + RC_ERROR); + } + ////////////////////////////////////////////////////////////////////////// + // + ////////////////////////////////////////////////////////////////////////// + CORBA::Object_var naming_object = + orb_->resolve_initial_references(ACE_TEXT_ALWAYS_CHAR ("NameService")); + + CosNaming::NamingContextExt_var name_service_ = + CosNaming::NamingContextExt::_narrow (naming_object.in ()); + + if (RC_SUCCESS != svc_.set_name_context (name_service_)) + { + ACE_ERROR_RETURN (( LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to get Name Service ") + ACE_TEXT ("Reference\n")), + RC_ERROR); + } + ////////////////////////////////////////////////////////////////////////// + // + ////////////////////////////////////////////////////////////////////////// + + } + catch (const CORBA::Exception& ex) + { + ex._tao_print_exception (ACE_TEXT("\nException raised initialising ORB\n")); + return RC_ERROR; + } + + return RC_SUCCESS; + +} + +int +NSGROUP::run_cmd(void) +{ + const int RC_ERROR = -1; + const int RC_BADARG = -2; + + int rc = RC_ERROR; + + switch( parse_command_line () ) + { + + case NSGROUP_HELP: + return show_usage (); + break; + + case NSGROUP_GROUP_CREATE: + rc = svc_.group_create ( group_arg(), policy_arg() ); + break; + + case NSGROUP_GROUP_BIND: + rc = svc_.group_bind ( group_arg(), namepath_arg() ); + break; + + case NSGROUP_GROUP_UNBIND: + rc = svc_.group_unbind ( namepath_arg() ); + break; + + case NSGROUP_GROUP_MODIFY: + rc = svc_.group_modify ( group_arg(), policy_arg() ); + break; + + case NSGROUP_GROUP_LIST: + rc = svc_.group_list (); + break; + + case NSGROUP_GROUP_REMOVE: + rc = svc_.group_remove ( group_arg() ); + break; + + case NSGROUP_MEMBER_LIST: + rc = svc_.member_list ( group_arg() ); + break; + + case NSGROUP_MEMBER_ADD: + rc = svc_.member_add ( group_arg(), location_arg(), ior_arg() ); + break; + + case NSGROUP_MEMBER_REMOVE: + rc = svc_.member_remove ( group_arg(), location_arg() ); + break; + + case NSGROUP_MEMBER_SHOW: + rc = svc_.member_show ( group_arg(), location_arg() ); + break; + + default: + show_usage (); + return rc; + break; + } + + if (rc == RC_BADARG) + { + show_usage (); + } + + return rc; +} + +NSGROUP::NSGROUP_COMMAND +NSGROUP::parse_command_line (void) +{ + #if 0 + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("parse_command_line::argc(%u)\n"), + this->argc_)); + for( int i = 0; i < this->argc_; ++i){ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("parse_command_line::argv(%u:%s)\n"), + i, + this->argv_[i])); + } + #endif + + static const ACE_TCHAR options[] = ACE_TEXT("g:p:t:l:i:n:h"); + static const int skip_args = 1; + static const int report_errors = 0; + static const int ordering = ACE_Get_Opt::PERMUTE_ARGS; + static const int long_only = 1; + + ACE_Get_Opt get_opts ( + this->argc_, + this->argv_, + options, + skip_args, + report_errors, + ordering, + long_only + ); + + this->group_arg_ = 0; + if (get_opts.long_option (ACE_TEXT ("group"), + 'g', + ACE_Get_Opt::ARG_REQUIRED) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Unable to add long option 'g'\n")), + NSGROUP_NONE); + + this->policy_arg_ = 0; + if (get_opts.long_option (ACE_TEXT ("policy"), + 'p', + ACE_Get_Opt::ARG_REQUIRED) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Unable to add long option 'p'\n")), + NSGROUP_NONE); + + this->location_arg_ = 0; + if (get_opts.long_option (ACE_TEXT ("location"), + 'l', + ACE_Get_Opt::ARG_REQUIRED) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Unable to add long option 'l'\n")), + NSGROUP_NONE); + + this->ior_arg_ = 0; + if (get_opts.long_option (ACE_TEXT ("ior"), + 'i', + ACE_Get_Opt::ARG_REQUIRED) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Unable to add long option 'i'\n")), + NSGROUP_NONE); + + this->namepath_arg_ = 0; + if (get_opts.long_option (ACE_TEXT ("name"), + 'n', + ACE_Get_Opt::ARG_REQUIRED) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Unable to add long option 'n'\n")), + NSGROUP_NONE); + + if (get_opts.long_option (ACE_TEXT ("help"), 'h') != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Unable to add long option 'h'\n")), + NSGROUP_NONE); + + int c; + while ((c = get_opts ()) != -1) + switch (c) + { + case 'g': // group + this->group_arg_ = get_opts.opt_arg (); + break; + case 'p': // policy + this->policy_arg_ = get_opts.opt_arg (); + break; + case 'l': // location + this->location_arg_ = get_opts.opt_arg (); + break; + case 'i': // ior + this->ior_arg_ = get_opts.opt_arg (); + break; + case 'n': // name + this->namepath_arg_ = get_opts.opt_arg (); + break; + case 'h': + return NSGROUP_HELP; + } + + // handle non-option arguments + int non_option_arg_count = 0; + for( int i = get_opts.opt_ind (); i < this->argc_; ++i) + { + + non_option_arg_count++; + + + if( ACE_OS::strncmp (this->argv_[i],ACE_TEXT("group_create"), + ACE_OS::strlen (ACE_TEXT("group_create"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_GROUP_CREATE; + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_bind"), + ACE_OS::strlen (ACE_TEXT("group_bind"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_GROUP_BIND; + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_unbind"), + ACE_OS::strlen (ACE_TEXT("group_unbind"))) + == 0 ) + { + nsgroup_cmd_ = NSGROUP_GROUP_UNBIND; + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_modify"), + ACE_OS::strlen (ACE_TEXT("group_modify"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_GROUP_MODIFY; + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_list"), + ACE_OS::strlen (ACE_TEXT("group_list"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_GROUP_LIST; + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("group_remove"), + ACE_OS::strlen (ACE_TEXT("group_remove"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_GROUP_REMOVE; + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("member_list"), + ACE_OS::strlen (ACE_TEXT("member_list"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_MEMBER_LIST; + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("member_add"), + ACE_OS::strlen (ACE_TEXT("member_add"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_MEMBER_ADD; + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("member_remove"), + ACE_OS::strlen (ACE_TEXT("member_remove"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_MEMBER_REMOVE; + + } + else if(ACE_OS::strncmp (this->argv_[i], ACE_TEXT("member_show"), + ACE_OS::strlen (ACE_TEXT("member_show"))) == 0 ) + { + nsgroup_cmd_ = NSGROUP_MEMBER_SHOW; + } + else + { + nsgroup_cmd_ = NSGROUP_NONE; + } + } + + // The command should be the only non option argument + if ( non_option_arg_count > 1 ) { + nsgroup_cmd_ = NSGROUP_NONE; + } + + return nsgroup_cmd_; +} + + +int +NSGROUP::show_usage ( void ) +{ + const int RC_SUCCESS = 0; + + ACE_DEBUG ((LM_INFO, + ACE_TEXT ("Usage:\n") + ACE_TEXT (" %s\n") + ACE_TEXT (" group_create -group <group> -policy <round | rand | least> \n") + ACE_TEXT (" group_bind -group <group> -name <name>\n") + ACE_TEXT (" group_unbind -name <name>\n") + ACE_TEXT (" group_modify -group <group> -policy <round | rand | least> \n") + ACE_TEXT (" group_list\n") + ACE_TEXT (" group_remove -group <group>\n") + ACE_TEXT (" member_list -group <group>\n") + ACE_TEXT (" member_add -group <group> -location <location> -ior <IOR>\n") + ACE_TEXT (" member_remove -group <group> -location <location>\n") + ACE_TEXT (" member_show -group <group> -location <location>\n") + ACE_TEXT (" -help\n") + ACE_TEXT ("\n"), + this->argv_[0])); + return RC_SUCCESS; +} + + +//============================================================================ +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + const int RC_ERROR = -1; + const int RC_SUCCESS = 0; + + int rc = RC_ERROR; + + try + { + + NSGROUP ns_group (argc, argv); + + if ( show_help (argc, argv) ) + { + rc = ns_group.show_usage (); + } + else if ( RC_SUCCESS == ns_group.start_orb ()) + { + rc = ns_group.run_cmd (); + } + + } + catch (const CORBA::Exception&) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Unable to run %C\n"), + argv[0]), + 1); + } + + return (rc == RC_SUCCESS) ? 0 : 1; +} diff --git a/TAO/utils/nsgroup/nsgroup.mpc b/TAO/utils/nsgroup/nsgroup.mpc new file mode 100644 index 00000000000..490334f5247 --- /dev/null +++ b/TAO/utils/nsgroup/nsgroup.mpc @@ -0,0 +1,9 @@ +// $Id$ + +project(nsgroup): orbsvcsexe, ftnaming, naming, install, svc_utils { + install = $(ACE_ROOT)/bin + exename = tao_nsgroup + Source_Files { + nsgroup.cpp + } +} diff --git a/TAO/utils/nsgroup/run_test.pl b/TAO/utils/nsgroup/run_test.pl new file mode 100755 index 00000000000..bd8818e5ffa --- /dev/null +++ b/TAO/utils/nsgroup/run_test.pl @@ -0,0 +1,443 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib "$ENV{ACE_ROOT}/bin"; +use PerlACE::TestTarget; + +my $status = 0; +my $debug_level = 0; +my $redirection_enabled = 0; + + +foreach $i (@ARGV) { + if ($i eq '-debug') { + $debug_level = '10'; + } +} + +#$ENV{ACE_TEST_VERBOSE} = "1"; + +my $server = PerlACE::TestTarget::create_target (1) || die "Create target 1 failed\n"; +my $client = PerlACE::TestTarget::create_target (2) || die "Create target 2 failed\n"; + +## The LoadManager needs to register signals with the ORB's reactor (on +## Windows only) and thus can not use the TP Reactor since it doesn't +## support that kind of thing. So, we swith to the Select MT Reactor. +my $NM_conf = $server->LocalFile ("windows" . $PerlACE::svcconf_ext); + +my $name_mgr_iorbase = "nm.ior"; +my $name_srv_iorbase = "ns.ior"; +my $stdout_file = "test.out"; +my $stderr_file = "test.err"; + +my $server_hostname = $server->HostName (); +my $name_mgr_iorfile = $server->LocalFile ($name_mgr_iorbase); +my $name_server_iorfile = $server->LocalFile ($name_srv_iorbase); + +my $naming_mgr_client_iorfile = $client->LocalFile ($name_mgr_iorbase); +my $name_srv_client_iorfile = $client->LocalFile ($name_srv_iorbase); +my $client_stdout_file = $client->LocalFile ($stdout_file); +my $client_stderr_file = $client->LocalFile ($stderr_file); + +$server->DeleteFile($name_mgr_iorbase); +$server->DeleteFile($name_srv_iorbase); +$client->DeleteFile($name_mgr_iorbase); +$client->DeleteFile($name_srv_iorbase); +$client->DeleteFile($stdout_file); +$client->DeleteFile($stderr_file); + +my $DEBUG_LEVEL = "-ORBDebugLevel $debug_level"; +my $hostname = $server->HostName (); +my $ns_orb_port1 = 10001 + $server->RandomPort (); +my $ns_endpoint1 = "iiop://$hostname:$ns_orb_port1"; + +my $DEF_REF = "-ORBDefaultInitRef corbaloc:iiop:$hostname:$ns_orb_port1"; +#my $NM_REF = "-ORBInitRef NameService=file://$name_srv_client_iorfile"; +#my $RM_REF = "-ORBInitRef NamingManager=file://$naming_mgr_client_iorfile"; +my $NS_REF = "--ns file://$name_srv_client_iorfile"; +my $LOAD_ARG = "$DEF_REF $DEBUG_LEVEL"; + +my $tao_ft_naming = "$ENV{TAO_ROOT}/orbsvcs/Naming_Service/tao_ft_naming"; +my $name_dir = "NameService"; +my $group_dir = "Groups"; +my $ns_args = "$DEBUG_LEVEL " . + "-ORBListenEndPoints $ns_endpoint1 " . + "-h $name_mgr_iorbase " . + "-o $name_srv_iorbase " . + "-v $group_dir " . + "-u $name_dir " . + ($^O eq 'MSWin32' ? "-ORBSvcConf $NM_conf" : ''); + +my $NM = $server->CreateProcess ($tao_ft_naming, $ns_args); +my $NSGROUP = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsgroup"); +my $NSLIST = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nslist"); +my $NSADD = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsadd"); +my $NSDEL = $client->CreateProcess ("$ENV{ACE_ROOT}/bin/tao_nsdel"); + +my $POSITIVE_TEST_RESULT = 0; +my $NEGATIVE_TEST_RESULT = 1; + +sub clean_persistence_dir($$) +{ + my $target = shift; + my $directory_name = shift; + + chdir $directory_name; + opendir(THISDIR, "."); + @allfiles = grep(!/^\.\.?$/, readdir(THISDIR)); + closedir(THISDIR); + foreach $tmp (@allfiles){ + $target->DeleteFile ($tmp); + } + chdir ".."; +} + +# Make sure that the directory to use to hold the persistence data +# exists and is cleaned out. +sub init_persistence_directory($$) +{ + my $target = shift; + my $directory_name = shift; + + if ( ! -d $directory_name ) { + mkdir ($directory_name, 0777); + } else { + clean_persistence_dir ($target, $directory_name); + } +} + +sub cat_file($) +{ + my $file_name = shift; + if (-s $file_name ) # size of file is greater than zero + { + open TESTFILE, $file_name or die "Couldn't open file: $!"; + my @teststring = <TESTFILE>; # read in all of the file + print STDERR "\n@teststring\n"; + close TESTFILE; + } +} + +sub redirect_output() +{ + open(OLDOUT, ">&", \*STDOUT) or die "Can't dup STDOUT: $!"; + open(OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!"; + open STDERR, '>', $client_stderr_file; + open STDOUT, '>', $client_stdout_file; +} + +sub restore_output() +{ + open(STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!"; + open(STDOUT, ">&OLDOUT") or die "Can't dup OLDOUT: $!"; +} + +sub run_client ($$) +{ + my $args = shift; + my $expected_test_result = shift; + + my $arglist = "$LOAD_ARG $args"; + + if ($expected_test_result != $POSITIVE_TEST_RESULT ) { + print STDERR "\n\n======== Running Negative Test ================\n"; + } else { + print STDERR "\n\n======== Running Positive Test ================\n"; + } + print STDERR "$args\n"; + + $NSGROUP->Arguments ($arglist); + + if ($redirection_enabled) { + redirect_output(); + } + + my $client_status = $NSGROUP->SpawnWaitKill ($client->ProcessStartWaitInterval()); + + if ($redirection_enabled) { + restore_output(); + } + + + if ($client_status != $expected_test_result) { + my $time = localtime; + print STDERR "ERROR: client returned $client_status at $time\n"; + if ($redirection_enabled) { + cat_file($client_stderr_file); + cat_file($client_stdout_file); + } + $status = 1; + } +} + +sub run_nsadd($) +{ + print STDERR "\n\n======== Running tao_nsadd ================\n"; + my $args = shift; + $NSADD->Arguments ($args); + + if ($redirection_enabled) { + redirect_output(); + } + + #tao_nsadd --ns file://ns.ior --name iso --ctx + my $client_status = $NSADD->SpawnWaitKill ($client->ProcessStartWaitInterval()); + + if ($redirection_enabled) { + restore_output(); + } + + if ($client_status != $0) { + my $time = localtime; + print STDERR "ERROR: nsadd returned $client_status at $time\n"; + if ($redirection_enabled) { + cat_file($client_stderr_file); + } + $status = 1; + } +} + +sub run_nsdel($) +{ + print STDERR "\n\n======== Running tao_nsdel ================\n"; + my $args = shift; + $NSDEL->Arguments ($args); + + if ($redirection_enabled) { + redirect_output(); + } + + #tao_nsdel --ns file://ns.ior --name iso --destroy + my $client_status = $NSDEL->SpawnWaitKill ($client->ProcessStartWaitInterval()); + + if ($redirection_enabled) { + restore_output(); + } + + if ($client_status != $0) { + my $time = localtime; + print STDERR "ERROR: nsdel returned $client_status at $time\n"; + if ($redirection_enabled) { + cat_file($client_stderr_file); + } + $status = 1; + } +} + +sub run_nslist($) +{ + print STDERR "\n\n======== Running tao_nslist ================\n"; + my $args = shift; + $NSLIST->Arguments ($args); + + if ($redirection_enabled) { + redirect_output(); + } + + #tao_nslist --ns file://ns.ior + my $client_status = $NSLIST->SpawnWaitKill ($client->ProcessStartWaitInterval()); + + if ($redirection_enabled) { + restore_output(); + } + + if ($client_status != $0) { + my $time = localtime; + print STDERR "ERROR: nslist returned $client_status at $time\n"; + if ($redirection_enabled) { + cat_file($client_stderr_file); + } + $status = 1; + } +} + +sub run_clients () +{ + run_client ( + "group_list", + $POSITIVE_TEST_RESULT); + + run_client ( + "group_create -group ieee -policy round", + $POSITIVE_TEST_RESULT); + + run_client ( + "group_create -group ieed -policy rand", + $POSITIVE_TEST_RESULT); + + run_client ( + "group_create -group ieee -policy round", + $NEGATIVE_TEST_RESULT); + + run_client ( + "group_list", + $POSITIVE_TEST_RESULT); + + run_client ( + "member_list -group ieee", + $POSITIVE_TEST_RESULT); + + run_client ( + "member_add -group ieee -location $server_hostname -ior file://$naming_mgr_client_iorfile", + $POSITIVE_TEST_RESULT); + + run_client ( + "member_list -group ieee", + $POSITIVE_TEST_RESULT); + + run_nsadd("$DEF_REF"." --name iso --ctx"); + + run_nslist("$NS_REF"); + + run_client ( + "group_unbind -name iso/ieee", + $NEGATIVE_TEST_RESULT); + + run_nslist("$NS_REF"); + + run_client ( + "group_bind -group ieee -name iso/ieee", + $POSITIVE_TEST_RESULT); + + run_nslist("$NS_REF"); + + run_client ( + "group_modify -group ieee -policy rand", + $POSITIVE_TEST_RESULT); + + # Change the policy back to a supported one before + # doing the nslist to avoid the error message. + run_client ( + "group_modify -group ieee -policy round", + $POSITIVE_TEST_RESULT); + + run_nslist("$NS_REF"); + + run_client ( + "member_add -group ieee -location $server_hostname -ior file://$naming_mgr_client_iorfile", + $NEGATIVE_TEST_RESULT); + + run_client ( + "member_list -group ieee", + $POSITIVE_TEST_RESULT); + + run_client ( + "member_show -group ieee -location $server_hostname", + $POSITIVE_TEST_RESULT); + + run_client ( + "member_remove -group ieee -location $server_hostname", + $POSITIVE_TEST_RESULT); + + run_client ( + "member_list -group ieee", + $POSITIVE_TEST_RESULT); + + run_client ( + "group_remove -group ieee", + $POSITIVE_TEST_RESULT); + + run_client ( + "group_unbind -name iso/ieee", + $POSITIVE_TEST_RESULT); + + run_nslist("$NS_REF"); + + run_client ( + "group_list", + $POSITIVE_TEST_RESULT); + + run_nsdel("$DEF_REF"." --name iso --destroy"); + + # Verify we can handle a non-existent ior to add to the list + run_nsadd("$DEF_REF --name does_not_exist --ior file://thisfiledoesnotexist"); + run_nslist("$NS_REF"); + run_nsdel("$DEF_REF"." --name does_not_exist"); + run_nslist("$NS_REF"); + + + run_client ( + "-help", + $POSITIVE_TEST_RESULT); +} + +print STDERR "\n\n======== Running tao_nsgroup Test================\n"; +print STDERR "\n"; + +print STDERR "This test will check the methods of the tao_nsgroup\n"; +print STDERR "\n"; + +init_persistence_directory ($server, $name_dir ); +init_persistence_directory ($server, $group_dir ); + +################################################################################ +# setup END block to cleanup after exit call +################################################################################ +END +{ + $server->DeleteFile($name_mgr_iorbase); + $server->DeleteFile($name_srv_iorbase); + $client->DeleteFile($name_mgr_iorbase); + $client->DeleteFile($name_srv_iorbase); + $client->DeleteFile($stdout_file); + $client->DeleteFile($stderr_file); + + if ( -d $name_dir ) { + clean_persistence_dir ($server, $name_dir); + rmdir ($name_dir); + } + + if ( -d $group_dir ) { + clean_persistence_dir ($server, $group_dir); + rmdir ($group_dir); + } +} + +################################################################################ +## Start tao_ft_naming Service +################################################################################ + +$server_status = $NM->Spawn (); + +if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + exit 1; +} + +if ($server->WaitForFileTimed ($name_mgr_iorbase, + $server->ProcessStartWaitInterval()) == -1) { + print STDERR "ERROR: cannot find file <$name_mgr_iorbase>\n"; + $NM->Kill (); $NM->TimedWait (1); + exit 1; +} + +print STDERR "Waiting for $name_mgr_iorbase\n"; +if ($server->GetFile ($name_mgr_iorbase) == -1) { + print STDERR "ERROR: cannot retrieve file <$name_mgr_iorbase>\n"; + $NM->Kill (); $NM->TimedWait (1); + exit 1; +} + +if ($client->PutFile ($name_mgr_iorbase) == -1) { + print STDERR "ERROR: cannot set file <$naming_mgr_client_iorfile>\n"; + $NM->Kill (); $NM->TimedWait (1); + exit 1; +} + +run_clients(); + +print STDERR "\n\n====================================================\n"; +print STDERR "\n"; +$server_status = $NM->TerminateWaitKill ($server->ProcessStopWaitInterval()); + +if ($server_status != 0) { + print STDERR "ERROR: server returned $server_status\n"; + $status = 1; +} + + +exit $status; diff --git a/TAO/utils/nsgroup/windows.conf b/TAO/utils/nsgroup/windows.conf new file mode 100644 index 00000000000..e02d5089fce --- /dev/null +++ b/TAO/utils/nsgroup/windows.conf @@ -0,0 +1,3 @@ +# $Id$ + +dynamic Advanced_Resource_Factory Service_Object* TAO_Strategies:_make_TAO_Advanced_Resource_Factory () "-ORBReactorType select_mt" diff --git a/TAO/utils/nsgroup/windows.conf.xml b/TAO/utils/nsgroup/windows.conf.xml new file mode 100644 index 00000000000..37af1733d3b --- /dev/null +++ b/TAO/utils/nsgroup/windows.conf.xml @@ -0,0 +1,10 @@ +<?xml version='1.0'?> +<!-- Converted from windows.conf by svcconf-convert.pl --> +<ACE_Svc_Conf> + <!-- --> + <!-- $Id$ --> + <!-- --> + <dynamic id="Advanced_Resource_Factory" type="Service_Object"> + <initializer path="TAO_Strategies" init="_make_TAO_Advanced_Resource_Factory" params="-ORBReactorType select_mt"/> + </dynamic> +</ACE_Svc_Conf> diff --git a/TAO/utils/nslist/nslist.cpp b/TAO/utils/nslist/nslist.cpp index 6ac49370a10..1633680618d 100644 --- a/TAO/utils/nslist/nslist.cpp +++ b/TAO/utils/nslist/nslist.cpp @@ -41,15 +41,19 @@ namespace const char *myTree = "|", // Default string to draw tree "tram-lines" *myNode = "+"; // Default string to draw tree node end-points - int - sizeMyTree, // Initialised by main to strlen (myTree) - sizeMyNode, // Initialised by main to strlen (myNode) - maxDepth= 0; // Limit to display depth (default unlimited) + int sizeMyTree; // Initialised by main to strlen (myTree) + int sizeMyNode; // Initialised by main to strlen (myNode) + int maxDepth= 0; // Limit to display depth (default unlimited) ACE_Time_Value rtt = ACE_Time_Value::zero; // relative roundtrip timeout for ctx + const CORBA::ULong MAX_COUNT_DEFAULT = 100; + CORBA::ULong max_count = MAX_COUNT_DEFAULT; + void list_context (const CosNaming::NamingContext_ptr, - int level); + int level, + CORBA::ULong max_count); + CORBA::Object_ptr set_rtt(CORBA::Object_ptr obj); //========================================================================== @@ -271,7 +275,7 @@ namespace ACE_DEBUG ((LM_DEBUG, "\n")); if (xc.in ()) { - list_context (xc.in (), level + 1); + list_context (xc.in (), level + 1, max_count); } } else @@ -301,14 +305,15 @@ namespace //========================================================================== void - list_context (const CosNaming::NamingContext_ptr nc, int level) + list_context (const CosNaming::NamingContext_ptr nc, + int level, + CORBA::ULong max_count) { CosNaming::BindingIterator_var it; CosNaming::BindingList_var bl; - CORBA::ULong const CHUNK = 100; NestedNamingContexts::add (nc); - nc->list (CHUNK, bl, it); + nc->list (max_count, bl, it); show_chunk (nc, bl.in (), level); @@ -318,7 +323,7 @@ namespace do { - more = it->next_n (CHUNK, bl); + more = it->next_n (max_count, bl); show_chunk (nc, bl.in (), level); } while (more); @@ -567,14 +572,15 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) else if (1 != ACE_OS::strlen(*(++argv))) { ACE_DEBUG ((LM_DEBUG, - "Error: --kindsep takes a single character (not %s)\n", *argv)); + ACE_TEXT ("Error: --kindsep takes a single ") + ACE_TEXT ("character (not %s)\n"), *argv)); failed = true; } else if (showNSonly) { ACE_DEBUG ((LM_DEBUG, - "Error: --nsior and --kindsep are " - "both specified\n")); + ACE_TEXT ("Error: --nsior and --kindsep are ") + ACE_TEXT ("both specified\n"))); failed = true; } else @@ -591,14 +597,14 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) else if (!--argc || !ACE_OS::ace_isdigit (ACE_TEXT_ALWAYS_CHAR (*(++argv))[0])) { ACE_DEBUG ((LM_DEBUG, - "Error: --max requires a number\n")); + ACE_TEXT ("Error: --max requires a number\n"))); failed = true; } else if (showNSonly) { ACE_DEBUG ((LM_DEBUG, - "Error: --nsior and --max are " - "both specified\n")); + ACE_TEXT ("Error: --nsior and --max are ") + ACE_TEXT ("both specified\n"))); failed = true; } else @@ -609,22 +615,53 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) if (rtt != ACE_Time_Value::zero) { ACE_DEBUG ((LM_DEBUG, - "Error: --rtt given more than once\n")); + ACE_TEXT ("Error: --rtt given more than once\n"))); + failed = true; + } + else if (!--argc || !ACE_OS::ace_isdigit (ACE_TEXT_ALWAYS_CHAR (*(++argv))[0])) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Error: --rtt requires a number\n"))); + failed = true; + } + else + rtt.set (ACE_OS::atoi (*argv), 0); + } + else if (0 == ACE_OS::strcmp(*argv, ACE_TEXT ("--count"))) + { + if (max_count != MAX_COUNT_DEFAULT) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Error: --count given more than once\n"))); failed = true; } else if (!--argc || !ACE_OS::ace_isdigit (ACE_TEXT_ALWAYS_CHAR (*(++argv))[0])) { ACE_DEBUG ((LM_DEBUG, - "Error: --rtt requires a number\n")); + ACE_TEXT ("Error: --count requires a number\n"))); failed = true; } else - rtt.set(ACE_OS::atoi (*argv), 0); + { + CORBA::ULong count = ACE_OS::strtoul (ACE_TEXT_ALWAYS_CHAR (*argv), 0, 10); + if (count > 0) + { + max_count = count; + } + else + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Error: --count requires a number") + ACE_TEXT (" greater than 0\n"))); + failed = true; + } + } } else { ACE_DEBUG ((LM_DEBUG, - "Unknown option %s\n", *argv)); + ACE_TEXT ("Unknown option %s\n"), + *argv)); failed = true; } } @@ -632,20 +669,22 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) if (failed) { - ACE_DEBUG ((LM_DEBUG, "\n%s options:\n" - " --nsior {Display the naming service IOR and exit}\n" - "or:\n" - " --ns <ior> {Defaults to standard NameService}\n" - " --ior {Display ior for end points}\n" - " --ctxior {Display ior for naming contexts}\n" - " --tree \"xx\" {Defaults to | for drawing tramlines}\n" - " --node \"xx\" {Defaults to + for drawing nodes}\n" - " --noloops {Inhibit drawing of naming context loops}\n" - " --name <name> {Lists sub-set, defaults to root}\n" - " --ctxsep <character> {<name> Context separation character, default /}\n" - " --kindsep <character> {<name> ID/Kind separation character, default .}\n" - " --max <number> {If given, limits displayed sub-context depth}\n", - " --rtt <seconds> {If given, sets the relative round trip timeout policy}\n", + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n%s options:\n") + ACE_TEXT (" --nsior {Display the naming service IOR and exit}\n") + ACE_TEXT ("or:\n") + ACE_TEXT (" --ns <ior> {Defaults to standard NameService}\n") + ACE_TEXT (" --ior {Display ior for end points}\n") + ACE_TEXT (" --ctxior {Display ior for naming contexts}\n") + ACE_TEXT (" --tree \"xx\" {Defaults to | for drawing tramlines}\n") + ACE_TEXT (" --node \"xx\" {Defaults to + for drawing nodes}\n") + ACE_TEXT (" --noloops {Inhibit drawing of naming context loops}\n") + ACE_TEXT (" --name <name> {Lists sub-set, defaults to root}\n") + ACE_TEXT (" --ctxsep <character> {<name> Context separation character, default /}\n") + ACE_TEXT (" --kindsep <character> {<name> ID/Kind separation character, default .}\n") + ACE_TEXT (" --max <number> {If given, limits displayed sub-context depth}\n") + ACE_TEXT (" --rtt <seconds> {If given, sets the relative round trip timeout policy}\n") + ACE_TEXT (" --count <number> {If given, sets the maximum ") + ACE_TEXT ("number of entries per request from the NameService}\n"), pname)); orb->destroy (); return 1; @@ -718,7 +757,7 @@ ACE_TMAIN (int argc, ACE_TCHAR *argv[]) ACE_DEBUG ((LM_DEBUG, "Naming Service: %C\n---------------\n", ((showCtxIOR)? str.in () : ""))); - list_context (root_nc.in (), 1); + list_context (root_nc.in (), 1, max_count); } } catch (const CORBA::Exception& ex) diff --git a/TAO/utils/utils.mwc b/TAO/utils/utils.mwc index eb8edb1783e..e6c25693aa5 100644 --- a/TAO/utils/utils.mwc +++ b/TAO/utils/utils.mwc @@ -10,4 +10,6 @@ workspace { // must have mfc=1 in $ACE_ROOT/bin/MakeProjectCreator/config/default.features to generate Makefile for wxNamingViewer NamingViewer + + nsgroup } |