diff options
author | Benoit Foucher <benoit@zeroc.com> | 2006-06-02 16:11:51 +0000 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2006-06-02 16:11:51 +0000 |
commit | 8d90c43bd49c728f3c553a4e4d2ad7d25367a872 (patch) | |
tree | 078cd0193fcdfa12936eae5a6372ae750ecb79f7 /cpp | |
parent | warm up JIT compiler before measuring latency (diff) | |
download | ice-8d90c43bd49c728f3c553a4e4d2ad7d25367a872.tar.bz2 ice-8d90c43bd49c728f3c553a4e4d2ad7d25367a872.tar.xz ice-8d90c43bd49c728f3c553a4e4d2ad7d25367a872.zip |
Bug fixes
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/IceGrid/AdminI.cpp | 13 | ||||
-rw-r--r-- | cpp/src/IceGrid/Allocatable.cpp | 46 | ||||
-rw-r--r-- | cpp/src/IceGrid/Allocatable.h | 1 | ||||
-rw-r--r-- | cpp/src/IceGrid/Database.cpp | 328 | ||||
-rw-r--r-- | cpp/src/IceGrid/Database.h | 7 | ||||
-rw-r--r-- | cpp/src/IceGrid/NodeCache.cpp | 9 | ||||
-rw-r--r-- | cpp/src/IceGrid/ObjectCache.cpp | 36 | ||||
-rw-r--r-- | cpp/src/IceGrid/ObjectCache.h | 4 | ||||
-rw-r--r-- | cpp/src/IceGrid/ServerCache.cpp | 3 | ||||
-rw-r--r-- | cpp/src/IceGrid/ServerI.cpp | 89 | ||||
-rw-r--r-- | cpp/src/IceGrid/ServerI.h | 2 | ||||
-rw-r--r-- | cpp/src/IceGrid/SessionI.cpp | 5 | ||||
-rw-r--r-- | cpp/src/IceGrid/SessionI.h | 6 |
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: |