[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