From 353cd4756993ed1358bdc3c797762ac5595f3bf5 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Tue, 6 Dec 2016 09:00:48 +0100 Subject: [PATCH 1/3] pdist: Support symlink mtimes in index We want to maintain the mtime of symlinks in the slaves. As a first step we need to pass that information to the slave. So we expand the external format of an index record to include that time. The exporter and importer functions are updated. --- pdist/pdist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdist/pdist b/pdist/pdist index 9372193..b0ac949 100755 --- a/pdist/pdist +++ b/pdist/pdist @@ -86,7 +86,7 @@ sub export_index $type eq 'B' || $type eq 'C' ? $self->rdev : '-' ), - $type eq 'F'||$type eq 'D' ? $self->mtime : '-', + $type eq 'F' || $type eq 'D' || $type eq 'L' ? $self->mtime : '-', ); } @@ -103,7 +103,7 @@ sub import_index $F[3],$F[4], # uid,gid ($type eq 'B' || $type eq 'C' ? $F[5] : 0), # rdev ($type eq 'F' ? $F[5] : 0 ), # size - ($type eq 'F'||$type eq 'D' ? $F[6] : 0 ), # mtime + ($type eq 'F'|| $type eq 'D' || $type eq 'L' ? $F[6] : 0 ), # mtime ($type eq 'L' ? fn_unescape($F[5]) : ''), # target ], From 7b981122e68c0307cf13469f5b9a77bc72ed7b6a Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Tue, 6 Dec 2016 09:03:26 +0100 Subject: [PATCH 2/3] pdist: Add fileop_lmtime Add a function to change the mtime of a symlink. There is no perl function available for that, but newer kernels have a syscall. Syscall number and arguments depend on architecture. --- pdist/pdist | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/pdist/pdist b/pdist/pdist index b0ac949..a1534e0 100755 --- a/pdist/pdist +++ b/pdist/pdist @@ -306,7 +306,7 @@ sub index_file_sort { return sort @_; } #---------------------------- lchown / mknod -our ($machine,$SYS_lchown,$SYS_mknod); +our ($machine,$SYS_lchown,$SYS_mknod,$lmtime_sub); chomp($machine=`uname -m`); if ($machine eq 'i686') { $SYS_lchown=198; # __NR_lchown32 in /usr/include/asm/unistd.h @@ -325,6 +325,24 @@ if ($machine eq 'i686') { warn "unknown machine type $machine: named pipes,character and block devices can't be created\n"; } +if ($machine eq 'x86_64') { + our $SYS_utimensat=280; # /usr/include/asm/unistd_64.h + our $AT_FDCWD=-100; # /usr/include/fcntl.h + our $UTIME_OMIT=(1<<30)-2; # /usr/include/bits/stat.h + our $AT_SYMLINK_NOFOLLOW=0x100; # /usr/include/fcntl.h + + $lmtime_sub=sub { + my ($path,$mtime)=@_; + my $tsa=pack 'qqqq',0,$UTIME_OMIT,$mtime,0; + syscall($SYS_utimensat,$AT_FDCWD,$path,$tsa,$AT_SYMLINK_NOFOLLOW) and die "$path: $!\n"; + } +} else { + $lmtime_sub=sub { + my ($path,$mtime)=@_; + warn "$path: don't known how to change symlink mtime on target architecture\n"; + } +} + sub lchown { my ($uid,$gid,$path)=@_; @@ -453,6 +471,13 @@ sub fileop_ln_or_cp } } +sub fileop_lmtime { + my ($mtime,$path)=@_; + $fileop_debug and warn "lmtime $mtime $path\n"; + $fileop_noop and return; + $lmtime_sub->($path,$mtime); +} + #-------------------------------------------- sub index_wanted From 43687f3edc379212ca8b8e0e03c2792a787b10b1 Mon Sep 17 00:00:00 2001 From: Donald Buczek Date: Tue, 6 Dec 2016 09:05:26 +0100 Subject: [PATCH 3/3] pdist: Maintain symlink mtime on client Create symlinks with the mtime from master or fix the mtime on existing symlinks if needed. --- pdist/pdist | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pdist/pdist b/pdist/pdist index a1534e0..9318b3f 100755 --- a/pdist/pdist +++ b/pdist/pdist @@ -748,11 +748,16 @@ sub prog_update $quiet or warn "ln -s ".$st_want->target." $filename\n"; fileop_symlink($st_want->target,$filename); fileop_lchown($st_want->uid,$st_want->gid,$filename); + fileop_lmtime($st_want->mtime,$filename); } else { if ($st_is->uid != $st_want->uid || $st_is->gid != $st_want->gid) { $quiet or warn "lchown ".$st_want->uid.':'.$st_want->gid." $filename\n"; fileop_lchown($st_want->uid,$st_want->gid,$filename); } + if ($st_is->mtime != $st_want->mtime) { + $quiet or warn "set mtime of $filename\n"; + fileop_lmtime($st_want->mtime,$filename); + } } } elsif ($st_want->type eq 'P') { if (!$st_is || $st_is->type ne 'P') {