summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/ServerI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceGrid/ServerI.cpp')
-rw-r--r--cpp/src/IceGrid/ServerI.cpp949
1 files changed, 414 insertions, 535 deletions
diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp
index 2ed1d397e65..f68aa8cbcac 100644
--- a/cpp/src/IceGrid/ServerI.cpp
+++ b/cpp/src/IceGrid/ServerI.cpp
@@ -111,6 +111,83 @@ chownRecursive(const string& path, uid_t uid, gid_t gid)
}
#endif
+static bool
+descriptorWithoutRevisionEqual(const InternalServerDescriptorPtr& lhs, const InternalServerDescriptorPtr& rhs)
+{
+ if(lhs->id != rhs->id ||
+ lhs->application != rhs->application ||
+ lhs->uuid != rhs->uuid ||
+// lhs->revision != rhs->revision ||
+ lhs->sessionId != rhs->sessionId ||
+ lhs->exe != rhs->exe ||
+ lhs->pwd != rhs->pwd ||
+ lhs->user != rhs->user ||
+ lhs->activation != rhs->activation ||
+ lhs->activationTimeout != rhs->activationTimeout ||
+ lhs->deactivationTimeout != rhs->deactivationTimeout ||
+ lhs->iceVersion != rhs->iceVersion ||
+ lhs->applicationDistrib != rhs->applicationDistrib ||
+ lhs->processRegistered != rhs->processRegistered ||
+ lhs->options != rhs->options ||
+ lhs->envs != rhs->envs ||
+ lhs->logs != rhs->logs)
+ {
+ return false;
+ }
+
+ if(!lhs->distrib && rhs->distrib || lhs->distrib && !rhs->distrib)
+ {
+ return false;
+ }
+ else if(lhs->distrib && rhs->distrib)
+ {
+ if(lhs->distrib->icepatch != rhs->distrib->icepatch ||
+ lhs->distrib->directories != rhs->distrib->directories)
+ {
+ return false;
+ }
+ }
+
+ if(lhs->adapters.size() != rhs->adapters.size())
+ {
+ return false;
+ }
+ else
+ {
+ InternalAdapterDescriptorSeq::const_iterator q = rhs->adapters.begin();
+ for(InternalAdapterDescriptorSeq::const_iterator p = lhs->adapters.begin(); p != lhs->adapters.end(); ++p, ++q)
+ {
+ if((*p)->id != (*q)->id || (*p)->serverLifetime != (*q)->serverLifetime)
+ {
+ return false;
+ }
+ }
+ }
+
+ if(lhs->dbEnvs.size() != rhs->dbEnvs.size())
+ {
+ return false;
+ }
+ else
+ {
+ InternalDbEnvDescriptorSeq::const_iterator q = rhs->dbEnvs.begin();
+ for(InternalDbEnvDescriptorSeq::const_iterator p = lhs->dbEnvs.begin(); p != lhs->dbEnvs.end(); ++p, ++q)
+ {
+ if((*p)->name != (*q)->name || (*p)->properties != (*q)->properties)
+ {
+ return false;
+ }
+ }
+ }
+
+ if(lhs->properties != rhs->properties)
+ {
+ return false;
+ }
+
+ return true;
+}
+
class CommandTimeoutItem : public WaitItem
{
public:
@@ -312,16 +389,16 @@ LoadCommand::execute()
}
void
-LoadCommand::setUpdate(const ServerInfo& info, bool clearDir)
+LoadCommand::setUpdate(const InternalServerDescriptorPtr& descriptor, bool clearDir)
{
_clearDir = clearDir;
- _info = info;
+ _desc = descriptor;
}
-ServerInfo
-LoadCommand::getServerInfo() const
+InternalServerDescriptorPtr
+LoadCommand::getInternalServerDescriptor() const
{
- return _info;
+ return _desc;
}
bool
@@ -354,9 +431,9 @@ LoadCommand::finished(const ServerPrx& proxy, const AdapterPrxDict& adapters, in
}
}
-DestroyCommand::DestroyCommand(const ServerIPtr& server, bool kill) :
+DestroyCommand::DestroyCommand(const ServerIPtr& server, bool loadFailure) :
ServerCommand(server),
- _kill(kill)
+ _loadFailure(loadFailure)
{
}
@@ -375,14 +452,7 @@ DestroyCommand::nextState()
void
DestroyCommand::execute()
{
- if(_kill)
- {
- _server->kill();
- }
- else
- {
- _server->destroy();
- }
+ _server->destroy();
}
void
@@ -400,6 +470,12 @@ DestroyCommand::finished()
}
}
+bool
+DestroyCommand::loadFailure() const
+{
+ return _loadFailure;
+}
+
PatchCommand::PatchCommand(const ServerIPtr& server) :
ServerCommand(server),
_notified(false),
@@ -590,28 +666,6 @@ ServerI::ServerI(const NodeIPtr& node, const ServerPrx& proxy, const string& ser
assert(_node->getActivator());
const_cast<int&>(_disableOnFailure) =
_node->getCommunicator()->getProperties()->getPropertyAsIntWithDefault("IceGrid.Node.DisableOnFailure", 0);
-
- //
- // Read the server application uuid and revision. This is to
- // ensure that a registry won't try to load an older server
- // definition than the one for which this server was loaded.
- //
- string idFilePath = _serverDir + "/revision";
- ifstream is(idFilePath.c_str());
- if(is.good())
- {
- char line[1024];
- is.getline(line, 1024); // Ignore comments
- is.getline(line, 1024);
- is.getline(line, 1024);
- string ignore;
- is >> ignore >> _info.uuid;
- is >> ignore >> _info.revision;
- }
- else
- {
- _info.revision = 0;
- }
}
ServerI::~ServerI()
@@ -701,12 +755,12 @@ ServerI::setEnabled(bool enabled, const ::Ice::Current&)
{
Lock sync(*this);
checkDestroyed();
- assert(_info.descriptor);
+ assert(_desc);
if(enabled && _activation == Disabled)
{
_failureTime = IceUtil::Time();
- _activation = toServerActivation(_info.descriptor->activation);
+ _activation = toServerActivation(_desc->activation);
activate = _state == Inactive && _activation == Always;
}
else if(!enabled && (_activation != Disabled || _failureTime != IceUtil::Time()))
@@ -787,13 +841,13 @@ bool
ServerI::isAdapterActivatable(const string& id) const
{
Lock sync(*this);
- if(!_info.descriptor || _activation == Disabled)
+ if(!_desc || _activation == Disabled)
{
return false;
}
- if(_info.descriptor->activation == "manual" ||
- _info.descriptor->activation == "session" && _info.sessionId.empty())
+ if(_desc->activation == "manual" ||
+ _desc->activation == "session" && _desc->sessionId.empty())
{
return false;
}
@@ -826,11 +880,11 @@ ServerI::getId() const
return _id;
}
-DistributionDescriptor
+InternalDistributionDescriptorPtr
ServerI::getDistribution() const
{
Lock sync(*this);
- return _info.descriptor ? _info.descriptor->distrib : DistributionDescriptor();
+ return _desc ? _desc->distrib : InternalDistributionDescriptorPtr();
}
void
@@ -870,7 +924,7 @@ ServerI::start(ServerActivation activation, const AMD_Server_startPtr& amdCB)
{
throw ServerStartException(_id, "The server activation doesn't allow this activation mode.");
}
- else if(_activation == Session && _info.sessionId.empty())
+ else if(_activation == Session && _desc->sessionId.empty())
{
throw ServerStartException(_id, "The server is not owned by a session.");
}
@@ -920,43 +974,11 @@ ServerI::start(ServerActivation activation, const AMD_Server_startPtr& amdCB)
}
ServerCommandPtr
-ServerI::load(const AMD_Node_loadServerPtr& amdCB, const ServerInfo& info, bool fromMaster)
+ServerI::load(const AMD_Node_loadServerPtr& amdCB, const InternalServerDescriptorPtr& desc, const string& replicaName)
{
Lock sync(*this);
checkDestroyed();
-
- //
- // Don't reload the server if:
- //
- // - the application uuid, the application revision and the
- // session id didn't change.
- //
- // - the load command if from a slave and the given descriptor
- // is from another application or doesn't have the same
- // version.
- //
- // - the descriptor and the session id didn't change.
- //
- // In any case, we update the server application revision if
- // it needs to be updated.
- //
- if(!_info.uuid.empty() && !fromMaster)
- {
- if(_info.uuid != info.uuid)
- {
- DeploymentException ex;
- ex.reason = "server descriptor from replica is from another application (`" + info.uuid + "')";
- throw ex;
- }
- else if(_info.revision != info.revision)
- {
- ostringstream os;
- os << "server descriptor from replica has different version:\n";
- os << "current revision: " << _info.revision << "\n";
- os << "replica revision: " << info.revision;
- throw DeploymentException(os.str());
- }
- }
+ checkRevision(replicaName, desc->uuid, desc->revision);
//
// Otherwise, if the following conditions are met:
@@ -968,16 +990,13 @@ ServerI::load(const AMD_Node_loadServerPtr& amdCB, const ServerInfo& info, bool
// we don't re-load the server. We just return the server
// proxy and the proxies of its adapters.
//
- if(_info.descriptor &&
- (!fromMaster || _info.sessionId == info.sessionId) &&
- (_info.uuid == info.uuid && _info.revision == info.revision ||
- descriptorEqual(_node->getCommunicator(), _info.descriptor, info.descriptor)))
+ if(_desc &&
+ (replicaName != "Master" || _desc->sessionId == desc->sessionId) &&
+ (_desc->uuid == desc->uuid && _desc->revision == desc->revision || descriptorWithoutRevisionEqual(_desc, desc)))
{
- if(_info.uuid != info.uuid || _info.revision != info.revision)
+ if(_desc->revision != desc->revision)
{
- _info.uuid = info.uuid;
- _info.revision = info.revision;
- updateRevisionFile();
+ updateRevision(desc->uuid, desc->revision);
}
if(amdCB)
@@ -991,8 +1010,7 @@ ServerI::load(const AMD_Node_loadServerPtr& amdCB, const ServerInfo& info, bool
}
return 0;
}
-
- assert(fromMaster || _info.uuid.empty() || _info.uuid == info.uuid && _info.revision == info.revision);
+
if(!StopCommand::isStopped(_state) && !_stop)
{
_stop = new StopCommand(this, _node->getWaitQueue(), _deactivationTimeout);
@@ -1001,7 +1019,7 @@ ServerI::load(const AMD_Node_loadServerPtr& amdCB, const ServerInfo& info, bool
{
_load = new LoadCommand(this);
}
- _load->setUpdate(info, _destroy);
+ _load->setUpdate(desc, _destroy);
if(_destroy && _state != Destroying)
{
_destroy->finished();
@@ -1015,32 +1033,16 @@ ServerI::load(const AMD_Node_loadServerPtr& amdCB, const ServerInfo& info, bool
}
ServerCommandPtr
-ServerI::destroy(const AMD_Node_destroyServerPtr& amdCB, const string& uuid, int revision)
+ServerI::destroy(const AMD_Node_destroyServerPtr& amdCB, const string& uuid, int revision, const string& replicaName)
{
Lock sync(*this);
checkDestroyed();
+ checkRevision(replicaName, uuid, revision);
- if(!uuid.empty()) // Empty if from checkConsistency.
+ if(!_desc)
{
- if(_info.uuid.empty())
- {
- amdCB->ice_response();
- return 0; // Server doesn't exist.
- }
- else if(_info.uuid != uuid)
- {
- DeploymentException ex;
- ex.reason = "server descriptor from replica is from another application (`" + uuid + "')";
- throw ex;
- }
- else if(_info.revision > revision)
- {
- ostringstream os;
- os << "server descriptor from replica is too old:\n";
- os << "current revision: " << _info.revision << "\n";
- os << "replica revision: " << revision;
- throw DeploymentException(os.str());
- }
+ amdCB->ice_response();
+ return 0; // Server is already destroyed.
}
if(!StopCommand::isStopped(_state) && !_stop)
@@ -1049,8 +1051,7 @@ ServerI::destroy(const AMD_Node_destroyServerPtr& amdCB, const string& uuid, int
}
if(!_destroy)
{
- //_destroy = new DestroyCommand(this, _state != Inactive && _state != Loading && _state != Patching);
- _destroy = new DestroyCommand(this, false);
+ _destroy = new DestroyCommand(this);
}
if(amdCB)
{
@@ -1279,7 +1280,7 @@ ServerI::activationFailed(bool destroyed)
void
ServerI::activate()
{
- ServerInfo info;
+ InternalServerDescriptorPtr desc;
ServerAdapterDict adpts;
bool waitForReplication;
@@ -1289,8 +1290,8 @@ ServerI::activate()
#endif
{
Lock sync(*this);
- assert(_state == Activating && _info.descriptor);
- info = _info;
+ assert(_state == Activating && _desc);
+ desc = _desc;
adpts = _adapters;
//
@@ -1321,7 +1322,7 @@ ServerI::activate()
if(session)
{
AMI_NodeSession_waitForApplicationUpdatePtr cb = new WaitForApplicationUpdateCB(this);
- _node->getMasterNodeSession()->waitForApplicationUpdate_async(cb, info.uuid, info.revision);
+ _node->getMasterNodeSession()->waitForApplicationUpdate_async(cb, desc->uuid, desc->revision);
return;
}
}
@@ -1329,7 +1330,6 @@ ServerI::activate()
//
// Compute the server command line options.
//
- ServerDescriptorPtr desc = info.descriptor;
Ice::StringSeq options;
copy(desc->options.begin(), desc->options.end(), back_inserter(options));
options.push_back("--Ice.Config=" + _serverDir + "/config/config");
@@ -1441,6 +1441,7 @@ ServerI::deactivate()
Ice::ProcessPrx process;
{
Lock sync(*this);
+ assert(_desc);
if(_state != Deactivating && _state != DeactivatingWaitForProcess)
{
return;
@@ -1451,7 +1452,7 @@ ServerI::deactivate()
// not set yet, we wait for the server to set this process
// object before attempting to deactivate the server again.
//
- if(_processRegistered && !_process)
+ if(_desc->processRegistered && !_process)
{
setStateNoSync(ServerI::DeactivatingWaitForProcess);
return;
@@ -1497,11 +1498,12 @@ ServerI::destroy()
ServerAdapterDict adpts;
{
Lock sync(*this);
+ assert(_desc);
assert(_state == Destroying);
adpts = _adapters;
}
- _node->removeServer(this, _info.application, _info.descriptor->applicationDistrib);
+ _node->removeServer(this, _desc->application, _desc->applicationDistrib);
try
{
@@ -1509,8 +1511,11 @@ ServerI::destroy()
}
catch(const string& msg)
{
- Ice::Warning out(_node->getTraceLevels()->logger);
- out << "removing server directory `" << _serverDir << "' failed: " << msg;
+ if(!_destroy->loadFailure())
+ {
+ Ice::Warning out(_node->getTraceLevels()->logger);
+ out << "removing server directory `" << _serverDir << "' failed: " << msg;
+ }
}
//
@@ -1635,7 +1640,7 @@ ServerI::update()
return;
}
- ServerInfo oldInfo = _info;
+ InternalServerDescriptorPtr oldDescriptor = _desc;
try
{
if(_load->clearDir())
@@ -1656,7 +1661,7 @@ ServerI::update()
try
{
- updateImpl(_load->getServerInfo());
+ updateImpl(_load->getInternalServerDescriptor());
}
catch(const Ice::Exception& ex)
{
@@ -1672,13 +1677,13 @@ ServerI::update()
{
throw DeploymentException(msg);
}
-
- if(oldInfo.descriptor)
+
+ if(oldDescriptor)
{
- _node->removeServer(this, oldInfo.application, oldInfo.descriptor->applicationDistrib);
+ _node->removeServer(this, oldDescriptor->application, oldDescriptor->applicationDistrib);
}
- _node->addServer(this, _info.application, _info.descriptor->applicationDistrib);
-
+ _node->addServer(this, _desc->application, _desc->applicationDistrib);
+
AdapterPrxDict adapters;
for(ServerAdapterDict::const_iterator p = _adapters.begin(); p != _adapters.end(); ++p)
{
@@ -1691,25 +1696,33 @@ ServerI::update()
//
// Rollback old descriptor.
//
- try
- {
- updateImpl(oldInfo);
- }
- catch(const Ice::Exception& e)
+ if(oldDescriptor)
{
- Ice::Warning out(_node->getTraceLevels()->logger);
- out << "update failed:\n" << ex.reason << "\nand couldn't rollback old descriptor:\n" << e;
+ try
+ {
+ updateImpl(oldDescriptor);
+ }
+ catch(const Ice::Exception& e)
+ {
+ Ice::Warning out(_node->getTraceLevels()->logger);
+ out << "update failed:\n" << ex.reason << "\nand couldn't rollback old descriptor:\n" << e;
+ }
+ catch(const string& msg)
+ {
+ Ice::Warning out(_node->getTraceLevels()->logger);
+ out << "update failed:\n" << ex.reason << "\nand couldn't rollback old descriptor:\n" << msg;
+ }
+ catch(const char* msg)
+ {
+ Ice::Warning out(_node->getTraceLevels()->logger);
+ out << "update failed:\n" << ex.reason << "\nand couldn't rollback old descriptor:\n" << msg;
+ }
}
- catch(const string& msg)
+ else if(!_destroy)
{
- Ice::Warning out(_node->getTraceLevels()->logger);
- out << "update failed:\n" << ex.reason << "\nand couldn't rollback old descriptor:\n" << msg;
- }
- catch(const char* msg)
- {
- Ice::Warning out(_node->getTraceLevels()->logger);
- out << "update failed:\n" << ex.reason << "\nand couldn't rollback old descriptor:\n" << msg;
+ _destroy = new DestroyCommand(this, true);
}
+
_load->failed(ex);
}
@@ -1723,9 +1736,12 @@ ServerI::update()
}
void
-ServerI::updateImpl(const ServerInfo& info)
+ServerI::updateImpl(const InternalServerDescriptorPtr& descriptor)
{
- assert(_load);
+ assert(_load && descriptor);
+
+ _desc = descriptor;
+ _waitForReplication = true;
//
// Remember if the server was just released by a session, this
@@ -1735,64 +1751,69 @@ ServerI::updateImpl(const ServerInfo& info)
// if the server configuration is bogus and the session server
// can't start).
//
- bool serverSessionReleased = _info.descriptor && _info.descriptor->activation == "session" &&
- _info.revision == info.revision && !_info.sessionId.empty() && info.sessionId.empty();
-
- _info = info;
- _waitForReplication = true;
-
- if(!_info.descriptor)
- {
- return;
- }
+ bool serverSessionReleased = _desc && _desc->activation == "session" &&
+ _desc->revision == descriptor->revision && !_desc->sessionId.empty() && descriptor->sessionId.empty();
//
- // Create the object adapter objects if necessary.
+ // Go through the adapters and create the object adapter Ice
+ // objects if necessary, also remove the old ones.
//
- _processRegistered = false;
- ServerAdapterDict oldAdapters;
- oldAdapters.swap(_adapters);
- _serverLifetimeAdapters.clear();
- AdapterDescriptorSeq::const_iterator r;
- for(r = _info.descriptor->adapters.begin(); r != _info.descriptor->adapters.end(); ++r)
- {
- assert(!r->id.empty());
- oldAdapters.erase(addAdapter(*r, _info.descriptor));
- _processRegistered |= r->registerProcess;
- }
- IceBoxDescriptorPtr iceBox = IceBoxDescriptorPtr::dynamicCast(_info.descriptor);
- if(iceBox)
{
- ServiceInstanceDescriptorSeq::const_iterator s;
- for(s = iceBox->services.begin(); s != iceBox->services.end(); ++s)
+ ServerAdapterDict oldAdapters;
+ oldAdapters.swap(_adapters);
+ _serverLifetimeAdapters.clear();
+ Ice::ObjectAdapterPtr adapter = _node->getAdapter();
+ for(InternalAdapterDescriptorSeq::const_iterator r = _desc->adapters.begin(); r != _desc->adapters.end(); ++r)
{
- CommunicatorDescriptorPtr svc = s->descriptor;
- for(r = svc->adapters.begin(); r != svc->adapters.end(); ++r)
+ try
+ {
+ Ice::Identity id;
+ id.category = _this->ice_getIdentity().category + "Adapter";
+ id.name = _id + "-" + (*r)->id;
+ ServerAdapterIPtr servant = ServerAdapterIPtr::dynamicCast(adapter->find(id));
+ if(!servant)
+ {
+ AdapterPrx proxy = AdapterPrx::uncheckedCast(adapter->createProxy(id));
+ servant = new ServerAdapterI(_node, this, _id, proxy, (*r)->id);
+ adapter->add(servant, id);
+ }
+ _adapters.insert(make_pair((*r)->id, servant));
+
+ if((*r)->serverLifetime)
+ {
+ _serverLifetimeAdapters.insert((*r)->id);
+ }
+ }
+ catch(const Ice::ObjectAdapterDeactivatedException&)
+ {
+ // IGNORE
+ }
+ catch(const Ice::LocalException& ex)
{
- assert(!r->id.empty());
- oldAdapters.erase(addAdapter(*r, svc));
- _processRegistered |= r->registerProcess;
+ Ice::Error out(_node->getTraceLevels()->logger);
+ out << "couldn't add adapter `" << (*r)->id << "':\n" << ex;
}
+ oldAdapters.erase((*r)->id);
}
- }
- //
- // Remove old object adapters.
- //
- for(ServerAdapterDict::const_iterator t = oldAdapters.begin(); t != oldAdapters.end(); ++t)
- {
- try
- {
- t->second->destroy();
- }
- catch(const Ice::ObjectAdapterDeactivatedException&)
- {
- // IGNORE
- }
- catch(const Ice::LocalException& ex)
+ //
+ // Remove old object adapters.
+ //
+ for(ServerAdapterDict::const_iterator t = oldAdapters.begin(); t != oldAdapters.end(); ++t)
{
- Ice::Error out(_node->getTraceLevels()->logger);
- out << "couldn't destroy adapter `" << t->first << "':\n" << ex;
+ try
+ {
+ t->second->destroy();
+ }
+ catch(const Ice::ObjectAdapterDeactivatedException&)
+ {
+ // IGNORE
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ Ice::Error out(_node->getTraceLevels()->logger);
+ out << "couldn't destroy adapter `" << t->first << "':\n" << ex;
+ }
}
}
@@ -1805,7 +1826,7 @@ ServerI::updateImpl(const ServerInfo& info)
//
if(_activation != Disabled || _failureTime != IceUtil::Time())
{
- _activation = toServerActivation(_info.descriptor->activation);
+ _activation = toServerActivation(_desc->activation);
_failureTime = IceUtil::Time();
}
@@ -1820,9 +1841,9 @@ ServerI::updateImpl(const ServerInfo& info)
// mode and if it's not currently owned by a session.
//
string user;
- if(_info.descriptor->activation != "session" || !_info.sessionId.empty())
+ if(_desc->activation != "session" || !_desc->sessionId.empty())
{
- user = _info.descriptor->user;
+ user = _desc->user;
#ifndef _WIN32
//
// Check if the node is running as root, if that's the case we
@@ -1835,7 +1856,7 @@ ServerI::updateImpl(const ServerInfo& info)
// a session we set the user to the session id, otherwise
// we set it to "nobody".
//
- user = !_info.sessionId.empty() ? _info.sessionId : "nobody";
+ user = !_desc->sessionId.empty() ? _desc->sessionId : "nobody";
}
#endif
}
@@ -1939,59 +1960,60 @@ ServerI::updateImpl(const ServerInfo& info)
}
#endif
- istringstream at(_info.descriptor->activationTimeout);
+ istringstream at(_desc->activationTimeout);
if(!(at >> _activationTimeout) || !at.eof() || _activationTimeout == 0)
{
_activationTimeout = _waitTime;
}
- istringstream dt(_info.descriptor->deactivationTimeout);
+ istringstream dt(_desc->deactivationTimeout);
if(!(dt >> _deactivationTimeout) || !dt.eof() || _deactivationTimeout == 0)
{
_deactivationTimeout = _waitTime;
}
//
- // Cache the path of each log file.
+ // Make sure the log paths are sorted.
//
- _logs.clear();
- LogDescriptorSeq::const_iterator l;
- for(l = _info.descriptor->logs.begin(); l != _info.descriptor->logs.end(); ++l)
- {
- _logs.insert(IcePatch2::simplify(l->path));
- }
- if(iceBox)
+ _logs = _desc->logs;
+ sort(_desc->logs.begin(), _desc->logs.begin());
+
+ //
+ // Copy the descriptor properties. We shouldn't modify the
+ // descriptor since it's used for the comparison when the server
+ // needs to be updated.
+ //
+ PropertyDescriptorSeqDict properties = _desc->properties;
+ PropertyDescriptorSeq& props = properties["config"];
+ if(getProperty(props, "Ice.Default.Locator") == "")
{
- ServiceInstanceDescriptorSeq::const_iterator s;
- for(s = iceBox->services.begin(); s != iceBox->services.end(); ++s)
- {
- CommunicatorDescriptorPtr svc = s->descriptor;
- for(l = svc->logs.begin(); l != svc->logs.end(); ++l)
- {
- _logs.insert(IcePatch2::simplify(l->path));
- }
- }
+ props.push_back(createProperty("Ice.Default.Locator",
+ _node->getCommunicator()->getProperties()->getProperty("Ice.Default.Locator")));
}
-
+
//
- // Cache the path of the stderr/stdout file.
+ // Cache the path of the stderr/stdout file, first check if the
+ // node OutputDir property is set and then we check the server
+ // configuration file for the Ice.StdErr and Ice.StdOut
+ // properties.
//
+ _stdErrFile = getProperty(props, "Ice.StdErr");
+ _stdOutFile = getProperty(props, "Ice.StdOut");
string outputDir = _node->getOutputDir();
- _stdOutFile = outputDir.empty() ? string() : (outputDir + "/" + _id + ".out");
- string suffix = _node->getRedirectErrToOut() ? ".out" : ".err";
- _stdErrFile = outputDir.empty() ? string() : (outputDir + "/" + _id + suffix);
- PropertyDescriptorSeq::const_iterator s;
- for(s = _info.descriptor->propertySet.properties.begin(); s != _info.descriptor->propertySet.properties.end(); ++s)
+ if(!outputDir.empty())
{
- if(s->name == "Ice.StdErr")
+ if(_stdErrFile.empty())
{
- _stdErrFile = s->value;
+ _stdErrFile = outputDir + "/" + _id + (_node->getRedirectErrToOut() ? ".out" : ".err");
+ props.push_back(createProperty("Ice.StdErr", _stdErrFile));
}
- else if(s->name == "Ice.StdOut")
+ if(_stdOutFile.empty())
{
- _stdOutFile = s->value;
+ _stdOutFile = outputDir + "/" + _id + ".out";
+ props.push_back(createProperty("Ice.StdOut", _stdOutFile));
}
}
+
//
// If the server is a session server and it wasn't udpated but
// just released by a session, we don't update the configuration,
@@ -2005,7 +2027,7 @@ ServerI::updateImpl(const ServerInfo& info)
//
// Update the revision file.
//
- updateRevisionFile();
+ updateRevision(_desc->uuid, _desc->revision);
//
// Create or update the server directories exists.
@@ -2016,89 +2038,120 @@ ServerI::updateImpl(const ServerInfo& info)
createOrUpdateDirectory(_serverDir + "/distrib");
//
- // Update the configuration file(s) of the server if necessary.
+ // Create the configuration files, remove the old ones.
//
- Ice::StringSeq knownFiles;
- updateConfigFile(_serverDir, _info.descriptor);
- knownFiles.push_back("config");
- if(iceBox)
{
- ServiceInstanceDescriptorSeq::const_iterator p;
- for(p = iceBox->services.begin(); p != iceBox->services.end(); ++p)
+ Ice::StringSeq knownFiles;
+ for(PropertyDescriptorSeqDict::const_iterator p = properties.begin(); p != properties.end(); ++p)
{
- updateConfigFile(_serverDir, ServiceDescriptorPtr::dynamicCast(p->descriptor));
- knownFiles.push_back("config_" + p->descriptor->name);
+ knownFiles.push_back(p->first);
+
+ const string configFilePath = _serverDir + "/config/" + p->first;
+ ofstream configfile(configFilePath.c_str());
+ if(!configfile.good())
+ {
+ throw "couldn't create configuration file: " + configFilePath;
+ }
+ configfile << "# Server configuration file (" << IceUtil::Time::now().toDateTime();
+ configfile << ", " << _desc->iceVersion << ")" << endl << endl;
+ for(PropertyDescriptorSeq::const_iterator r = p->second.begin(); r != p->second.end(); ++r)
+ {
+ if(r->value.empty() && r->name.find('#') == 0)
+ {
+ configfile << r->name << endl;
+ }
+ else
+ {
+ configfile << r->name << "=" << r->value << endl;
+ }
+ }
+ configfile.close();
}
- }
- sort(knownFiles.begin(), knownFiles.end());
+ sort(knownFiles.begin(), knownFiles.end());
- //
- // Update the database environments if necessary.
- //
- Ice::StringSeq knownDbEnvs;
- for(DbEnvDescriptorSeq::const_iterator q = _info.descriptor->dbEnvs.begin();
- q != _info.descriptor->dbEnvs.end(); ++q)
- {
- updateDbEnv(_serverDir, *q);
- knownDbEnvs.push_back(q->name);
- }
- if(iceBox)
- {
- ServiceInstanceDescriptorSeq::const_iterator s;
- for(s = iceBox->services.begin(); s != iceBox->services.end(); ++s)
+ //
+ // Remove old configuration files.
+ //
+ Ice::StringSeq files = IcePatch2::readDirectory(_serverDir + "/config");
+ Ice::StringSeq toDel;
+ set_difference(files.begin(), files.end(), knownFiles.begin(), knownFiles.end(), back_inserter(toDel));
+ for(Ice::StringSeq::const_iterator q = toDel.begin(); q != toDel.end(); ++q)
{
- CommunicatorDescriptorPtr svc = s->descriptor;
- for(DbEnvDescriptorSeq::const_iterator q = svc->dbEnvs.begin(); q != svc->dbEnvs.end(); ++q)
+ if(q->find("config_") == 0)
{
- updateDbEnv(_serverDir, *q);
- knownDbEnvs.push_back(q->name);
+ try
+ {
+ IcePatch2::remove(_serverDir + "/config/" + *q);
+ }
+ catch(const string& msg)
+ {
+ Ice::Warning out(_node->getTraceLevels()->logger);
+ out << "couldn't remove file `" + _serverDir + "/config/" + *q + "':\n" + msg;
+ }
}
}
}
- sort(knownDbEnvs.begin(), knownDbEnvs.end());
//
- // Remove old configuration files.
+ // Update the database environments if necessary and remove the
+ // old ones.
//
- Ice::StringSeq files = IcePatch2::readDirectory(_serverDir + "/config");
- Ice::StringSeq toDel;
- set_difference(files.begin(), files.end(), knownFiles.begin(), knownFiles.end(), back_inserter(toDel));
- Ice::StringSeq::const_iterator p;
- for(p = toDel.begin(); p != toDel.end(); ++p)
{
- if(p->find("config_") == 0)
+ Ice::StringSeq knownDbEnvs;
+ for(InternalDbEnvDescriptorSeq::const_iterator q = _desc->dbEnvs.begin(); q != _desc->dbEnvs.end(); ++q)
+ {
+ knownDbEnvs.push_back((*q)->name);
+
+ string dbEnvHome = _serverDir + "/dbs/" + (*q)->name;
+ createOrUpdateDirectory(dbEnvHome);
+
+ if(!(*q)->properties.empty())
+ {
+ string file = dbEnvHome + "/DB_CONFIG";
+ ofstream configfile(file.c_str());
+ if(!configfile.good())
+ {
+ throw "couldn't create configuration file `" + file + "'";
+ }
+
+ PropertyDescriptorSeq::const_iterator p;
+ for(p = (*q)->properties.begin(); p != (*q)->properties.end(); ++p)
+ {
+ if(!p->name.empty())
+ {
+ configfile << p->name;
+ if(!p->value.empty())
+ {
+ configfile << " " << p->value;
+ }
+ configfile << endl;
+ }
+ }
+ configfile.close();
+ }
+ }
+ sort(knownDbEnvs.begin(), knownDbEnvs.end());
+
+ //
+ // Remove old database environments.
+ //
+ Ice::StringSeq dbEnvs = IcePatch2::readDirectory(_serverDir + "/dbs");
+ Ice::StringSeq toDel;
+ set_difference(dbEnvs.begin(), dbEnvs.end(), knownDbEnvs.begin(), knownDbEnvs.end(), back_inserter(toDel));
+ for(Ice::StringSeq::const_iterator p = toDel.begin(); p != toDel.end(); ++p)
{
try
{
- IcePatch2::remove(_serverDir + "/config/" + *p);
+ IcePatch2::removeRecursive(_serverDir + "/dbs/" + *p);
}
catch(const string& msg)
{
Ice::Warning out(_node->getTraceLevels()->logger);
- out << "couldn't remove file `" + _serverDir + "/config/" + *p + "':\n" + msg;
+ out << "couldn't remove directory `" + _serverDir + "/dbs/" + *p + "':\n" + msg;
}
}
}
- //
- // Remove old database environments.
- //
- Ice::StringSeq dbEnvs = IcePatch2::readDirectory(_serverDir + "/dbs");
- toDel.clear();
- set_difference(dbEnvs.begin(), dbEnvs.end(), knownDbEnvs.begin(), knownDbEnvs.end(), back_inserter(toDel));
- for(p = toDel.begin(); p != toDel.end(); ++p)
- {
- try
- {
- IcePatch2::removeRecursive(_serverDir + "/dbs/" + *p);
- }
- catch(const string& msg)
- {
- Ice::Warning out(_node->getTraceLevels()->logger);
- out << "couldn't remove directory `" + _serverDir + "/dbs/" + *p + "':\n" + msg;
- }
- }
-
#ifndef _WIN32
if(newUser)
{
@@ -2110,17 +2163,69 @@ ServerI::updateImpl(const ServerInfo& info)
}
void
-ServerI::updateRevisionFile()
+ServerI::checkRevision(const string& replicaName, const string& uuid, int revision) const
{
+ if(replicaName == "Master")
+ {
+ return;
+ }
+
+ string descUUID;
+ int descRevision;
+ if(_desc)
+ {
+ descUUID = _desc->uuid;
+ descRevision = _desc->revision;
+ }
+ else
+ {
+ string idFilePath = _serverDir + "/revision";
+ ifstream is(idFilePath.c_str());
+ if(!is.good())
+ {
+ return;
+ }
+
+ char line[1024];
+ is.getline(line, 1024); // Ignore comments
+ is.getline(line, 1024);
+ is.getline(line, 1024);
+ string ignore;
+ is >> ignore >> descUUID;
+ is >> ignore >> descRevision;
+ }
+
+ if(uuid != descUUID)
+ {
+ DeploymentException ex;
+ ex.reason = "server from replica `" + replicaName + "' is from another application (`" + uuid + "')";
+ throw ex;
+ }
+ else if(revision != descRevision)
+ {
+ ostringstream os;
+ os << "server from replica `" + replicaName + "' has a different version:\n";
+ os << "current revision: " << descRevision << "\n";
+ os << "replica revision: " << revision;
+ throw DeploymentException(os.str());
+ }
+}
+
+void
+ServerI::updateRevision(const string& uuid, int revision)
+{
+ _desc->uuid = uuid;
+ _desc->revision = revision;
+
string idFilePath = _serverDir + "/revision";
ofstream os(idFilePath.c_str());
if(os.good())
{
os << "#" << endl;
- os << "# This server belongs to the application `" << _info.application << "'" << endl;
+ os << "# This server belongs to the application `" << _desc->application << "'" << endl;
os << "#" << endl;
- os << "uuid: " << _info.uuid << endl;
- os << "revision: " << _info.revision << endl;
+ os << "uuid: " << _desc->uuid << endl;
+ os << "revision: " << _desc->revision << endl;
}
}
@@ -2235,6 +2340,7 @@ ServerI::setStateNoSync(InternalServerState st, const std::string& reason)
//
// Check if some commands are done.
//
+ bool loadFailure = false;
switch(_state)
{
case Inactive:
@@ -2274,6 +2380,7 @@ ServerI::setStateNoSync(InternalServerState st, const std::string& reason)
}
break;
case Destroying:
+ loadFailure = _destroy->loadFailure();
if(_patch)
{
_patch->destroyed();
@@ -2298,6 +2405,7 @@ ServerI::setStateNoSync(InternalServerState st, const std::string& reason)
case Destroyed:
if(_destroy)
{
+ loadFailure = _destroy->loadFailure();
_destroy->finished();
_destroy = 0;
}
@@ -2320,7 +2428,7 @@ ServerI::setStateNoSync(InternalServerState st, const std::string& reason)
{
// IGNORE
}
- _info = ServerInfo();
+ _desc = 0;
}
else if(_state == Inactive)
{
@@ -2346,9 +2454,14 @@ ServerI::setStateNoSync(InternalServerState st, const std::string& reason)
//
// Don't send the server update if the state didn't change or if
- // the server couldn't be forked.
+ // the server couldn't be forked. If the server is destroyed, we
+ // also check if it's the result of a load failure. If that's the
+ // case we don't send an update because the server was never
+ // actually loaded.
//
- if(toServerState(previous) != toServerState(_state) && !(previous == Inactive && _state == Deactivating))
+ if(toServerState(previous) != toServerState(_state) &&
+ !(previous == Inactive && _state == Deactivating) &&
+ !loadFailure)
{
_node->observerUpdateServer(getDynamicInfo());
}
@@ -2416,240 +2529,6 @@ ServerI::setStateNoSync(InternalServerState st, const std::string& reason)
}
}
-string
-ServerI::addAdapter(const AdapterDescriptor& desc, const CommunicatorDescriptorPtr& comm)
-{
- assert(!desc.id.empty());
-
- Ice::Identity id;
- id.category = _this->ice_getIdentity().category + "Adapter";
- id.name = _id + "-" + desc.id;
- try
- {
- AdapterPrx proxy = AdapterPrx::uncheckedCast(_node->getAdapter()->createProxy(id));
- ServerAdapterIPtr servant = ServerAdapterIPtr::dynamicCast(_node->getAdapter()->find(id));
- if(!servant)
- {
- servant = new ServerAdapterI(_node, this, _id, proxy, desc.id);
- _node->getAdapter()->add(servant, id);
- }
- _adapters.insert(make_pair(desc.id, servant));
- if(desc.serverLifetime)
- {
- _serverLifetimeAdapters.insert(desc.id);
- }
- }
- catch(const Ice::ObjectAdapterDeactivatedException&)
- {
- // IGNORE
- }
- catch(const Ice::LocalException& ex)
- {
- Ice::Error out(_node->getTraceLevels()->logger);
- out << "couldn't add adapter `" << desc.id << "':\n" << ex;
- }
-
- return desc.id;
-}
-
-void
-ServerI::updateConfigFile(const string& serverDir, const CommunicatorDescriptorPtr& descriptor)
-{
- string configFilePath;
-
- PropertyDescriptorSeq props;
- if(ServerDescriptorPtr::dynamicCast(descriptor))
- {
- ServerDescriptorPtr svrDesc = ServerDescriptorPtr::dynamicCast(descriptor);
-
- configFilePath = serverDir + "/config/config";
-
- //
- // Add server properties.
- //
- props.push_back(createProperty("# Server configuration"));
- props.push_back(createProperty("Ice.ServerId", _id));
- props.push_back(createProperty("Ice.ProgramName", _id));
- props.push_back(createProperty("Ice.Default.Locator",
- _node->getCommunicator()->getProperties()->getProperty("Ice.Default.Locator")));
-
- //
- // Add Ice.StdOut, Ice.StdErr if necessary.
- //
- string outputDir = _node->getOutputDir();
- if(!outputDir.empty())
- {
- props.push_back(createProperty("Ice.StdOut", outputDir + "/" + _id + ".out"));
- string suffix = _node->getRedirectErrToOut() ? ".out" : ".err";
- props.push_back(createProperty("Ice.StdErr", outputDir + "/" + _id + suffix));
- }
-
- //
- // Add server descriptor properties.
- //
- copy(svrDesc->propertySet.properties.begin(), svrDesc->propertySet.properties.end(), back_inserter(props));
-
- //
- // Add service properties.
- //
- string servicesStr;
- IceBoxDescriptorPtr iceBox = IceBoxDescriptorPtr::dynamicCast(descriptor);
- if(iceBox)
- {
- ServiceInstanceDescriptorSeq::const_iterator p;
- for(p = iceBox->services.begin(); p != iceBox->services.end(); ++p)
- {
- ServiceDescriptorPtr s = ServiceDescriptorPtr::dynamicCast(p->descriptor);
- const string path = serverDir + "/config/config_" + s->name;
- props.push_back(createProperty("IceBox.Service." + s->name,
- s->entry + " --Ice.Config=\"" + path + "\""));
- servicesStr += s->name + " ";
- }
- props.push_back(createProperty("IceBox.LoadOrder", servicesStr));
- }
- }
- else
- {
- ServiceDescriptorPtr svcDesc = ServiceDescriptorPtr::dynamicCast(descriptor);
- assert(svcDesc);
- configFilePath = serverDir + "/config/config_" + svcDesc->name;
- props.push_back(createProperty("# Service configuration"));
- copy(svcDesc->propertySet.properties.begin(), svcDesc->propertySet.properties.end(), back_inserter(props));
- }
-
- //
- // Add database environment properties.
- //
- for(DbEnvDescriptorSeq::const_iterator p = descriptor->dbEnvs.begin(); p != descriptor->dbEnvs.end(); ++p)
- {
- const string path = serverDir + "/dbs/" + p->name;
- props.push_back(createProperty("# Database environment " + p->name));
- props.push_back(createProperty("Freeze.DbEnv." + p->name + ".DbHome", path));
- }
-
- //
- // Add object adapter properties.
- //
- for(AdapterDescriptorSeq::const_iterator q = descriptor->adapters.begin(); q != descriptor->adapters.end(); ++q)
- {
- if(!q->id.empty() || q->registerProcess)
- {
- //
- // DEPREACTED PROPERTIES: Removed extra code in future release
- //
- props.push_back(createProperty("# Object adapter " + q->name));
- if(!q->id.empty())
- {
- props.push_back(createProperty("Ice.OA." + q->name + ".AdapterId", q->id));
- props.push_back(createProperty(q->name + ".AdapterId", q->id));
- if(!q->replicaGroupId.empty())
- {
- props.push_back(createProperty("Ice.OA." + q->name + ".ReplicaGroupId", q->replicaGroupId));
- props.push_back(createProperty(q->name + ".ReplicaGroupId", q->replicaGroupId));
- }
- }
- if(q->registerProcess)
- {
- props.push_back(createProperty("Ice.OA." + q->name + ".RegisterProcess", "1"));
- props.push_back(createProperty(q->name + ".RegisterProcess", "1"));
- }
- }
-
- ObjectDescriptorSeq::const_iterator o;
- for(o = q->objects.begin(); o != q->objects.end(); ++o)
- {
- if(!o->property.empty())
- {
- props.push_back(createProperty(o->property, _node->getCommunicator()->identityToString(o->id)));
- }
- }
- for(o = q->allocatables.begin(); o != q->allocatables.end(); ++o)
- {
- if(!o->property.empty())
- {
- props.push_back(createProperty(o->property, _node->getCommunicator()->identityToString(o->id)));
- }
- }
- }
-
- //
- // Add log properties.
- //
- if(!descriptor->logs.empty())
- {
- props.push_back(createProperty("# Log paths"));
- for(LogDescriptorSeq::const_iterator l = descriptor->logs.begin(); l != descriptor->logs.end(); ++l)
- {
- if(!l->property.empty())
- {
- props.push_back(createProperty(l->property, l->path));
- }
- }
- }
-
- ofstream configfile(configFilePath.c_str());
- if(!configfile.good())
- {
- throw "couldn't create configuration file: " + configFilePath;
- }
- for(PropertyDescriptorSeq::const_iterator r = props.begin(); r != props.end(); ++r)
- {
- if(r->value.empty() && r->name.find('#') == 0)
- {
- configfile << r->name << endl;
- }
- else
- {
- configfile << r->name << "=" << r->value << endl;
- }
- }
- configfile.close();
-}
-
-void
-ServerI::updateDbEnv(const string& serverDir, const DbEnvDescriptor& dbEnv)
-{
- string dbEnvHome = dbEnv.dbHome;
- if(dbEnvHome.empty())
- {
- dbEnvHome = serverDir + "/dbs/" + dbEnv.name;
- createOrUpdateDirectory(dbEnvHome);
- }
-
- if(!dbEnv.properties.empty())
- {
- string file = dbEnvHome + "/DB_CONFIG";
- ofstream configfile(file.c_str());
- if(!configfile.good())
- {
- throw "couldn't create configuration file `" + file + "'";
- }
-
- for(PropertyDescriptorSeq::const_iterator p = dbEnv.properties.begin(); p != dbEnv.properties.end(); ++p)
- {
- if(!p->name.empty())
- {
- configfile << p->name;
- if(!p->value.empty())
- {
- configfile << " " << p->value;
- }
- configfile << endl;
- }
- }
- configfile.close();
- }
-}
-
-PropertyDescriptor
-ServerI::createProperty(const string& name, const string& value)
-{
- PropertyDescriptor prop;
- prop.name = name;
- prop.value = value;
- return prop;
-}
-
void
ServerI::createOrUpdateDirectory(const string& dir)
{
@@ -2727,18 +2606,18 @@ ServerI::toServerActivation(const string& activation) const
ServerDynamicInfo
ServerI::getDynamicInfo() const
{
- ServerDynamicInfo info;
- info.id = _id;
- info.state = toServerState(_state);
+ ServerDynamicInfo descriptor;
+ descriptor.id = _id;
+ descriptor.state = toServerState(_state);
//
// NOTE: this must be done only for the active state. Otherwise, we could get a
// deadlock since getPid() will lock the activator and since this method might
// be called from the activator locked.
//
- info.pid = _pid;
- info.enabled = _activation != Disabled;
- return info;
+ descriptor.pid = _pid;
+ descriptor.enabled = _activation != Disabled;
+ return descriptor;
}
string
@@ -2763,7 +2642,7 @@ ServerI::getFilePath(const string& filename) const
else if(!filename.empty() && filename[0] == '#')
{
string path = IcePatch2::simplify(filename.substr(1));
- if(_logs.find(path) == _logs.end())
+ if(find(_desc->logs.begin(), _desc->logs.end(), path) == _desc->logs.end())
{
throw FileNotAvailableException("unknown log file `" + path + "'");
}