Cleanup orphaned media attach points (bnc#751221)
authorMichael Andres <ma@suse.de>
Mon, 26 Mar 2012 12:45:06 +0000 (14:45 +0200)
committerMichael Andres <ma@suse.de>
Mon, 26 Mar 2012 12:45:06 +0000 (14:45 +0200)
zypp/media/MediaHandler.cc

index f7ab340a01b186e97ceb473e2bb5ed3116395c06..622473c5bc7a72590e5186ddd86ec3e0406a7517 100644 (file)
@@ -15,6 +15,7 @@
 #include <sstream>
 
 #include "zypp/TmpPath.h"
+#include "zypp/Date.h"
 #include "zypp/base/LogTools.h"
 #include "zypp/base/String.h"
 #include "zypp/media/MediaHandler.h"
@@ -383,45 +384,51 @@ MediaHandler::createAttachPoint(const Pathname &attach_root) const
     return apoint;
   }
 
-  PathInfo adir( attach_root);
+  PathInfo adir( attach_root );
   if( !adir.isDir() || (getuid() != 0 && !adir.userMayRWX())) {
     DBG << "Create attach point: attach root is not a writable directory: '"
         << attach_root << "'" << std::endl;
     return apoint;
   }
 
-  DBG << "Trying to create attach point in " << attach_root << std::endl;
-
-  //
-  // FIXME: use mkdtemp?
-  //
-#warning Use class TmpDir from TmpPath.h
-  Pathname abase( attach_root + "AP_" );
-  //        ma and sh need more than 42 for debugging :-)
-  //        since the readonly fs are handled now, ...
-  for ( unsigned i = 1; i < 1000; ++i ) {
-    adir( Pathname::extend( abase, str::hexstring( i ) ) );
-    if ( ! adir.isExist() ) {
-      int err = mkdir( adir.path() );
-      if (err == 0 ) {
-        apoint = getRealPath(adir.asString());
-       if( apoint.empty())
-       {
-         ERR << "Unable to resolve a real path for "
-             << adir.path() << std::endl;
-         rmdir(adir.path());
-       }
-        break;
+  static bool cleanup_once( true );
+  if ( cleanup_once )
+  {
+    cleanup_once = false;
+    DBG << "Look for orphaned attach points in " << adir << std::endl;
+    std::list<std::string> entries;
+    filesystem::readdir( entries, attach_root, false );
+    for ( const std::string & entry : entries )
+    {
+      if ( ! str::hasPrefix( entry, "AP_0x" ) )
+       continue;
+      PathInfo sdir( attach_root + entry );
+      if ( sdir.isDir()
+       && sdir.dev() == adir.dev()
+       && ( Date::now()-sdir.mtime() > Date::month ) )
+      {
+       DBG << "Remove orphaned attach point " << sdir << std::endl;
+       filesystem::recursive_rmdir( sdir.path() );
       }
-      else
-      if (err != EEXIST)       // readonly fs or other, dont try further
-        break;
     }
   }
 
-  if ( apoint.empty()) {
-    ERR << "Unable to create an attach point below of "
-        << attach_root << std::endl;
+  filesystem::TmpDir tmpdir( attach_root, "AP_0x" );
+  if ( tmpdir )
+  {
+    apoint = getRealPath( tmpdir.path().asString() );
+    if ( ! apoint.empty() )
+    {
+      tmpdir.autoCleanup( false );     // Take responsibility for cleanup.
+    }
+    else
+    {
+      ERR << "Unable to resolve real path for attach point " << tmpdir << std::endl;
+    }
+  }
+  else
+  {
+    ERR << "Unable to create attach point below " << attach_root << std::endl;
   }
   return apoint;
 }