Skip to content

Commit

Permalink
Merge branch 'symlinks'
Browse files Browse the repository at this point in the history
* symlinks:
  update receiver to handle symlinks
  enable push to send symlink
  add lchown() , lmitime()
  • Loading branch information
donald committed Jul 1, 2016
2 parents 9869c77 + 83cf6d4 commit 586918f
Showing 1 changed file with 89 additions and 13 deletions.
102 changes: 89 additions & 13 deletions clusterd
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ our ($udp_peer_addr,$udp_peer_port); # ('141.14.12.12',1234)
our %UDP_HANDLER=
(
'filedata' => \&udp_rx_filedata,
'filedata.2' => \&udp_rx_filedata,
'amdtardata' => \&udp_rx_amdtardata,
'loadavg.2' => \&udp_rx_loadavg2,
'restart' => \&udp_rx_restart,
Expand Down Expand Up @@ -381,23 +382,32 @@ sub push_file {

my $st=Donald::FileInfo->lstat($filename);
defined $st or return warn "$filename: $!\n";
$st->type eq 'F' or die "$filename: not a plain file\n";
$st->size<=65536 or die "$filename: to big for broadcast (max 65536 bytes)\n";
my $rpc;
if ($st->type eq 'F') {
$rpc='filedata';
$st->size<=65536 or die "$filename: to big for broadcast (max 65536 bytes)\n";
if ($st->size==0) {
udp_broadcast_message($donald_s,$rpc,$st,0,'');
return;
}

if ($st->size==0) {
udp_broadcast_message($donald_s,'filedata',$st,0,'');
my $fh=new IO::File $filename,'<' or return warn "$filename: $!\n";
my $i=0;
for (my $pos=0;$pos<$st->size;$pos+=1024) {
my $data;
defined $fh->sysread($data,1024) or return warn "$filename: $!\n";
# warn "send bytes $pos to ",$pos+length($data),"\n";
udp_broadcast_message($donald_s,$rpc,$st,$pos,$data);
++$i % $BC_RATE or sleep 1;
}
} elsif ($st->type eq 'L') {
$rpc='filedata.2';
udp_broadcast_message($donald_s,$rpc,$st,0,'');
return;
} else {
die "file type not supported\n";
}

my $fh=new IO::File $filename,'<' or return warn "$filename: $!\n";
my $i=0;
for (my $pos=0;$pos<$st->size;$pos+=1024) {
my $data;
defined $fh->sysread($data,1024) or return warn "$filename: $!\n";
# warn "send bytes $pos to ",$pos+length($data),"\n";
udp_broadcast_message($donald_s,'filedata',$st,$pos,$data);
++$i % $BC_RATE or sleep 1;
}
}

our %CMD=(
Expand Down Expand Up @@ -511,6 +521,54 @@ sub udp_rx_amdtardata {
system '/sbin/make-automaps';
}

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
$SYS_mknod=14; # __NR_mknod
} elsif ($machine eq 'x86_64') {
$SYS_lchown=94; # __NR_lchown in /usr/include/asm-x86_64/unistd.h
$SYS_mknod=133; # __NR_mknod
} elsif ($machine eq 'alpha') {
$SYS_lchown=208; # SYS_lchown in /usr/include/syscall.h
$SYS_mknod=14; # SYS_mknod
} elsif ($machine eq 'amd64') {
$SYS_lchown=254; # SYS_lchown in /usr/include/syscall.h
$SYS_mknod=14; # SYS_mknod
} else {
warn "unknown machine type $machine: symlink ownership can't be set.\n";
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)==0 or return warn "$path: failed to lmtime: $!\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)=@_;
$SYS_lchown or return;
syscall($SYS_lchown,$path,$uid+0,$gid+0)==0 or return warn "$path: failed to lchown: $!\n";
}

sub lmtime {
my ($mtime,$path)=@_;
$lmtime_sub or return;
$lmtime_sub->($path,$mtime);
}

sub udp_rx_filedata {

# set rx_filedata_done as a side effect
Expand All @@ -530,6 +588,24 @@ sub udp_rx_filedata {
return;
}

if ($st_want->type eq 'L') {
if (!$st_is || $st_is->type ne 'L' || $st_is->target ne $st_want->target) {
$st_is and (unlink($filename) or return warn "$filename: failed to unlink: $!\n");
symlink($st_want->target,$filename) or return warn "$filename: failed to create symlink: $!\n";
lchown($st_want->uid,$st_want->gid,$filename);
lmtime($st_want->mtime,$filename);
warn "installed $filename -> ".$st_want->target."\n";
} else {
if ($st_is->uid != $st_want->uid || $st_is->gid != $st_want->gid) {
lchown($st_want->uid,$st_want->gid,$filename);
}
if ($st_is->mtime != $st_want->mtime) {
lmtime($st_want->mtime,$filename);
}
}
return;
}

if (length($data) == $st_want->size) {
# complete file in one broadcast
my $fh=IO::File->new($tmp_filename,O_WRONLY|O_CREAT,0);
Expand Down

0 comments on commit 586918f

Please sign in to comment.