ぐぐってみると、
You must actually own a directory in order to set its access and modification times to an arbitrary value. Just having write permissions is not sufficient.
Either chown the directory, or don't use the -t or -a flags in rsync (-a includes -t). Note that this will have a small performance penalty since rsync will no longer be able to detect unmodified files and it will perform additional checking to see if they are different.
http://www.errorhelp.com/search/details/73579/rsync-failed-to-set-times-on-directory-operation-not-permitted
rsync のソースを見てみると、
$ uname -a Darwin yohei-no-macbook-air.local 9.6.0 Darwin Kernel Version 9.6.0: Mon Nov 24 17:37:00 PST 2008; root:xnu-1228.9.59~1/RELEASE_I386 i386 $ cd ~/Documents/src $ git clone git://git.samba.org/rsync.git Initialized empty Git repository in /Users/yohei/Documents/src/rsync/.git/ remote: Counting objects: 23252, done. remote: Compressing objects: 100% (7519/7519), done. remote: Total 23252 (delta 16217), reused 22275 (delta 15511) Receiving objects: 100% (23252/23252), 4.51 MiB | 285 KiB/s, done. Resolving deltas: 100% (16217/16217), done. $ grep -R 'failed to set times on' * rsync.c: rsyserr(FERROR_XFER, errno, "failed to set times on %s", $ less -N rsync.c 492 if (!preserve_times || (S_ISDIR(sxp->st.st_mode) && preserve_times == 1)) 493 flags |= ATTRS_SKIP_MTIME; 494 if (!(flags & ATTRS_SKIP_MTIME) 495 && cmp_time(sxp->st.st_mtime, file->modtime) != 0) { 496 int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode); 497 if (ret < 0) { 498 rsyserr(FERROR_XFER, errno, "failed to set times on %s", 499 full_fname(fname)); 500 goto cleanup; 501 } 502 if (ret == 0) /* ret == 1 if symlink could not be set */ 503 updated = 1; 504 else 505 file->flags |= FLAG_TIME_FAILED; 506 } $ grep -R set_modtime * generator.c: set_modtime(fname, file->modtime, F_MOD_NSEC(file), file->mode); rsync.c: int ret = set_modtime(fname, file->modtime, F_MOD_NSEC(file), sxp->st.st_mode); util.c:int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) $ less -N util.c 126 int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode) 127 { 128 #ifndef CAN_SET_SYMLINK_TIMES 129 if (S_ISLNK(mode)) 130 return 1; 131 #endif 132 133 if (DEBUG_GTE(TIME, 1)) { 134 rprintf(FINFO, "set modtime of %s to (%ld) %s", 135 fname, (long)modtime, 136 asctime(localtime(&modtime))); 137 } 138 139 if (dry_run) 140 return 0; 141 137 } 138 139 if (dry_run) 140 return 0; 141 142 { 143 #ifdef HAVE_UTIMENSAT 144 struct timespec t[2]; 145 t[0].tv_sec = 0; 146 t[0].tv_nsec = UTIME_NOW; 147 t[1].tv_sec = modtime; 148 t[1].tv_nsec = mod_nsec; 149 if (utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW) < 0) 150 return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1; 151 return 0; 152 #elif defined HAVE_UTIMES || defined HAVE_LUTIMES 153 struct timeval t[2]; 154 t[0].tv_sec = time(NULL); 155 t[0].tv_usec = 0; 156 t[1].tv_sec = modtime; 157 t[1].tv_usec = mod_nsec / 1000; 158 # ifdef HAVE_LUTIMES 159 if (lutimes(fname, t) < 0) 160 return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1; 161 return 0; 162 # else 163 return utimes(fname, t); 164 # endif 165 #elif defined HAVE_STRUCT_UTIMBUF 166 struct utimbuf tbuf; 167 tbuf.actime = time(NULL); 168 tbuf.modtime = modtime; 169 return utime(fname,&tbuf); 170 #elif defined HAVE_UTIME 171 time_t t[2]; 172 t[0] = time(NULL); 173 t[1] = modtime; 174 return utime(fname,t); 175 #else 176 #error No file-time-modification routine found! 177 #endif 178 } 179 } 180
utime/utimes でエラーになってるぽいので、ぐぐってみると、
説明
utime - システムコールの説明 - Linux コマンド集 一覧表
utime ()は filename で示される inode のアクセス時刻と修正時刻を buf 中の actime と modtime にそれぞれ変更する。
buf が NULL の場合、ファイルのアクセス時刻と修正時刻は現在の時刻に設定される。
タイムスタンプの変更は以下の場合に許可される: プロセスに適切な特権がある (Linux では CAP_FOWNER ケーパビリティ (capability) がある)。 または実効 (effective) ユーザ ID が、ファイルのユーザ ID と等しい。 または buf が NULL で、かつプロセスがファイルへの書き込み許可を持っている。
The utime() system call changes the access and modification times of the inode
specified by filename to the actime and modtime fields of times respectively.If times is NULL, then the access and modification times of the file are set
to the current time.Changing timestamps is permitted when: either the process has appropriate
utime(2) - Linux manual page
privileges, or the effective user ID equals the user ID of the file, or times
is NULL and the process has write permission for the file.
つぶやいていたら、親切な人からアドバイスが。
@yoheia http://bit.ly/arbitr you must actually own a directory in order to set its access and modification times to a definite value. (con
Twitter / Account Suspended
ソースとターゲットで完全同期するなら、chown。そうじゃなければ、rsync で -t、-a オプションを使わないようにする。オプションの変更が難しい場合は、ターゲットで動く処理の実効ユーザを rsync を実行するユーザと合わせるとかか。