wiki:GEC19Agenda/GIMI/Procedure/Execute

Version 10 (modified by divyashri.bhat@gmail.com, 9 years ago) (diff)

--

Image Map

How to use OML4R to write your OML application

1. Setup your Application

1.1 Download and build the tar file of your application

sudo su
wget http://www.gpolab.bbn.com/experiment-support/gec17/pingPlus/pingPlus_v3.tar.gz
tar xvzf pingPlus_v3.tar.gz
cd pingPlus_v3
make

1.2 Test connectivity

On the receiver

chmod +x pingPlusListener
ping -c 5 10.10.10.1
ifconfig eth1 0.0.0.0
ping -c 5 10.10.10.1
./pingPlusListener 10002

The format for the pingPlusListener is sudo ./pingPlusListener <EtherType>

On the sender

ping -c 5 10.10.10.2
ifconfig eth1 0.0.0.0
ping -c 5 10.10.10.2
chmod +x pingPlus
./pingPlus 02:26:ae:0e:9b:3e eth1 10002

The format for the sender is

./pingPlus <server mac> <client i/f name> <EtherType> <count>

1. Observe your Output

root@sender:/users/dbhat/pingPlus_v3# ./pingPlus 02:26:ae:0e:9b:3e eth1 10002 5
RQ:'9641+4173' to 2:26:ae:e:9b:3e.
RL:9641+4173=13814 from 2:26:ae:e:9b:3e.
RTT = 0.920166
RQ:'2271+7533' to 2:26:ae:e:9b:3e.
RL:2271+7533=9804 from 2:26:ae:e:9b:3e.
RTT = 0.654053
RQ:'8858+353' to 2:26:ae:e:9b:3e.
RL:8858+353=9211 from 2:26:ae:e:9b:3e.
RTT = 0.489014
RQ:'447+5696' to 2:26:ae:e:9b:3e.
RL:447+5696=6143 from 2:26:ae:e:9b:3e.
RTT = 0.290039
RQ:'7238+5082' to 2:26:ae:e:9b:3e.
RL:7238+5082=12320 from 2:26:ae:e:9b:3e.
RTT = 0.252930

2. Write your OML Application

2.1 Write your OML Parser

def process_output(row)
  if not (parse= /RQ:'(?<pktsnt1>\d*)\+(?<pktsnt2>\d*)' to (?<host>[a-f0-9:]*)/.match(row)).nil?
  puts "ReturnQual #{parse[:pktsnt1]}\n" 
  MPrt.inject(parse[:pktsnt1], parse[:pktsnt2],parse[:host])

  elsif not (parse= /RL:(?<numofpkt1>\d*)\+(?<numofpkt2>\d*)=(?<totpktrec>\d*) from (?<dest_hw_addr>[a-f0-9:]*)/.match(row)).nil?
  puts "ReturnLength\n"
  p parse
  p MPrl.inject(parse[:numofpkt1],parse[:numofpkt2],parse[:totpktrec],parse[:dest_hw_addr]) 

  elsif not (parse = /RTT = (?<rtt>[0-9.]*)/.match(row)).nil?
  puts "RoundTripTime #{parse[:rtt]}\n"
  p parse
  p MPrtt.inject(parse[:rtt])
  end
end

2.2 Write your OML Application

Define all varying parameters as properties that can be set within your Application.

Save the following code to any location on your node. E.g /usr/local/bin/pingl2.rb

#!/usr/bin/ruby1.9.1
require 'rubygems'
require 'oml4r'

class MPrt < OML4R::MPBase
   name :pingrt
   param :pktsnt1, :type => :uint64
   param :pktsnt2, :type => :uint64
   param :host, :type => :string
end

class MPrl < OML4R::MPBase
   name :pingrl
   param :totpktrec, :type => :uint64
   param :numofpkt1, :type => :uint64
   param :numofpkt2, :type => :uint64
   param :dest_hw_addr, :type => :string
end

class MPrtt < OML4R::MPBase
   name :pingrtt
   param :rtt, :type => :double
end

class Pingl2Wrapper

  def initialize(args)
     @addr = nil
     @if_num = ''
     @eth = nil
     @verbose = true
     @numeric = ''

     leftover = OML4R::init(args, :appName => 'pingl2') do |argParser|
       argParser.banner = "Runs layer 2 ping and reports measurements via OML\n\n"
       argParser.on("-a" , "--dest_hw_addr ADDRESS", "Hardware address to ping (the -a switch is optional)"){ |address| @addr = address.to_s() }
       argParser.on("-i","--interface IFNUM","Interface number"){ |if_num| @if_num ="#{if_num.to_i()}" }
       argParser.on("-e", "--eth ETHTYPE","Ethernet Type") { |ethtype| @eth = ethtype.to_s() }
       argParser.on("-c","--count NUMBER","Number of pings (default: infinite)"){ |count| @count = "#{count.to_i()}"}
       argParser.on("-q", "--no-quiet ","Don't show layer 2 ping output on console"){ @verbose = false }
       argParser.on("-n", "--[no]-numeric ", "No attempt twill be made to look up symbolic names for host addresses"){ @numeric ='-n' }
    end

    if @addr.nil?
      if leftover.length > 0
        @addr = leftover [0]
      else
        raise "You did not specify an address to ping!"
      end
    end

end

def process_output(row)
  if not (parse= /RQ:'(?<pktsnt1>\d*)\+(?<pktsnt2>\d*)' to (?<host>[a-f0-9:]*)/.match(row)).nil?
  puts "ReturnQual #{parse[:pktsnt1]}\n" 
  MPrt.inject(parse[:pktsnt1], parse[:pktsnt2],parse[:host])

  elsif not (parse= /RL:(?<numofpkt1>\d*)\+(?<numofpkt2>\d*)=(?<totpktrec>\d*) from (?<dest_hw_addr>[a-f0-9:]*)/.match(row)).nil?
  puts "ReturnLength\n"
  p parse
  p MPrl.inject(parse[:numofpkt1],parse[:numofpkt2],parse[:totpktrec],parse[:dest_hw_addr]) 

  elsif not (parse = /RTT = (?<rtt>[0-9.]*)/.match(row)).nil?
  puts "RoundTripTime #{parse[:rtt]}\n"
  p parse
  p MPrtt.inject(parse[:rtt])
  end
end

def pingl2()
   @pingio = IO.popen("/bin/pingPlus #{@addr} #{@eth} #{@if_num} #{@count}")
   while true
    row = @pingio.readline
    puts row if @verbose
    process_output(row)
    end
end

def start()
    return if not @pingio.nil?

    # handle for OMF's exit command
    a = Thread.new do
      $stdin.each do |line|
    if /^exit/ =~ line
      Process.kill("INT",0)    
    end
      end
    end

3. Instrument your Application using LabWiki

3.1 Copy binaries and set permissions

cp pingPlusListener /bin
cp ping2.rb /usr/local/bin
chmod +x /bin/pingPluListener
chmod +x /usr/local/bin/pingl2.rb

3.2 Write your LabWiki Application

3.2.1 Create a new OEDL Script in the Prepare Window

3.2.2 Copy the following script into the Prepare Window

defProperty('source1', "sender-gimiinsta", "ID of a resource")

defProperty('sinkaddr11', '02:ee:1a:a2:51:11', "Ping destination address")
defProperty('eth11','eth1',"Output Eth interface")


defApplication('pingl2') do |app|
  app.description = 'Simple Definition for the pingl2 application'
  # Define the path to the binary executable for this application
  app.binary_path = '/usr/local/bin/pingl2.rb'
  # Define the configurable parameters for this application
  # For example if target is set to foo.com and count is set to 2, then the 
  # application will be started with the command line:
  # /usr/bin/ping-oml2 -a macaddress -c 2
  app.defProperty('target', 'Address to ping', '-a', {:type => :string})
  app.defProperty('count', 'Number of times to ping', '-c', {:type => :integer})
  app.defProperty('if_num', 'interface number', '-i', {:type => :integer})
  app.defProperty('eth', 'Ethernet Type', '-e', {:type => :string})
  # Define the OML2 measurement point that this application provides.
  app.defMeasurement('pingrl') do |m|
    m.defMetric('dest_hw_addr',:string)
  end
    app.defMeasurement('pingrtt') do |m|
    m.defMetric('rtt',:double)
  end
end
defGroup('Source1', property.source1) do |node|
  node.addApplication("pingl2") do |app|
    app.setProperty('target', property.sinkaddr11)
    app.setProperty('count', 30)
    app.setProperty('if_num', 10002)
    app.setProperty('eth',property.eth11)
    app.measure('pingrl', :samples => 1)
    app.measure('pingrtt', :samples => 1)
  end
end



onEvent(:ALL_UP_AND_INSTALLED) do |event|
  info "Starting the ping"
  after 5 do
    allGroups.startApplications
  end
  after 70 do
    info "Stopping the ping"
    allGroups.stopApplications
    Experiment.done
  end
end

defGraph 'RTT' do |g|
  g.ms('pingrtt').select(:rtt__oml_seq, :rtt__rtt, :rl__dest_hw_addr)\
     .from(:pingl2_pingrtt___rtt, :pingl2_pingrl___rl)\
     .where(:rtt__oml_seq => :rl__oml_seq)
  g.caption "RTT of received packets."
  g.type 'line_chart3'
  g.mapping :x_axis => :oml_seq, :y_axis => :rtt, :group_by => :dest_hw_addr
  g.xaxis :legend => 'oml_seq'
  g.yaxis :legend => 'rtt', :ticks => {:format => 's'}
end

defGraph 'RTT2' do |g|
  g.ms('pingrtt').select(:rtt__oml_seq, :rtt__rtt, :rl__dest_hw_addr)\
     .from(:pingl2_pingrtt___rtt, :pingl2_pingrl___rl)\
     .where(:rtt__oml_seq => :rl__oml_seq)
  g.caption "RTT of received packets."
  g.type 'histogram2'
  g.mapping :value => :rtt, :group_by => :dest_hw_addr
  g.xaxis :legend => 'RTT [ms]'
  g.yaxis :legend => 'Density [%]'
end

3.2.3 Start your application from LabWiki

Attachments (4)

Download all attachments as: .zip