14 #include <unordered_set>
33 #undef ZYPP_BASE_LOGGER_LOGGROUP
34 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::misc"
53 typedef std::pair<std::string,std::unordered_set<std::string>> CacheEntry;
61 struct FilterRunsInLXC
63 bool operator()( pid_t pid_r )
const
64 {
return( nsIno( pid_r,
"pid" ) !=
pidNS ); }
67 :
pidNS( nsIno(
"self",
"pid" ) )
70 static inline ino_t nsIno(
const std::string & pid_r,
const std::string & ns_r )
71 {
return PathInfo(
"/proc/"+pid_r+
"/ns/"+ns_r).ino(); }
73 static inline ino_t nsIno( pid_t pid_r,
const std::string & ns_r )
74 {
return nsIno(
asString(pid_r), ns_r ); }
86 using target::rpm::librpmDb;
91 : _wasBlocked( librpmDb::isBlocked() )
92 {
if ( _wasBlocked ) librpmDb::unblockAccess(); }
94 {
if ( _wasBlocked ) librpmDb::blockAccess(); }
99 librpmDb::db_const_iterator it;
100 return( it.findPackage(
"lsof" ) && it->tag_edition() < Edition(
"4.90") && !it->tag_provides().count( Capability(
"backported-option-Ki") ) );
111 bool addDataIf(
const CacheEntry & cache_r, std::vector<std::string> *debMap =
nullptr );
112 void addCacheIf( CacheEntry & cache_r,
const std::string & line_r, std::vector<std::string> *debMap =
nullptr );
117 std::vector<CheckAccessDeleted::ProcInfo>
_data;
137 const auto & filelist( cache_r.second );
139 if ( filelist.empty() )
145 pinfo.
files.insert( pinfo.files.begin(), filelist.begin(), filelist.end() );
147 const std::string & pline( cache_r.first );
148 std::string commandname;
149 std::ostringstream pLineStr;
150 for_( ch, pline.begin(), pline.end() )
155 pinfo.pid = &*(ch+1);
157 pLineStr <<&*(ch)<<
'\0';
160 pinfo.ppid = &*(ch+1);
162 pLineStr <<&*(ch)<<
'\0';
165 pinfo.puid = &*(ch+1);
167 pLineStr <<&*(ch)<<
'\0';
170 pinfo.login = &*(ch+1);
172 pLineStr <<&*(ch)<<
'\0';
175 if ( pinfo.command.empty() ) {
176 commandname = &*(ch+1);
178 if (!_fromLsofFileMode)
180 if ( pinfo.command.empty() )
181 pinfo.command = std::move(commandname);
183 pLineStr <<
'c'<<pinfo.command<<
'\0';
187 if ( *ch ==
'\n' )
break;
188 do { ++ch; }
while ( *ch !=
'\0' );
194 debMap->front() = pLineStr.str();
213 for_( ch, line_r.c_str(), ch+line_r.size() )
218 if ( *(ch+1) !=
'0' )
231 if ( *ch ==
'\n' )
break;
232 do { ++ch; }
while ( *ch !=
'\0' );
235 if ( !t || !f || !n )
238 if ( !( ( *t ==
'R' && *(t+1) ==
'E' && *(t+2) ==
'G' && *(t+3) ==
'\0' )
239 || ( *t ==
'D' && *(t+1) ==
'E' && *(t+2) ==
'L' && *(t+3) ==
'\0' ) ) )
242 if ( !( ( *f ==
'm' && *(f+1) ==
'e' && *(f+2) ==
'm' && *(f+3) ==
'\0' )
243 || ( *f ==
't' && *(f+1) ==
'x' && *(f+2) ==
't' && *(f+3) ==
'\0' )
244 || ( *f ==
'D' && *(f+1) ==
'E' && *(f+2) ==
'L' && *(f+3) ==
'\0' )
245 || ( *f ==
'l' && *(f+1) ==
't' && *(f+2) ==
'x' && *(f+3) ==
'\0' ) ) )
257 if ( *f ==
'm' || *f ==
'D' )
259 static const char * black[] = {
274 if ( debMap && cache_r.second.find(n) == cache_r.second.end() ) {
275 debMap->push_back(line_r);
277 cache_r.second.insert( n );
283 if ( doCheck_r )
check();
291 FILE *inFile = fopen( lsofOutput_r.c_str(),
"r" );
306 std::map<pid_t,CacheEntry> cachemap;
311 FilterRunsInLXC runsInLXC;
315 if ( line[0] ==
'p' )
319 if ( debugEnabled ) {
321 if ( pidMad.empty() )
322 debugMap[cachepid].push_back( line );
326 cachemap[cachepid].first.swap( line );
334 addCacheIf( cachemap[cachepid], line, debugEnabled ? &dbgMap :
nullptr);
342 static const char* argv[] = {
"lsof",
"-n",
"-FpcuLRftkn0",
"-K",
"i", NULL };
352 int ret = prog.
close();
369 std::ofstream debugFileOut;
370 bool debugEnabled =
false;
371 if ( !_debugFile.empty() ) {
372 debugFileOut.open( _debugFile.c_str() );
373 debugEnabled = debugFileOut.is_open();
375 if ( !debugEnabled ) {
376 ERR<<
"Unable to open debug file: "<<_debugFile<<endl;
381 for (
const auto &cached : in )
384 addDataIf( cached.second);
386 std::vector<std::string> *mapPtr =
nullptr;
388 auto dbgInfo = debugMap.find(cached.first);
389 if ( dbgInfo != debugMap.end() )
390 mapPtr = &(dbgInfo->second);
392 if( !addDataIf( cached.second, mapPtr ) )
395 for (
const std::string &dbgLine: dbgInfo->second ) {
396 debugFileOut.write( dbgLine.c_str(), dbgLine.length() );
437 static const str::regex rx(
"[0-9]+:name=systemd:/system.slice/(.*/)?(.*).service$" );
441 [&](
int num_r, std::string line_r )->
bool
460 return dumpRange( str <<
"CheckAccessDeleted ",
472 if ( obj.
pid.empty() )
473 return str <<
"<NoProc>";