I am a network admin looking to store some info about our switches/routers in a postgres db. We have several hundred devices, so I am looking to poll data via snmp, and store it in my db. Since we have so many devices it takes quite a while to poll them all sequentially. For this reason I am attempting to fork off child processes in order to speed things up a bit.
I am having a problem with my database handles being closed before they should be. I get these errors when I run my script:
Database handle destroyed without explicit disconnect.
Database handle destroyed without explicit disconnect.
DBD::Pg::db do failed: server closed the connection unexpectedly at ./
+vlan.pl line 203.
Here is the main part of the program. I stripped out the sql for the sake of shortening it down a bit.
# DESCRIPTION
# This script gets a list of non-access layer, failover switches from
+a database.It will
# then poll those switches for all active vlans and add them to the da
+tabase.
# The script will automatically delete any vlans from the db that have
+ been
# removed from our switches, and are not marked with the 'dnd' flag.
#===================================================================
# MAIN
#-------------------
# open db
my $parent_dbh = DBI->connect($DATASOURCE, $USER);
if (!$parent_dbh) {
exit(0);
}
#---------
#-------------------
# get list of switches from db
my $switch_ref = $parent_dbh->selectall_arrayref($get_switch);
#---------
#-------------------
# fork off child processes, poll snmp, update database
for (my $count = 0; $count < @$switch_ref; ++$count) {
my $switch = $switch_ref->[$count];
my $pid;
#-------------------
# parent process
if ($pid = fork) {
push @pids, $pid;
}
#---------
#-------------------
# children processes
elsif (defined $pid) {
#-------------------
# set some variables
my $ip = $switch->[0];
my $stp_domain_id = $switch->[1];
my $ro_community = $switch->[2];
my $params = {'community' => $ro_community,
'default_max_repetitions' => '48'
};
#---------
#-------------------
# walk mib for vlan info from this switch.
my @ret = &snmpwalk($ip, $params, "ifalias");
#---------
#-------------------
# open db
my $child_dbh = DBI->connect($DATASOURCE, $USER);
if (!$child_dbh) {
exit(0);
}
#---------
#-------------------
# set 'updated' field of the 'vlan' table to false for all
# vlans in current domain
$child_dbh->do($set_updated);
#---------
#-------------------
# insert data into vlan table
foreach my $val (@ret){
my ($vlan, $name) = split(':', $val, 2);
# if entry for this vlan exists, do
# SQL UPDATE. else insert new data.
my $result_h = $child_dbh->selectrow_array($exists_vlan);
if ($result_h > 0){
$child_dbh->do($update_data);
}
else {
$child_dbh->do($insert_data);
}
}
#---------
$child_dbh->disconnect;
exit;
}
#---------
#-------------------
# error, the parent is saying this...
else {
die "Fork failed: $!\n";
}
#---------
}
#---------
#-------------------
# wait for children to finish before proceeding
foreach my $pid (@pids){
waitpid($pid,0);
}
#---------
#-------------------
# delete all vlans that have 'dnd'='f' and where 'updated'='f'
# this is query that fails because of a closed db handle
$parent_dbh->do($delete_vlan);
#---------
$parent_dbh->disconnect;
exit(0);
#=======================================
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.