30 #include <boost/interprocess/sync/file_lock.hpp> 31 #include <boost/interprocess/sync/scoped_lock.hpp> 32 #include <boost/interprocess/sync/sharable_lock.hpp> 34 using boost::interprocess::file_lock;
35 using boost::interprocess::scoped_lock;
36 using boost::interprocess::sharable_lock;
48 void sigsegvHandler(
int sig );
49 ::sighandler_t lastSigsegvHandler = ::signal( SIGSEGV, sigsegvHandler );
52 void sigsegvHandler(
int sig )
55 ::signal( SIGSEGV, lastSigsegvHandler );
63 {
return getenv(
"ZYPP_LOCKFILE_ROOT") ? getenv(
"ZYPP_LOCKFILE_ROOT") :
"/"; }
67 namespace zypp_readonly_hack
70 static bool active = getenv(
"ZYPP_READONLY_HACK");
75 MIL <<
"ZYPP_READONLY promised." << endl;
116 MIL <<
"Cleaned lock file. (" << getpid() <<
")" << std::endl;
194 MIL <<
"Checking " << status << endl;
196 if ( ! status.
isDir() )
198 DBG <<
"No such process." << endl;
202 static char buffer[513];
203 buffer[0] = buffer[512] = 0;
205 if ( std::ifstream( (procdir/
"cmdline").c_str() ).read( buffer, 512 ).gcount() > 0 )
212 DBG <<
"In zombie state." << endl;
222 MIL <<
"read: Lockfile " <<
_zyppLockFilePath <<
" has pid " << readpid <<
" (our pid: " << getpid() <<
") "<< std::endl;
223 return (pid_t)readpid;
244 if ( geteuid() != 0 )
269 WAR <<
_lockerPid <<
" is running and has a ZYpp lock. Sorry." << std::endl;
274 MIL <<
_lockerPid <<
" is dead. Taking the lock file." << std::endl;
280 INT <<
"Oops! We should not be here!" << std::endl;
292 ZYppGlobalLock & globalLock()
294 if ( !_theGlobalLock )
295 _theGlobalLock.reset(
new ZYppGlobalLock );
296 return *_theGlobalLock;
311 MIL <<
"ZYpp is on..." << endl;
316 _theGlobalLock.reset();
317 MIL <<
"ZYpp is off..." << endl;
328 , _lockerPid( lockerPid_r )
329 , _lockerName( lockerName_r )
354 ZYpp::Ptr _instance = _theZYppInstance.lock();
357 if ( geteuid() != 0 )
359 MIL <<
"Running as user. Skip creating " << globalLock().zyppLockFilePath() << std::endl;
363 MIL <<
"ZYPP_READONLY active." << endl;
365 else if ( globalLock().zyppLocked() )
368 const long LOCK_TIMEOUT = str::strtonum<long>( getenv(
"ZYPP_LOCK_TIMEOUT" ) );
369 if ( LOCK_TIMEOUT != 0 )
373 if ( LOCK_TIMEOUT > 0 ) {
374 giveup = logwait+LOCK_TIMEOUT;
375 MIL <<
"$ZYPP_LOCK_TIMEOUT=" << LOCK_TIMEOUT <<
" sec. Waiting for the zypp lock until " << giveup << endl;
378 MIL <<
"$ZYPP_LOCK_TIMEOUT=" << LOCK_TIMEOUT <<
" sec. Waiting for the zypp lock..." << endl;
387 WAR <<
"$ZYPP_LOCK_TIMEOUT=" << LOCK_TIMEOUT <<
" sec. Another day has passed waiting for the zypp lock..." << endl;
394 failed = globalLock().zyppLocked();
396 }
while ( failed && ( not giveup ||
Date::now() <= giveup ) );
399 MIL <<
"$ZYPP_LOCK_TIMEOUT=" << LOCK_TIMEOUT <<
" sec. Gave up waiting for the zypp lock." << endl;
402 MIL <<
"$ZYPP_LOCK_TIMEOUT=" << LOCK_TIMEOUT <<
" sec. Finally got the zypp lock." << endl;
407 std::string t =
str::form(
_(
"System management is locked by the application with pid %d (%s).\n" 408 "Close this application before trying again."),
409 globalLock().lockerPid(),
410 globalLock().lockerName().c_str()
417 if ( !_theImplInstance )
419 _instance.reset(
new ZYpp( _theImplInstance ) );
420 _theZYppInstance = _instance;
429 {
return !_theZYppInstance.expired(); }
438 return str <<
"ZYppFactory";
ScopedGuard accessLockFile()
Exception safe access to the lockfile.
static const ValueType day
int assert_dir(const Pathname &path, unsigned mode)
Like 'mkdir -p'.
std::ostream & dumpBacktrace(std::ostream &stream_r)
Dump current stack trace to a stream.
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
bool haveZYpp() const
Whether the ZYpp instance is already created.
void IWantIt() ZYPP_DEPRECATED
virtual ~ZYppFactoryException()
const char * c_str() const
String representation.
const std::string & lockerName() const
String related utilities and Regular expression matching.
Pathname ZYPP_LOCKFILE_ROOT()
Hack to circumvent the currently poor –root support.
shared_ptr< Impl > Impl_Ptr
static ZYppFactory instance()
Singleton ctor.
Exchange LineWriter for the lifetime of this object.
std::string form(const char *format,...) __attribute__((format(printf
Printf style construction of std::string.
ZYpp(const Impl_Ptr &impl_r)
Factory ctor.
bool isProcessRunning(pid_t pid_r)
Pathname _zyppLockFilePath
Store and operate on date (time_t).
std::ostream & operator<<(std::ostream &str, const Exception &obj)
const std::string & asString() const
String representation.
shared_ptr< void > ScopedGuard
Pathname dirname() const
Return all but the last component od this path.
::boost::shared_ptr< ZYpp > Ptr
ZYpp::Ptr getZYpp() const
ZYppFactoryException(const std::string &msg_r, pid_t lockerPid_r, const std::string &lockerName_r)
ZYpp factory class (Singleton)
ZYppFactory()
Default ctor.
const Pathname & zyppLockFilePath() const
std::string numstring(char n, int w=0)
void _closeLockFile()
Use accessLockFile.
Base class for Exception.
static Date now()
Return the current time.
Wrapper class for ::stat/::lstat.
bool zyppLocked()
Try to aquire a lock.
void _openLockFile()
Use accessLockFile.
Easy-to use interface to the ZYPP dependency resolver.
void repoVariablesReset()
file_lock _zyppLockFileLock