Hi!
Using rsync under FreeBSD with hard links and files having schg set
result in EPERM "Operation not permitted". This behavior can be observed
if rsyncing /usr/bin/.
The patch fileflags.diff tries to deal with this situation but changes
the flags of the parent directory only. It doesn't change the flags of
the files itself.
do_link() in syscall.c has to be fixed. The attached
syscall-do_link.c.txt contains the complete function do_link().
patch-syscall.c.txt is a patch which have the be applied after
fileflags.diff.
Please have a look at the changes.
What is the "official" way of asking for inclusion in the rsync
distribution? Reporting a bug via bugzilla?
Best regards
Franz
#ifdef HAVE_LINK
int do_link(const char *fname1, const char *fname2)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
if (link(fname1, fname2) == 0)
return 0;
#ifdef SUPPORT_FORCE_CHANGE
if (force_change && (errno == EPERM || errno == EACCES)) {
char parent[MAXPATHLEN];
int parent_flags;
int saved_errno = errno;
int file_flags = make_mutable(fname1, NULL, NO_FFLAGS,
force_change);
if (file_flags) {
int ret = link(fname1, fname2);
undo_make_mutable(fname1, file_flags);
if (ret == 0)
return 0;
}
parent_flags = make_parentdir_mutable(fname2, force_change,
parent, sizeof parent);
if (parent_flags) {
int ret = link(fname1, fname2);
undo_make_mutable(parent, parent_flags);
if (ret == 0)
return 0;
}
errno = saved_errno;
}
#endif
return -1;
}
#endif
--- syscall.c.orig 2012-05-07 16:30:28.000000000 +0200
+++ syscall.c 2012-05-07 16:30:44.000000000 +0200
@@ -114,8 +114,16 @@
#ifdef SUPPORT_FORCE_CHANGE
if (force_change && (errno == EPERM || errno == EACCES)) {
char parent[MAXPATHLEN];
+ int parent_flags;
int saved_errno = errno;
- int parent_flags = make_parentdir_mutable(fname2, force_change,
parent, sizeof parent);
+ int file_flags = make_mutable(fname1, NULL, NO_FFLAGS,
force_change);
+ if (file_flags) {
+ int ret = link(fname1, fname2);
+ undo_make_mutable(fname1, file_flags);
+ if (ret == 0)
+ return 0;
+ }
+ parent_flags = make_parentdir_mutable(fname2, force_change,
parent, sizeof parent);
if (parent_flags) {
int ret = link(fname1, fname2);
undo_make_mutable(parent, parent_flags);
--
Please use reply-all for most replies to avoid omitting the mailing list.
To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html