diff options
author | Johnny Willemsen <jwillemsen@remedy.nl> | 2017-03-31 14:16:51 +0200 |
---|---|---|
committer | Johnny Willemsen <jwillemsen@remedy.nl> | 2017-03-31 14:16:51 +0200 |
commit | 09ac8a3f7ac83cac488913546187a8180e138db1 (patch) | |
tree | 43ca2a0272a32482d06ccb3b4d7044a2f37d6ac0 | |
parent | bb4a031ea9f1373dfd65ea52339608d09d9f588c (diff) | |
parent | a65d9ccf57ff9ba922285c66468b53421b93ab9a (diff) | |
download | ATCD-09ac8a3f7ac83cac488913546187a8180e138db1.tar.gz |
Merge branch 'master' of git://github.com/DOCGroup/ATCD
23 files changed, 1506 insertions, 1234 deletions
diff --git a/ACE/ace/INET_Addr.cpp b/ACE/ace/INET_Addr.cpp index cf25f94196e..a9b3649142d 100644 --- a/ACE/ace/INET_Addr.cpp +++ b/ACE/ace/INET_Addr.cpp @@ -364,7 +364,6 @@ ACE_INET_Addr::set (u_short port_number, } this->reset_i (); - ACE_OS::memset (&this->inet_addr_, 0, sizeof this->inet_addr_); #if defined ACE_HAS_IPV6 && defined ACE_USES_IPV4_IPV6_MIGRATION if (address_family == AF_UNSPEC && !ACE::ipv6_enabled ()) diff --git a/ACE/tests/INET_Addr_Test.cpp b/ACE/tests/INET_Addr_Test.cpp index 0910a62b24a..816c2eb2b7d 100644 --- a/ACE/tests/INET_Addr_Test.cpp +++ b/ACE/tests/INET_Addr_Test.cpp @@ -387,6 +387,20 @@ int run_main (int, ACE_TCHAR *[]) #if defined (ACE_HAS_IPV6) if (ACE::ipv6_enabled ()) { + { + ACE_INET_Addr addr; + int old_type = addr.get_type(); + addr.set(12345, ACE_TEXT ("localhost")); + if (addr.get_type() != old_type) { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("IPv6 set failed: before addr.set(12345), addr.type() = %d\n") + ACE_TEXT (" after addr.set(12345), addr.type() = %d\n"), + old_type, + addr.get_type ())); + status = 1; + } + } + const char *ipv6_addresses[] = { "1080::8:800:200c:417a", // unicast address "ff01::101", // multicast address diff --git a/TAO/orbsvcs/orbsvcs/FT_NamingReplication.idl b/TAO/orbsvcs/orbsvcs/FT_NamingReplication.idl index d499c6d1321..ef78d5ea9ed 100644 --- a/TAO/orbsvcs/orbsvcs/FT_NamingReplication.idl +++ b/TAO/orbsvcs/orbsvcs/FT_NamingReplication.idl @@ -3,6 +3,7 @@ /** * @file FT_NamingReplication.idl * + * * This file is part of Fault Tolerant Naming Service in support of * replication between redundant servers. * @@ -20,12 +21,17 @@ module FT_Naming { - enum ChangeType { NEW, UPDATED, DELETED }; + enum ChangeType { NEW, UPDATED, DELETED, NONE }; exception NotAvailable { }; + exception InvalidPeer + { + string reason; + }; + /* * A structure that describes the updated element in a Naming Service */ @@ -39,6 +45,7 @@ module FT_Naming struct ReplicaInfo { + boolean combined; CosNaming::NamingContext root_context; FT_Naming::NamingManager naming_manager; }; @@ -55,6 +62,28 @@ module FT_Naming ChangeType change_type; }; + enum EntityKind { + ctx_name, + obj_grp + }; + + union UpdateInfo switch (EntityKind) { + case ctx_name : NamingContextUpdate ctx; + case obj_grp : ObjectGroupUpdate grp; + }; + + typedef sequence<UpdateInfo> UpdateInfoSeq; + + interface UpdatePushNotifier + { + oneway void register_peer (in UpdatePushNotifier peer, + in ReplicaInfo info, + in unsigned long long initial_seq_num); + + void notify_update (in unsigned long long seq_num, + inout UpdateInfoSeq info); + }; + interface ReplicationManager { /* diff --git a/TAO/orbsvcs/orbsvcs/FT_Naming_Serv.mpc b/TAO/orbsvcs/orbsvcs/FT_Naming_Serv.mpc index b114898507e..0cf779b7de3 100644 --- a/TAO/orbsvcs/orbsvcs/FT_Naming_Serv.mpc +++ b/TAO/orbsvcs/orbsvcs/FT_Naming_Serv.mpc @@ -1,4 +1,5 @@ // -*- MPC -*- + project (FT_Naming_Serv) : orbsvcslib, orbsvcs_output, ftnaming, ftnaming_replication, install, naming_serv, naming, portablegroup, loadbalancing, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro { sharedname = TAO_FT_Naming_Serv idlflags += -Wb,export_macro=TAO_FtNaming_Export -Wb,export_include=orbsvcs/Naming/FaultTolerant/ftnaming_export.h @@ -39,4 +40,3 @@ project (FT_Naming_Serv) : orbsvcslib, orbsvcs_output, ftnaming, ftnaming_replic } } - diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp index f5fc60b5f05..4178727920b 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp @@ -4,6 +4,7 @@ /** * @file FT_Naming_Manager.cpp * + * * @author Kevin Stanley <stanleyk@ociweb.com> */ //============================================================================= @@ -66,7 +67,6 @@ TAO_FT_Naming_Manager::TAO_FT_Naming_Manager (void) global_strategy_ (::FT_Naming::ROUND_ROBIN), built_in_balancing_strategy_name_ (1), object_group_property_name_ (1) - { // The name for the property which contains the load balancing strategy value this->built_in_balancing_strategy_name_.length (1); @@ -859,4 +859,10 @@ TAO_FT_Naming_Manager::set_object_group_stale (const FT_Naming::ObjectGroupUpdat this->group_factory_.set_object_group_stale (group_info); } +void +TAO_FT_Naming_Manager::set_replicator (TAO_FT_Naming_Replication_Manager *repl) +{ + this->group_factory_.set_replicator (repl); +} + TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h index 7b89990f47a..ae7868261e6 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h @@ -4,6 +4,7 @@ /** * @file FT_Naming_Manager.h * + * * @author Kevin Stanley <stanleyk@ociweb.com> */ //============================================================================= @@ -18,6 +19,7 @@ #include "orbsvcs/FT_NamingManagerS.h" #include "orbsvcs/FT_NamingManagerC.h" +#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h" #include "orbsvcs/PortableGroup/PG_FactoryRegistry.h" #include "orbsvcs/PortableGroup/PG_Properties_Support.h" #include "orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h" @@ -39,6 +41,8 @@ namespace TAO class Storable_Factory; } +class TAO_FT_Naming_Replication_Manager; + /** * @class TAO_FT_Naming_Manager * @brief Implements the NamingManager interface for the Fault @@ -59,6 +63,8 @@ public: /// Constructor. TAO_FT_Naming_Manager (void); + void set_replicator (TAO_FT_Naming_Replication_Manager *repl); + /** * @name FT::NamingManager Methods * diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp index 5e18dcd5421..ce69843d5a6 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.cpp @@ -5,172 +5,474 @@ * @file FT_Naming_Replication_Manager.cpp * * @author Kevin Stanley <stanleyk@ociweb.com> + * @author Phil Mesnier */ //============================================================================= #include "orbsvcs/Log_Macros.h" #include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h" #include "orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h" -#include "tao/corba.h" -#include "ace/SStringfwd.h" +#include "tao/ORB_Core.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_strings.h" +#include "ace/OS_NS_ctype.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" -::FT_Naming::ReplicationManager_var -TAO_FT_Naming_Replication_Manager::peer_replica_ (0); +TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_FT_Naming_Replication_Manager::TAO_FT_Naming_Replication_Manager ( - TAO_FT_Naming_Server *naming_svr, - const char* repl_mgr_name) - : naming_svr_ (naming_svr), - repl_mgr_name_ (repl_mgr_name) +FT_Update_Replicant_i::FT_Update_Replicant_i (TAO_FT_Naming_Replication_Manager &owner) + :owner_ (owner) { } - -TAO_FT_Naming_Replication_Manager::~TAO_FT_Naming_Replication_Manager(void) +void +FT_Update_Replicant_i::notify_update (CORBA::ULongLong seq_num, + FT_Naming::UpdateInfoSeq& info) { - this->reference_ = ::FT_Naming::ReplicationManager::_nil (); + CORBA::ULongLong expected = ++this->owner_.replica_seq_num_; + if (expected < seq_num) + { + if (TAO_debug_level > 0) + { + ORBSVCS_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) FT_Update_Replicant_i::notify_updated_entity ") + ACE_TEXT ("expected %Lu got %Lu\n"), + expected, seq_num )); + } + this->owner_.replica_seq_num_ = seq_num; + } + else if (expected > seq_num) + { + if (TAO_debug_level > 0) + { + ORBSVCS_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) FT_Update_Replicant_i::notify_updated_entity ") + ACE_TEXT ("expected %Lu got %Lu\n"), + expected, seq_num )); + } + --this->owner_.replica_seq_num_; + } + this->owner_.server_.update_info (info); } void -TAO_FT_Naming_Replication_Manager::initialize (CORBA::ORB_ptr orb, - PortableServer::POA_ptr repl_mgr_poa) +FT_Update_Replicant_i::register_peer (FT_Naming::UpdatePushNotifier_ptr peer, + const FT_Naming::ReplicaInfo& iors, + CORBA::ULongLong seq_num) { - ACE_UNUSED_ARG (orb); - repl_mgr_poa_ = PortableServer::POA::_duplicate (repl_mgr_poa); - PortableServer::ObjectId_var id = - PortableServer::string_to_ObjectId (this->repl_mgr_name_.c_str ()); - CORBA::Object_var obj = repl_mgr_poa_->id_to_reference (id.in ()); - this->reference_ = ::FT_Naming::ReplicationManager::_narrow (obj.in ()); + this->owner_.peer_ = FT_Naming::UpdatePushNotifier::_duplicate (peer); + this->owner_.replica_seq_num_ = seq_num; + this->owner_.server_.update_iors (iors); } -::FT_Naming::ReplicaInfo* -TAO_FT_Naming_Replication_Manager::register_replica ( - ::FT_Naming::ReplicationManager_ptr replica, - const ::FT_Naming::ReplicaInfo & replica_info) +//--------------------------------------------------------------------------- + +TAO_FT_Naming_Replication_Manager::TAO_FT_Naming_Replication_Manager (TAO_FT_Naming_Server &owner) + : me_ (), + peer_ (), + seq_num_ (0), + replica_seq_num_ (0), + server_ (owner), + orb_ (), + reactor_ (0), + lock_ (), + notified_ (false), + to_send_ (10), + endpoint_ (owner.ft_endpoint ()), + update_delay_ (owner.ft_update_delay ()), + replica_ior_ () { - ACE_TRACE ( ACE_TEXT("TAO_FT_Naming_Replication_Manager::register_replica")); +} - ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, - ace_mon, - this->lock_, - CORBA::INTERNAL ()); +TAO_FT_Naming_Replication_Manager::~TAO_FT_Naming_Replication_Manager(void) +{ +} - // Store a copy of the provided reference and other ReplicaInfo - peer_replica_ = ::FT_Naming::ReplicationManager::_duplicate (replica); +void +TAO_FT_Naming_Replication_Manager::init_orb (void) +{ + int argc = 8; + ACE_TCHAR *argv[11]; + argv[0] = ACE_OS::strdup (ACE_TEXT ("")); + argv[1] = ACE_OS::strdup (ACE_TEXT ("-ORBIgnoreDefaultSvcConfFile")); + argv[2] = ACE_OS::strdup (ACE_TEXT ("-ORBGestalt")); + argv[3] = ACE_OS::strdup (ACE_TEXT ("Local")); + argv[4] = ACE_OS::strdup (ACE_TEXT ("-ORBSvcConfDirective")); + argv[5] = ACE_OS::strdup (ACE_TEXT ("static Client_Strategy_Factory \"-ORBConnectStrategy Blocked -ORBDefaultSyncScope server\"")); + argv[6] = ACE_OS::strdup (ACE_TEXT ("-ORBDottedDecimalAddresses")); + argv[7] = ACE_OS::strdup (ACE_TEXT ("1")); + if (endpoint_.length ()) + { + argv[8] = ACE_OS::strdup (ACE_TEXT ("-ORBListenEndpoints")); + argv[9] = ACE_OS::strdup (ACE_TEXT_CHAR_TO_TCHAR (endpoint_.c_str ())); + argc += 2; + } + else + { + argv[8] = 0; + argv[9] = 0; + } + argv[10] = 0; + + this->orb_ = CORBA::ORB_init (argc, argv, "replicator_orb"); + this->reactor_ = this->orb_->orb_core ()->reactor (); + CORBA::Object_var obj = this->orb_->resolve_initial_references ("RootPOA"); + PortableServer::POA_var poa = PortableServer::POA::_narrow (obj.in ()); + PortableServer::ServantBase_var servant; + ACE_NEW (servant, FT_Update_Replicant_i (*this)); + PortableServer::ObjectId_var oid = poa->activate_object (servant.in ()); + obj = poa->id_to_reference (oid.in ()); + this->me_ = + FT_Naming::UpdatePushNotifier::_narrow (obj.in ()); + PortableServer::POAManager_var mgr = poa->the_POAManager (); + mgr->activate (); +} + +char * +TAO_FT_Naming_Replication_Manager::ior (void) +{ + return this->orb_->object_to_string (this->me_.in ()); +} - // Store the provided peer references - this->naming_svr_->peer_root_context (replica_info.root_context); - this->naming_svr_->peer_naming_manager (replica_info.naming_manager); +bool +TAO_FT_Naming_Replication_Manager::peer_available (void) +{ + return !CORBA::is_nil (this->peer_.in ()); +} - // Return my references to the peer - ::FT_Naming::ReplicaInfo* my_info = new ::FT_Naming::ReplicaInfo; +void +TAO_FT_Naming_Replication_Manager::stop (void) +{ + if (this->reactor_ == 0) + { + return; + } + this->orb_->shutdown (true); + this->wait(); +} - my_info->root_context = this->naming_svr_->my_root_context (); +int +TAO_FT_Naming_Replication_Manager::svc (void) +{ + if (this->reactor_ == 0) + { + return 0; + } + try + { + + this->orb_->run (); + } + catch (const CORBA::SystemException &ex) + { + if (TAO_debug_level > 0) + { + ORBSVCS_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) TAO_FT_Naming_Replication_Manager::svc caught %C\n"), + ex._name ())); + } + } + return 0; +} - my_info->naming_manager = this->naming_svr_->my_naming_manager (); - return my_info; +int +TAO_FT_Naming_Replication_Manager::handle_exception (ACE_HANDLE ) +{ + ACE_OS::sleep (this->update_delay_); + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, mon, this->lock_, -1); + if (!this->peer_available()) + { + mon.release (); + if (!this->peer_init_i ()) + { + this->server_.no_replica(); + } + mon.acquire(); + this->notified_ = false; + return 0; + } + if (this->refresh_peer_) + { + this->refresh_peer_ = false; + mon.release (); + if (!this->update_peer_registration()) + { + mon.acquire (); + this->notified_ = false; + return 0; + } + mon.acquire (); + } + + if (this->to_send_.length () == 0) + { + this->notified_ = false; + return 0; + } + if (CORBA::is_nil (this->peer_)) + { + this->to_send_.length (0); + this->notified_ = false; + return 0; + } + try + { + CORBA::Long len = this->to_send_.length (); + FT_Naming::UpdateInfoSeq payload (len); + payload.length (len); + CORBA::Long p = 0; + for (CORBA::Long l = 0; l < len; l++) + { + payload[p++] = this->to_send_[l]; + } + payload.length (p); + this->to_send_.length (0); + CORBA::ULongLong seq = ++this->seq_num_; + mon.release (); + + this->peer_->notify_update (seq, payload); + } + catch (const CORBA::Exception &) + { + this->peer_ = FT_Naming::UpdatePushNotifier::_nil (); + } + this->notified_ = false; + return 0; } void -TAO_FT_Naming_Replication_Manager::notify_updated_object_group ( - const ::FT_Naming::ObjectGroupUpdate & group_info) +TAO_FT_Naming_Replication_Manager::send_objgrp_update (PortableGroup::ObjectGroupId id, + FT_Naming::ChangeType change) { - ACE_TRACE ( ACE_TEXT ("TAO_FT_Naming_Replication_Manager::") - ACE_TEXT ("notify_updated_object_group")); - - // Make sure that we have a valid naming server - ACE_ASSERT (naming_svr_); - int result = this->naming_svr_->update_object_group (group_info); + if (this->reactor_ == 0) + { + return; + } + ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_); + CORBA::Long len = this->to_send_.length (); + bool found = false; + for (CORBA::Long i = len -1; !found && i >= 0; i--) + { + if (this->to_send_[i]._d() == FT_Naming::obj_grp && + this->to_send_[i].grp().id == id) + { + found = true; + FT_Naming::ChangeType pending = this->to_send_[i].grp().change_type; + if (pending == FT_Naming::DELETED) + { + if (change == FT_Naming::UPDATED) + { + // shouldn't have an update after a deleted + change = FT_Naming::DELETED; + } + else if (change == FT_Naming::NEW) + {// put both in cueue + found = false; + break; + } + } + this->to_send_[i].grp().change_type = change; + } + } + if (!found) + { + this->to_send_.length (len+1); + FT_Naming::ObjectGroupUpdate ogu; + ogu.id = id; + ogu.change_type = change; + this->to_send_[len].grp(ogu); + } + if (!this->notified_) + { + this->notified_ = true; + this->reactor_->notify (this); + } +} - if (result != 0) - ORBSVCS_ERROR ((LM_ERROR, - ACE_TEXT ("Unable to update object group.\n"))); +void +TAO_FT_Naming_Replication_Manager::send_context_update (const ACE_CString & name, + FT_Naming::ChangeType change) +{ + if (this->reactor_ == 0) + { + return; + } + + ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_); + CORBA::Long len = this->to_send_.length (); + bool found = false; + + for (CORBA::Long i = len -1; !found && i >= 0; i--) + { + if (this->to_send_[i]._d() == FT_Naming::ctx_name && + ACE_OS::strcmp (this->to_send_[i].ctx().context_name, + name.c_str()) == 0) + { + found = true; + FT_Naming::ChangeType pending = this->to_send_[i].ctx().change_type; + if (pending == FT_Naming::DELETED) + { + if (change == FT_Naming::UPDATED) + { + // shouldn't have an update after a deleted + change = FT_Naming::DELETED; + } + else if (change == FT_Naming::NEW) + {// put both in cueue + found = false; + break; + } + } + this->to_send_[i].ctx().change_type = change; + } + } + + if (!found) + { + this->to_send_.length (len+1); + FT_Naming::NamingContextUpdate ncu; + ncu.context_name = CORBA::string_dup (name.c_str()); + ncu.change_type = change; + this->to_send_[len].ctx(ncu); + } + if (!this->notified_) + { + this->notified_ = true; + this->reactor_->notify (this); + } } void -TAO_FT_Naming_Replication_Manager::notify_updated_context ( - const ::FT_Naming::NamingContextUpdate & context_info) +TAO_FT_Naming_Replication_Manager::send_registration (bool use_combo_refs) { - ACE_TRACE (ACE_TEXT ("TAO_FT_Naming_Replication_Manager::") - ACE_TEXT ("notify_updated_context")); - ACE_ASSERT (naming_svr_); - int result = this->naming_svr_->update_naming_context (context_info); - if (result != 0) - { - ORBSVCS_ERROR ((LM_ERROR, - ACE_TEXT ("Error while updating naming context.\n"))); - } + if (TAO_debug_level > 1) + { + ORBSVCS_DEBUG((LM_INFO, + ACE_TEXT("(%P|%t) Registering with peer naming server \n"))); + } + if (this->reactor_ == 0) + { + return; + } + + ACE_GUARD (TAO_SYNCH_MUTEX, mon, this->lock_); + this->send_combos_ = use_combo_refs; + if (!this->notified_) + { + this->refresh_peer_ = true; + this->notified_ = true; + this->reactor_->notify (this); + } } -::FT_Naming::ReplicationManager_ptr -TAO_FT_Naming_Replication_Manager::peer_replica (void) +bool +TAO_FT_Naming_Replication_Manager::peer_init_i (void) { - ACE_TRACE (ACE_TEXT ("TAO_FT_Naming_Replication_Manager::peer_replica")); - // Return a copy of the stored peer to the requester - return ::FT_Naming::ReplicationManager::_duplicate (peer_replica_.in ()); + CORBA::Object_var obj = this->orb_->string_to_object (replica_ior_.c_str()); + bool non_exist = true; + bool was_nil = CORBA::is_nil (this->peer_.in()); + if (!CORBA::is_nil (obj.in ())) + { + try + { + this->peer_ = FT_Naming::UpdatePushNotifier::_narrow (obj.in()); + non_exist = (this->peer_->_non_existent() == 1); + } + catch (const CORBA::Exception& ex) + { + if (TAO_debug_level > 0) + { + ORBSVCS_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) FT_Repl_mgr::peer_init_i ") + ACE_TEXT ("caught %C\n"), ex._name())); + } + } + } + if (non_exist) + { + this->peer_ = FT_Naming::UpdatePushNotifier::_nil(); + return was_nil; + } + + if (this->peer_available ()) + { + if (!this->update_peer_registration ()) + { + this->peer_ = FT_Naming::UpdatePushNotifier::_nil (); + return was_nil; + } + } + else + { + return was_nil; + } + + if (this->to_send_.length () > 0) + { + this->notified_ = true; + this->reactor_->notify (this); + } + return true; } -int -TAO_FT_Naming_Replication_Manager::register_with_peer_replica ( - ::FT_Naming::ReplicationManager_ptr replica, - CosNaming::NamingContext_ptr nc, - ::FT_Naming::NamingManager_ptr nm) -{ - ACE_TRACE (ACE_TEXT ("TAO_FT_Naming_Replication_Manager::") - ACE_TEXT ("register_with_peer_replica")); - - int result = 0; - ::FT_Naming::ReplicaInfo my_info; - { // Guard the access to the Replication Manager state - ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, - ace_mon, - this->lock_, - CORBA::INTERNAL ()); - - // Store a copy of the peer reference for future access - this->peer_replica_ = - ::FT_Naming::ReplicationManager::_duplicate (replica); - - my_info.root_context = CosNaming::NamingContext::_duplicate (nc); - my_info.naming_manager = ::FT_Naming::NamingManager::_duplicate (nm); - } - - try { - ::FT_Naming::ReplicationManager_var my_ref = - this->reference (); - - // Register with the peer replica - ::FT_Naming::ReplicaInfo_var peer_info = - this->peer_replica_->register_replica (my_ref.in (), - my_info); - - ACE_GUARD_THROW_EX (TAO_SYNCH_MUTEX, - ace_mon, - this->lock_, - CORBA::INTERNAL ()); - - // Store the returned references locally - this->naming_svr_->peer_root_context (peer_info->root_context. in ()); - this->naming_svr_->peer_naming_manager (peer_info->naming_manager.in ()); - } - catch (const CORBA::Exception& ex) { - // Unable to contact the peer replica. - if (TAO_debug_level > 1) - ex._tao_print_exception ( - ACE_TEXT ("TAO_FT_Naming_Replication_Manager::") - ACE_TEXT ("register_with_peer_replica\n")); - result = -1; - } - - return result; - -} - -::FT_Naming::ReplicationManager_ptr -TAO_FT_Naming_Replication_Manager::reference (void) -{ - ACE_TRACE (ACE_TEXT ("TAO_FT_Naming_Replication_Manager::reference")); - return ::FT_Naming::ReplicationManager::_duplicate (reference_.in ()); +bool +TAO_FT_Naming_Replication_Manager::update_peer_registration (void) +{ + FT_Naming::ReplicaInfo info; + info.combined = this->send_combos_; + if (this->send_combos_) + { + info.root_context = this->server_.ft_root_context (); + info.naming_manager = this->server_.ft_naming_manager (); + this->send_combos_ = false; + } + else + { + info.root_context = this->server_.my_root_context (); + info.naming_manager = this->server_.my_naming_manager (); + } + bool success = false; + try + { + this->peer_->register_peer (this->me_, info, this->seq_num_); + success = true; + } + catch (const CORBA::Exception &) + { + } + return success; +} + + +bool +TAO_FT_Naming_Replication_Manager::init_peer (void) +{ + ACE_TString replica_ior_file = this->server_.replica_ior_filename (true); + + if (TAO_debug_level > 1) + { + ORBSVCS_DEBUG ((LM_INFO, + ACE_TEXT("Resolving Naming replica from file %C\n"), + replica_ior_file.c_str())); + } + + if (ACE_OS::access (replica_ior_file.c_str (), F_OK) != 0) + { + this->peer_ = + FT_Naming::UpdatePushNotifier::_nil(); + return false; + } + + this->replica_ior_ = ACE_CString ("file://") + +#if defined (ACE_USES_WCHAR) + ACE_CString (ACE_TEXT_ALWAYS_CHAR (replica_ior_file.c_str())); +#else + replica_ior_file; +#endif /* ACE_USES_WCHAR */ + return true; } + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h index a751bf7e3cc..b812777263b 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h @@ -1,113 +1,114 @@ -// -*- C++ -*- +/* -*- C++ -*- */ //============================================================================= /** - * @file FT_Naming_Replication_Manager.h - * - * @author Kevin Stanley <stanleyk@ociweb.com> - */ +* @file FT_Naming_Replication_Manager.h +* +* +* Based on the replicator class used in the ImR. +* +*/ //============================================================================= +#ifndef FT_REPLICATOR_H +#define FT_REPLICATOR_H -#ifndef TAO_FT_NAMING_REPLICATION_MANAGER_H -#define TAO_FT_NAMING_REPLICATION_MANAGER_H - -#include /**/ "ace/pre.h" - -#include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h" -#include "orbsvcs/FT_NamingReplicationS.h" -#include "ace/Recursive_Thread_Mutex.h" +#include "ace/config-lite.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) -#pragma once +# pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "orbsvcs/FT_NamingReplicationC.h" +#include "orbsvcs/FT_NamingReplicationS.h" +#include "ace/Bound_Ptr.h" +#include "ace/Vector_T.h" +#include "ace/Task.h" + +#include <set> TAO_BEGIN_VERSIONED_NAMESPACE_DECL +class TAO_FT_Naming_Replication_Manager; class TAO_FT_Naming_Server; -/** - * @class TAO_FT_Naming_Replication_Manager - * @brief The class that implements the FT_Naming::ReplicationManager - * interface. - */ -class TAO_FtNaming_Export TAO_FT_Naming_Replication_Manager - : public virtual POA_FT_Naming::ReplicationManager +class FT_Update_Replicant_i : public virtual POA_FT_Naming::UpdatePushNotifier { public: + FT_Update_Replicant_i (TAO_FT_Naming_Replication_Manager &owner); - /// Create a Replication Manager and provide it with the naming server - /// to be updated whenever notified by the peer replica - TAO_FT_Naming_Replication_Manager(TAO_FT_Naming_Server *naming_svr, - const char* repl_mgr_name); - - virtual ~TAO_FT_Naming_Replication_Manager(void); - - /// Initialize the naming manager. This will provide the poa to - /// the naming manager and underlying components for use in - /// managing the object groups. - void initialize (CORBA::ORB_ptr orb, - PortableServer::POA_ptr root_poa); - - - /// Implementation of the FT_Naming::ReplicationManager interface - virtual ::FT_Naming::ReplicaInfo * register_replica ( - ::FT_Naming::ReplicationManager_ptr replica, - const ::FT_Naming::ReplicaInfo & replica_info); - - /// This method implements the operation invoked by the peer replica when an - /// object group is updated on the remote process. - virtual void notify_updated_object_group ( - const FT_Naming::ObjectGroupUpdate & group_info); + virtual void register_peer (::FT_Naming::UpdatePushNotifier_ptr peer, + const ::FT_Naming::ReplicaInfo & info, + CORBA::ULongLong seq_num); - /// This method implements the operation invoked by the peer replica when an - /// naming context is updated on the remote process. - virtual void notify_updated_context ( - const FT_Naming::NamingContextUpdate & group_info); + virtual void notify_update (CORBA::ULongLong seq_num, + FT_Naming::UpdateInfoSeq& info); - /// Retrieve the object reference for the peer naming service - /// ReplicationManager. - static FT_Naming::ReplicationManager_ptr peer_replica (void); - - /* - * Utilities for implementing the FT_Naming::ReplicationManager - */ - - /// Stores the peer in the peer_replica_ data member and invokes the - /// register_replica interface method with the peer. Returns 0 if - /// successful and -1 if unable to contact the peer. - int register_with_peer_replica (FT_Naming::ReplicationManager_ptr replica, - CosNaming::NamingContext_ptr nc, - FT_Naming::NamingManager_ptr rm); - - /// The object reference for this servant instance - FT_Naming::ReplicationManager_ptr reference (void); - -protected: - - // The object which implements the naming service and the object manager - TAO_FT_Naming_Server *naming_svr_; +private: + TAO_FT_Naming_Replication_Manager &owner_; +}; - // Store the reference to the replica object reference - // For now only a single replica is supported. - static FT_Naming::ReplicationManager_var peer_replica_; +/** +* @class Replicator +* +* @brief Manages the notification between the peers whenever a +* context or object group changes state. The goal is to ensure +* the servicing ORB never blocks for want of a channel to notify +* the peer. +* +* This goal is attained by running a separate ORB in a separate thread, +* and using the ORB's reactor notification mechanism as a way to ensure +* the application ORB never blocks. +*/ + +class TAO_FT_Naming_Replication_Manager : public ACE_Task_Base +{ +public: + friend class FT_Update_Replicant_i; - PortableServer::POA_var repl_mgr_poa_; + typedef FT_Naming::UpdatePushNotifier_var Replica_var; + typedef FT_Naming::UpdatePushNotifier_ptr Replica_ptr; - ACE_CString repl_mgr_name_; + TAO_FT_Naming_Replication_Manager (TAO_FT_Naming_Server &owner); - FT_Naming::ReplicationManager_var reference_; + virtual ~TAO_FT_Naming_Replication_Manager(void); - /// Lock used to serialize access to fault tolerant extensions - /// to Naming Service. + virtual int svc (void); + virtual int handle_exception (ACE_HANDLE ); + + void stop (void); + void send_context_update (const ACE_CString &ctx, + FT_Naming::ChangeType update); + void send_objgrp_update (PortableGroup::ObjectGroupId id, + FT_Naming::ChangeType update); + + void init_orb (void); + + bool init_peer (void ); + bool peer_init_i (void ); + void send_registration (bool use_combo); + bool update_peer_registration (); + + bool peer_available (void); + char * ior (void); + +private: + Replica_var me_; + Replica_var peer_; + CORBA::ULongLong seq_num_; + CORBA::ULongLong replica_seq_num_; + TAO_FT_Naming_Server &server_; + CORBA::ORB_var orb_; + ACE_Reactor *reactor_; TAO_SYNCH_MUTEX lock_; - + bool notified_; + FT_Naming::UpdateInfoSeq to_send_; + ACE_CString endpoint_; + ACE_Time_Value update_delay_; + ACE_CString replica_ior_; + bool send_combos_; + bool refresh_peer_; }; TAO_END_VERSIONED_NAMESPACE_DECL -#include /**/ "ace/post.h" - -#endif /* TAO_FT_NAMING_REPLICATION_MANAGER_H */ +#endif /* FT_REPLICATOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp index 0de2088acd3..506d4efafde 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.cpp @@ -4,6 +4,7 @@ /** * @file FT_Naming_Server.cpp * + * * @author Kevin Stanley <stanleyk@ociweb.com> */ //============================================================================= @@ -30,7 +31,6 @@ #include "ace/Get_Opt.h" #include "ace/OS_NS_unistd.h" -#include "tao/IORTable/IORTable.h" #include "tao/ORB_Core.h" #include "tao/debug.h" @@ -39,7 +39,7 @@ #include "tao/debug.h" #include "tao/default_ports.h" - +#include "tao/IORTable/IORTable.h" #include "tao/IORManipulation/IORManip_Loader.h" #if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 @@ -48,33 +48,143 @@ #include "tao/AnyTypeCode/Any.h" -const ACE_TCHAR* -TAO_FT_Naming_Server::primary_replica_ior_filename = +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +const ACE_TCHAR* primary_replica_ior_filename = ACE_TEXT ("ns_replica_primary.ior"); -const ACE_TCHAR* -TAO_FT_Naming_Server::backup_replica_ior_filename = +const ACE_TCHAR* backup_replica_ior_filename = ACE_TEXT ("ns_replica_backup.ior"); + +TAO_FTNS_Notifier::TAO_FTNS_Notifier (TAO_FT_Naming_Server &owner, bool iors) + : owner_ (owner), + iors_ (iors) +{ +} + +int +TAO_FTNS_Notifier::handle_exception (ACE_HANDLE ) +{ + if (this->iors_) + owner_.update_iors_i(); + else + owner_.update_info_i(); + return 0; +} + /// Default Constructor. TAO_FT_Naming_Server::TAO_FT_Naming_Server (void) - : replica_id_ (0), + : TAO_Naming_Server (IOR_ARRAY_SIZE), naming_manager_ (), - replication_manager_ (0), - combined_naming_service_ior_file_name_ (0), - combined_naming_manager_ior_file_name_ (0), - naming_manager_ior_file_name_ (0), - naming_manager_persistence_file_name_ (0), + replicator_ (0), use_object_group_persistence_ (0), - server_role_ (STANDALONE) + server_role_ (STANDALONE), + ft_endpoint_ (""), + ft_update_delay_ (ACE_Time_Value::zero), + registered_ (false), + ior_notifier_ (*this, true), + info_notifier_ (*this, false), + u_iors_(), + u_infos_(), + ior_lock_(), + info_lock_() + +{ +} + +void +TAO_FT_Naming_Server::update_info_i (void) +{ + while (true) + { + FT_Naming::UpdateInfoSeq_var block; + { + ACE_GUARD(TAO_SYNCH_MUTEX, guard, this->info_lock_); + if (this->u_infos_.dequeue_head(block.out()) == -1) + { + break; + } + } + + for (CORBA::ULong i = 0; i < block->length(); i++) + { + FT_Naming::UpdateInfo &infoRef = (*block)[i]; + + if (infoRef._d() == FT_Naming::ctx_name) + { + this->update_naming_context (infoRef.ctx()); + } + else + { + this->update_object_group (infoRef.grp()); + } + } + } +} + +void +TAO_FT_Naming_Server::update_info (FT_Naming::UpdateInfoSeq &infos) +{ + + CORBA::ULong count = infos.length(); + FT_Naming::UpdateInfo* guts = infos.get_buffer(true); + FT_Naming::UpdateInfoSeq* block = 0; + ACE_NEW(block, FT_Naming::UpdateInfoSeq (count,count,guts,true)); + { + ACE_GUARD(TAO_SYNCH_MUTEX, guard, this->info_lock_); + this->u_infos_.enqueue_tail (block); + } + + this->orb_->orb_core ()->reactor ()->notify (&this->info_notifier_); +} + +void +TAO_FT_Naming_Server::update_iors_i (void) +{ + while (true) + { + FT_Naming::ReplicaInfo rep; + { + ACE_GUARD(TAO_SYNCH_MUTEX, guard, this->ior_lock_); + if (this->u_iors_.dequeue_head(rep) == -1) + { + break; + } + } + + if (rep.combined) + { + this->update_ior (FT_Naming::ctx_name, rep.root_context.in()); + this->update_ior (FT_Naming::obj_grp, rep.naming_manager.in()); + } + else + { + this->combine_iors (FT_Naming::ctx_name, rep.root_context.in()); + this->combine_iors (FT_Naming::obj_grp, rep.naming_manager.in()); + this->replicator_->send_registration (true); + } + } +} + +void +TAO_FT_Naming_Server::update_iors (const FT_Naming::ReplicaInfo & iors ) { + { + ACE_GUARD(TAO_SYNCH_MUTEX, guard, this->ior_lock_); + this->u_iors_.enqueue_tail(iors); + } + this->orb_->orb_core ()->reactor ()->notify (&this->ior_notifier_); } + int TAO_FT_Naming_Server::init_with_orb (int argc, ACE_TCHAR *argv [], CORBA::ORB_ptr orb) { + ACE_NEW_RETURN (this->replicator_, TAO_FT_Naming_Replication_Manager (*this), -1); + // Invoke the base class initialization to setup the naming service // What follows after that are the initialization steps to support // fault tolerance and load balancing with the FT_Naming_Manager @@ -96,9 +206,17 @@ TAO_FT_Naming_Server::init_with_orb (int argc, } TAO::Storable_Factory * object_group_storable_factory; +#if defined (ACE_USES_WCHAR) + ACE_CString alt_group_dir = + ACE_TEXT_ALWAYS_CHAR (this->object_group_dir_.c_str()); + ACE_NEW_RETURN (object_group_storable_factory, + TAO::Storable_FlatFileFactory (alt_group_dir), + -1); +#else ACE_NEW_RETURN (object_group_storable_factory, TAO::Storable_FlatFileFactory (this->object_group_dir_), -1); +#endif /* ACE_USES_WCHAR */ naming_manager_.set_object_group_storable_factory ( object_group_storable_factory); @@ -114,45 +232,21 @@ TAO_FT_Naming_Server::init_with_orb (int argc, if (result != 0) return result; - try { - - // Initialize the replication manager - result = init_replication_manager_with_orb (argc, argv, orb); - if (result != 0) - return result; - - // Setup the pairing with peer - result = init_replication_pairing (); - - // If we successfully paired, we are a backup and - // we have a peer_root_context, then export the combined IORs - if ((result == 0) && - (this->server_role_ == TAO_FT_Naming_Server::BACKUP) && - (!CORBA::is_nil (peer_root_context_.in ()))) - { // If we successfully initialized the replication manager and we are - // a backup server, then we should export the multi-profile - // references to files. No need to write out the IOR if we - - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server ") - ACE_TEXT ("Writing combined IOR.\n"))); - - result = export_ft_naming_references (); - } - else if (result == 1) - { // Primary was started in the past, but it is not currently - // accessible for pairing. Primary will initiate pairing when - // it is restarted. - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("Unable to pair with primary\n"))); - result = 0; // This is a normal situation on backup restart. - } - } + try + { + // Initialize the replicator if necessary + result = init_replicator (); + if (result != 0) + return result; + + // Setup the pairing with peer + init_replication_pairing (); + this->naming_manager_.set_replicator (this->replicator_); + } catch (const CORBA::Exception& ex) { // No exceptions are expected. - ex._tao_print_exception ( - ACE_TEXT ("TAO_FT_Naming_Server::init_with_orb")); + ex._tao_print_exception + (ACE_TEXT ("TAO_FT_Naming_Server::init_with_orb")); return -1; } @@ -160,13 +254,8 @@ TAO_FT_Naming_Server::init_with_orb (int argc, } int -TAO_FT_Naming_Server::init_naming_manager_with_orb (int argc, - ACE_TCHAR *argv [], - CORBA::ORB_ptr orb) +TAO_FT_Naming_Server::init_naming_manager_with_orb (int, ACE_TCHAR *[], CORBA::ORB_ptr orb) { - ACE_UNUSED_ARG (argc); - ACE_UNUSED_ARG (argv); - int result = 0; // Need to lock during startup to prevent access of partially @@ -176,441 +265,161 @@ TAO_FT_Naming_Server::init_naming_manager_with_orb (int argc, this->lock_, CORBA::INTERNAL ()); - try { - - // Get the POA from the ORB. - CORBA::Object_var poa_object = - orb->resolve_initial_references ("RootPOA"); - - if (CORBA::is_nil (poa_object.in ())) + try { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT(" (%P|%t) ERROR: Unable to initialize the POA.\n")), - -1); - } - - if (result != 0) - return result; - - // Get the POA object. - this->root_poa_ = PortableServer::POA::_narrow (poa_object.in ()); - - // Get the POA_Manager. - PortableServer::POAManager_var poa_manager = - this->root_poa_->the_POAManager (); - - int numPolicies = 2; + if (CORBA::is_nil (this->orb_.in ())) + { + this->orb_ = CORBA::ORB::_duplicate (orb); + } - CORBA::PolicyList policies (numPolicies); - policies.length (numPolicies); + // Get the POA from the ORB. + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA"); - // Id Assignment policy - policies[0] = - this->root_poa_->create_id_assignment_policy (PortableServer::USER_ID); + if (CORBA::is_nil (poa_object.in ())) + { + ORBSVCS_ERROR_RETURN ((LM_ERROR, + ACE_TEXT(" (%P|%t) ERROR: Unable to initialize the POA.\n")), + -1); + } - // Lifespan policy - policies[1] = - this->root_poa_->create_lifespan_policy (PortableServer::PERSISTENT); + if (result != 0) + return result; - /* Register the naming manager with a POA - * TODO: 1) Error checking - * 2) Write IOR to file - * 3) Persistence for Object Group Manager - */ + this->root_poa_ = PortableServer::POA::_narrow (poa_object.in ()); + PortableServer::POAManager_var poa_manager = + this->root_poa_->the_POAManager (); - // We use a different POA, otherwise the user would have to change - // the object key each time it invokes the server. - this->naming_manager_poa_ = this->root_poa_->create_POA ( - "NamingManager", - poa_manager.in (), - policies); - // Warning! If create_POA fails, then the policies won't be - // destroyed and there will be hell to pay in memory leaks! + int numPolicies = 2; + CORBA::PolicyList policies (numPolicies); + policies.length (numPolicies); + policies[0] = + this->root_poa_->create_id_assignment_policy (PortableServer::USER_ID); + policies[1] = + this->root_poa_->create_lifespan_policy (PortableServer::PERSISTENT); - // Creation of the new POAs over, so destroy the Policy_ptr's. - for (CORBA::ULong i = 0; - i < policies.length (); - ++i) - { - CORBA::Policy_ptr policy = policies[i]; - policy->destroy (); - } + this->naming_manager_poa_ = + this->root_poa_->create_POA ("NamingManager", + poa_manager.in (), + policies); - poa_manager->activate (); + for (CORBA::ULong i = 0; i < policies.length (); ++i) + { + CORBA::Policy_ptr policy = policies[i]; + policy->destroy (); + } + poa_manager->activate (); - // Register with the POA. - PortableServer::ObjectId_var id = - PortableServer::string_to_ObjectId ( - "NamingManager"); + PortableServer::ObjectId_var id = + PortableServer::string_to_ObjectId ("NamingManager"); - this->naming_manager_poa_->activate_object_with_id ( - id.in (), - &this->naming_manager_); + this->naming_manager_poa_->activate_object_with_id (id.in (), &this->naming_manager_); + this->assign (size_t(GROUP), true, this->naming_manager_poa_->id_to_reference (id.in ())); - CORBA::Object_var nm_obj = - this->naming_manager_poa_->id_to_reference (id.in ()); + if (write (size_t(GROUP)) != 0) + return -1; - this->my_naming_manager_ = FT_Naming::NamingManager::_narrow (nm_obj.in ()); - this->naming_manager_ior_ = - orb->object_to_string (this->my_naming_manager_.in ()); + this->naming_manager_.initialize (this->orb_.in (), + this->naming_manager_poa_.in ()); - // write out our object reference to the file defined in the -h option - if (this->naming_manager_ior_file_name_ != 0) - { - if (this->write_ior_to_file ( - this->naming_manager_ior_.in (), - ACE_TEXT_ALWAYS_CHAR (this->naming_manager_ior_file_name_)) != 0) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: Unable to open %s ") - ACE_TEXT ("for writing:(%u) %p\n"), - this->naming_manager_ior_file_name_, - ACE_ERRNO_GET, - ACE_TEXT ("TAO_Naming_Server::") - ACE_TEXT ("init_naming_manager_with_orb")), - -1); - } } - - this->naming_manager_.initialize (this->orb_.in (), - this->naming_manager_poa_.in ()); - - } catch (const CORBA::Exception& ex) { ex._tao_print_exception ( - ACE_TEXT ("TAO_FT_Naming_Server::init_naming_manager_with_orb")); + ACE_TEXT ("TAO_FT_Naming_Server::init_naming_manager_with_orb")); return -1; } - - // Make the Object Group Manager easily accessible using Interoperable - // Naming Service IORs CORBA::Object_var table_object = orb->resolve_initial_references ("IORTable"); - IORTable::Table_var adapter = + IORTable::Table_var ior_table = IORTable::Table::_narrow (table_object.in ()); - if (CORBA::is_nil (adapter.in ())) - { - ORBSVCS_ERROR ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: TAO_FT_Naming_Server::") - ACE_TEXT ("init_naming_manager_with_orb - Nil IORTable\n"))); - } - else - { - CORBA::String_var ior = this->naming_manager_ior (); - adapter->bind ("NamingManager", ior.in ()); - } - + if (!CORBA::is_nil (ior_table)) + { + ior_table->bind ("NamingManager", + this->iors_[GROUP].ior_.c_str ()); + } return 0; } int -TAO_FT_Naming_Server::init_replication_manager_with_orb (int argc, - ACE_TCHAR *argv [], - CORBA::ORB_ptr orb) +TAO_FT_Naming_Server::init_replicator (void) { - ACE_UNUSED_ARG (argc); - ACE_UNUSED_ARG (argv); + if (this->server_role_ == STANDALONE ) + return 0; - // Need to lock during startup to prevent access of partially initialized - // variables ACE_GUARD_THROW_EX (ACE_SYNCH_RECURSIVE_MUTEX, ace_mon, this->lock_, CORBA::INTERNAL ()); - - // If redundancy is not requested, then do not initialize the - // replication manager - if (!this->use_redundancy_) - return 0; - - int result = 0; - - try { - - // Get the POA from the ORB. - CORBA::Object_var poa_object = - orb->resolve_initial_references ("RootPOA"); - - if (CORBA::is_nil (poa_object.in ())) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT(" (%P|%t) ERROR: Unable to initialize the POA.\n")), - -1); - } - - if (result != 0) - return result; - - // Get the POA object. - this->root_poa_ = PortableServer::POA::_narrow (poa_object.in ()); - - // Get the POA_Manager. - PortableServer::POAManager_var poa_manager = - this->root_poa_->the_POAManager (); - - int numPolicies = 2; - - CORBA::PolicyList policies (numPolicies); - policies.length (numPolicies); - - // Id Assignment policy - policies[0] = - this->root_poa_->create_id_assignment_policy (PortableServer::USER_ID); - - // Lifespan policy - policies[1] = - this->root_poa_->create_lifespan_policy (PortableServer::PERSISTENT); - - // We use a different POA, otherwise the user would have to change - // the object key each time it invokes the server. - this->replication_manager_poa_ = this->root_poa_->create_POA ( - ACE_TEXT_ALWAYS_CHAR (this->replica_id_ ), - poa_manager.in (), - policies); - - // Warning! If create_POA fails, then the policies won't be - // destroyed and there will be hell to pay in memory leaks! - - // Creation of the new POAs over, so destroy the Policy_ptr's. - for (CORBA::ULong i = 0; - i < policies.length (); - ++i) + try { - CORBA::Policy_ptr policy = policies[i]; - policy->destroy (); + this->replicator_->init_orb(); + this->replicator_->activate(); + this->iors_[REPLICATOR].ior_ = this->replicator_->ior (); + this->iors_[REPLICATOR].filename_ = this->replica_ior_filename (false); + this->write(REPLICATOR); } - - poa_manager->activate (); - - // Construct the replication manager providing it with its ID - ACE_NEW_RETURN (this->replication_manager_, - TAO_FT_Naming_Replication_Manager ( - this, - ACE_TEXT_ALWAYS_CHAR (this->replica_id_)), - -1); - - // Register with the POA. - PortableServer::ObjectId_var id = - PortableServer::string_to_ObjectId ( - ACE_TEXT_ALWAYS_CHAR (this->replica_id_)); - - this->replication_manager_poa_->activate_object_with_id ( - id.in (), - this->replication_manager_); - - CORBA::Object_var repl_mgr_ref = - this->replication_manager_poa_->id_to_reference (id.in ()); - - this->replication_manager_ior_ = - orb->object_to_string (repl_mgr_ref.in ()); - - // Provide the replication manager its ORB and POA - this->replication_manager_->initialize ( - this->orb_.in (), - this->replication_manager_poa_.in ()); - } catch (const CORBA::Exception& ex) { ex._tao_print_exception ( - ACE_TEXT ("TAO_FT_Naming_Server::init_replication_manager_with_orb.\n")); + ACE_TEXT ("TAO_FT_Naming_Server::init_replicator\n")); return -1; } - // Success return 0; } -int -TAO_FT_Naming_Server::init_replication_pairing (void) +ACE_TString +TAO_FT_Naming_Server::replica_ior_filename (bool peer_ior_file) const { - - ACE_CString primary_file_name ( - ACE_TEXT_ALWAYS_CHAR (this->persistence_file_name_)); - primary_file_name += "/"; - primary_file_name += - ACE_TEXT_ALWAYS_CHAR (TAO_FT_Naming_Server::primary_replica_ior_filename); - - ACE_CString backup_file_name ( - ACE_TEXT_ALWAYS_CHAR (this->persistence_file_name_)); - backup_file_name += "/"; - backup_file_name += - ACE_TEXT_ALWAYS_CHAR (TAO_FT_Naming_Server::backup_replica_ior_filename); - - if (this->server_role_ == PRIMARY) - { // We are the primary - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server ") - ACE_TEXT ("is a primary\n"))); - - // Write out this replicas IOR for the backup to use to bootstrap - CORBA::String_var replication_ior = naming_service_ior (); - this->write_ior_to_file ( - this->replication_manager_ior_.in (), - primary_file_name.c_str ()); - - // Check if there is already a backup IOR file. If so, then the backup - // may be up and running so we should register with it. - CORBA::Object_var backup_ior; - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server reading ") - ACE_TEXT ("backup ior file\n"))); - - if ((ACE_OS::access (primary_file_name.c_str (), - R_OK) == 0) && - this->read_reference_from_file (backup_file_name.c_str (), - backup_ior.out ()) == 0) - {// Success in reading backup IOR file - // Store the backup reference as our peer - FT_Naming::ReplicationManager_var peer_ref = - FT_Naming::ReplicationManager::_narrow (backup_ior.in ()); - - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server ") - ACE_TEXT ("narrowing IOR\n"))); - if (CORBA::is_nil (peer_ref.in ())) - ORBSVCS_ERROR_RETURN ( - (LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: IOR in file %s is not ") - ACE_TEXT ("a FT_Naming::ReplicationManager\n"), - primary_file_name.c_str ()), - -1); - - try { - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ( - (LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server registering ") - ACE_TEXT ("with backup.\n"))); - - // Register with the backup - CosNaming::NamingContext_var root = this->my_root_context (); - FT_Naming::NamingManager_var nm = this->my_naming_manager (); - - int registration_result = - this->replication_manager_->register_with_peer_replica ( - peer_ref.in (), - root.in (), - nm.in ()); - - if (registration_result == 0) - { - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server ") - ACE_TEXT ("registered with backup.\n"))); - } - else - { - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server:Backup peer ") - ACE_TEXT ("replica not started yet.\n"))); - } - } - catch (const CORBA::Exception& ex) - { - // Its Ok that we were unable to contact the backup peer. - // It has apparently not started yet. - // It will register with the primary when it starts up. - ex._tao_print_exception ( - ACE_TEXT ("Backup peer replica not started yet.\n")); - } - } - else - { - // Could not get the backup replica from the IOR file, which is OK. - // The backup will register with us in the future. - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server no Replica ") - ACE_TEXT ("IOR file. Waiting for registration.\n"))); - } + ServerRole desired = this->server_role_; + if (peer_ior_file) + { + desired = (desired == PRIMARY) ? BACKUP : PRIMARY; } - else if (this->server_role_ == TAO_FT_Naming_Server::BACKUP) - { // We are the backup - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server:Is a Backup\n"))); - - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server writing ") - ACE_TEXT ("replica ior\n"))); - // Write out the backup ior for use by the primary if it must be restarted. - this->write_ior_to_file ( - replication_manager_ior_.in (), - backup_file_name.c_str ()); - - CORBA::Object_var primary_ref = CORBA::Object::_nil (); + ACE_TString path = this->persistence_dir_; + path += ACE_DIRECTORY_SEPARATOR_STR; + if (desired == PRIMARY) + { + path += primary_replica_ior_filename; + } + else + { + path += backup_replica_ior_filename; + } + return path; +} +void +TAO_FT_Naming_Server::init_replication_pairing (void) +{ + if (this->server_role_ == STANDALONE) + { if (TAO_debug_level > 3) ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server ") - ACE_TEXT ("reading primary ior file\n"))); - // Check for the primary IOR. We must have it to bootstrap the redundant - // naming pair. - if ((ACE_OS::access (primary_file_name.c_str (), R_OK) == 0) && - (this->read_reference_from_file (primary_file_name.c_str (), - primary_ref.out ()) == 0)) - { // There is a primary IOR file, so we must be restarting. - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server ") - ACE_TEXT ("storing the primary reference ior\n"))); - // Store the primary reference as our peer - FT_Naming::ReplicationManager_var peer_ref = - FT_Naming::ReplicationManager::_narrow (primary_ref.in ()); - - if (CORBA::is_nil (peer_ref.in ())) - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: IOR in file %s ") - ACE_TEXT ("is not a FT_Naming::ReplicationManager\n"), - primary_file_name.c_str ()), - -1); + ACE_TEXT ("(%P|%t) - FT_Naming_Server:Is ") + ACE_TEXT ("Standalone\n"))); + } - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server ") - ACE_TEXT ("backup registering with primary.\n"))); - // Register with the primary - CosNaming::NamingContext_var root = this->my_root_context (); - FT_Naming::NamingManager_var nm = this->my_naming_manager (); - int registration_result = - this->replication_manager_->register_with_peer_replica (peer_ref.in (), - root.in (), - nm.in ()); - if (registration_result == -1) - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("(%P|%t) Backup unable to ") - ACE_TEXT ("register with the primary at this time.\n")), - 1); - } - else - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: No primary IOR ") - ACE_TEXT ("available. Have you started the ") - ACE_TEXT ("primary? Exiting.\n")), - -1); - } + if (this->replicator_->init_peer ()) + { + this->replicator_->send_registration (false); } - else - {// We are neither a primary or replica, but running in standalone mode - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server:Is Standalone\n"))); +} - } +void +TAO_FT_Naming_Server::no_replica () +{ - return 0; + if (this->server_role_ == BACKUP) + { + this->recover_iors (); + } } + int TAO_FT_Naming_Server::parse_args (int argc, ACE_TCHAR *argv[]) @@ -620,7 +429,8 @@ TAO_FT_Naming_Server::parse_args (int argc, // Define the arguments for primary and backup get_opts.long_option (ACE_TEXT ("primary"), ACE_Get_Opt::NO_ARG); get_opts.long_option (ACE_TEXT ("backup"), ACE_Get_Opt::NO_ARG); - bool role_defined = false; + get_opts.long_option (ACE_TEXT ("ftendpoint"), ACE_Get_Opt::ARG_REQUIRED); + get_opts.long_option (ACE_TEXT ("ftupdatedelay"), ACE_Get_Opt::ARG_REQUIRED); int c; int size; @@ -641,7 +451,6 @@ TAO_FT_Naming_Server::parse_args (int argc, int f_opt_used = 0; int u_opt_used = 0; int r_opt_used = 0; - int v_opt_used = 0; // TODO: remove unsupported options with FT Naming Server @@ -652,16 +461,16 @@ TAO_FT_Naming_Server::parse_args (int argc, ++TAO_debug_level; break; case 'o': // outputs this servers naming service ior to a file. - this->ior_file_name_ = get_opts.opt_arg (); + this->iors_[ROOT].filename_ = get_opts.opt_arg (); break; case 'c': // outputs the multi-profile naming service ior file - this->combined_naming_service_ior_file_name_ = get_opts.opt_arg (); + this->iors_[FT_ROOT].filename_ = get_opts.opt_arg (); break; case 'g': // outputs the mutli-profile object group manager ior file - this->combined_naming_manager_ior_file_name_ = get_opts.opt_arg (); + this->iors_[FT_GROUP].filename_ = get_opts.opt_arg (); break; case 'h': // outputs the object group manager ior to a file - this->naming_manager_ior_file_name_ = get_opts.opt_arg (); + this->iors_[GROUP].filename_ = get_opts.opt_arg (); break; case 'l': this->naming_manager_.set_global_strategy (get_opts.opt_arg ()); @@ -694,24 +503,24 @@ TAO_FT_Naming_Server::parse_args (int argc, this->base_address_ = (void *) address; break; case 'f': - this->persistence_file_name_ = get_opts.opt_arg (); + this->persistence_dir_ = get_opts.opt_arg (); f_opt_used = 1; break; #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) case 'r': this->use_redundancy_ = 1; this->use_storable_context_ = 1; - this->persistence_file_name_ = get_opts.opt_arg (); + this->persistence_dir_ = get_opts.opt_arg (); r_opt_used = 1; break; case 'u': this->use_storable_context_ = 1; - this->persistence_file_name_ = get_opts.opt_arg (); + this->persistence_dir_ = get_opts.opt_arg (); u_opt_used = 1; break; case 'v': this->use_object_group_persistence_ = 1; - this->object_group_dir_ = ACE_TEXT_ALWAYS_CHAR (get_opts.opt_arg ()); + this->object_group_dir_ = get_opts.opt_arg (); v_opt_used = 1; break; @@ -727,25 +536,38 @@ TAO_FT_Naming_Server::parse_args (int argc, const ACE_TCHAR *long_option = get_opts.long_option (); if (ACE_OS::strcmp (long_option, ACE_TEXT ("backup")) == 0) { - this->replica_id_ = ACE_TEXT ("Backup"); this->server_role_ = TAO_FT_Naming_Server::BACKUP; - role_defined = true; + break; } else if (ACE_OS::strcmp (long_option, ACE_TEXT ("primary")) == 0) { - this->replica_id_ = ACE_TEXT ("Primary"); this->server_role_ = TAO_FT_Naming_Server::PRIMARY; - role_defined = true; + break; + } + else if (ACE_OS::strcasecmp (long_option, + ACE_TEXT ("ftendpoint")) == 0) + { + this->ft_endpoint_ = ACE_TEXT_ALWAYS_CHAR (get_opts.opt_arg()); + break; + } + else if (ACE_OS::strcasecmp (long_option, + ACE_TEXT ("ftupdatedelay")) == 0) + { + this->ft_update_delay_ = + ACE_Time_Value (0, 1000 * ACE_OS::atoi (get_opts.opt_arg())); + break; } } - break; case '?': default: + ORBSVCS_ERROR ((LM_ERROR,ACE_TEXT ("Unknown arg %c\n"), c )); ORBSVCS_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("usage: %s\n") ACE_TEXT ("--primary (not used with --backup)\n") ACE_TEXT ("--backup (not used with --primary)\n") + ACE_TEXT ("--FtEndpoint <endpoint for FT ORB>\n") + ACE_TEXT ("--FtUpdateDelay <msec>\n") ACE_TEXT ("-d\n") ACE_TEXT ("-c <multi-profile_name_service_ior_file>\n") ACE_TEXT ("-o <name_svc_ior_output_file>\n") @@ -758,7 +580,7 @@ TAO_FT_Naming_Server::parse_args (int argc, ACE_TEXT ("-m <1=enable multicast,") ACE_TEXT (" 0=disable multicast(default)>\n") ACE_TEXT ("-n <num_threads>\n") - ACE_TEXT ("-f <persistence_file_name>\n") + ACE_TEXT ("-f <persistence_directory>\n") ACE_TEXT ("-u <storable_persistence_directory") ACE_TEXT (" (not used with -f)>\n") ACE_TEXT ("-v <storable_object_group_persistence") @@ -779,39 +601,20 @@ TAO_FT_Naming_Server::parse_args (int argc, // If naming context or object group persistence is being used then // enable backup/restore compability of persitent files. - if (u_opt_used || r_opt_used || v_opt_used) + if (u_opt_used || v_opt_used || r_opt_used) { TAO::Storable_Base::use_backup_default = true; } - if (!role_defined) - { // No role specified, so we will become a STANDALONE server - this->replica_id_ = ACE_TEXT ("Standalone"); - this->server_role_ = TAO_FT_Naming_Server::STANDALONE; - // User has not provided a role, so we will not use redundancy option - if (this->use_redundancy_ == 1) - { - ORBSVCS_ERROR ((LM_ERROR, - ACE_TEXT ("INFO: Standalone name server ignoring ") - ACE_TEXT ("-r option, treating it as -u instead.\n") - ACE_TEXT ("Start a '--primary' and a '--backup' ") - ACE_TEXT ("server to run as a Fault Tolerant ") - ACE_TEXT ("Naming Service. \n"))); - this->use_redundancy_ = 0; - } - - } - else + if (server_role_ != STANDALONE) { - // Only the backup should be requested to write the multi-profile IOR - // so fail if (role is backup) is the same as (no filename) - if ((this->server_role_ == TAO_FT_Naming_Server::BACKUP) == - (this->combined_naming_service_ior_file_name_ == 0)) + if ((this->server_role_ == BACKUP) == + (this->iors_[FT_ROOT].filename_.length() == 0)) ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("ERROR: Must export the multi-profile ") - ACE_TEXT ("IOR (using '-c' option) from the backup ") - ACE_TEXT ("server.\n\n")), - -1); + ACE_TEXT ("ERROR: Must export the multi-profile ") + ACE_TEXT ("IOR (using '-c' option) from the backup ") + ACE_TEXT ("server.\n\n")), + -1); } return 0; } @@ -819,34 +622,49 @@ TAO_FT_Naming_Server::parse_args (int argc, int TAO_FT_Naming_Server::fini (void) { - // Destroy the child POAs created when initializing - // the FT Naming Service + if (this->replicator_ != 0) + { + try + { + this->replicator_->stop (); + } + catch (const CORBA::Exception&) + { + // Ignore + } + delete replicator_; + replicator_ = 0; + } try { if (!CORBA::is_nil (this->naming_manager_poa_.in ())) this->naming_manager_poa_->destroy (1, 1); this->naming_manager_poa_ = PortableServer::POA::_nil (); + } + catch (const CORBA::Exception&) + { + // Ignore + } - if (!CORBA::is_nil (this->replication_manager_poa_.in ())) - this->replication_manager_poa_->destroy (1, 1); - - this->replication_manager_poa_ = PortableServer::POA::_nil (); + try + { CORBA::Object_var table_object = this->orb_->resolve_initial_references ("IORTable"); - - IORTable::Table_var adapter = + IORTable::Table_var ior_table = IORTable::Table::_narrow (table_object.in ()); - if (CORBA::is_nil (adapter.in ())) - { - ORBSVCS_ERROR ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: Nil IORTable\n"))); - } - else + if (!CORBA::is_nil (ior_table.in())) { - adapter->unbind ("NameService"); - adapter->unbind ("NamingManager"); + ior_table->unbind ("NameService"); + ior_table->unbind ("NamingManager"); } + } + catch (const CORBA::Exception&) + { + // Ignore + } + try + { #if !defined (CORBA_E_MICRO) CORBA::Object_var svc = this->orb_->unregister_initial_reference ("NameService"); @@ -861,14 +679,8 @@ TAO_FT_Naming_Server::fini (void) // Specific FT_Naming cleanup naming_manager_poa_ = PortableServer::POA::_nil (); - replication_manager_poa_ = PortableServer::POA::_nil (); - my_naming_manager_ = FT_Naming::NamingManager::_nil (); - peer_naming_manager_ = FT_Naming::NamingManager::_nil (); - peer_root_context_ = CosNaming::NamingContext::_nil (); + iors_[GROUP].ref_ = FT_Naming::NamingManager::_nil (); -#if !defined (CORBA_E_MICRO) - delete replication_manager_; -#endif /* CORBA_E_MICRO */ // Invoke the base class fini return TAO_Naming_Server::fini (); @@ -878,9 +690,9 @@ TAO_Storable_Naming_Context_Factory * TAO_FT_Naming_Server::storable_naming_context_factory (size_t context_size) { #if defined (ACE_HAS_NEW_NOTHROW) - return new (ACE_nothrow) TAO_FT_Storable_Naming_Context_Factory (context_size); + return new (ACE_nothrow) TAO_FT_Storable_Naming_Context_Factory (context_size, this->replicator_); #else - return new TAO_FT_Storable_Naming_Context_Factory (context_size); + return new TAO_FT_Storable_Naming_Context_Factory (context_size, this->replicator_); #endif /* ACE_HAS_NEW_NOTHROW */ } @@ -894,198 +706,18 @@ TAO_FT_Naming_Server::persistent_naming_context_factory (void) #endif /* ACE_HAS_NEW_NOTHROW */ } - -int -TAO_FT_Naming_Server::read_reference_from_file (const char* replica_file_name, - CORBA::Object_out obj_ref) -{ - - ACE_CString replica_ior_string ("file://"); - replica_ior_string += replica_file_name; - - try { - CORBA::Object_var object = - this->orb_->string_to_object (replica_ior_string.c_str ()); - if (CORBA::is_nil (object.in ())) - { - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_ERROR, - ACE_TEXT ("(%P|%t) - invalid ior in file <%s>\n"), - replica_file_name)); - - return -1; - } - - obj_ref = object._retn (); - - } - catch (const CORBA::Exception& ex) - { - ex._tao_print_exception ( - ACE_TEXT ("Invalid object reference in file: %s\n")); - return -1; - } - - return 0; -} - -int -TAO_FT_Naming_Server::export_ft_naming_references (void) -{ - int result = 0; - - switch (this->server_role_) { - // Neither the PRIMARY or STANDALONE server roles are able to write - // a multi-profile IOR for the redundant server pair. - case TAO_FT_Naming_Server::STANDALONE: - case TAO_FT_Naming_Server::PRIMARY: - - if (this->naming_manager_ior_file_name_ != 0) - { - FT_Naming::NamingManager_var my_nm = - this->my_naming_manager (); - CORBA::String_var naming_manager_ior_string = - this->orb_->object_to_string (my_nm.in ()); - this->write_ior_to_file ( - naming_manager_ior_string.in (), - ACE_TEXT_ALWAYS_CHAR (this->naming_manager_ior_file_name_)); - } - - // Make sure the user provided an ior_file_name for the comb - if (this->combined_naming_service_ior_file_name_ != 0) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: Unable to write combined") - ACE_TEXT (" NameService IOR file. ") - ACE_TEXT ("Only supported by the backup naming service.\n") - ACE_TEXT ("Provide the -c option to the --backup role.\n")), - -1); - } - return 0; - break; - - case TAO_FT_Naming_Server::BACKUP: - { - // Make sure the user provided an ior_file_name for the multi-profile ior file - if (this->combined_naming_service_ior_file_name_ == 0) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: Unable to write combined") - ACE_TEXT (" NameService IOR file. ") - ACE_TEXT ("No file name provided.\n")), - -1); - return 0; - } - - CORBA::Object_var peer_root_cxt = this->peer_root_context (); - if (CORBA::is_nil (peer_root_cxt.in ())) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: Unable to get the primary") - ACE_TEXT (" NameService object ref")), - -1); - } - - CORBA::Object_var my_root_cxt = this->my_root_context (); - if (CORBA::is_nil (my_root_cxt.in ())) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("(%P|%t) ERROR: Unable to get this") - ACE_TEXT (" services NameService object ref")), - -1); - } - - CORBA::Object_var IORM = - this->orb_->resolve_initial_references (TAO_OBJID_IORMANIPULATION, 0); - - TAO_IOP::TAO_IOR_Manipulation_var iorm = - TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM.in ()); - - // Combine the primary and backup (my) object references for the naming service - CORBA::Object_var combined_obj_ref = - iorm->add_profiles (peer_root_cxt.in (), - my_root_cxt.in ()); - - if (CORBA::is_nil (combined_obj_ref.in ())) - { - ORBSVCS_ERROR((LM_ERROR, - ACE_TEXT("(%P|%t) ERROR: could not combine") - ACE_TEXT(" primary and backup IORs for") - ACE_TEXT(" fault tolerant Naming Service.\n"))); - return -1; - } - - CORBA::String_var combined_nameservice_ior_string = - this->orb_->object_to_string (combined_obj_ref.in ()); - - // Write out the combined IOR for the NameService - this->write_ior_to_file ( - combined_nameservice_ior_string.in (), - ACE_TEXT_ALWAYS_CHAR (this->combined_naming_service_ior_file_name_)); - - // Verify that a naming manager ior file name was provided by user - if (this->combined_naming_manager_ior_file_name_ == 0) - { - if (TAO_debug_level > 3) - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("(%P|%t) - FT_Naming_Server:No NamingManager") - ACE_TEXT (" IOR file name provided") - ACE_TEXT (" with -g option. Not writing IOR.\n"))); - } - else - {// A file name was provided to store the naming manager IOR - - FT_Naming::NamingManager_var peer_nm = - this->peer_naming_manager (); - FT_Naming::NamingManager_var my_nm = - this->my_naming_manager (); - - // This is the object reference for the fault tolerant - // naming manager. The primary should be first. - combined_obj_ref = - iorm->add_profiles (peer_nm.in (), - my_nm.in ()); - - if (CORBA::is_nil (combined_obj_ref.in ())) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT("(%P|%t) ERROR: could not combine") - ACE_TEXT(" primary and backup IORs for") - ACE_TEXT(" fault tolerant Naming Manager.\n")), - -1); - } - - CORBA::String_var combined_naming_manager_ior_string = - this->orb_->object_to_string (combined_obj_ref.in ()); - - // Write out the combined IOR for the NameService - this->write_ior_to_file ( - combined_naming_manager_ior_string.in (), - ACE_TEXT_ALWAYS_CHAR (this->combined_naming_manager_ior_file_name_)); - } - - return 0; - } - break; - }; - return result; -} - - - /// Return the IOR for the registered replication manager char* -TAO_FT_Naming_Server::replication_manager_ior (void) +TAO_FT_Naming_Server::replicator_ior (void) { - return CORBA::string_dup (this->replication_manager_ior_.in ()); + return CORBA::string_dup (this->iors_[REPLICATOR].ior_.c_str()); } - /// Return the IOR for the registered object group manager char* TAO_FT_Naming_Server::naming_manager_ior (void) { - return CORBA::string_dup (this->naming_manager_ior_.in ()); + return CORBA::string_dup (this->iors_[GROUP].ior_.c_str()); } int @@ -1186,39 +818,189 @@ TAO_FT_Naming_Server::~TAO_FT_Naming_Server (void) TAO_FT_Persistent_Naming_Context::set_naming_manager_impl (0); } +CosNaming::NamingContext_ptr +TAO_FT_Naming_Server::my_root_context (void) const +{ + if (CORBA::is_nil (this->iors_[ROOT].ref_.in())) + { + return CosNaming::NamingContext::_nil (); + } -void -TAO_FT_Naming_Server::peer_root_context (CosNaming::NamingContext_ptr peer_cxt) + CosNaming::NamingContext_ptr ret = + CosNaming::NamingContext::_narrow (this->iors_[ROOT].ref_); + + return ret; + // return CosNaming::NamingContext::_narrow (this->iors_[ROOT].ref_.in()); +} + +FT_Naming::NamingManager_ptr +TAO_FT_Naming_Server::my_naming_manager (void) const { - peer_root_context_ = CosNaming::NamingContext::_duplicate (peer_cxt); + if (CORBA::is_nil (this->iors_[GROUP].ref_)) + { + return FT_Naming::NamingManager::_nil (); + } + + FT_Naming::NamingManager_ptr ret = + FT_Naming::NamingManager::_narrow (this->iors_[GROUP].ref_); + + return ret; + + // return FT_Naming::NamingManager::_narrow (this->iors_[GROUP].ref_.in ()); } CosNaming::NamingContext_ptr -TAO_FT_Naming_Server::peer_root_context (void) +TAO_FT_Naming_Server::ft_root_context (void) const { - return CosNaming::NamingContext::_duplicate (peer_root_context_.in ()); + if (CORBA::is_nil (this->iors_[FT_ROOT].ref_)) + { + return CosNaming::NamingContext::_nil (); + } + + CosNaming::NamingContext_ptr ret = + CosNaming::NamingContext::_narrow (this->iors_[FT_ROOT].ref_); + + return ret; + // return CosNaming::NamingContext::_narrow (this->iors_[FT_ROOT].ref_.in()); } -CosNaming::NamingContext_ptr -TAO_FT_Naming_Server::my_root_context (void) const +FT_Naming::NamingManager_ptr +TAO_FT_Naming_Server::ft_naming_manager (void) const +{ + if (CORBA::is_nil (this->iors_[FT_GROUP].ref_)) + { + return FT_Naming::NamingManager::_nil (); + } + + FT_Naming::NamingManager_ptr ret = + FT_Naming::NamingManager::_narrow (this->iors_[FT_GROUP].ref_); + + return ret; + + // return FT_Naming::NamingManager::_narrow (this->iors_[FT_GROUP].ref_.in ()); +} + +const ACE_CString & +TAO_FT_Naming_Server::ft_endpoint (void) { - return CosNaming::NamingContext::_duplicate (this->naming_context_.in ()); + return this->ft_endpoint_; +} + +const ACE_Time_Value & +TAO_FT_Naming_Server::ft_update_delay (void) +{ + return this->ft_update_delay_; } void -TAO_FT_Naming_Server::peer_naming_manager (FT_Naming::NamingManager_ptr peer_cxt) +TAO_FT_Naming_Server::update_ior (FT_Naming::EntityKind kind, CORBA::Object_ptr ft_obj) { - peer_naming_manager_ = FT_Naming::NamingManager::_duplicate (peer_cxt); + size_t combo = kind == FT_Naming::obj_grp ? FT_GROUP : FT_ROOT; + + this->assign(combo, false, ft_obj); + this->write (combo); } -FT_Naming::NamingManager_ptr -TAO_FT_Naming_Server::peer_naming_manager (void) +void +TAO_FT_Naming_Server::combine_iors (FT_Naming::EntityKind kind, CORBA::Object_ptr peer) { - return FT_Naming::NamingManager::_duplicate (peer_naming_manager_.in ()); + size_t local = ROOT; + size_t combo = FT_ROOT; + if (kind == FT_Naming::obj_grp) + { + local = GROUP; + combo = FT_GROUP; + } + + CORBA::Object_var IORM = + this->orb_->resolve_initial_references (TAO_OBJID_IORMANIPULATION, 0); + + TAO_IOP::TAO_IOR_Manipulation_var iorm = + TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM.in ()); + + bool peer_nil = CORBA::is_nil (peer); + bool local_nil = CORBA::is_nil (this->iors_[local].ref_.in ()); + + if (peer_nil || local_nil) + { + if (peer_nil) + { + this->assign (combo, false, this->iors_[local].ref_.in()); + } + } + else + { + if (this->server_role_ == PRIMARY) + { + this->assign (combo, false, iorm->add_profiles (this->iors_[local].ref_.in (), + peer)); + } + else + { + + this->assign (combo, false, iorm->add_profiles (peer, + this->iors_[local].ref_.in ())); + } + } + + if (CORBA::is_nil (this->iors_[combo].ref_.in ()) && TAO_debug_level > 0) + { + ORBSVCS_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) ERROR: could not combine") + ACE_TEXT(" primary and backup IORs for") + ACE_TEXT(" fault tolerant Naming Service.\n"))); + } + + this->write (size_t(combo)); } -FT_Naming::NamingManager_ptr -TAO_FT_Naming_Server::my_naming_manager (void) const +int +TAO_FT_Naming_Server::recover_iors (void) { - return FT_Naming::NamingManager::_duplicate (this->my_naming_manager_.in ()); + if (this->registered_) + { + ORBSVCS_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("ERROR: already registered IOR. ") + ACE_TEXT ("recover_ior should not be called.\n")), -1); + } + + size_t index[2] = {FT_ROOT, FT_GROUP}; + for (int i = 0; i < 2; i++) + { + ACE_TString fname = this->iors_[index[i]].filename_; + if (TAO_debug_level > 0) + { + ORBSVCS_DEBUG ((LM_INFO, ACE_TEXT ("recover_ior <%C>\n"), + fname.c_str())); + } + if (ACE_OS::access (fname.c_str (), F_OK) != 0) + return -1; + + CORBA::Object_ptr obj = CORBA::Object::_nil(); + try + { + ACE_TString combined_ior = ACE_TEXT ("file://") + fname; + obj = this->orb_->string_to_object (combined_ior.c_str()); + if (!CORBA::is_nil (obj)) + { + this->assign(index[i], true, obj); + } + } + catch (const CORBA::Exception& ex) + { + if (TAO_debug_level > 0) + { + ORBSVCS_DEBUG ((LM_INFO, + ACE_TEXT ("Caught %C loading from %C\n"), + ex._name(), + fname.c_str())); + } + return -1; + } + } + this->registered_ = true; + + return 0; } + +TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h index f7ab9e7d538..791a0fed973 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Server.h @@ -4,6 +4,7 @@ /** * @file FT_Naming_Server.h * + * * Implement functionality necessary for fault tolerant naming service. * Adds support for Object Group Manager interfaces as well. This class * extends the TAO_Naming_Server. @@ -21,10 +22,25 @@ #include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h" #include "orbsvcs/Naming/FaultTolerant/ftnaming_export.h" #include "tao/IORManipulation/IORManip_Loader.h" +#include "orbsvcs/FT_NamingReplicationC.h" #include "ace/Recursive_Thread_Mutex.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL +class TAO_FT_Naming_Server; + +class TAO_FTNS_Notifier : public ACE_Event_Handler +{ +public: + TAO_FTNS_Notifier (TAO_FT_Naming_Server &owner, bool iors); + + virtual int handle_exception (ACE_HANDLE ); + + TAO_FT_Naming_Server &owner_; + bool iors_; +}; + + /** * @class TAO_FT_Naming_Server * @@ -39,43 +55,41 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL class TAO_FtNaming_Export TAO_FT_Naming_Server : public TAO_Naming_Server { public: - /// Default Constructor. + friend class TAO_FTNS_Notifier; + TAO_FT_Naming_Server (void); /// Initialize the Naming Service and Object Group Manager with the command line /// arguments and the ORB. Overrridden from TAO_Naming_Server - virtual int init_with_orb (int argc, ACE_TCHAR *argv [], CORBA::ORB_ptr orb); + virtual int init_with_orb (int , ACE_TCHAR * [], CORBA::ORB_ptr orb); /** * Accessors and mutators for object references. */ /// Returns a <NamingContext_ptr> for the root Naming Context. CosNaming::NamingContext_ptr my_root_context (void) const; + CosNaming::NamingContext_ptr ft_root_context (void) const; /// Returns the reference for this servers local naming manager servant. ::FT_Naming::NamingManager_ptr my_naming_manager (void) const; - - void peer_root_context (CosNaming::NamingContext_ptr peer_cxt); - CosNaming::NamingContext_ptr peer_root_context (void); - - void peer_naming_manager (::FT_Naming::NamingManager_ptr peer_nm); - ::FT_Naming::NamingManager_ptr peer_naming_manager (void); + ::FT_Naming::NamingManager_ptr ft_naming_manager (void) const; /// Initialize the naming manager with the ORB. - int init_naming_manager_with_orb (int argc, - ACE_TCHAR *argv [], - CORBA::ORB_ptr orb); + int init_naming_manager_with_orb (int , ACE_TCHAR * [], CORBA::ORB_ptr orb); - /// Initialize the replication manager with the ORB. - int init_replication_manager_with_orb (int argc, - ACE_TCHAR *argv [], - CORBA::ORB_ptr orb); + int init_replicator (); - /// Setup pairing with peer replica. + ACE_TString replica_ior_filename (bool ) const; + +/// Setup pairing with peer replica. /// Returns 0 on successful pairing with peer. /// Returns 1 if peer IOR file is present, but peer is not responding /// Returns -1 if pairing is not possible. - int init_replication_pairing (void); + void init_replication_pairing (void); + + void no_replica (void); + + // TAO_FTNS_Notifier ¬ifier (void); /// Overridden parse operation. Only allows options supported by the FT_Naming_Server /// and adds options for the object group manager @@ -93,7 +107,7 @@ public: persistent_naming_context_factory (void); /// Returns the IOR of the replication manager. - char* replication_manager_ior (void); + char* replicator_ior (void); /// Returns the IOR of the naming manager. char * naming_manager_ior (void); @@ -104,6 +118,12 @@ public: virtual int update_naming_context ( const ::FT_Naming::NamingContextUpdate & naming_context); + void update_ior (FT_Naming::EntityKind, const CORBA::Object_ptr); + void combine_iors (FT_Naming::EntityKind, const CORBA::Object_ptr); + + const ACE_CString & ft_endpoint (void); + const ACE_Time_Value & ft_update_delay (void); + /// Destroy the child POAs created in @c init_with_orb, /// @c init_naming_manager_with_orb, and /// @c init_replication_manager_with_orb @@ -112,66 +132,38 @@ public: /// Destructor. virtual ~TAO_FT_Naming_Server (void); -protected: + void update_info (FT_Naming::UpdateInfoSeq &infos); + void update_iors (const FT_Naming::ReplicaInfo & iors); + void update_info_i (void); + void update_iors_i (void); - /// Read the replica from the specified file - int read_reference_from_file (const char* replica_file_name, - CORBA::Object_out obj_ref); +protected: - /// Export the NameService and NameManager combined object references - /// to the file names provided - int export_ft_naming_references (void); + enum FT_IOR_Indexes { + PEER_ROOT = 1, + FT_ROOT, + GROUP, + PEER_GROUP, + FT_GROUP, + REPLICATOR, + IOR_ARRAY_SIZE + }; - const ACE_TCHAR * replica_id_; + int recover_iors (void); /// The object that implements the ObjectGroupManager, PropertyManager, /// and GenericFactory interfaces. TAO_FT_Naming_Manager naming_manager_; - /// Object reference for the local naming manager servant. - ::FT_Naming::NamingManager_var my_naming_manager_; - - /// Object reference for the peer naming service's naming manager. - ::FT_Naming::NamingManager_var peer_naming_manager_; - - /// Object reference for the peer naming service's naming manager. - CosNaming::NamingContext_var peer_root_context_; - /// The object that implements the FT_Naming::Replication_Manager /// interface. - TAO_FT_Naming_Replication_Manager* replication_manager_; - - /// File to output for the multi-profile root naming context IOR. - const ACE_TCHAR *combined_naming_service_ior_file_name_; - - /// File to output the multi-profile object group manager IOR. - const ACE_TCHAR *combined_naming_manager_ior_file_name_; - - /// File to output the object group manager IOR. - const ACE_TCHAR *naming_manager_ior_file_name_; - - /// Path to the file to be used to store/read in Object Group Manager - /// persistent state. - const ACE_TCHAR *naming_manager_persistence_file_name_; - - /// The IOR string of the object group manager. - CORBA::String_var naming_manager_ior_; - - /// The IOR string of the object group manager. - CORBA::String_var replication_manager_ior_; - - /// The IOR string of the peer replica. - CORBA::String_var replica_peer_ior_; + TAO_FT_Naming_Replication_Manager* replicator_; /// The Object Group Manager POA. PortableServer::POA_var naming_manager_poa_; - /// The POA used for replication coordination between - /// primary and backup. - PortableServer::POA_var replication_manager_poa_; - int use_object_group_persistence_; - ACE_CString object_group_dir_; + ACE_TString object_group_dir_; /// The role this server is supporting in the dual redundant /// replication scheme. @@ -186,9 +178,28 @@ protected: /// to Naming Service. TAO_SYNCH_RECURSIVE_MUTEX lock_; -private: - static const ACE_TCHAR* primary_replica_ior_filename; - static const ACE_TCHAR* backup_replica_ior_filename; + /// The endpoint used by the replicator ORB, otherwise it + /// just picks one + ACE_CString ft_endpoint_; + + /// The minimum amount of time to wait before issuing a new + /// update notice to the peer. Heavily loaded systems may want + /// to use this option to avoid overloading the peer with lots + /// of small, possibly contradictory changes. During the delay + /// time, the replicator will hold update notices, removing + /// earlier ones in favor of later updates. + ACE_Time_Value ft_update_delay_; + + bool registered_; + + TAO_FTNS_Notifier ior_notifier_; + TAO_FTNS_Notifier info_notifier_; + + ACE_Unbounded_Queue<FT_Naming::ReplicaInfo> u_iors_; + ACE_Unbounded_Queue<FT_Naming::UpdateInfoSeq*> u_infos_; + TAO_SYNCH_MUTEX ior_lock_; + TAO_SYNCH_MUTEX info_lock_; + }; diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp index 55c91405378..7a7bb1aa7b7 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.cpp @@ -4,6 +4,7 @@ /** * @file FT_PG_Group_Factory.cpp * + * * @author Byron Harris <harrisb@ociweb.com> */ //============================================================================= @@ -11,12 +12,14 @@ #include "orbsvcs/Log_Macros.h" #include "orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h" #include "orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h" +#include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h" #include "orbsvcs/PortableGroup/PG_Group_List_Store.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO::FT_PG_Group_Factory::FT_PG_Group_Factory() + : replicator_ (0) { } @@ -25,6 +28,12 @@ TAO::FT_PG_Group_Factory::~FT_PG_Group_Factory() } void +TAO::FT_PG_Group_Factory::set_replicator (TAO_FT_Naming_Replication_Manager *repl) +{ + this->replicator_ = repl; +} + +void TAO::FT_PG_Group_Factory::set_object_group_stale ( const FT_Naming::ObjectGroupUpdate & group_info) { @@ -65,7 +74,7 @@ TAO::FT_PG_Group_Factory::set_object_group_stale ( ORBSVCS_ERROR ((LM_ERROR, ACE_TEXT ("TAO (%P|%t) - FT_PG_Group_Factory ") ACE_TEXT ("In setting object group stale could not cast ") - ACE_TEXT ("to FT_PG_Object_Group_Storable\n"))); + ACE_TEXT ("to FT_PG_Object_Group_Storable\n"))); throw CORBA::INTERNAL (); } @@ -109,7 +118,8 @@ TAO::FT_PG_Group_Factory::create_persistent_group ( type_id, the_criteria, type_properties, - storable_factory + storable_factory, + this->replicator_ ), CORBA::NO_MEMORY()); return objectGroup; @@ -131,7 +141,8 @@ TAO::FT_PG_Group_Factory::restore_persistent_group ( orb, factory_registry, manipulator, - storable_factory + storable_factory, + this->replicator_ ), CORBA::NO_MEMORY()); return objectGroup; diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h index a5524804843..1945dffda5c 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h @@ -4,6 +4,7 @@ /** * @file FT_PG_Group_Factory.h * + * * @author Byron Harris <harrisb@ociweb.com> */ //============================================================================= @@ -28,6 +29,8 @@ namespace FT_Naming TAO_BEGIN_VERSIONED_NAMESPACE_DECL +class TAO_FT_Naming_Replication_Manager; + namespace TAO { @@ -50,6 +53,8 @@ namespace TAO */ void set_object_group_stale (const FT_Naming::ObjectGroupUpdate & group_info); + void set_replicator (TAO_FT_Naming_Replication_Manager *repl); + protected: virtual PG_Object_Group_Storable * create_persistent_group ( @@ -70,6 +75,7 @@ namespace TAO TAO::PG_Object_Group_Manipulator & manipulator, TAO::Storable_Factory & storable_factory); + TAO_FT_Naming_Replication_Manager *replicator_; }; } // namespace TAO diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp index 38201c1a391..6f05c3decc5 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.cpp @@ -1,22 +1,24 @@ + #include "orbsvcs/Log_Macros.h" #include "orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h" #include "orbsvcs/PortableGroup/PG_Object_Group_Storable.h" - +#include "orbsvcs/Naming/FaultTolerant/FT_PG_Group_Factory.h" #include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h" #include "tao/Stub.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO::FT_PG_Object_Group_Storable::FT_PG_Object_Group_Storable ( - CORBA::ORB_ptr orb, - PortableGroup::FactoryRegistry_ptr factory_registry, - TAO::PG_Object_Group_Manipulator & manipulator, - CORBA::Object_ptr empty_group, - const PortableGroup::TagGroupTaggedComponent & tagged_component, - const char * type_id, - const PortableGroup::Criteria & the_criteria, - const TAO::PG_Property_Set_var & type_properties, - TAO::Storable_Factory & storable_factory) +TAO::FT_PG_Object_Group_Storable::FT_PG_Object_Group_Storable +(CORBA::ORB_ptr orb, + PortableGroup::FactoryRegistry_ptr factory_registry, + TAO::PG_Object_Group_Manipulator & manipulator, + CORBA::Object_ptr empty_group, + const PortableGroup::TagGroupTaggedComponent & tagged_component, + const char * type_id, + const PortableGroup::Criteria & the_criteria, + const TAO::PG_Property_Set_var & type_properties, + TAO::Storable_Factory & storable_factory, + TAO_FT_Naming_Replication_Manager *repl) : PG_Object_Group_Storable(orb, factory_registry, manipulator, @@ -28,15 +30,17 @@ TAO::FT_PG_Object_Group_Storable::FT_PG_Object_Group_Storable ( storable_factory) , stale_ (false) , file_created_ (false) + , replicator_ (repl) { } -TAO::FT_PG_Object_Group_Storable::FT_PG_Object_Group_Storable ( - PortableGroup::ObjectGroupId group_id, +TAO::FT_PG_Object_Group_Storable::FT_PG_Object_Group_Storable +( PortableGroup::ObjectGroupId group_id, CORBA::ORB_ptr orb, PortableGroup::FactoryRegistry_ptr factory_registry, TAO::PG_Object_Group_Manipulator & manipulator, - TAO::Storable_Factory & storable_factory) + TAO::Storable_Factory & storable_factory, + TAO_FT_Naming_Replication_Manager *repl) : PG_Object_Group_Storable(group_id, orb, factory_registry, @@ -44,6 +48,7 @@ TAO::FT_PG_Object_Group_Storable::FT_PG_Object_Group_Storable ( storable_factory) , stale_ (false) , file_created_ (true) + , replicator_ (repl) { } @@ -67,48 +72,16 @@ int TAO::FT_PG_Object_Group_Storable::propagate_update_notification (FT_Naming::ChangeType change_type) { - // Notify the peer of the changed context - FT_Naming::ReplicationManager_var peer = - TAO_FT_Naming_Replication_Manager::peer_replica (); - - if (CORBA::is_nil (peer.in ())) - { - // Replication is not supported without a peer replica. - return 1; - } - - FT_Naming::ObjectGroupUpdate object_group_info; - object_group_info.id = PG_Object_Group::get_object_group_id (); - object_group_info.change_type = change_type; - - try { - // Notify the naming_manager of the updated context - if (TAO_debug_level > 3) - { - ORBSVCS_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - propagate_update_notification ") - ACE_TEXT ("Notifying peer that object group with ID %lld ") - ACE_TEXT ("has been updated\n"), object_group_info.id - )); - } - peer->notify_updated_object_group (object_group_info); - } - catch (const CORBA::Exception& ex) - { - if (TAO_debug_level > 3) - ex._tao_print_exception ( - ACE_TEXT ("Unable to communicate with peer.\n")); - return -1; - } - - return 0; + if (this->replicator_) + this->replicator_->send_objgrp_update (this->get_object_group_id(), + change_type); + return 0; } void TAO::FT_PG_Object_Group_Storable::state_written (void) { FT_Naming::ChangeType change_type; - if (!this->file_created_) { change_type = FT_Naming::NEW; diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h index 3c3586f2574..d63f0878507 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_PG_Object_Group_Storable.h @@ -4,6 +4,7 @@ /** * @file FT_PG_Object_Group_Storable.h * + * * Contains declaration for class FT_PG_Object_Group_Storable. * * @author Byron Harris <harrisb@ociweb.com> @@ -28,6 +29,7 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL +class TAO_FT_Naming_Replication_Manager; //////////////// // Class declarations namespace TAO @@ -57,7 +59,8 @@ namespace TAO const char * type_id, const PortableGroup::Criteria & the_criteria, const TAO::PG_Property_Set_var & type_properties, - TAO::Storable_Factory & storable_factory); + TAO::Storable_Factory & storable_factory, + TAO_FT_Naming_Replication_Manager *replicator); /** * This constructor is suitable for creating an object group from @@ -68,7 +71,8 @@ namespace TAO CORBA::ORB_ptr orb, PortableGroup::FactoryRegistry_ptr factory_registry, TAO::PG_Object_Group_Manipulator & manipulator, - TAO::Storable_Factory & storable_factory); + TAO::Storable_Factory & storable_factory, + TAO_FT_Naming_Replication_Manager *replicator); /// Destructor virtual ~FT_PG_Object_Group_Storable (); @@ -109,6 +113,7 @@ namespace TAO /// so can know if we should propagate a change type of NEW. bool file_created_; + TAO_FT_Naming_Replication_Manager *replicator_; /** * Although it is assumed for replication that services * using object groups share the persistent store, a diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp index 5258debc311..f72bc9456ac 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.cpp @@ -1,8 +1,10 @@ + #include "orbsvcs/Log_Macros.h" #include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h" +#include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h" #include "orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.h" #include "orbsvcs/Naming/FaultTolerant/FT_Naming_Replication_Manager.h" -#include "orbsvcs/FT_NamingManagerC.h" + #include "orbsvcs/PortableGroup/PG_Utils.h" #include "orbsvcs/PortableGroup/PG_Property_Utils.h" @@ -26,7 +28,8 @@ TAO_FT_Storable_Naming_Context::TAO_FT_Storable_Naming_Context (CORBA::ORB_ptr o poa_id, cxt_factory, pers_factory), - stale_ (false) + stale_ (false), + replicator_ (((TAO_FT_Storable_Naming_Context_Factory *)cxt_factory)->replicator()) { } @@ -43,7 +46,7 @@ TAO_FT_Storable_Naming_Context::is_object_group (CORBA::Object_ptr obj) const { // Ensure the object is not nil first. If so, it cannot be an ObjectGroup. if (CORBA::is_nil (obj)) - return false; + return 0; // If there is a tagged component with tag = IOP::TAG_FT_GROUP in the // object reference then it is an object group @@ -97,38 +100,13 @@ TAO_FT_Storable_Naming_Context::resolve (const CosNaming::Name& n) return resolved_ref._retn (); } -int +void TAO_FT_Storable_Naming_Context::propagate_update_notification ( FT_Naming::ChangeType change_type) { - // Notify the peer of the changed context - FT_Naming::ReplicationManager_var peer = - TAO_FT_Naming_Replication_Manager::peer_replica (); - - if (CORBA::is_nil (peer.in ())) - { - // Replication is not supported without a peer replica. - return 1; - } - - FT_Naming::NamingContextUpdate context_info; - context_info.context_name = this->context_name_.c_str (); - - // We are are updating the context one element before the specified name - context_info.change_type = change_type; - - try { - // Notify the naming_manager of the updated context - peer->notify_updated_context (context_info); - } - catch (const CORBA::Exception& ex) - { - if (TAO_debug_level > 3) - ex._tao_print_exception (ACE_TEXT ("Unable to communicate with peer.\n")); - return -1; - } - - return 0; + if (this->replicator_) + this->replicator_->send_context_update (this->context_name_, + change_type); } void diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h index fecdde77e52..4a2ede62436 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h @@ -4,6 +4,7 @@ /** * @file FT_Storable_Naming_Context.h * + * * @author Kevin Stanley <stanleyk@ociweb.com> */ //============================================================================= @@ -21,12 +22,15 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL +class TAO_FT_Naming_Replication_Manager; + /** * @class FT_TAO_Storable_Naming_Context * * @brief This class specializes the TAO_Storable_Naming_Context * 'ConcreteImplementor' in the Bridge pattern architecture of the * CosNaming::NamingContext implementation. + * */ class TAO_FtNaming_Export TAO_FT_Storable_Naming_Context : public TAO_Storable_Naming_Context @@ -59,15 +63,13 @@ public: // naming context implementations. static void set_naming_manager (TAO_FT_Naming_Manager *mgr_impl); - CORBA::Boolean is_object_group (CORBA::Object_ptr obj) const; + bool is_object_group (const CORBA::Object_ptr obj) const; /** - * Tell the peer replica that this context has been updated. - * Returns 0 if successfully reported. Returns 1 if no peer - * has been registered. Returns -1 on failure to communicate - * with the peer. + * Queues a request to update the peer replica instance of this + * context. */ - int propagate_update_notification (FT_Naming::ChangeType change_type); + void propagate_update_notification (FT_Naming::ChangeType change_type); /** * Find the indicated context below this context. Returns 0 @@ -100,6 +102,7 @@ protected: static TAO_FT_Naming_Manager *naming_manager_; bool stale_; + TAO_FT_Naming_Replication_Manager *replicator_; }; diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp index 3841f3ab41c..65a0e759562 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.cpp @@ -1,21 +1,40 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file FT_Storable_Naming_Context_Factory.cpp + * + * @author Kevin Stanley <stanleyk@ociweb.com> + */ +//============================================================================= + #include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h" #include "orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context.h" TAO_BEGIN_VERSIONED_NAMESPACE_DECL /// Constructor. -TAO_FT_Storable_Naming_Context_Factory::TAO_FT_Storable_Naming_Context_Factory ( - size_t hash_table_size) - : TAO_Storable_Naming_Context_Factory (hash_table_size) +TAO_FT_Storable_Naming_Context_Factory:: +TAO_FT_Storable_Naming_Context_Factory (size_t hash_table_size, + TAO_FT_Naming_Replication_Manager *rep) + : TAO_Storable_Naming_Context_Factory (hash_table_size), + replicator_ (rep) { } -/// Destructor. Does not deallocate the hash map: if an instance of -/// this class goes out of scope, its hash_map remains in persistent storage. + /// Destructor. Does not deallocate the hash map: if an instance of + /// this class goes out of scope, its hash_map remains in persistent storage. TAO_FT_Storable_Naming_Context_Factory::~TAO_FT_Storable_Naming_Context_Factory (void) { } + +TAO_FT_Naming_Replication_Manager * +TAO_FT_Storable_Naming_Context_Factory::replicator () +{ + return this->replicator_; +} + TAO_Storable_Naming_Context* TAO_FT_Storable_Naming_Context_Factory::create_naming_context_impl ( CORBA::ORB_ptr orb, @@ -38,4 +57,5 @@ TAO_FT_Storable_Naming_Context_Factory::create_naming_context_impl ( return context_impl; } + TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h index 32696dff77f..c401f17dd7e 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h +++ b/TAO/orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Storable_Naming_Context_Factory.h @@ -4,6 +4,7 @@ /** * @file FT_Storable_Naming_Context_Factory.h * + * * @author Kevin Stanley stanleyk@ociweb.com> */ //============================================================================= @@ -22,6 +23,8 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL +class TAO_FT_Naming_Replication_Manager; + /** * @class TAO_Naming_Context_Factory * @@ -40,12 +43,15 @@ public: /// Constructor. TAO_FT_Storable_Naming_Context_Factory ( - size_t hash_table_size = ACE_DEFAULT_MAP_SIZE); + size_t hash_table_size = ACE_DEFAULT_MAP_SIZE, + TAO_FT_Naming_Replication_Manager * rep = 0); /// Destructor. Does not deallocate the hash map: if an instance of /// this class goes out of scope, its hash_map remains in persistent storage. virtual ~TAO_FT_Storable_Naming_Context_Factory (void); + TAO_FT_Naming_Replication_Manager * replicator (void); + /// Factory method for creating an implementation object for naming contexts. /// If an existing naming context implementation is being rebuilt, /// the map and counter parameters should be provided to the underlying @@ -56,6 +62,7 @@ public: const char *poa_id, TAO::Storable_Factory *factory); + TAO_FT_Naming_Replication_Manager *replicator_; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp b/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp index dabfec5c7e2..cc75e1d3729 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.cpp @@ -1,3 +1,4 @@ + #include "orbsvcs/Log_Macros.h" #include "orbsvcs/Naming/Naming_Server.h" @@ -38,17 +39,16 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL -TAO_Naming_Server::TAO_Naming_Server (void) - : naming_context_ (), - ior_multicast_ (0), - naming_service_ior_ (), - ior_file_name_ (0), +TAO_Naming_Server::TAO_Naming_Server (size_t bsize) + : ior_multicast_ (0), pid_file_name_ (0), + iors_ (0), + bundle_size_ (bsize), context_size_ (ACE_DEFAULT_MAP_SIZE), multicast_ (0), #if !defined (CORBA_E_MICRO) context_index_ (0), - persistence_file_name_ (0), + persistence_dir_ (0), base_address_ (TAO_NAMING_BASE_ADDR), use_storable_context_ (0), use_servant_activator_ (false), @@ -58,6 +58,7 @@ TAO_Naming_Server::TAO_Naming_Server (void) round_trip_timeout_ (0), use_round_trip_timeout_ (0) { + ACE_NEW (iors_, IOR_Bundle[bsize]); } TAO_Naming_Server::TAO_Naming_Server (CORBA::ORB_ptr orb, @@ -70,17 +71,17 @@ TAO_Naming_Server::TAO_Naming_Server (CORBA::ORB_ptr orb, int enable_multicast, int use_storable_context, int round_trip_timeout, - int use_round_trip_timeout) - : naming_context_ (), - ior_multicast_ (0), - naming_service_ior_ (), - ior_file_name_ (0), + int use_round_trip_timeout, + size_t bsize) + : ior_multicast_ (0), pid_file_name_ (0), + iors_ (0), + bundle_size_ (bsize), context_size_ (ACE_DEFAULT_MAP_SIZE), multicast_ (0), #if !defined (CORBA_E_MICRO) context_index_ (0), - persistence_file_name_ (0), + persistence_dir_ (0), base_address_ (TAO_NAMING_BASE_ADDR), use_storable_context_ (use_storable_context), use_servant_activator_ (false), @@ -90,6 +91,7 @@ TAO_Naming_Server::TAO_Naming_Server (CORBA::ORB_ptr orb, round_trip_timeout_ (0), use_round_trip_timeout_ (0) { + ACE_NEW (iors_, IOR_Bundle[bsize]); if (this->init (orb, poa, context_size, @@ -106,7 +108,6 @@ TAO_Naming_Server::TAO_Naming_Server (CORBA::ORB_ptr orb, "TAO_Naming_Server::init")); } - int TAO_Naming_Server::init (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, @@ -120,6 +121,15 @@ TAO_Naming_Server::init (CORBA::ORB_ptr orb, int round_trip_timeout, int use_round_trip_timeout) { + if (CORBA::is_nil (this->orb_.in ())) + { + this->orb_ = CORBA::ORB::_duplicate (orb); + } + for (size_t i = 0; i < bundle_size_; i++ ) + { + this->iors_[i].ref_ = CORBA::Object::_nil(); + } + if (resolve_for_existing_naming_service) { try @@ -135,14 +145,9 @@ TAO_Naming_Server::init (CORBA::ORB_ptr orb, // if (TAO_debug_level > 0) ORBSVCS_DEBUG ((LM_DEBUG, - "\nNameService found!\n")); - - this->naming_context_ = - CosNaming::NamingContext::_narrow (naming_obj.in ()); - - this->naming_service_ior_ = - orb->object_to_string (naming_obj.in ()); + "\nNameService found!\n")); + this->assign (size_t(ROOT), false, naming_obj); return 0; } } @@ -205,7 +210,7 @@ TAO_Naming_Server::parse_args (int argc, ++TAO_debug_level; break; case 'o': // outputs the naming service ior to a file. - this->ior_file_name_ = get_opts.opt_arg (); + this->iors_[ROOT].filename_ = get_opts.opt_arg (); break; case 'p': this->pid_file_name_ = get_opts.opt_arg (); @@ -234,19 +239,19 @@ TAO_Naming_Server::parse_args (int argc, this->base_address_ = (void *) address; break; case 'f': - this->persistence_file_name_ = get_opts.opt_arg (); + this->persistence_dir_ = get_opts.opt_arg (); f_opt_used = 1; break; #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) case 'r': this->use_redundancy_ = 1; this->use_storable_context_ = 1; - this->persistence_file_name_ = get_opts.opt_arg (); + this->persistence_dir_ = get_opts.opt_arg (); r_opt_used = 1; break; case 'u': this->use_storable_context_ = 1; - this->persistence_file_name_ = get_opts.opt_arg (); + this->persistence_dir_ = get_opts.opt_arg (); u_opt_used = 1; break; #endif /* TAO_HAS_MINIMUM_POA == 0 */ @@ -409,7 +414,7 @@ TAO_Naming_Server::init_with_orb (int argc, this->context_size_, 0, 0, - this->persistence_file_name_, + this->persistence_dir_, this->base_address_, this->multicast_, this->use_storable_context_, @@ -428,20 +433,9 @@ TAO_Naming_Server::init_with_orb (int argc, } // If an ior file name was provided on command line - if (this->ior_file_name_ != 0) + if (this->write (size_t(ROOT)) != 0) { - CORBA::String_var ns_ior = this->naming_service_ior (); - if (this->write_ior_to_file ( - ns_ior.in (), - ACE_TEXT_ALWAYS_CHAR (this->ior_file_name_)) != 0) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT("Unable to open %C for writing:(%u) %p\n"), - this->ior_file_name_, - ACE_ERRNO_GET, - ACE_TEXT("TAO_Naming_Server::init_with_orb")), - -1); - } + return -1; } if (this->pid_file_name_ != 0) @@ -472,6 +466,11 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, { try { + if (CORBA::is_nil (this->orb_.in ())) + { + this->orb_ = CORBA::ORB::_duplicate (orb); + } + #if defined (CORBA_E_MICRO) ACE_UNUSED_ARG (persistence_location); ACE_UNUSED_ARG (base_addr); @@ -509,7 +508,9 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, // Now make sure this directory exists if (ACE_OS::access (persistence_location, W_OK|X_OK)) { - ORBSVCS_ERROR_RETURN ((LM_ERROR, "Invalid persistence directory\n"), -1); + ORBSVCS_ERROR_RETURN ((LM_ERROR, + "Invalid persistence directory %C %p\n", + persistence_location, "access"), -1); } #if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) @@ -525,15 +526,15 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, } #endif /* TAO_HAS_MINIMUM_POA */ try { // The following might throw an exception. - this->naming_context_ = - TAO_Storable_Naming_Context::recreate_all (orb, - poa, - TAO_ROOT_NAMING_CONTEXT, - context_size, - 0, - contextFactory.get (), - persFactory.get (), - use_redundancy_); + this->assign (size_t(ROOT), false, TAO_Storable_Naming_Context:: + recreate_all (orb, + poa, + TAO_ROOT_NAMING_CONTEXT, + context_size, + 0, + contextFactory.get (), + persFactory.get (), + use_redundancy_)); } catch (const CORBA::Exception& ex) { @@ -595,8 +596,7 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, } // Set the root Naming Context reference. - this->naming_context_ = - this->context_index_->root_context (); + this->assign (size_t(ROOT), false, this->context_index_->root_context ()); } else #endif /* CORBA_E_MICRO */ @@ -604,10 +604,10 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, // // Initialize Transient Naming Service. // - this->naming_context_ = + this->assign (size_t(ROOT), false, TAO_Transient_Naming_Context::make_new_context (poa, TAO_ROOT_NAMING_CONTEXT, - context_size); + context_size)); } @@ -616,27 +616,22 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, // mechanism. Primarily useful for dynamically loaded Name // Services. orb->register_initial_reference ("NameService", - this->naming_context_.in ()); + this->iors_[ROOT].ref_.in ()); #endif /* CORBA_E_MICRO */ - // Set the ior of the root Naming Context. - this->naming_service_ior_= - orb->object_to_string (this->naming_context_.in ()); - CORBA::Object_var table_object = orb->resolve_initial_references ("IORTable"); - IORTable::Table_var adapter = + IORTable::Table_var ior_table = IORTable::Table::_narrow (table_object.in ()); - if (CORBA::is_nil (adapter.in ())) + if (CORBA::is_nil (ior_table.in ())) { ORBSVCS_ERROR ((LM_ERROR, "Nil IORTable\n")); } else { - CORBA::String_var ior = - orb->object_to_string (this->naming_context_.in ()); - adapter->bind ("NameService", ior.in ()); + ior_table->bind ("NameService", + this->iors_[ROOT].ior_.c_str()); } #if defined (ACE_HAS_IP_MULTICAST) @@ -683,14 +678,14 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, if (mde.length () != 0) { - if (this->ior_multicast_->init (this->naming_service_ior_.in (), + if (this->ior_multicast_->init (this->iors_[ROOT].ior_.c_str (), mde.c_str (), TAO_SERVICEID_NAMESERVICE) == -1) return -1; } else { - if (this->ior_multicast_->init (this->naming_service_ior_.in (), + if (this->ior_multicast_->init (this->iors_[ROOT].ior_.c_str (), port, #if defined (ACE_HAS_IPV6) ACE_DEFAULT_MULTICASTV6_ADDR, @@ -707,13 +702,13 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, { if (TAO_debug_level > 0) ORBSVCS_DEBUG ((LM_DEBUG, - "TAO_Naming_Server: cannot register Event handler\n")); + ACE_TEXT ("TAO_Naming_Server: cannot register Event handler\n"))); return -1; } if (TAO_debug_level > 0) ORBSVCS_DEBUG ((LM_DEBUG, - "TAO_Naming_Server: The multicast server setup is done.\n")); + ACE_TEXT ("TAO_Naming_Server: The multicast server setup is done.\n"))); } #else ACE_UNUSED_ARG (enable_multicast); @@ -757,39 +752,6 @@ TAO_Naming_Server::init_new_naming (CORBA::ORB_ptr orb, return 0; } -int -TAO_Naming_Server::write_ior_to_file (const char* ior_string, - const char* file_name) -{ - if ((file_name != 0) && - (ior_string != 0)) - { - FILE *iorf = ACE_OS::fopen (file_name, ACE_TEXT("w")); - if (iorf == 0) - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT("Unable to open %s for writing:(%u) %p\n"), - file_name, - ACE_ERRNO_GET, - ACE_TEXT("Naming_Server::write_ior_to_file")), - -1); - } - - ACE_OS::fprintf (iorf, "%s\n", ior_string); - ACE_OS::fclose (iorf); - } - else - { - ORBSVCS_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("Invalid file name or IOR string provided") - ACE_TEXT ("to TAO_Naming_Server::write_ior_to_file\n")), - -1); - - } - - return 0; -} - TAO_Storable_Naming_Context_Factory * TAO_Naming_Server::storable_naming_context_factory (size_t context_size) { @@ -822,6 +784,11 @@ TAO_Naming_Server::fini (void) this->ior_multicast_ = 0; } + for (size_t i = 0; i < bundle_size_; i++ ) + { + this->iors_[i].ref_ = CORBA::Object::_nil(); + } + // Destroy the child POA ns_poa that is created when initializing // the Naming Service try @@ -829,20 +796,32 @@ TAO_Naming_Server::fini (void) if (!CORBA::is_nil (this->ns_poa_.in ())) this->ns_poa_->destroy (1, 1); + } + catch (const CORBA::Exception&) + { + // Ignore + } + try + { CORBA::Object_var table_object = this->orb_->resolve_initial_references ("IORTable"); - IORTable::Table_var adapter = + IORTable::Table_var ior_table = IORTable::Table::_narrow (table_object.in ()); - if (CORBA::is_nil (adapter.in ())) - { - ORBSVCS_ERROR ((LM_ERROR, "Nil IORTable\n")); - } - else + + if (!CORBA::is_nil (ior_table.in ())) { - adapter->unbind ("NameService"); + ior_table->unbind ("NameService"); } + } + catch (const CORBA::Exception&) + { + // Ignore + } + + try + { #if !defined (CORBA_E_MICRO) CORBA::Object_var svc = this->orb_->unregister_initial_reference ("NameService"); @@ -854,7 +833,6 @@ TAO_Naming_Server::fini (void) // Ignore } - naming_context_ = CosNaming::NamingContext::_nil (); ns_poa_ = PortableServer::POA::_nil (); root_poa_ = PortableServer::POA::_nil (); orb_ = CORBA::ORB::_nil (); @@ -869,18 +847,28 @@ TAO_Naming_Server::fini (void) char* TAO_Naming_Server::naming_service_ior (void) { - return CORBA::string_dup (this->naming_service_ior_.in ()); + return CORBA::string_dup (this->iors_[ROOT].ior_.c_str()); } CosNaming::NamingContext_ptr TAO_Naming_Server::operator-> (void) const { - return this->naming_context_.ptr (); + if (CORBA::is_nil (this->iors_[ROOT].ref_)) + { + return CosNaming::NamingContext::_nil (); + } + + CosNaming::NamingContext_ptr ret = + CosNaming::NamingContext::_narrow (this->iors_[ROOT].ref_); + + return ret; } TAO_Naming_Server::~TAO_Naming_Server (void) { + delete [] this->iors_; + #if (TAO_HAS_MINIMUM_POA == 0) && \ !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) if (this->use_servant_activator_ && @@ -892,4 +880,93 @@ TAO_Naming_Server::~TAO_Naming_Server (void) #endif /* TAO_HAS_MINIMUM_POA */ } + +TAO_Naming_Server::IOR_Bundle * +TAO_Naming_Server::bundle_at(size_t ndx) + { + if (ndx >= this->bundle_size_) + { + if (TAO_debug_level) + { + ORBSVCS_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) TAO_naming_Server::bundle_at, ") + ACE_TEXT("index %d out of range\n"), + ndx)); + } + return 0; + } + return &iors_[ndx]; + } + +const TAO_Naming_Server::IOR_Bundle * +TAO_Naming_Server::bundle_at(size_t ndx) const + { + if (ndx >= this->bundle_size_) + { + if (TAO_debug_level) + { + ORBSVCS_ERROR((LM_ERROR, + ACE_TEXT("(%P|%t) const TAO_naming_Server::bundle_at, ") + ACE_TEXT("index %d out of range\n"), + ndx)); + } + return 0; + } + return &iors_[ndx]; + } + + + +int +TAO_Naming_Server::write(size_t ndx) const +{ + const IOR_Bundle *b = bundle_at(ndx); + if (b == 0) + return -1; + + if (b->filename_.length() == 0) + return 0; + + if (b->ior_.length() == 0) + { + if (TAO_debug_level > 0) + { + ORBSVCS_ERROR ((LM_ERROR, + ACE_TEXT ("IOR_Bundle::write called with ") + ACE_TEXT ("empty IOR \n"))); + } + return -1; + } + + FILE *iorf = ACE_OS::fopen (b->filename_.c_str(), ACE_TEXT("w")); + if (iorf == 0) + { + if (TAO_debug_level > 0) + { + ORBSVCS_ERROR ((LM_ERROR, + ACE_TEXT("Unable to open %C for writing:(%u) %p\n"), + b->filename_.c_str(), + ACE_ERRNO_GET, + ACE_TEXT("IOR_Bundle::write"))); + } + return -1; + } + ACE_OS::fprintf (iorf, "%s\n", b->ior_.c_str()); + ACE_OS::fclose (iorf); + + return 0; +} + +void +TAO_Naming_Server::assign (size_t ndx, bool take, CORBA::Object_ptr obj) +{ + IOR_Bundle *b = this->bundle_at(ndx); + if (b == 0) + return; + + b->ref_ = take ? obj : CORBA::Object::_duplicate (obj); + b->ior_ = this->orb_->object_to_string (b->ref_.in()); +} + + TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h b/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h index 3a6bbf180e8..b3bd2b1cd3a 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h +++ b/TAO/orbsvcs/orbsvcs/Naming/Naming_Server.h @@ -4,14 +4,17 @@ /** * @file Naming_Server.h * + * * Implement wrappers useful to Naming Service servers. * + * * @author Nagarajan Surendran (naga@cs.wustl.edu) * @author Matt Braun <mjb2@cs.wustl.edu> * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>. */ //============================================================================= + #ifndef TAO_NAMING_SERVER_H #define TAO_NAMING_SERVER_H #include /**/ "ace/pre.h" @@ -28,6 +31,7 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL // Forward decl; class TAO_Persistent_Context_Index; class TAO_Storable_Naming_Context_Activator; + #endif /* !CORBA_E_MICRO */ class TAO_Storable_Naming_Context_Factory; @@ -64,7 +68,7 @@ class TAO_Naming_Serv_Export TAO_Naming_Server { public: /// Default constructor. - TAO_Naming_Server (void); + TAO_Naming_Server (size_t bsize = 1); /** * Constructor. Attempts to find an existing Naming Service if @@ -90,7 +94,8 @@ public: int enable_multicast = 1, int use_storable_context = 0, int round_trip_timeout = 0, - int use_round_trip_timeout = 0); + int use_round_trip_timeout = 0, + size_t bsize = 1); /** * Initializer. Attempts to find an existing Naming Service if @@ -131,19 +136,32 @@ public: /// Returns the IOR of the naming service. char * naming_service_ior (void); - /// Returns a NamingContext_ptr for the root Naming Context. + /// Returns a <NamingContext_ptr> for the root Naming Context. CosNaming::NamingContext_ptr operator-> (void) const; protected: + struct IOR_Bundle { + CORBA::Object_var ref_; + ACE_CString ior_; + ACE_TString filename_; + }; + + void assign (size_t ndx, bool take, CORBA::Object_ptr obj); + int write (size_t ndx) const; + + enum Base_IOR_Indexes { + ROOT = 0 + }; + /** * Helper method: create Naming Service locally. Can be specialized to * refine how Naming Service components are created and initialized * Make the root context of size * @a context_size, register it under the @a root_poa, and make the Naming - * Service persistent if @a persistence_location is not 0. - * (@a persistence_location specifies name of the file to use for + * Service persistent if <persistence_location> is not 0. + * (<persistence_location> specifies name of the file to use for * persistent storage). - * If @a enable_multicast is not zero then the service will respond + * If <enable_multicast> is not zero then the service will respond * to multicast location queries. */ virtual int init_new_naming (CORBA::ORB_ptr orb, @@ -175,15 +193,9 @@ protected: virtual TAO_Persistent_Naming_Context_Factory * persistent_naming_context_factory (void); - /// Root NamingContext_ptr. - CosNaming::NamingContext_var naming_context_; - /// The ior_multicast event handler. TAO_IOR_Multicast *ior_multicast_; - /// The IOR string of the root naming context. - CORBA::String_var naming_service_ior_; - /// The ORB CORBA::ORB_var orb_; @@ -193,12 +205,17 @@ protected: /// The Naming Service POA. PortableServer::POA_var ns_poa_; - /// File to output the Naming Service IOR. - const ACE_TCHAR *ior_file_name_; - /// File to output the process id. const ACE_TCHAR *pid_file_name_; + /// Although this class only manages the root context info + /// the FT class adds primary/backup IORs for the root context + /// as well as IORs for LB groups as well. + IOR_Bundle *iors_; + size_t bundle_size_; + IOR_Bundle *bundle_at (size_t ndx); + const IOR_Bundle *bundle_at (size_t ndx) const; + /** * Size of the hash_table allocated upon the creation of the Naming * Service context (if one is created). Note: all the contexts @@ -220,7 +237,7 @@ protected: /// Path to the file to be used to store/read in Naming Service /// persistent state. - const ACE_TCHAR *persistence_file_name_; + const ACE_TCHAR *persistence_dir_; /// Address to be used for memory mapping Naming Service state file, /// identified by the <persistence_file_name_>. diff --git a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp index f92ff94e7d8..c6e8cc22dbb 100644 --- a/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp +++ b/TAO/orbsvcs/orbsvcs/Naming/Storable_Naming_Context.cpp @@ -1,3 +1,4 @@ + #include "orbsvcs/Log_Macros.h" #include "orbsvcs/Naming/Storable_Naming_Context.h" #include "orbsvcs/Naming/Storable_Naming_Context_Factory.h" @@ -247,7 +248,6 @@ void TAO_Storable_Naming_Context::Write (TAO::Storable_Base& wrtr) ACE_TRACE("Write"); TAO_Storable_Naming_Context_ReaderWriter rw(wrtr); rw.write(*this); - } // Helpers function to load a new context into the binding_map @@ -270,7 +270,7 @@ File_Open_Lock_and_Check::File_Open_Lock_and_Check try { this->init_no_load (method_type); - if (force_load || method_type == CREATE_WITHOUT_FILE) + if (force_load) this->reload (); else { @@ -298,10 +298,9 @@ File_Open_Lock_and_Check::~File_Open_Lock_and_Check () // notify the context if it did. if (context_->write_occurred_ == 1) { - context_->context_written (); - // We have to make sure we clear the flag - // for subsequent times through. + // clear first to avoid potential nested upcalls context_->write_occurred_ = 0; + context_->context_written (); } } @@ -402,16 +401,6 @@ TAO_Storable_Naming_Context::TAO_Storable_Naming_Context ( write_occurred_ (0) { ACE_TRACE("TAO_Storable_Naming_Context"); - // Create a temporary stream simply to check if a readable - // version already exists. - - ACE_Auto_Ptr<TAO::Storable_Base> stream - (this->factory_->create_stream(context_name_.c_str(), "r")); - if (!stream->exists ()) - { - File_Open_Lock_and_Check fg(this, SFG::CREATE_WITHOUT_FILE, false); - this->Write (fg.peer ()); - } } TAO_Storable_Naming_Context::~TAO_Storable_Naming_Context (void) @@ -940,6 +929,8 @@ TAO_Storable_Naming_Context::list (CORBA::ULong how_many, CosNaming::BindingIterator_out &bi) { ACE_TRACE("TAO_Storable_Naming_Context::list"); + // Allocate nil out parameters in case we won't be able to complete + // the operation. bi = CosNaming::BindingIterator::_nil (); ACE_NEW_THROW_EX (bl, @@ -953,11 +944,14 @@ TAO_Storable_Naming_Context::list (CORBA::ULong how_many, this->lock_, CORBA::INTERNAL ()); + // Dynamically allocate iterator for traversing the underlying hash map. HASH_MAP::ITERATOR *hash_iter = 0; ACE_NEW_THROW_EX (hash_iter, HASH_MAP::ITERATOR (storable_context_->map ()), CORBA::NO_MEMORY ()); + // Store <hash_iter temporarily in auto pointer, in case we'll have + // some failures and throw an exception. ACE_Auto_Basic_Ptr<HASH_MAP::ITERATOR> temp (hash_iter); // Silliness below is required because of broken old g++!!! E.g., @@ -968,14 +962,27 @@ TAO_Storable_Naming_Context::list (CORBA::ULong how_many, typedef ACE_Hash_Map_Manager<TAO_Storable_ExtId, TAO_Storable_IntId, ACE_Null_Mutex>::ENTRY ENTRY_DEF; + + // Typedef to the type of BindingIterator servant for ease of use. typedef TAO_Bindings_Iterator<ITER_DEF, ENTRY_DEF> ITER_SERVANT; - CORBA::ULong n = (this->context_->current_size () > how_many) ? - how_many : - static_cast<CORBA::ULong> (this->context_->current_size ()); + // A pointer to BindingIterator servant. + ITER_SERVANT *bind_iter = 0; + + // Number of bindings that will go into the BindingList <bl>. + CORBA::ULong n; + + // Calculate number of bindings that will go into <bl>. + if (this->context_->current_size () > how_many) + n = how_many; + else + n = static_cast<CORBA::ULong> (this->context_->current_size ()); + + // Use the hash map iterator to populate <bl> with bindings. bl->length (n); ENTRY_DEF *hash_entry = 0; + for (CORBA::ULong i = 0; i < n; i++) { hash_iter->next (hash_entry); @@ -985,26 +992,35 @@ TAO_Storable_Naming_Context::list (CORBA::ULong how_many, throw CORBA::NO_MEMORY(); } + // Now we are done with the BindingsList, and we can follow up on + // the BindingIterator business. + + // If we do not need to pass back BindingIterator. if (this->context_->current_size () <= how_many) return; else if (redundant_) { + ACE_UNUSED_ARG (bind_iter); throw CORBA::NO_IMPLEMENT (); } else { - ITER_SERVANT *bind_iter = 0; + // Create a BindingIterator for return. ACE_NEW_THROW_EX (bind_iter, ITER_SERVANT (this, hash_iter, this->poa_.in ()), CORBA::NO_MEMORY ()); + // Release <hash_iter> from auto pointer, and start using + // reference counting to control our servant. temp.release (); - PortableServer::ServantBase_var svt = bind_iter; + PortableServer::ServantBase_var iter = bind_iter; // Increment reference count on this Naming Context, so it doesn't get // deleted before the BindingIterator servant gets deleted. interface_->_add_ref (); + // Register with the POA. + // Is an ACE_UINT32 enough? char poa_id[BUFSIZ]; ACE_OS::snprintf (poa_id, BUFSIZ, @@ -1014,9 +1030,9 @@ TAO_Storable_Naming_Context::list (CORBA::ULong how_many, PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId (poa_id); - this->poa_->activate_object_with_id (id.in (), svt.in()); - CORBA::Object_var obj = this->poa_->id_to_reference (id.in ()); - bi = CosNaming::BindingIterator::_narrow (obj.in()); + this->poa_->activate_object_with_id (id.in (), + bind_iter); + bi = bind_iter->_this (); } } @@ -1098,7 +1114,10 @@ TAO_Storable_Naming_Context::recreate_all ( TAO_Storable_Naming_Context_ReaderWriter rw(*gfl_.get()); rw.read_global(global); gcounter_ = global.counter(); - if(redundant_) gfl_->close(); + if (redundant_) + { + gfl_->close(); + } return result._retn (); } diff --git a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc index 6ce5d82e654..22dcff47246 100644 --- a/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc +++ b/TAO/orbsvcs/tests/FT_Naming/FaultTolerant/FaultTolerant.mpc @@ -1,4 +1,5 @@ // -*- MPC -*- + project(*idl): taoidldefaults { IDL_Files { Test.idl @@ -23,12 +24,10 @@ project(*server): ftnaming { project(*Client) : ftnaming { exename = client after += *idl - Source_Files { client.cpp TestC.cpp } - IDL_Files { test_object.idl } diff --git a/TAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl b/TAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl index 22c0a13caa7..d4ba7ec0499 100755 --- a/TAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl +++ b/TAO/orbsvcs/tests/FT_Naming/Replication/run_test.pl @@ -28,8 +28,12 @@ $hostname = $test->HostName (); $ns_orb_port1 = 10001 + $test->RandomPort (); $ns_orb_port2 = 10002 + $test->RandomPort (); +$ft_orb_port1 = 12001 + $test->RandomPort (); +$ft_orb_port2 = 12002 + $test->RandomPort (); $ns_endpoint1 = "iiop://$hostname:$ns_orb_port1"; $ns_endpoint2 = "iiop://$hostname:$ns_orb_port2"; +$ft_endpoint1 = "iiop://$hostname:$ft_orb_port1"; +$ft_endpoint2 = "iiop://$hostname:$ft_orb_port2"; $naming_persistence_dir = "NameService"; $groups_persistence_dir = "Groups"; @@ -95,7 +99,8 @@ sub init_persistence_directory($$) # Run two Naming Servers and one client. Client uses iors # in files to find the individual copies of the Naming Servers. -my $args = "-ORBEndPoint $ns_endpoint1 " . +my $args = "-orbdebuglevel 1 -orbverboselogging 1 -ORBLogFile primary.log -ORBEndPoint $ns_endpoint1 " . + "-ftendpoint $ft_endpoint1 " . "-m 0 " . "-r $naming_persistence_dir " . "-v $groups_persistence_dir " . @@ -122,17 +127,19 @@ if ($test->WaitForFileTimed ($primary_iorfile, } $args = "-ORBEndPoint $ns_endpoint2 " . + "-ftendpoint $ft_endpoint2 " . "-g $nm_iorfile " . "-c $combined_ns_iorfile " . "-m 0 " . "-n 100 " . "-r $naming_persistence_dir " . "-v $groups_persistence_dir " . + "-orbdebuglevel 1 -orbverboselogging 1 -ORBLogFile backup.log " . "--backup"; $prog = "$startdir/../../../FT_Naming_Service/tao_ft_naming"; -print STDERR "Starting Backup: $prog $args\n"; +print STDERR "Starting Backup: $prog $args\n in $startdir\n"; $NS2 = $test->CreateProcess ("$prog", "$args"); |