[paludis-commits] r4599 - in trunk: . paludis paludis/repositories/e

ciaranm at svn.pioto.org ciaranm at svn.pioto.org
Tue Apr 22 12:52:55 UTC 2008


Author: ciaranm
Date: 2008-04-22 12:52:55 +0000 (Tue, 22 Apr 2008)
New Revision: 4599

Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/configure.ac
   trunk/paludis/merger.cc
   trunk/paludis/merger.hh
   trunk/paludis/merger.se
   trunk/paludis/ndbam_merger.cc
   trunk/paludis/repositories/e/vdb_merger.cc
Log:
Preserve extended attributes, where supported


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-04-22 12:00:43 UTC (rev 4598)
+++ trunk/ChangeLog	2008-04-22 12:52:55 UTC (rev 4599)
@@ -5,6 +5,10 @@
 only listed in SVN log. For a summary of what has changed between releases,
 see the NEWS file. This file is occasionally pruned to ChangeLog.old.bz2.
 
+2008-04-22 Ciaran McCreesh
+
+	* paludis/: Preserve extended attributes on merge, where supported.
+
 2008-04-22 David Leverton
 
 	* doc/, paludis/, paludis/environments/, paludis/repositories/,

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2008-04-22 12:00:43 UTC (rev 4598)
+++ trunk/NEWS	2008-04-22 12:52:55 UTC (rev 4599)
@@ -12,6 +12,8 @@
       Portage-compatible configuration files without caring about Portage
       compatibility.
 
+    * Extended attributes are now preserved when merging, where supported.
+
 0.26.0_pre3:
     * reconcilio no longer accepts the --verbose switch; verbose display is
       now turned on unconditionally.

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2008-04-22 12:00:43 UTC (rev 4598)
+++ trunk/configure.ac	2008-04-22 12:52:55 UTC (rev 4599)
@@ -473,6 +473,28 @@
 AM_CONDITIONAL(HAVE_LCHFLAGS, test x$ac_cv_func_lchflags = xyes)
 dnl }}}
 
+dnl {{{ check for listxattrf etc
+AC_MSG_CHECKING([for f*xattr function family])
+AC_COMPILE_IFELSE([
+#include <sys/types.h>
+#include <attr/xattr.h>
+
+int main(int, char **)
+{
+	flistxattr(0, 0, 0);
+	fgetxattr(0, 0, 0, 0);
+	fsetxattr(0, 0, 0, 0, 0);
+}
+],
+	[AC_MSG_RESULT([yes])
+	 HAVE_XATTRS=yes],
+	[AC_MSG_RESULT([no])
+	 HAVE_XATTRS=])
+if test "x$HAVE_XATTRS" = "xyes"; then
+    AC_DEFINE([HAVE_XATTRS], [1], [Have xattrs support])
+fi
+dnl }}}
+
 dnl {{{ check for canonicalize_file_name function
 AC_CHECK_FUNCS([canonicalize_file_name])
 AM_CONDITIONAL(HAVE_CANONICALIZE_FILE_NAME, test x$ac_cv_func_canonicalize_file_name = xyes)

Modified: trunk/paludis/merger.cc
===================================================================
--- trunk/paludis/merger.cc	2008-04-22 12:00:43 UTC (rev 4598)
+++ trunk/paludis/merger.cc	2008-04-22 12:52:55 UTC (rev 4599)
@@ -35,6 +35,11 @@
 #include <cstring>
 #include <list>
 
+#include "config.h"
+#ifdef HAVE_XATTRS
+#  include <attr/xattr.h>
+#endif
+
 using namespace paludis;
 
 #include <paludis/merger-se.cc>
@@ -721,6 +726,7 @@
         /* set*id bits */
         if (0 != ::fchmod(output_fd, src_perms))
             throw MergerError("Cannot fchmod '" + stringify(dst) + "': " + stringify(::strerror(errno)));
+        try_to_copy_xattrs(src, output_fd, result);
 
         char buf[4096];
         ssize_t count;
@@ -910,11 +916,18 @@
     {
         Log::get_instance()->message("merger.dir.rename_failed", ll_debug, lc_context) <<
             "rename failed. Falling back to recursive copy.";
+
         dst.mkdir(mode);
+        FDHolder dst_fd(::open(stringify(dst).c_str(), O_RDONLY | O_DIRECTORY));
+        if (-1 == dst_fd)
+            throw MergerError("Could not get an FD for the directory '"
+                    + stringify(dst) + "' that we just created: " + stringify(::strerror(errno)));
         if (! _params[k::no_chown()])
-            dst.chown(dest_uid, dest_gid);
+            ::fchown(dst_fd, dest_uid, dest_gid);
         /* pick up set*id bits */
-        dst.chmod(mode);
+        ::fchmod(dst_fd, mode);
+        try_to_copy_xattrs(src, dst_fd, result);
+        ::close(dst_fd);
     }
 
     if (0 != _params[k::environment()]->perform_hook(extend_hook(
@@ -1089,3 +1102,83 @@
         ("IMAGE", stringify(_params[k::image()]));
 }
 
+#ifdef HAVE_XATTRS
+
+void
+Merger::try_to_copy_xattrs(const FSEntry & src, int dst_fd, MergeStatusFlags & flags)
+{
+    FDHolder src_fd(::open(stringify(src).c_str(), O_RDONLY));
+
+    ssize_t list_sz(flistxattr(src_fd, 0, 0));
+    if (-1 == list_sz)
+    {
+        if (ENOTSUP != errno)
+            Log::get_instance()->message("merger.xattrs.failure", ll_warning, lc_context) <<
+                "Got error '" << ::strerror(errno) << "' when trying to find extended attributes size for '" << src << "'";
+        return;
+    }
+
+    tr1::shared_ptr<char> list_holder(static_cast<char *>(::operator new(list_sz)));
+    list_sz = flistxattr(src_fd, list_holder.get(), list_sz);
+    if (-1 == list_sz)
+    {
+        Log::get_instance()->message("merger.xattrs.failure", ll_warning, lc_context) <<
+            "Got error '" << ::strerror(errno) << "' when trying to find extended attributes for '" << src << "'";
+        return;
+    }
+
+    for (int offset(0) ; list_sz > 0 ; )
+    {
+        std::string key(list_holder.get() + offset);
+        do
+        {
+            ssize_t value_sz(fgetxattr(src_fd, key.c_str(), 0, 0));
+            if (-1 == value_sz)
+            {
+                Log::get_instance()->message("merger.xattrs.failure", ll_warning, lc_context) <<
+                    "Got error '" << ::strerror(errno) << "' when trying to read size of extended attribute '" <<
+                    key << "' for '" << src << "'";
+                break;
+            }
+
+            tr1::shared_ptr<char> value_holder(static_cast<char *>(::operator new(value_sz)));
+            value_sz = fgetxattr(src_fd, key.c_str(), value_holder.get(), value_sz);
+            if (-1 == value_sz)
+            {
+                Log::get_instance()->message("merger.xattrs.failure", ll_warning, lc_context) <<
+                    "Got error '" << ::strerror(errno) << "' when trying to read extended attribute '" <<
+                    key << "' for '" << src << "'";
+            }
+
+            if (-1 == fsetxattr(dst_fd, key.c_str(), value_holder.get(), value_sz, 0))
+            {
+                if (ENOTSUP == errno)
+                {
+                    Log::get_instance()->message("merger.xattrs.failure", ll_warning, lc_context) <<
+                        "Could not copy extended attributes from source file '" << src << "'";
+                    return;
+                }
+                else
+                    Log::get_instance()->message("merger.xattrs.failure", ll_warning, lc_context) <<
+                        "Got error '" << ::strerror(errno) << "' when trying to set extended attribute '" <<
+                        key << "' taken from source file '" << src << "'";
+            }
+
+            flags += msi_xattr;
+
+        } while (false);
+
+        list_sz -= (key.length() + 1);
+        offset += (key.length() + 1);
+    }
+}
+
+#else
+
+void
+Merger::try_to_copy_xattrs(const FSEntry &, int, MergeStatusFlags &)
+{
+}
+
+#endif
+

Modified: trunk/paludis/merger.hh
===================================================================
--- trunk/paludis/merger.hh	2008-04-22 12:00:43 UTC (rev 4598)
+++ trunk/paludis/merger.hh	2008-04-22 12:52:55 UTC (rev 4599)
@@ -84,6 +84,7 @@
             void record_renamed_dir_recursive(const FSEntry &);
             void relabel_dir_recursive(const FSEntry &, const FSEntry &);
             void rewrite_symlink_as_needed(const FSEntry &, const FSEntry &);
+            void try_to_copy_xattrs(const FSEntry &, int, MergeStatusFlags &);
             bool symlink_needs_rewriting(const FSEntry & sym);
 
         protected:

Modified: trunk/paludis/merger.se
===================================================================
--- trunk/paludis/merger.se	2008-04-22 12:00:43 UTC (rev 4598)
+++ trunk/paludis/merger.se	2008-04-22 12:52:55 UTC (rev 4599)
@@ -11,6 +11,7 @@
     key msi_used_existing           "We used the existing entry (e.g. dir over dir)"
     key msi_fixed_ownership         "We fixed owner or group from the reduced id"
     key msi_setid_bits              "The source file had set*id bits"
+    key msi_xattr                   "The source file had xattr bits"
     key msi_as_hardlink             "We detected a hardlink and merged it as such"
 
     doxygen_comment << "END"

Modified: trunk/paludis/ndbam_merger.cc
===================================================================
--- trunk/paludis/ndbam_merger.cc	2008-04-22 12:00:43 UTC (rev 4598)
+++ trunk/paludis/ndbam_merger.cc	2008-04-22 12:52:55 UTC (rev 4599)
@@ -311,6 +311,10 @@
                 result[2] = '*';
                 continue;
 
+            case msi_xattr:
+                result[2] = '+';
+                continue;
+
             case last_msi:
                 break;
         }

Modified: trunk/paludis/repositories/e/vdb_merger.cc
===================================================================
--- trunk/paludis/repositories/e/vdb_merger.cc	2008-04-22 12:00:43 UTC (rev 4598)
+++ trunk/paludis/repositories/e/vdb_merger.cc	2008-04-22 12:52:55 UTC (rev 4599)
@@ -344,6 +344,10 @@
                 result[2] = '*';
                 continue;
 
+            case msi_xattr:
+                result[2] = '+';
+                continue;
+
             case last_msi:
                 break;
         }



More information about the paludis-commits mailing list