I have been struggling with a recursive ACL collection program for some time now. It has been displaying memory leak problems and when unleashed on a server with 10's of thousands of folders it runs out of memory.
I desperately searched for solutions, researching my use of hash references and
localized variables, etc. to no avail. Mostly I found thread of people arguing about
perl vs. java and other useless junk.
I tried perl's -d switch but could not get a listing of my variables with "V" or "X
variablename" or "V main::processLevel" or anything. I could always see just the
built-in vars and a couple of others. I was looking for dangling anonymous hashes.
So I resorted to the old standby. I created a small perl script to emulate the
recursive behavior of the larger script.
First I looped the dir command and watched the memory. Stuck around 1700 for the
entire script. Good. Second I added hash references to the localized variables during
the loop. Still only went up to about 2600 and stayed put. Hmmm. Third I added a call
to Win32::Perms. Bingo! Memory climbed and climbed, only stopping when the script
finished all directories! For the test server, it climbed over 12000 before it
finished. I won't even try a large file system.
So the question is: How do I kill the Perms object? Close() and undef don't do it?
Here's the script (and attached is a "clean the heck out of everything" version):
###########################################################
### test recursion using scope alone for cleanup
###
use Win32::Perms;
my %r_level = ();
my $r_level = \%r_level;
$r_level->{var_Path} = "\\\\server\\C\$";
processLevel( $r_level );
sub processLevel {
### a recursive function
my $level = shift( @_ );
my $result = undef;
addHashRef( $level );
my @dirs = `dir /A:D /B /-C /O:N $level->{var_Path}`;
foreach my $dir ( @dirs )
{
chomp( $dir );
### create a hash reference to hold our child data
my %c_level = ();
my $c_level = \%c_level;
### add the var_Path variable to our child level by concatenation of
the parent var_Path
### that is, put 'em together...
$c_level->{var_Path} = $level->{var_Path}."\\".$dir;
addHashRef( $c_level );
processLevel( $c_level );
}
}
sub addHashRef{
### this is an immitation of what the getACLs sub does
### it uses Win32::Perms to get DACLKS, then adds them as hashes
my $level = shift( @_ );
$oPerms = new Win32::Perms( $level->{var_Path} );
if ( $oPerms )
{
$oPerms->Close();
undef $oPerms;
}
### manually add junk just for testing
$level->{var_DACL}->{var_File}->{S-1-1-01} = 1;
$level->{var_DACL}->{var_File}->{S-1-1-02} = 1;
$level->{var_DACL}->{var_File}->{S-1-1-03} = 1;
$level->{var_DACL}->{var_File}->{S-1-1-04} = 1;
$level->{var_DACL}->{var_File}->{S-1-1-05} = 1;
$level->{var_DACL}->{var_Dir}->{S-1-1-01} = 1;
$level->{var_DACL}->{var_Dir}->{S-1-1-02} = 1;
$level->{var_DACL}->{var_Dir}->{S-1-1-03} = 1;
$level->{var_DACL}->{var_Dir}->{S-1-1-04} = 1;
}
###########################################################
<<recurse_cleanit.pl>>
Doug Hornyak
CPS, UBSW
[EMAIL PROTECTED]
recurse_cleanit.pl
Description: recurse_cleanit.pl
Visit our website at http://www.ubswarburg.com This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secure or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message which arise as a result of e-mail transmission. If verification is required please request a hard-copy version. This message is provided for informational purposes and should not be construed as a solicitation or offer to buy or sell any securities or related financial instruments.
