Skip Menu |

This queue is for tickets about the Control-CLI CPAN distribution.

Report information
The Basics
Id: 118679
Status: resolved
Priority: 0/
Queue: Control-CLI

People
Owner: LSTEVENS [...] cpan.org
Requestors: quakehunter5225 [...] yahoo.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 2.04



Subject: Too many open files
Date: Tue, 8 Nov 2016 19:37:29 +0000 (UTC)
To: "bug-Control-CLI [...] rt.cpan.org" <bug-Control-CLI [...] rt.cpan.org>
From: Jon Wolfert <quakehunter5225 [...] yahoo.com>
In running a script which connects to about 1200 network devices, it got to ~650, and then had the below error when it went to create the next session.  I checked how many Input/Output/Dump files had been written in the director so far and it was just shy of ~2,000 .  I believe the number of open files is a limit of the OS, but as each of the SSH sessions is closed, I would expect the file handles to be closed as well.  Below is the code "problem creating ./XXXX - Test-Input.txt: Too many open files at D:/Strawberry/perl/site/lib/Control/CLI.pm line 869" Below is the code I'm using, 'conn' is a method I use that just attempts a Telnet session, if that fails it attempts an SSH connection, but the variable $conn is now the Control::CLI object and I am able to throw all commands at it without issue.  The object is not stored in any way outside of this 'for' loop, but is there a chance the file handlers are not being closed upon 'disconnect'?  Thank you as always for any insight in to this! for my $ip_address (@ip_list) {     #Attempt to connect to device     if(conn(\$conn, $ip_address, $username, $login_pass, $enable_pass)) {         print "Connection successful to $ip_address.\n"     } else { next; }     #Check if device is already in device list     if(!exists $devices{$ip_address}) {         ...     } else { print "Error: Device($ip_address) should not exist already\n"; }     #Close SSH/Telnet session     $conn->disconnect; } J. Wolfert
Hi Indeed, the disconnect method does not close the logging file handles. The input/output/dump _log methods are pretty much a copy of the same Net::Telnet methods; for Telnet connections Control::CLI even calls the Net::Telnet ones. The Net::Telnet documentation does actually state that the logging file handles are not closed if logging is disabled (which I need to add to Control::CLI's pod). The Net::Telnet::close method (equivalent to disconnect here) also does not close those file handles... I think the intent is that you can pass your own file handles to the logging methods, so the logging and close methods defer from closing them. Maybe it might be best to close them in the Control::CLI's DESTROY method. I take it when you re-assign $conn to a new Control::CLI object, the previous object is not referenced anymore in your for loop. Until I suss it out, as a workaround you should be able to close the file handles just before doing disconnect: #Close SSH/Telnet session close $conn->input_log if defined $conn->input_log; close $conn->output_log if defined $conn->output_log; close $conn->dump_log if defined $conn->dump_log; $conn->disconnect; Best regards Ludovico Stevens On Tue Nov 08 14:41:34 2016, quakehunter5225@yahoo.com wrote: Show quoted text
> > In running a script which connects to about 1200 network devices, it > got to ~650, and then had the below error when it went to create the > next session.  I checked how many Input/Output/Dump files had been > written in the director so far and it was just shy of ~2,000 .  I > believe the number of open files is a limit of the OS, but as each of > the SSH sessions is closed, I would expect the file handles to be > closed as well.  Below is the code > > "problem creating ./XXXX - Test-Input.txt: Too many open files at > D:/Strawberry/perl/site/lib/Control/CLI.pm line 869" > > Below is the code I'm using, 'conn' is a method I use that just > attempts a Telnet session, if that fails it attempts an SSH > connection, but the variable $conn is now the Control::CLI object and > I am able to throw all commands at it without issue.  The object is > not stored in any way outside of this 'for' loop, but is there a > chance the file handlers are not being closed upon 'disconnect'?  > Thank you as always for any insight in to this! > > > > for my $ip_address (@ip_list) { >     #Attempt to connect to device >     if(conn(\$conn, $ip_address, $username, $login_pass, > $enable_pass)) { >         print "Connection successful to $ip_address.\n" >     } else { next; } > >     #Check if device is already in device list >     if(!exists $devices{$ip_address}) { >         ... >     } else { print "Error: Device($ip_address) should not exist > already\n"; } > >     #Close SSH/Telnet session >     $conn->disconnect; > } > > J. Wolfert
Hi Sorry, slow turn around..! I have posted a new version where you can now pass a close_logs flag into the disconnect() method. This maintains the existing default behaviour while giving you a shorthand option to make sure all logging files get closed on disconnect. Best regards Ludovico Stevens On Thu Nov 10 16:22:04 2016, LSTEVENS wrote: Show quoted text
> Hi > > Indeed, the disconnect method does not close the logging file handles. > The input/output/dump _log methods are pretty much a copy of the same > Net::Telnet methods; for Telnet connections Control::CLI even calls > the Net::Telnet ones. > The Net::Telnet documentation does actually state that the logging > file handles are not closed if logging is disabled (which I need to > add to Control::CLI's pod). The Net::Telnet::close method (equivalent > to disconnect here) also does not close those file handles... > I think the intent is that you can pass your own file handles to the > logging methods, so the logging and close methods defer from closing > them. > > Maybe it might be best to close them in the Control::CLI's DESTROY > method. > I take it when you re-assign $conn to a new Control::CLI object, the > previous object is not referenced anymore in your for loop. > > Until I suss it out, as a workaround you should be able to close the > file handles just before doing disconnect: > > #Close SSH/Telnet session > close $conn->input_log if defined $conn->input_log; > close $conn->output_log if defined $conn->output_log; > close $conn->dump_log if defined $conn->dump_log; > $conn->disconnect; > > Best regards > Ludovico Stevens > > > On Tue Nov 08 14:41:34 2016, quakehunter5225@yahoo.com wrote:
> > > > In running a script which connects to about 1200 network devices, it > > got to ~650, and then had the below error when it went to create the > > next session.  I checked how many Input/Output/Dump files had been > > written in the director so far and it was just shy of ~2,000 .  I > > believe the number of open files is a limit of the OS, but as each of > > the SSH sessions is closed, I would expect the file handles to be > > closed as well.  Below is the code > > > > "problem creating ./XXXX - Test-Input.txt: Too many open files at > > D:/Strawberry/perl/site/lib/Control/CLI.pm line 869" > > > > Below is the code I'm using, 'conn' is a method I use that just > > attempts a Telnet session, if that fails it attempts an SSH > > connection, but the variable $conn is now the Control::CLI object and > > I am able to throw all commands at it without issue.  The object is > > not stored in any way outside of this 'for' loop, but is there a > > chance the file handlers are not being closed upon 'disconnect'? > > Thank you as always for any insight in to this! > > > > > > > > for my $ip_address (@ip_list) { > >     #Attempt to connect to device > >     if(conn(\$conn, $ip_address, $username, $login_pass, > > $enable_pass)) { > >         print "Connection successful to $ip_address.\n" > >     } else { next; } > > > >     #Check if device is already in device list > >     if(!exists $devices{$ip_address}) { > >         ... > >     } else { print "Error: Device($ip_address) should not exist > > already\n"; } > > > >     #Close SSH/Telnet session > >     $conn->disconnect; > > } > > > > J. Wolfert