Background: I've been commissioned by my supervisor to create a script that will identify what virtual machines are located on a given server. This problem arose because no naming convention was established between the virtual machine configuration name and the DNS name (ie. a VM called taco has a DNS name of hotdog). While I think it would just be better to go establish a naming convention and spend a few hours to rename all the configuration files to the DNS names, my superiors want a "clever solution".


Purpose: If a machine critical VM goes down, they need to know what machine it is on to resolve the problem(s).


What I Use: Doing some voodoo I manage to pull out possible DNS names from the database to what an actual VM might be associated with. The goal initially was to use tcpdump to listen for traffic on each DNS, timing out after say 15 seconds or a minute or even 5 minutes if there is not traffic. Since this runs as a cron job at night, there isn't a lot of traffic and the script thinks that the real DNS name is bogus since tcpdump ends up not returning anything useful.


Proposed Solution: I am new to thread programming, but I understand the concept to a minimal degree. The idea is to launch a series of say 10 pings at the DNS name and have tcpdump listen for those pings. I had two terminals open, I started the pinging and then started the tcpdump. With pefect commands and associated parameters I figured I could plug and chug and everything would work wonderfully.


Problem: I run tcpdump in an eval block with a SIG{ALRM} to kill it after so long if it doesn't get any packets. Unfortunately it doesn't seem to be working. I'm suspicious this is a newbish misuse of threads that's causing the problem, because a previous eval statement killed tcpdump just fine, but now it won't.


Code:

sub vm_tcp_dump { my $macaddress = $_[0]; my $dns_name = $_[1]; my $good_dns_name = undef;; eval{ local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n req +uired alarm 15; my $ping_thread = threads->new(\&vm_ping, $dns_name); print ("CMD: tcpdump -q -i eth0 'ether dst host $macad +dress and proto ICMP and src host $hostname' -c 1\n"); my $dumpdata = undef; my $dump_thread = threads->new(sub {my $ipaddress = un +def; $dumpdata = `tcpdump -q -i eth +0 'ether dst host $macaddress and proto ICMP and src host $hostname' +-c 1`; return $dumpdata; }); $dumpdata = $dump_thread->join(); print "\nTEST\n\n"; print "\n".$dumpdata."\n\n"; $good_dns_name = $ping_thread->join(); alarm 0; }; print "tcpdump done\n"; return $good_dns_name; } sub vm_ping { my $dns_name = $_[0]; my $good_dns_name; print("DNS: $dns_name\n"); eval{ local $SIG{ALRM} = sub {die "alarm\n" }; alarm 15; my $data = `ping $dns_name -c 10 -s 256`; if(!($data =~ m/Destination Host Unreachable/g)){ $data =~ m/PING (.*).et.byu.edu/g; $good_dns_name = $1; print($data."\n"); } alarm 0; }; print "\nDONE\n\n"; return $good_dns_name; }

I've tweaked and tweaked and now I'm looking for that good ol' perlmonk wisdom. Does my thread management look okay? The ping function does execute and finish after the tcpdump is started. Tcpdump just doesn't break out of the 15 second timeout I set up for it.


In reply to Threads, bash, and networking by morganda

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.