djamu has asked for the wisdom of the Perl Monks concerning the following question:
when I copy 2 files from a single smb client I get a result ( as it should ) that is similar to this#!/usr/bin/perl use strict; use warnings; use threads; use threads::shared; use Linux::Inotify2; my @jobstack :shared ; # shared array for filenames # spawn thread sub # start inotify in separate thread my $thr1 = threads->create(\&jobinotifydetect); $thr1->detach(); #main while (1) { sleep 1; { # here comes main > for now remove every second a file out of stac +k lock (@jobstack); # I can't splice shared arrays so I copy it onto a nonshared one > + later I need splice to pull out specific files 1st # now it's just a pop replacement my @temp=@jobstack; my $t = scalar (@temp); splice (@temp,$t-1,1) if ($t ); @jobstack=@temp; } } sub jobinotifydetect { my $smbroot = "/media/lrfp/"; my $sharedfolder = "jobs/"; my $path = $smbroot . $sharedfolder ; my $jobinotify; my $file; my $count; my $tt; $jobinotify = new Linux::Inotify2 or die "unable to create new inotify + object: $!"; # add watcher $jobinotify->watch ("$path", IN_MOVED_TO | IN_MODIFY | IN_CREATE, s +ub { my $e = shift; if ( $e->IN_MOVED_TO || $e->IN_MODIFY || $e->IN_CREATE ) { # wait for file locks to be removed > when data is still written b +y server my $file = $e->name; my $t=$e->fullname; my $exec = `smbstatus | grep "EXCLUSIVE" | grep "$sharedfolder" | +grep "$file"`; if (!($exec)) { # check if filesize <> 0,don't if file has zero length if ( -s $t ) { { # lock @jobstack while I push filename onto it lock (@jobstack); # don't push onto stack if already exist if (!( grep( /^$file/, @jobstack ) ) ){ push (@jobstack,$file); $tt=scalar (@jobstack); print "$count \t $file \t $tt \n"; $count = 0; }}} } else { # count how much times routine gets called just out of curiosity, +I'll remove this later $count +=1 ; } } }); 1 while $jobinotify->poll; }
( last nr is amount of files in array ) but when I copy 2 files simultaneously from 2 different smb clients ( 2 different computers ) I'm getting something like this which is according to me not even possible as the array size doesn't increase while calling the print command ( there is only 1 print command that is called after a push ). Even stranger is that results are printed with a 1 sec interval after the 1st file is finished copying.1358 a.dd 1 458 b.dd 2
any help is greatly appreciated, an alternate method to check smb filelocks even more.1266 a.dd 1 18 a.dd 1 43 a.dd 1 34 a.dd 1 56 a.dd 1 49 a.dd 1 34 a.dd 1 3 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2 0 b.dd 2
#!/usr/bin/perl use strict; use warnings; use threads; use threads::shared; use Linux::Inotify2; my @jobstack :shared ; # shared array for filenames # spawn thread sub my $thr1 = threads->create(\&jobinotifydetect); # start inotify in se +perate thread $thr1->detach(); #main while (1) { sleep 1; { # here comes main > for now remove every second a file out of stac +k lock (@jobstack); shift (@jobstack); } } sub jobinotifydetect { my $smbroot = "/media/lrfp/"; my $sharedfolder = "jobs/"; my $path = $smbroot . $sharedfolder ; my $jobinotify; my $file; $jobinotify = new Linux::Inotify2 or die "unable to create new inotify + object: $!"; $jobinotify->watch ("$path", IN_MOVED_TO | IN_CLOSE_WRITE, sub { my $e = shift; my $file = $e->name; my $t=$e->fullname; #only do for files with non-zero size if ( -s $t ) { if ( $e->IN_MOVED_TO || $e->IN_CLOSE_WRITE ) { # don't push onto stack if already exist if (!( grep( /^$file/, @jobstack ) ) ){ { lock (@jobstack); push (@jobstack,$file); }}}} # } }); 1 while $jobinotify->poll; }
|
|---|