summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2006-06-02 16:11:51 +0000
committerBenoit Foucher <benoit@zeroc.com>2006-06-02 16:11:51 +0000
commit8d90c43bd49c728f3c553a4e4d2ad7d25367a872 (patch)
tree078cd0193fcdfa12936eae5a6372ae750ecb79f7 /cpp/src
parentwarm up JIT compiler before measuring latency (diff)
downloadice-8d90c43bd49c728f3c553a4e4d2ad7d25367a872.tar.bz2
ice-8d90c43bd49c728f3c553a4e4d2ad7d25367a872.tar.xz
ice-8d90c43bd49c728f3c553a4e4d2ad7d25367a872.zip
Bug fixes
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/IceGrid/AdminI.cpp13
-rw-r--r--cpp/src/IceGrid/Allocatable.cpp46
-rw-r--r--cpp/src/IceGrid/Allocatable.h1
-rw-r--r--cpp/src/IceGrid/Database.cpp328
-rw-r--r--cpp/src/IceGrid/Database.h7
-rw-r--r--cpp/src/IceGrid/NodeCache.cpp9
-rw-r--r--cpp/src/IceGrid/ObjectCache.cpp36
-rw-r--r--cpp/src/IceGrid/ObjectCache.h4
-rw-r--r--cpp/src/IceGrid/ServerCache.cpp3
-rw-r--r--cpp/src/IceGrid/ServerI.cpp89
-rw-r--r--cpp/src/IceGrid/ServerI.h2
-rw-r--r--cpp/src/IceGrid/SessionI.cpp5
-rw-r--r--cpp/src/IceGrid/SessionI.h6
13 files changed, 341 insertions, 208 deletions
diff --git a/cpp/src/IceGrid/AdminI.cpp b/cpp/src/IceGrid/AdminI.cpp
index e10e55a6c1e..f1e07dee4b4 100644
--- a/cpp/src/IceGrid/AdminI.cpp
+++ b/cpp/src/IceGrid/AdminI.cpp
@@ -627,6 +627,12 @@ AdminI::addObject(const Ice::ObjectPrx& proxy, const ::Ice::Current& current)
void
AdminI::updateObject(const Ice::ObjectPrx& proxy, const ::Ice::Current& current)
{
+ const Ice::Identity id = proxy->ice_getIdentity();
+ if(id.category == _database->getInstanceName())
+ {
+ throw DeploymentException("updating object `" + current.adapter->getCommunicator()->identityToString(id) +
+ "' is not allowed");
+ }
_database->updateObject(proxy);
}
@@ -640,8 +646,13 @@ AdminI::addObjectWithType(const Ice::ObjectPrx& proxy, const string& type, const
}
void
-AdminI::removeObject(const Ice::Identity& id, const Ice::Current&)
+AdminI::removeObject(const Ice::Identity& id, const Ice::Current& current)
{
+ if(id.category == _database->getInstanceName())
+ {
+ throw DeploymentException("removing object `" + current.adapter->getCommunicator()->identityToString(id) +
+ "' is not allowed");
+ }
_database->removeObject(id);
}
diff --git a/cpp/src/IceGrid/Allocatable.cpp b/cpp/src/IceGrid/Allocatable.cpp
index 02026f014bc..536ec5f7aa5 100644
--- a/cpp/src/IceGrid/Allocatable.cpp
+++ b/cpp/src/IceGrid/Allocatable.cpp
@@ -164,19 +164,23 @@ Allocatable::~Allocatable()
{
}
-bool
-Allocatable::allocate(const AllocationRequestPtr& request, bool fromRelease)
+void
+Allocatable::checkAllocatable()
{
- if(!_allocatable)
+ if(!isAllocatable())
{
throw AllocationException("not allocatable");
}
+}
+bool
+Allocatable::allocate(const AllocationRequestPtr& request, bool fromRelease)
+{
try
{
return allocate(request, false, fromRelease);
}
- catch(const AllocationException&)
+ catch(const SessionDestroyedException&)
{
return false; // The session was destroyed
}
@@ -185,26 +189,19 @@ Allocatable::allocate(const AllocationRequestPtr& request, bool fromRelease)
bool
Allocatable::tryAllocate(const AllocationRequestPtr& request, bool fromRelease)
{
- if(!_allocatable)
+ try
{
- return false;
+ return allocate(request, true, fromRelease);
+ }
+ catch(const AllocationException& ex)
+ {
+ return false; // Not allocatable
}
-
- //
- // NOTE: We let exceptions go through here! The caller is
- // responsible for catching it.
- //
- return allocate(request, true, fromRelease);
}
bool
Allocatable::release(const SessionIPtr& session, bool fromRelease)
{
- if(!_allocatable)
- {
- throw AllocationException("not allocatable");
- }
-
bool isReleased = false;
bool hasRequests = false;
{
@@ -384,11 +381,13 @@ Allocatable::allocate(const AllocationRequestPtr& request, bool tryAllocate, boo
try
{
Lock sync(*this);
+ checkAllocatable();
+
if(!_session && (fromRelease || !_releasing))
{
if(request->finish(this, _session))
{
- allocated(request->getSession()); // This might throw.
+ allocated(request->getSession()); // This might throw SessionDestroyedException
assert(_count == 0);
_session = request->getSession();
++_count;
@@ -409,6 +408,14 @@ Allocatable::allocate(const AllocationRequestPtr& request, bool tryAllocate, boo
queueAllocationAttempt(this, request, tryAllocate);
}
}
+ catch(const SessionDestroyedException& ex)
+ {
+ if(_parent)
+ {
+ _parent->release(request->getSession(), fromRelease);
+ }
+ throw ex;
+ }
catch(const AllocationException& ex)
{
if(_parent)
@@ -417,6 +424,7 @@ Allocatable::allocate(const AllocationRequestPtr& request, bool tryAllocate, boo
}
throw ex;
}
+
if(_parent)
{
_parent->release(request->getSession(), fromRelease);
@@ -446,7 +454,7 @@ Allocatable::allocateFromChild(const AllocationRequestPtr& request,
{
allocated(request->getSession());
}
- catch(const AllocationException&)
+ catch(const SessionDestroyedException&)
{
// Ignore
}
diff --git a/cpp/src/IceGrid/Allocatable.h b/cpp/src/IceGrid/Allocatable.h
index ca8a8b04707..0a06134f5c3 100644
--- a/cpp/src/IceGrid/Allocatable.h
+++ b/cpp/src/IceGrid/Allocatable.h
@@ -77,6 +77,7 @@ public:
Allocatable(bool, const AllocatablePtr&);
virtual ~Allocatable();
+ virtual void checkAllocatable();
virtual bool allocate(const AllocationRequestPtr&, bool = false);
virtual bool tryAllocate(const AllocationRequestPtr&, bool = false);
virtual bool release(const SessionIPtr&, bool = false);
diff --git a/cpp/src/IceGrid/Database.cpp b/cpp/src/IceGrid/Database.cpp
index 7ca95468137..7a3f32bd760 100644
--- a/cpp/src/IceGrid/Database.cpp
+++ b/cpp/src/IceGrid/Database.cpp
@@ -185,31 +185,29 @@ Database::setObservers(const RegistryObserverPrx& registryObserver, const NodeOb
ApplicationDescriptorSeq applications;
AdapterInfoSeq adapters;
ObjectInfoSeq objects;
- {
- Lock sync(*this);
- _registryObserver = registryObserver;
- _nodeObserver = nodeObserver;
- serial = _serial;
-
- for(StringApplicationDescriptorDict::const_iterator p = _descriptors.begin(); p != _descriptors.end(); ++p)
- {
- applications.push_back(p->second);
- }
- for(StringAdapterInfoDict::const_iterator q = _adapters.begin(); q != _adapters.end(); ++q)
- {
- adapters.push_back(q->second);
- if(adapters.back().id.empty())
- {
- adapters.back().id = q->first;
- }
- }
-
- for(IdentityObjectInfoDict::const_iterator r = _objects.begin(); r != _objects.end(); ++r)
+ _registryObserver = registryObserver;
+ _nodeObserver = nodeObserver;
+ serial = _serial;
+
+ for(StringApplicationDescriptorDict::const_iterator p = _descriptors.begin(); p != _descriptors.end(); ++p)
+ {
+ applications.push_back(p->second);
+ }
+
+ for(StringAdapterInfoDict::const_iterator q = _adapters.begin(); q != _adapters.end(); ++q)
+ {
+ adapters.push_back(q->second);
+ if(adapters.back().id.empty())
{
- objects.push_back(r->second);
+ adapters.back().id = q->first;
}
}
+
+ for(IdentityObjectInfoDict::const_iterator r = _objects.begin(); r != _objects.end(); ++r)
+ {
+ objects.push_back(r->second);
+ }
//
// Notify the observers.
@@ -264,43 +262,64 @@ void
Database::addApplicationDescriptor(AdminSessionI* session, const ApplicationDescriptor& desc)
{
ServerEntrySeq entries;
- int serial;
- DistributionDescriptor appDistrib;
- map<string, DistributionDescriptorDict> nodeDistrib;
-
{
Lock sync(*this);
-
checkSessionLock(session);
- //
- // We first ensure that the application doesn't already exist
- // and that the application components don't already exist.
- //
+ while(_updating.find(desc.name) != _updating.end())
+ {
+ wait();
+ }
+
if(_descriptors.find(desc.name) != _descriptors.end())
{
throw DeploymentException("application `" + desc.name + "' already exists");
- }
+ }
ApplicationHelper helper(_communicator, desc);
-
- //
- // Ensure that the application servers, adapters and objects
- // aren't already registered.
- //
checkForAddition(helper);
-
- //
- // Register the application servers, adapters, objects.
- //
load(helper, entries);
-
- //
- // Save the application descriptor.
- //
- _descriptors.put(StringApplicationDescriptorDict::value_type(desc.name, desc));
-
- serial = ++_serial;
+ _updating.insert(desc.name);
+ }
+
+ //
+ // Synchronize the servers on the nodes. If a server couldn't be
+ // deployed we unload the application and throw.
+ //
+ try
+ {
+ for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
+ }
+ catch(const DeploymentException& ex)
+ {
+ {
+ Lock sync(*this);
+ entries.clear();
+ unload(ApplicationHelper(_communicator, desc), entries);
+ _updating.erase(desc.name);
+ notifyAll();
+ }
+ try
+ {
+ for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
+ }
+ catch(const DeploymentException& ex)
+ {
+ // TODO: warning?
+ }
+ throw ex;
+ }
+
+ //
+ // Save the application descriptor.
+ //
+ int serial;
+ {
+ Lock sync(*this);
+ _descriptors.put(StringApplicationDescriptorDict::value_type(desc.name, desc));
+ serial = ++_serial;
+ _updating.erase(desc.name);
+ notifyAll();
}
//
@@ -313,22 +332,23 @@ Database::addApplicationDescriptor(AdminSessionI* session, const ApplicationDesc
Ice::Trace out(_traceLevels->logger, _traceLevels->applicationCat);
out << "added application `" << desc.name << "'";
}
-
- //
- // Synchronize the servers on the nodes.
- //
- for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
}
void
Database::updateApplicationDescriptor(AdminSessionI* session, const ApplicationUpdateDescriptor& update)
{
ServerEntrySeq entries;
- int serial;
+ ApplicationDescriptor oldDesc;
+ ApplicationDescriptor newDesc;
{
Lock sync(*this);
checkSessionLock(session);
+ while(_updating.find(update.name) != _updating.end())
+ {
+ wait();
+ }
+
StringApplicationDescriptorDict::const_iterator p = _descriptors.find(update.name);
if(p == _descriptors.end())
{
@@ -337,40 +357,34 @@ Database::updateApplicationDescriptor(AdminSessionI* session, const ApplicationU
ApplicationHelper previous(_communicator, p->second);
ApplicationHelper helper(_communicator, previous.update(update));
-
+
checkForUpdate(previous, helper);
-
reload(previous, helper, entries);
-
- _descriptors.put(StringApplicationDescriptorDict::value_type(update.name, helper.getDefinition()));
-
- serial = ++_serial;
- }
- //
- // Notify the observers.
- //
- _registryObserver->applicationUpdated(serial, update);
+ oldDesc = previous.getDefinition();
+ newDesc = helper.getDefinition();
- if(_traceLevels->application > 0)
- {
- Ice::Trace out(_traceLevels->logger, _traceLevels->applicationCat);
- out << "updated application `" << update.name << "'";
+ _updating.insert(update.name);
}
- for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
+ finishUpdate(entries, update, oldDesc, newDesc);
}
void
Database::syncApplicationDescriptor(AdminSessionI* session, const ApplicationDescriptor& newDesc)
{
ServerEntrySeq entries;
- int serial;
ApplicationUpdateDescriptor update;
+ ApplicationDescriptor oldDesc;
{
Lock sync(*this);
checkSessionLock(session);
+ while(_updating.find(update.name) != _updating.end())
+ {
+ wait();
+ }
+
StringApplicationDescriptorDict::const_iterator p = _descriptors.find(newDesc.name);
if(p == _descriptors.end())
{
@@ -381,27 +395,56 @@ Database::syncApplicationDescriptor(AdminSessionI* session, const ApplicationDes
ApplicationHelper helper(_communicator, newDesc);
update = helper.diff(previous);
- checkForUpdate(previous, helper);
-
- reload(previous, helper, entries);
-
- _descriptors.put(StringApplicationDescriptorDict::value_type(newDesc.name, newDesc));
+ checkForUpdate(previous, helper);
+ reload(previous, helper, entries);
- serial = ++_serial;
+ oldDesc = previous.getDefinition();
+
+ _updating.insert(update.name);
}
- //
- // Notify the observers.
- //
- _registryObserver->applicationUpdated(serial, update);
+ finishUpdate(entries, update, oldDesc, newDesc);
+}
- if(_traceLevels->application > 0)
+void
+Database::instantiateServer(AdminSessionI* session,
+ const string& application,
+ const string& node,
+ const ServerInstanceDescriptor& instance)
+{
+ ServerEntrySeq entries;
+ ApplicationUpdateDescriptor update;
+ ApplicationDescriptor oldDesc;
+ ApplicationDescriptor newDesc;
{
- Ice::Trace out(_traceLevels->logger, _traceLevels->applicationCat);
- out << "synced application `" << newDesc.name << "'";
+ Lock sync(*this);
+ checkSessionLock(session);
+
+ while(_updating.find(update.name) != _updating.end())
+ {
+ wait();
+ }
+
+ StringApplicationDescriptorDict::const_iterator p = _descriptors.find(application);
+ if(p == _descriptors.end())
+ {
+ throw ApplicationNotExistException(application);
+ }
+
+ ApplicationHelper previous(_communicator, p->second);
+ ApplicationHelper helper(_communicator, previous.instantiateServer(node, instance));
+ update = helper.diff(previous);
+
+ checkForUpdate(previous, helper);
+ reload(previous, helper, entries);
+
+ oldDesc = previous.getDefinition();
+ newDesc = helper.getDefinition();
+
+ _updating.insert(update.name);
}
- for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
+ finishUpdate(entries, update, oldDesc, newDesc);
}
void
@@ -413,6 +456,11 @@ Database::removeApplicationDescriptor(AdminSessionI* session, const std::string&
Lock sync(*this);
checkSessionLock(session);
+ while(_updating.find(name) != _updating.end())
+ {
+ wait();
+ }
+
StringApplicationDescriptorDict::iterator p = _descriptors.find(name);
if(p == _descriptors.end())
{
@@ -452,52 +500,6 @@ Database::removeApplicationDescriptor(AdminSessionI* session, const std::string&
for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
}
-void
-Database::instantiateServer(AdminSessionI* session,
- const string& application,
- const string& node,
- const ServerInstanceDescriptor& instance)
-{
- ServerEntrySeq entries;
- int serial;
- ApplicationUpdateDescriptor update;
- {
- Lock sync(*this);
- checkSessionLock(session);
-
- StringApplicationDescriptorDict::const_iterator p = _descriptors.find(application);
- if(p == _descriptors.end())
- {
- throw ApplicationNotExistException(application);
- }
-
- ApplicationHelper previous(_communicator, p->second);
- ApplicationHelper helper(_communicator, previous.instantiateServer(node, instance));
- update = helper.diff(previous);
-
- checkForUpdate(previous, helper);
-
- reload(previous, helper, entries);
-
- _descriptors.put(StringApplicationDescriptorDict::value_type(application, helper.getDefinition()));
-
- serial = ++_serial;
- }
-
- //
- // Notify the observers.
- //
- _registryObserver->applicationUpdated(serial, update);
-
- if(_traceLevels->application > 0)
- {
- Ice::Trace out(_traceLevels->logger, _traceLevels->applicationCat);
- out << "updated application `" << update.name << "'";
- }
-
- for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
-}
-
ApplicationDescriptor
Database::getApplicationDescriptor(const std::string& name)
{
@@ -633,7 +635,6 @@ Database::setAdapterDirectProxy(const string& adapterId, const string& replicaGr
serial = ++_serial;
}
-
if(_traceLevels->adapter > 0)
{
Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat);
@@ -935,7 +936,7 @@ Database::removeObject(const Ice::Identity& id)
{
int serial;
{
- Lock sync(*this);
+ Lock sync(*this);
if(_objectCache.has(id))
{
DeploymentException ex;
@@ -1405,3 +1406,66 @@ Database::reload(const ApplicationHelper& oldApp, const ApplicationHelper& newAp
entries.push_back(_serverCache.add(*q));
}
}
+
+void
+Database::finishUpdate(ServerEntrySeq& entries,
+ const ApplicationUpdateDescriptor& update,
+ const ApplicationDescriptor& oldDesc,
+ const ApplicationDescriptor& newDesc)
+{
+
+ //
+ // Synchronize the servers on the nodes. If a server couldn't be
+ // deployed we unload the application and throw.
+ //
+ try
+ {
+ for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
+ }
+ catch(const DeploymentException& ex)
+ {
+ {
+ Lock sync(*this);
+ entries.clear();
+ ApplicationHelper previous(_communicator, newDesc);
+ ApplicationHelper helper(_communicator, oldDesc);
+ reload(previous, helper, entries);
+ _updating.erase(newDesc.name);
+ notifyAll();
+ }
+ try
+ {
+ for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
+ }
+ catch(const DeploymentException& ex)
+ {
+ // TODO: warning?
+ }
+ throw ex;
+ }
+
+ //
+ // Save the application descriptor.
+ //
+ int serial;
+ {
+ Lock sync(*this);
+ _descriptors.put(StringApplicationDescriptorDict::value_type(update.name, newDesc));
+ serial = ++_serial;
+ _updating.erase(update.name);
+ notifyAll();
+ }
+
+ //
+ // Notify the observers.
+ //
+ _registryObserver->applicationUpdated(serial, update);
+
+ if(_traceLevels->application > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->applicationCat);
+ out << "updated application `" << update.name << "'";
+ }
+
+}
+
diff --git a/cpp/src/IceGrid/Database.h b/cpp/src/IceGrid/Database.h
index 675fe2a69d8..e4d76add5a1 100644
--- a/cpp/src/IceGrid/Database.h
+++ b/cpp/src/IceGrid/Database.h
@@ -40,7 +40,7 @@ typedef IceUtil::Handle<ServerEntry> ServerEntryPtr;
class ApplicationHelper;
-class Database : public IceUtil::Shared, public IceUtil::Mutex
+class Database : public IceUtil::Shared, public IceUtil::Monitor<IceUtil::Mutex>
{
public:
@@ -59,8 +59,8 @@ public:
void addApplicationDescriptor(AdminSessionI*, const ApplicationDescriptor&);
void updateApplicationDescriptor(AdminSessionI*, const ApplicationUpdateDescriptor&);
void syncApplicationDescriptor(AdminSessionI*, const ApplicationDescriptor&);
- void removeApplicationDescriptor(AdminSessionI*, const std::string&);
void instantiateServer(AdminSessionI*, const std::string&, const std::string&, const ServerInstanceDescriptor&);
+ void removeApplicationDescriptor(AdminSessionI*, const std::string&);
ApplicationDescriptor getApplicationDescriptor(const std::string&);
Ice::StringSeq getAllApplications(const std::string& = std::string());
@@ -116,6 +116,8 @@ private:
void load(const ApplicationHelper&, ServerEntrySeq&);
void unload(const ApplicationHelper&, ServerEntrySeq&);
void reload(const ApplicationHelper&, const ApplicationHelper&, ServerEntrySeq&);
+ void finishUpdate(ServerEntrySeq&, const ApplicationUpdateDescriptor&, const ApplicationDescriptor&,
+ const ApplicationDescriptor&);
void checkSessionLock(AdminSessionI*);
@@ -151,6 +153,7 @@ private:
AdminSessionI* _lock;
std::string _lockUserId;
int _serial;
+ std::set<std::string> _updating;
};
typedef IceUtil::Handle<Database> DatabasePtr;
diff --git a/cpp/src/IceGrid/NodeCache.cpp b/cpp/src/IceGrid/NodeCache.cpp
index f41506fa8aa..0ff9ededd31 100644
--- a/cpp/src/IceGrid/NodeCache.cpp
+++ b/cpp/src/IceGrid/NodeCache.cpp
@@ -270,7 +270,14 @@ NodeEntry::setSession(const NodeSessionIPtr& session)
entries.push_back(q->second);
}
}
- for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
+
+ try
+ {
+ for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&ServerEntry::sync));
+ }
+ catch(const DeploymentException&)
+ {
+ }
}
else
{
diff --git a/cpp/src/IceGrid/ObjectCache.cpp b/cpp/src/IceGrid/ObjectCache.cpp
index 18aaee8964d..371f649e3c1 100644
--- a/cpp/src/IceGrid/ObjectCache.cpp
+++ b/cpp/src/IceGrid/ObjectCache.cpp
@@ -127,7 +127,7 @@ ObjectCache::TypeEntry::canTryAllocate(const ObjectEntryPtr& entry, bool fromRel
++p;
}
}
- catch(const AllocationException&)
+ catch(const SessionDestroyedException&)
{
p = _requests.erase(p);
}
@@ -229,7 +229,7 @@ ObjectCache::allocateByType(const string& type, const ObjectAllocationRequestPtr
}
}
}
- catch(const AllocationException&)
+ catch(const SessionDestroyedException&)
{
return;
}
@@ -312,7 +312,8 @@ ObjectEntry::ObjectEntry(ObjectCache& cache,
Allocatable(allocatable, parent),
_cache(cache),
_info(info),
- _application(application)
+ _application(application),
+ _destroyed(false)
{
}
@@ -353,10 +354,7 @@ ObjectEntry::allocated(const SessionIPtr& session)
// Add the object allocation to the session. The object will be
// released once the session is destroyed.
//
- if(!session->addAllocation(this))
- {
- throw AllocationException("session destroyed");
- }
+ session->addAllocation(this);
TraceLevelsPtr traceLevels = _cache.getTraceLevels();
if(traceLevels && traceLevels->object > 1)
@@ -414,8 +412,32 @@ ObjectEntry::released(const SessionIPtr& session)
}
}
+void
+ObjectEntry::destroy()
+{
+ SessionIPtr session;
+ {
+ Lock sync(*this);
+ _destroyed = true;
+ session = _session;
+ }
+ release(session);
+}
+
+void
+ObjectEntry::checkAllocatable()
+{
+ if(_destroyed)
+ {
+ throw ObjectNotRegisteredException(_info.proxy->ice_getIdentity());
+ }
+
+ Allocatable::checkAllocatable();
+}
+
bool
ObjectEntry::canTryAllocate()
{
return _cache.canTryAllocate(this);
}
+
diff --git a/cpp/src/IceGrid/ObjectCache.h b/cpp/src/IceGrid/ObjectCache.h
index cb9d049a6f9..079bfaf9465 100644
--- a/cpp/src/IceGrid/ObjectCache.h
+++ b/cpp/src/IceGrid/ObjectCache.h
@@ -42,11 +42,15 @@ public:
virtual void released(const SessionIPtr&);
virtual bool canTryAllocate();
+ void destroy();
+ virtual void checkAllocatable();
+
private:
ObjectCache& _cache;
const ObjectInfo _info;
const std::string _application;
+ bool _destroyed;
};
typedef IceUtil::Handle<ObjectEntry> ObjectEntryPtr;
diff --git a/cpp/src/IceGrid/ServerCache.cpp b/cpp/src/IceGrid/ServerCache.cpp
index baaa997b440..2d3f969845d 100644
--- a/cpp/src/IceGrid/ServerCache.cpp
+++ b/cpp/src/IceGrid/ServerCache.cpp
@@ -214,8 +214,9 @@ ServerEntry::sync()
{
syncImpl(true);
}
- catch(const Ice::Exception&)
+ catch(const NodeUnreachableException&)
{
+ // Ignore
}
}
diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp
index fff5841b897..fdab6755490 100644
--- a/cpp/src/IceGrid/ServerI.cpp
+++ b/cpp/src/IceGrid/ServerI.cpp
@@ -919,8 +919,7 @@ ServerI::load(const AMD_Node_loadServerPtr& amdCB, const string& app, const Serv
ServerCommandPtr command;
{
Lock sync(*this);
- bool descEqual = _desc && descriptorEqual(_node->getCommunicator(), _desc, desc);
- if(descEqual && _sessionId == sessionId)
+ if(_desc && descriptorEqual(_node->getCommunicator(), _desc, desc) && _sessionId == sessionId)
{
if(amdCB)
{
@@ -941,7 +940,7 @@ ServerI::load(const AMD_Node_loadServerPtr& amdCB, const string& app, const Serv
{
_load = new LoadCommand(this);
}
- _load->setUpdate(app, descEqual ? ServerDescriptorPtr() : desc, sessionId, _destroy);
+ _load->setUpdate(app, desc, sessionId, _destroy);
if(_destroy && _state != Destroying)
{
_destroy->finished();
@@ -1536,28 +1535,23 @@ ServerI::update()
}
}
- _sessionId = _load->sessionId();
-
- if(_load->getDescriptor())
+ try
{
- try
- {
- updateImpl(_load->getApplication(), _load->getDescriptor());
- }
- catch(const Ice::Exception& ex)
- {
- ostringstream os;
- os << ex;
- throw DeploymentException(os.str());
- }
- catch(const string& msg)
- {
- throw DeploymentException(msg);
- }
- catch(const char* msg)
- {
- throw DeploymentException(msg);
- }
+ updateImpl(_load->getApplication(), _load->getDescriptor(), _load->sessionId());
+ }
+ catch(const Ice::Exception& ex)
+ {
+ ostringstream os;
+ os << ex;
+ throw DeploymentException(os.str());
+ }
+ catch(const string& msg)
+ {
+ throw DeploymentException(msg);
+ }
+ catch(const char* msg)
+ {
+ throw DeploymentException(msg);
}
AdapterPrxDict adapters;
@@ -1572,25 +1566,24 @@ ServerI::update()
//
// Rollback old descriptor.
//
- _sessionId = oldSessionId;
try
{
- updateImpl(oldApp, oldDesc);
+ updateImpl(oldApp, oldDesc, oldSessionId);
}
- catch(const Ice::Exception& ex)
+ catch(const Ice::Exception& e)
{
Ice::Warning out(_node->getTraceLevels()->logger);
- out << "update failed and couldn't rollback old descriptor:\n" << ex;
+ 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 and couldn't rollback old descriptor:\n" << msg;
+ 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 and couldn't rollback old descriptor:\n" << msg;
+ out << "update failed:\n" << ex.reason << "\nand couldn't rollback old descriptor:\n" << msg;
}
_load->failed(ex);
}
@@ -1605,12 +1598,13 @@ ServerI::update()
}
void
-ServerI::updateImpl(const string& application, const ServerDescriptorPtr& desc)
+ServerI::updateImpl(const string& application, const ServerDescriptorPtr& desc, const string& sessionId)
{
assert(_load);
_application = application;
_desc = desc;
+ _sessionId = sessionId;
if(!_desc)
{
@@ -1710,6 +1704,10 @@ ServerI::updateImpl(const string& application, const ServerDescriptorPtr& desc)
#endif
}
+#ifndef _WIN32
+ bool newUser = false;
+#endif
+
if(!user.empty())
{
UserAccountMapperPrx mapper = _node->getUserAccountMapper();
@@ -1780,6 +1778,12 @@ ServerI::updateImpl(const string& application, const ServerDescriptorPtr& desc)
throw "node has insufficient privileges to load server under user account `" + user + "'";
}
+ if(pw->pw_uid == 0) // Don't allow running proccesses as "root"
+ {
+ throw "running server as `root' is not allowed";
+ }
+
+ newUser = _uid != pw->pw_uid || _gid != pw->pw_gid;
_uid = pw->pw_uid;
_gid = pw->pw_gid;
#endif
@@ -1791,9 +1795,11 @@ ServerI::updateImpl(const string& application, const ServerDescriptorPtr& desc)
// If no user is specified, we'll run the process as the
// current user.
//
- _uid = getuid();
- assert(_uid != 0);
- _gid = getgid();
+ uid_t uid = getuid();
+ uid_t gid = getgid();
+ newUser = _uid != uid || _gid != gid;
+ _uid = uid;
+ _gid = gid;
}
#endif
@@ -1832,9 +1838,6 @@ ServerI::updateImpl(const string& application, const ServerDescriptorPtr& desc)
}
}
sort(knownFiles.begin(), knownFiles.end());
-#ifndef _WIN32
- chownRecursive(_serverDir + "/config", _uid, _gid);
-#endif
//
// Update the database environments if necessary.
@@ -1859,9 +1862,6 @@ ServerI::updateImpl(const string& application, const ServerDescriptorPtr& desc)
}
}
sort(knownDbEnvs.begin(), knownDbEnvs.end());
-#ifndef _WIN32
- chownRecursive(_serverDir + "/dbs", _uid, _gid);
-#endif
//
// Remove old configuration files.
@@ -1904,6 +1904,15 @@ ServerI::updateImpl(const string& application, const ServerDescriptorPtr& desc)
out << "couldn't remove directory `" + _serverDir + "/dbs/" + *p + "':\n" + msg;
}
}
+
+#ifndef _WIN32
+ if(newUser)
+ {
+ chownRecursive(_serverDir + "/config", _uid, _gid);
+ chownRecursive(_serverDir + "/dbs", _uid, _gid);
+ chownRecursive(_serverDir + "/distrib", _uid, _gid);
+ }
+#endif
}
void
diff --git a/cpp/src/IceGrid/ServerI.h b/cpp/src/IceGrid/ServerI.h
index 1e0e4b48b03..f71aca358aa 100644
--- a/cpp/src/IceGrid/ServerI.h
+++ b/cpp/src/IceGrid/ServerI.h
@@ -111,7 +111,7 @@ public:
private:
- void updateImpl(const std::string&, const ServerDescriptorPtr&);
+ void updateImpl(const std::string&, const ServerDescriptorPtr&, const std::string&);
void checkActivation();
void checkDestroyed();
void disableOnFailure();
diff --git a/cpp/src/IceGrid/SessionI.cpp b/cpp/src/IceGrid/SessionI.cpp
index 2f6ced3a1b1..d150fd93f84 100644
--- a/cpp/src/IceGrid/SessionI.cpp
+++ b/cpp/src/IceGrid/SessionI.cpp
@@ -267,16 +267,15 @@ SessionI::removeAllocationRequest(const AllocationRequestPtr& request)
_requests.erase(request);
}
-bool
+void
SessionI::addAllocation(const AllocatablePtr& allocatable)
{
Lock sync(*this);
if(_destroyed)
{
- return false;
+ throw SessionDestroyedException();
}
_allocations.insert(allocatable);
- return true;
}
void
diff --git a/cpp/src/IceGrid/SessionI.h b/cpp/src/IceGrid/SessionI.h
index e5df4329923..21f0bad52e6 100644
--- a/cpp/src/IceGrid/SessionI.h
+++ b/cpp/src/IceGrid/SessionI.h
@@ -62,6 +62,10 @@ protected:
IceUtil::Time _timestamp;
};
+class SessionDestroyedException
+{
+};
+
class SessionI : virtual public Session, public BaseSessionI
{
public:
@@ -88,7 +92,7 @@ public:
bool addAllocationRequest(const AllocationRequestPtr&);
void removeAllocationRequest(const AllocationRequestPtr&);
- bool addAllocation(const AllocatablePtr&);
+ void addAllocation(const AllocatablePtr&);
void removeAllocation(const AllocatablePtr&);
protected: