getpwent performance


M

Michal Kwiatkowski

Hi,

Please look at the following code:

sub get_current_uids {
my(@uids, $uid);
setpwent;
push @uids, $uid while defined($uid = (getpwent)[2]);
endpwent;
return @uids;
}

&get_current_uids;

On systems with considerably large /etc/shadow and /etc/passwd files
(about 10.000 entries) it takes very long time to execute. Stracing it
shows really long loop of intructions quoted below:

open("/etc/shadow", O_RDONLY) = 4
fcntl64(4, F_GETFD) = 0
fcntl64(4, F_SETFD, FD_CLOEXEC) = 0
_llseek(4, 0, [0], SEEK_CUR) = 0
fstat64(4, {st_mode=S_IFREG|0640, st_size=1538953, ...}) = 0
fstat64(4, {st_mode=S_IFREG|0640, st_size=1538953, ...}) = 0
mmap2(NULL, 131072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0xb7d09000
read(4, "root:$1$uUu3dni5$qztZJWVijz2SQGv"..., 131072) = 131072
close(4) = 0
munmap(0xb7d09000, 131072) = 0
open("/etc/shadow", O_RDONLY) = 4
fcntl64(4, F_GETFD) = 0
etc.....

It seems as getpwent opens "/etc/shadow" each time it is called. Is this
really needed? In fact, subroutine get_current_uids is part of adduser
script, so this bug affects lots of users.

mk
 
Ad

Advertisements

C

Chris Richmond - MD6-FDC ~

This isn't especially slow on about the same number of users in NIS.
This an finding ~400 users in a particular group takes ~3 seconds.

Chris

%NIS = ();
$dn = "";

while( ($n,$pw,$uid,$grp,$dn,$cmt,$gcos,$home,$shell) = getpwent ) {
$NIS{$n} = {
'pw' => "$pw",
'uid' => "$uid",
'grp' => "$grp",
'cmt' => "$cmt",
'gcos' => "$gcos",
'home' => "$home",
'shell' => "$shell",
};
}
endpwent;
 
J

Joe Smith

Chris said:
$NIS{$n} = {
'pw' => "$pw",
'uid' => "$uid",
'grp' => "$grp",
'cmt' => "$cmt",
'gcos' => "$gcos",
'home' => "$home",
'shell' => "$shell",
};

Are you aware that that can be written without the unneeded quotes?

$NIS{$n} = {
pw => $pw,
uid => $uid,
grp => $grp,
cmt => $cmt,
gcos => $gcos,
home => $home,
shell => $shell,
};

-Joe
 
Ad

Advertisements

P

Paul Lalli

Joe said:
Are you aware that that can be written without the unneeded quotes?

$NIS{$n} = {
pw => $pw,
uid => $uid,
grp => $grp,
cmt => $cmt,
gcos => $gcos,
home => $home,
shell => $shell,
};

Not only "can", but in the case of the right-hand-side variables,
"should". Please see:
perldoc -q quoting
"What's wrong with always quoting "$vars"?"

Paul Lalli
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top