14 #include <unordered_set> 32 #undef ZYPP_BASE_LOGGER_LOGGROUP 33 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::misc" 52 typedef std::pair<std::string,std::unordered_set<std::string>> CacheEntry;
60 struct FilterRunsInLXC
62 bool operator()( pid_t pid_r )
const 63 {
return( nsIno( pid_r,
"pid" ) !=
pidNS ); }
66 :
pidNS( nsIno(
"self",
"pid" ) )
69 static inline ino_t nsIno(
const std::string & pid_r,
const std::string & ns_r )
70 {
return PathInfo(
"/proc/"+pid_r+
"/ns/"+ns_r).ino(); }
72 static inline ino_t nsIno( pid_t pid_r,
const std::string & ns_r )
73 {
return nsIno(
asString(pid_r), ns_r ); }
85 bool addDataIf(
const CacheEntry & cache_r, std::vector<std::string> *debMap =
nullptr );
86 void addCacheIf( CacheEntry & cache_r,
const std::string & line_r, std::vector<std::string> *debMap =
nullptr );
91 std::vector<CheckAccessDeleted::ProcInfo>
_data;
95 std::map<pid_t,std::vector<std::string>>
debugMap;
111 const auto & filelist( cache_r.second );
113 if ( filelist.empty() )
119 pinfo.
files.insert( pinfo.files.begin(), filelist.begin(), filelist.end() );
121 const std::string & pline( cache_r.first );
122 std::string commandname;
123 std::ostringstream pLineStr;
124 for_( ch, pline.begin(), pline.end() )
129 pinfo.pid = &*(ch+1);
131 pLineStr <<&*(ch)<<
'\0';
134 pinfo.ppid = &*(ch+1);
136 pLineStr <<&*(ch)<<
'\0';
139 pinfo.puid = &*(ch+1);
141 pLineStr <<&*(ch)<<
'\0';
144 pinfo.login = &*(ch+1);
146 pLineStr <<&*(ch)<<
'\0';
149 if ( pinfo.command.empty() ) {
150 commandname = &*(ch+1);
152 if (!_fromLsofFileMode)
154 if ( pinfo.command.empty() )
155 pinfo.command = std::move(commandname);
157 pLineStr <<
'c'<<pinfo.command<<
'\0';
161 if ( *ch ==
'\n' )
break;
162 do { ++ch; }
while ( *ch !=
'\0' );
168 debMap->front() = pLineStr.str();
187 for_( ch, line_r.c_str(), ch+line_r.size() )
192 if ( *(ch+1) !=
'0' )
205 if ( *ch ==
'\n' )
break;
206 do { ++ch; }
while ( *ch !=
'\0' );
209 if ( !t || !f || !n )
212 if ( !( ( *t ==
'R' && *(t+1) ==
'E' && *(t+2) ==
'G' && *(t+3) ==
'\0' )
213 || ( *t ==
'D' && *(t+1) ==
'E' && *(t+2) ==
'L' && *(t+3) ==
'\0' ) ) )
216 if ( !( ( *f ==
'm' && *(f+1) ==
'e' && *(f+2) ==
'm' && *(f+3) ==
'\0' )
217 || ( *f ==
't' && *(f+1) ==
'x' && *(f+2) ==
't' && *(f+3) ==
'\0' )
218 || ( *f ==
'D' && *(f+1) ==
'E' && *(f+2) ==
'L' && *(f+3) ==
'\0' )
219 || ( *f ==
'l' && *(f+1) ==
't' && *(f+2) ==
'x' && *(f+3) ==
'\0' ) ) )
231 if ( *f ==
'm' || *f ==
'D' )
233 static const char * black[] = {
247 if ( debMap && cache_r.second.find(n) == cache_r.second.end() ) {
248 debMap->push_back(line_r);
250 cache_r.second.insert( n );
256 if ( doCheck_r )
check();
264 FILE *inFile = fopen( lsofOutput_r.
c_str(),
"r" );
279 std::map<pid_t,CacheEntry> cachemap;
284 FilterRunsInLXC runsInLXC;
288 if ( line[0] ==
'p' )
292 if ( debugEnabled ) {
294 if ( pidMad.empty() )
295 debugMap[cachepid].push_back( line );
299 cachemap[cachepid].first.swap( line );
307 addCacheIf( cachemap[cachepid], line, debugEnabled ? &dbgMap :
nullptr);
315 static const char* argv[] =
317 "lsof",
"-n",
"-FpcuLRftkn0", NULL
326 int ret = prog.
close();
343 std::ofstream debugFileOut;
344 bool debugEnabled =
false;
345 if ( !_debugFile.empty() ) {
346 debugFileOut.open( _debugFile.c_str() );
347 debugEnabled = debugFileOut.is_open();
349 if ( !debugEnabled ) {
350 ERR<<
"Unable to open debug file: "<<_debugFile<<endl;
355 for (
const auto &cached : in )
358 addDataIf( cached.second);
360 std::vector<std::string> *mapPtr =
nullptr;
362 auto dbgInfo = debugMap.find(cached.first);
363 if ( dbgInfo != debugMap.end() )
364 mapPtr = &(dbgInfo->second);
366 if( !addDataIf( cached.second, mapPtr ) )
369 for (
const std::string &dbgLine: dbgInfo->second ) {
370 debugFileOut.write( dbgLine.c_str(), dbgLine.length() );
411 static const str::regex rx(
"[0-9]+:name=systemd:/system.slice/(.*/)?(.*).service$" );
415 [&](
int num_r, std::string line_r )->
bool 446 if ( obj.
pid.empty() )
447 return str <<
"<NoProc>";
bool addDataIf(const CacheEntry &cache_r, std::vector< std::string > *debMap=nullptr)
Add cache to data if the process is accessing deleted files.
Data about one running process accessing deleted files.
Bidirectional stream to external data.
bool contains(const C_Str &str_r, const C_Str &val_r)
Locate substring case sensitive.
std::map< pid_t, CacheEntry > filterInput(externalprogram::ExternalDataSource &source)
std::string asString(const DefaultIntegral< Tp, TInitial > &obj)
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
std::map< pid_t, std::vector< std::string > > debugMap
int readlink(const Pathname &symlink_r, Pathname &target_r)
Like 'readlink'.
void setDebugOutputFile(const Pathname &filename_r)
Writes all filtered process entries that make it into the final set into a file specified by filename...
std::ostream & dumpRange(std::ostream &str, TIterator begin, TIterator end, const std::string &intro="{", const std::string &pfx="\ ", const std::string &sep="\ ", const std::string &sfx="\, const std::string &extro="}")
Print range defined by iterators (multiline style).
const char * c_str() const
String representation.
std::string command
process command name
String related utilities and Regular expression matching.
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
std::ostream & operator<<(std::ostream &str, const CheckAccessDeleted &obj)
void remember(const Exception &old_r)
Store an other Exception as history.
CheckAccessDeleted::Impl * clone() const
bool empty() const
Test for an empty path.
size_type check(bool verbose_r=false)
Check for running processes which access deleted executables or libraries.
RWCOW_pointer< Impl > _pimpl
const_iterator begin() const
int simpleParseFile(std::istream &str_r, ParseFlags flags_r, function< bool(int, std::string)> consume_r)
Simple lineparser optionally trimming and skipping comments.
const std::string & execError() const
Some detail telling why the execution failed, if it failed.
std::string pid
process ID
Execute a program and give access to its io An object of this class encapsulates the execution of an ...
std::list< PublicKeyData > _data
std::vector< CheckAccessDeleted::ProcInfo > _data
TInt strtonum(const C_Str &str)
Parsing numbers from string.
std::string puid
process user ID
const_iterator end() const
std::string receiveLine()
Read one line from the input stream.
std::string numstring(char n, int w=0)
CheckAccessDeleted::size_type createProcInfo(const std::map< pid_t, CacheEntry > &in)
int close()
Wait for the progamm to complete.
#define arrayBegin(A)
Simple C-array iterator.
Regular expression match result.
Base class for Exception.
Check for running processes which access deleted executables or libraries.
CheckAccessDeleted(bool doCheck_r=true)
Default ctor performs check immediately.
std::ostream & dumpRangeLine(std::ostream &str, TIterator begin, TIterator end)
Print range defined by iterators (single line style).
bool regex_match(const std::string &s, smatch &matches, const regex ®ex)
regex ZYPP_STR_REGEX regex ZYPP_STR_REGEX
Easy-to use interface to the ZYPP dependency resolver.
bool hasPrefix(const C_Str &str_r, const C_Str &prefix_r)
Return whether str_r has prefix prefix_r.
std::vector< ProcInfo >::const_iterator const_iterator
std::string login
process login name
void addCacheIf(CacheEntry &cache_r, const std::string &line_r, std::vector< std::string > *debMap=nullptr)
Add file to cache if it refers to a deleted executable or library file:
std::vector< std::string > files
list of deleted executables or libraries accessed
std::string ppid
parent process ID
std::string service() const
Guess if command was started by a systemd service script.
static std::string findService(pid_t pid_r)
Guess if pid was started by a systemd service script.