trema 0.3.14 → 0.3.15

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1,3 +1,5 @@
1
+ language: ruby
2
+
1
3
  script: "rake travis"
2
4
 
3
5
  rvm:
@@ -9,5 +11,6 @@ branches:
9
11
  - develop
10
12
 
11
13
  before_install:
12
- - sudo apt-get update
13
- - sudo apt-get install libpcap-dev
14
+ - sudo apt-get update -qq
15
+ - sudo apt-get install libpcap-dev -qq
16
+ - gem install bundler
data/Gemfile CHANGED
@@ -21,8 +21,8 @@ group :development do
21
21
  gem "redcarpet", "~> 2.2.2"
22
22
  gem "reek", "~> 1.3.1"
23
23
  gem "relish", "~> 0.6"
24
- gem "rspec", "~> 2.12.0"
25
- gem "yard", "~> 0.8.4.1"
24
+ gem "rspec", "~> 2.13.0"
25
+ gem "yard", "~> 0.8.5"
26
26
  end
27
27
 
28
28
 
data/Rakefile CHANGED
@@ -16,11 +16,21 @@
16
16
  #
17
17
 
18
18
 
19
+ $LOAD_PATH.unshift( File.expand_path( File.dirname( __FILE__ ) + "/ruby" ) )
20
+
21
+
19
22
  require "rubygems"
20
23
  require "rake"
24
+ require "trema/path"
25
+
26
+ task :default => :build_trema
21
27
 
28
+ directory Trema.log
29
+ directory Trema.pid
30
+ directory Trema.sock
22
31
 
23
- task :default do
32
+ desc "Build Trema"
33
+ task :build_trema => [ Trema.log, Trema.pid, Trema.sock ] do
24
34
  sh "#{ Gem.ruby } ./build.rb"
25
35
  end
26
36
 
@@ -29,8 +39,8 @@ end
29
39
  # Maintenance Tasks
30
40
  ################################################################################
31
41
 
42
+ # Generate a monolithic rant file"
32
43
  # FIXME: Remove dependency to rant
33
- desc "Generate a monolithic rant file"
34
44
  task "build.rb" do
35
45
  sh "rant-import --force --auto .mono.rant"
36
46
  end
@@ -52,35 +62,43 @@ task :relish do
52
62
  end
53
63
 
54
64
 
65
+ ################################################################################
66
+ # Cruise
67
+ ################################################################################
68
+
69
+ task :setup do
70
+ sh "./build.rb distclean"
71
+ sh "bundle update"
72
+ sh "bundle install"
73
+ end
74
+
75
+
55
76
  ################################################################################
56
77
  # Tests
57
78
  ################################################################################
58
79
 
59
- task :travis => [ :default, "spec:travis" ]
80
+ task :travis => [ :setup, :spec ]
60
81
 
61
82
 
62
83
  begin
63
84
  require "rspec/core"
64
85
  require "rspec/core/rake_task"
65
86
 
87
+ task :spec => :build_trema
66
88
  RSpec::Core::RakeTask.new do | task |
67
89
  task.verbose = $trace
68
90
  task.pattern = FileList[ "spec/**/*_spec.rb" ]
69
91
  task.rspec_opts = "--format documentation --color"
70
92
  end
71
93
 
94
+ task "spec:actions" => :build_trema
72
95
  RSpec::Core::RakeTask.new( "spec:actions" ) do | task |
73
96
  task.verbose = $trace
74
97
  task.pattern = FileList[ "spec/**/*_spec.rb" ]
75
98
  task.rspec_opts = "--tag type:actions --format documentation --color"
76
99
  end
77
100
 
78
- RSpec::Core::RakeTask.new( "spec:travis" ) do | spec |
79
- spec.pattern = FileList[ "spec/**/*_spec.rb" ]
80
- # FIXME: use --tag ~sudo
81
- spec.rspec_opts = "--tag nosudo -fs -c"
82
- end
83
-
101
+ task :rcov => :build_trema
84
102
  RSpec::Core::RakeTask.new( :rcov ) do | spec |
85
103
  spec.pattern = "spec/**/*_spec.rb"
86
104
  spec.rcov = true
@@ -93,6 +111,7 @@ end
93
111
 
94
112
  begin
95
113
  require "cucumber/rake/task"
114
+ task :features => :build_trema
96
115
  Cucumber::Rake::Task.new( :features ) do | t |
97
116
  t.cucumber_opts = "features --tags ~@wip"
98
117
  end
data/Rantfile CHANGED
@@ -825,7 +825,7 @@ end
825
825
  def libtrema_unit_tests
826
826
  {
827
827
  :byteorder_test => [ :log, :utility, :wrapper, :trema_wrapper ],
828
- :daemon_test => [],
828
+ :daemon_test => [ :log, :utility, :wrapper, :trema_wrapper ],
829
829
  :ether_test => [ :buffer, :log, :utility, :wrapper, :trema_wrapper ],
830
830
  :messenger_test => [ :doubly_linked_list, :hash_table, :event_handler, :linked_list, :utility, :wrapper, :timer, :log, :trema_wrapper ],
831
831
  :openflow_application_interface_test => [ :buffer, :byteorder, :hash_table, :doubly_linked_list, :linked_list, :log, :openflow_message, :packet_info, :stat, :trema_wrapper, :utility, :wrapper ],
data/bin/trema CHANGED
@@ -22,6 +22,7 @@
22
22
  $LOAD_PATH.unshift File.expand_path( File.join File.dirname( __FILE__ ), "..", "ruby" )
23
23
 
24
24
  require "rubygems"
25
+ require "bundler/setup"
25
26
 
26
27
  require "gli"
27
28
  require "trema/command"
data/build.rb CHANGED
@@ -27,7 +27,7 @@ RUBY_PATH = File.join(
27
27
  )
28
28
 
29
29
  result = system "cd #{ File.dirname( __FILE__ ) } && #{ RUBY_PATH } .mono.rant #{ ARGV.join ' ' }"
30
- abort "#{ $0 } aborted!" unless result;
30
+ abort "#{ $0 } aborted!" unless result
31
31
 
32
32
 
33
33
  ### Local variables:
data/cruise.rb CHANGED
@@ -317,7 +317,6 @@ end
317
317
  def run_unit_test
318
318
  test "Running unit tests ..." do
319
319
  sh "./build.rb unittests"
320
- sh "./build.rb"
321
320
  sh "rake spec"
322
321
  end
323
322
  measure_coverage
@@ -326,7 +325,6 @@ end
326
325
 
327
326
  def run_acceptance_test
328
327
  test "Running acceptance tests ..." do
329
- sh "./build.rb"
330
328
  sh "rake features"
331
329
  end
332
330
  end
@@ -361,16 +359,12 @@ $options.parse! ARGV
361
359
 
362
360
 
363
361
  def init_cruise
364
- $start_time = Time.now
365
- sh "./build.rb distclean"
366
- sh "bundle install"
367
- mkdir_p Trema.log
368
- mkdir_p Trema.pid
369
- mkdir_p Trema.sock
362
+ sh "rake setup"
370
363
  end
371
364
 
372
365
 
373
366
  Blocker.start do
367
+ $start_time = Time.now
374
368
  cd Trema.home do
375
369
  init_cruise
376
370
  run_unit_test if not $acceptance_test_only
data/features/.nav CHANGED
@@ -36,3 +36,4 @@
36
36
  - switch_manager.feature
37
37
  - packetin_filter.feature
38
38
  - trema-config.feature
39
+ - get_pid_by_trema_name.feature
@@ -0,0 +1,137 @@
1
+ Feature: get_pid_by_trema_name()
2
+
3
+ The function get_pid_by_trema_name() returns the PID of the process
4
+ specified by its `name` argument.
5
+ If the `name` is not found, the function returns -1.
6
+
7
+ pid_t get_pid_by_trema_name( const char *name )
8
+
9
+ The `name` argument refers to controller process name called *trema-name*.
10
+ In the trema framework the trema-name is a unique identifier assigned to
11
+ each controller process.
12
+ It is determined automatically by the following rules:
13
+
14
+ **Rule 1:** When you start a Ruby controller:
15
+
16
+ class TopologyController < Controller
17
+ ...
18
+ end
19
+
20
+ $ trema run topology-controller.rb
21
+
22
+ then its trema-name is set to "TopologyController",
23
+ which is the same as the class name.
24
+
25
+ **Rule 2:** When you start a C controller:
26
+
27
+ $ trema run topology_controller
28
+
29
+ then its trema-name is set to "topology_controller",
30
+ which is same as the executable name.
31
+
32
+ **Rule 3:** Trema-name can be overwritten using the `-n` or `--name`
33
+ option given by the `trema run` command.
34
+
35
+ $ trema run "topology_controller -n topology"
36
+ $ trema run "topology_controller --name=topology"
37
+
38
+ Background:
39
+ Given a file named "print_pid.c" with:
40
+ """
41
+ #include <stdio.h>
42
+ #include "trema.h"
43
+
44
+ int
45
+ main( int argc, char* argv[] ) {
46
+ init_trema( &argc, &argv );
47
+
48
+ if ( argc >= 2 ) {
49
+ pid_t pid = get_pid_by_trema_name( argv[ 1 ] );
50
+ if ( pid == -1 ) {
51
+ printf( "No such process : %s\n", argv[ 1 ] );
52
+ }
53
+ else {
54
+ printf( "PID of %s = %d\n", argv[ 1 ], pid );
55
+ }
56
+ }
57
+
58
+ finalize_trema();
59
+ return 0;
60
+ }
61
+ """
62
+ And I compile "print_pid.c" into "print_pid"
63
+ And a file named "c_controller.c" with:
64
+ """
65
+ #include "trema.h"
66
+
67
+ int
68
+ main( int argc, char* argv[] ) {
69
+ init_trema( &argc, &argv );
70
+ start_trema();
71
+ return 0;
72
+ }
73
+ """
74
+ And I compile "c_controller.c" into "c_controller"
75
+
76
+ Scenario: Getting the PID of a Ruby controller process with a default name.
77
+ Given a file named "RubyController.rb" with:
78
+ """
79
+ class RubyController < Controller
80
+ end
81
+ """
82
+ And I run `trema run ./RubyController.rb -d`
83
+ And wait until "RubyController" is up
84
+ When I run `trema run "./print_pid RubyController"`
85
+ Then the output should match:
86
+ """
87
+ PID of RubyController = \d+
88
+ """
89
+
90
+ Scenario: Getting the PID of a C controller process with a default name.
91
+ Given I run `trema run "./c_controller" -d`
92
+ And wait until "c_controller" is up
93
+ When I run `trema run "./print_pid c_controller"`
94
+ Then the output should match:
95
+ """
96
+ PID of c_controller = \d+
97
+ """
98
+
99
+ Scenario: Getting the PID of a C controller process renamed through CLI option '-n'.
100
+ Given I run `trema run "./c_controller -n NewName" -d`
101
+ And wait until "NewName" is up
102
+ When I run `trema run "./print_pid NewName"`
103
+ Then the output should match:
104
+ """
105
+ PID of NewName = \d+
106
+ """
107
+
108
+ Scenario: Getting the PID of a C controller process renamed through CLI option '--name'.
109
+ Given I run `trema run "./c_controller --name=NewName" -d`
110
+ And wait until "NewName" is up
111
+ When I run `trema run "./print_pid NewName"`
112
+ Then the output should match:
113
+ """
114
+ PID of NewName = \d+
115
+ """
116
+
117
+ @wip
118
+ Scenario: Getting the PID of a Ruby controller process renamed through CLI option '-n'.
119
+ Given a file named "RubyController.rb" with:
120
+ """
121
+ class RubyController < Controller
122
+ end
123
+ """
124
+ And I run `trema run "./RubyController.rb -n NewName" -d`
125
+ And wait until "NewName" is up
126
+ When I run `trema run "./print_pid NewName"`
127
+ Then the output should match:
128
+ """
129
+ PID of NewName = \d+
130
+ """
131
+
132
+ Scenario: Getting the PID of non-existent controller returns an error code -1.
133
+ When I run `trema run "./print_pid NO_SUCH_TREMA_PROCESS"`
134
+ Then the output should match:
135
+ """
136
+ No such process : NO_SUCH_TREMA_PROCESS
137
+ """
@@ -16,10 +16,25 @@
16
16
  #
17
17
 
18
18
 
19
+ require "trema/path"
20
+
21
+
22
+ def wait_until_all_pid_files_are_deleted timeout = 10
23
+ elapsed = 0
24
+ loop do
25
+ raise "Failed to clean up remaining processes." if elapsed > timeout
26
+ break if Dir.glob( File.join( Trema.pid, "*.pid" ) ).empty?
27
+ sleep 1
28
+ elapsed += 1
29
+ end
30
+ sleep 1
31
+ end
32
+
33
+
19
34
  Before do
20
35
  @aruba_timeout_seconds = 10
21
36
  run "trema killall"
22
- sleep 5
37
+ wait_until_all_pid_files_are_deleted
23
38
  end
24
39
 
25
40
 
@@ -30,7 +45,7 @@ end
30
45
 
31
46
  After do
32
47
  run "trema killall"
33
- sleep 1
48
+ wait_until_all_pid_files_are_deleted
34
49
  end
35
50
 
36
51
 
@@ -21,11 +21,11 @@
21
21
  #include "barrier-reply.h"
22
22
  #include "buffer.h"
23
23
  #include "controller.h"
24
+ #include "default-logger.h"
24
25
  #include "features-reply.h"
25
26
  #include "flow-removed.h"
26
27
  #include "get-config-reply.h"
27
28
  #include "list-switches-reply.h"
28
- #include "logger.h"
29
29
  #include "openflow-error.h"
30
30
  #include "openflow.h"
31
31
  #include "packet-in.h"
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
  require "trema/app"
20
- require "trema/logger"
20
+ require "trema/default-logger"
21
21
  require "trema/monkey-patch/integer"
22
22
  require "trema/monkey-patch/string"
23
23
  require "trema/timers"
@@ -28,7 +28,7 @@ module Trema
28
28
  # @abstract The base class of Trema controller. Subclass and override handlers to implement a custom OpenFlow controller.
29
29
  #
30
30
  class Controller < App
31
- include Logger
31
+ include DefaultLogger
32
32
  include Timers
33
33
 
34
34
 
@@ -18,11 +18,11 @@
18
18
 
19
19
  #include "checks.h"
20
20
  #include "log.h"
21
- #include "logger.h"
21
+ #include "default-logger.h"
22
22
 
23
23
 
24
24
  extern VALUE mTrema;
25
- VALUE mLogger;
25
+ VALUE mDefaultLogger;
26
26
 
27
27
 
28
28
  static VALUE
@@ -45,7 +45,7 @@ do_log( void ( *log_function )( const char *format, ... ), int argc, VALUE *argv
45
45
  * additional arguments.
46
46
  */
47
47
  static VALUE
48
- logger_critical( int argc, VALUE *argv, VALUE self ) {
48
+ default_logger_critical( int argc, VALUE *argv, VALUE self ) {
49
49
  UNUSED( self );
50
50
  return( do_log( critical, argc, argv ) );
51
51
  }
@@ -63,7 +63,7 @@ logger_critical( int argc, VALUE *argv, VALUE self ) {
63
63
  * additional arguments.
64
64
  */
65
65
  static VALUE
66
- logger_error( int argc, VALUE *argv, VALUE self ) {
66
+ default_logger_error( int argc, VALUE *argv, VALUE self ) {
67
67
  UNUSED( self );
68
68
  return( do_log( error, argc, argv ) );
69
69
  }
@@ -81,7 +81,7 @@ logger_error( int argc, VALUE *argv, VALUE self ) {
81
81
  * additional arguments.
82
82
  */
83
83
  static VALUE
84
- logger_warn( int argc, VALUE *argv, VALUE self ) {
84
+ default_logger_warn( int argc, VALUE *argv, VALUE self ) {
85
85
  UNUSED( self );
86
86
  return( do_log( warn, argc, argv ) );
87
87
  }
@@ -99,7 +99,7 @@ logger_warn( int argc, VALUE *argv, VALUE self ) {
99
99
  * additional arguments.
100
100
  */
101
101
  static VALUE
102
- logger_notice( int argc, VALUE *argv, VALUE self ) {
102
+ default_logger_notice( int argc, VALUE *argv, VALUE self ) {
103
103
  UNUSED( self );
104
104
  return( do_log( notice, argc, argv ) );
105
105
  }
@@ -116,7 +116,7 @@ logger_notice( int argc, VALUE *argv, VALUE self ) {
116
116
  * additional arguments.
117
117
  */
118
118
  static VALUE
119
- logger_info( int argc, VALUE *argv, VALUE self ) {
119
+ default_logger_info( int argc, VALUE *argv, VALUE self ) {
120
120
  UNUSED( self );
121
121
  return( do_log( info, argc, argv ) );
122
122
  }
@@ -133,23 +133,23 @@ logger_info( int argc, VALUE *argv, VALUE self ) {
133
133
  * additional arguments.
134
134
  */
135
135
  static VALUE
136
- logger_debug( int argc, VALUE *argv, VALUE self ) {
136
+ default_logger_debug( int argc, VALUE *argv, VALUE self ) {
137
137
  UNUSED( self );
138
138
  return( do_log( debug, argc, argv ) );
139
139
  }
140
140
 
141
141
 
142
142
  void
143
- Init_logger() {
143
+ Init_default_logger() {
144
144
  mTrema = rb_define_module( "Trema" );
145
- mLogger = rb_define_module_under( mTrema, "Logger" );
146
-
147
- rb_define_method( mLogger, "critical", logger_critical, -1 );
148
- rb_define_method( mLogger, "error", logger_error, -1 );
149
- rb_define_method( mLogger, "warn", logger_warn, -1 );
150
- rb_define_method( mLogger, "notice", logger_notice, -1 );
151
- rb_define_method( mLogger, "info", logger_info, -1 );
152
- rb_define_method( mLogger, "debug", logger_debug, -1 );
145
+ mDefaultLogger = rb_define_module_under( mTrema, "DefaultLogger" );
146
+
147
+ rb_define_method( mDefaultLogger, "critical", default_logger_critical, -1 );
148
+ rb_define_method( mDefaultLogger, "error", default_logger_error, -1 );
149
+ rb_define_method( mDefaultLogger, "warn", default_logger_warn, -1 );
150
+ rb_define_method( mDefaultLogger, "notice", default_logger_notice, -1 );
151
+ rb_define_method( mDefaultLogger, "info", default_logger_info, -1 );
152
+ rb_define_method( mDefaultLogger, "debug", default_logger_debug, -1 );
153
153
  }
154
154
 
155
155
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Logger class.
2
+ * DefaultLogger module.
3
3
  *
4
4
  * Copyright (C) 2008-2013 NEC Corporation
5
5
  *
@@ -18,20 +18,20 @@
18
18
  */
19
19
 
20
20
 
21
- #ifndef LOGGER_H
22
- #define LOGGER_H
21
+ #ifndef DEFAULT_LOGGER_H
22
+ #define DEFAULT_LOGGER_H
23
23
 
24
24
 
25
25
  #include "ruby.h"
26
26
 
27
27
 
28
- extern VALUE mLogger;
28
+ extern VALUE mDefaultLogger;
29
29
 
30
30
 
31
- void Init_logger( void );
31
+ void Init_default_logger( void );
32
32
 
33
33
 
34
- #endif // LOGGER_H
34
+ #endif // DEFAULT_LOGGER_H
35
35
 
36
36
 
37
37
  /*
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
  module Trema
20
- module Logger
20
+ module DefaultLogger
21
21
  end
22
22
  end
23
23
 
data/ruby/trema/switch.c CHANGED
@@ -16,8 +16,8 @@
16
16
  */
17
17
 
18
18
 
19
+ #include "default-logger.h"
19
20
  #include "flow-mod.h"
20
- #include "logger.h"
21
21
  #include "ruby.h"
22
22
  #include "rubysig.h"
23
23
  #include "switch.h"
@@ -180,7 +180,7 @@ void
180
180
  Init_switch() {
181
181
  mTrema = rb_define_module( "Trema" );
182
182
  cSwitch = rb_define_class_under( mTrema, "Switch", rb_cObject );
183
- rb_include_module( cSwitch, mLogger );
183
+ rb_include_module( cSwitch, mDefaultLogger );
184
184
 
185
185
  rb_define_method( cSwitch, "run!", switch_run, 0 );
186
186
  rb_define_method( cSwitch, "send_message", switch_send_message, 1 );
data/ruby/trema/trema.c CHANGED
@@ -21,6 +21,7 @@
21
21
  #include "barrier-reply.h"
22
22
  #include "barrier-request.h"
23
23
  #include "controller.h"
24
+ #include "default-logger.h"
24
25
  #include "echo-reply.h"
25
26
  #include "echo-request.h"
26
27
  #include "error.h"
@@ -31,7 +32,6 @@
31
32
  #include "get-config-reply.h"
32
33
  #include "get-config-request.h"
33
34
  #include "hello.h"
34
- #include "logger.h"
35
35
  #include "match.h"
36
36
  #include "openflow-error.h"
37
37
  #include "packet-in.h"
@@ -85,6 +85,7 @@ Init_trema() {
85
85
  Init_barrier_reply();
86
86
  Init_barrier_request();
87
87
  Init_controller();
88
+ Init_default_logger();
88
89
  Init_echo_reply();
89
90
  Init_echo_request();
90
91
  Init_error();
@@ -95,7 +96,6 @@ Init_trema() {
95
96
  Init_get_config_reply();
96
97
  Init_get_config_request();
97
98
  Init_hello();
98
- Init_logger();
99
99
  Init_match();
100
100
  Init_openflow_error();
101
101
  Init_packet_in();
@@ -17,7 +17,7 @@
17
17
 
18
18
 
19
19
  module Trema
20
- VERSION = "0.3.14"
20
+ VERSION = "0.3.15"
21
21
  end
22
22
 
23
23
 
@@ -21,10 +21,10 @@ require "trema"
21
21
 
22
22
 
23
23
  module Trema
24
- describe Logger do
24
+ describe DefaultLogger do
25
25
  subject {
26
26
  class LoggingObject
27
- include Trema::Logger
27
+ include Trema::DefaultLogger
28
28
  end
29
29
  LoggingObject.new
30
30
  }
@@ -19,7 +19,7 @@
19
19
 
20
20
 
21
21
  class ForwardingEntry
22
- include Trema::Logger
22
+ include DefaultLogger
23
23
 
24
24
 
25
25
  attr_reader :mac
@@ -19,7 +19,7 @@
19
19
 
20
20
 
21
21
  class ARPEntry
22
- include Trema::Logger
22
+ include Trema::DefaultLogger
23
23
 
24
24
 
25
25
  attr_reader :port
data/src/lib/daemon.c CHANGED
@@ -26,6 +26,7 @@
26
26
  #include <string.h>
27
27
  #include <sys/stat.h>
28
28
  #include <unistd.h>
29
+ #include <getopt.h>
29
30
  #include "checks.h"
30
31
  #include "log.h"
31
32
  #include "wrapper.h"
@@ -290,12 +291,85 @@ read_pid( const char *directory, const char *name ) {
290
291
  exe_path[ readsiz ] = '\0';
291
292
 
292
293
  char *exe_name = basename( exe_path );
293
- if ( strcmp( name, exe_name ) != 0 ) {
294
- warn( "Failed to check process name %s ( %s [%d] ).", name, strerror( errno ), errno );
294
+ if ( strcmp( name, exe_name ) == 0 ) {
295
+ return pid;
296
+ }
297
+
298
+ // check if -n (service_name) option is used
299
+ sprintf( proc_path, "/proc/%d/cmdline", pid );
300
+ fd = open( proc_path, O_RDONLY, 0 );
301
+ if ( fd < 0 ) {
302
+ warn( "Failed to open %s ( %s [%d] ).", proc_path, strerror( errno ), errno );
295
303
  return -1;
296
304
  }
297
305
 
298
- return pid;
306
+ char *buffer = xcalloc( PATH_MAX + 2, sizeof( char ) );
307
+ char *write_head = buffer;
308
+ size_t buffer_left = PATH_MAX;
309
+ size_t read_byte = 0;
310
+ while ( ( readsiz = read( fd, write_head, buffer_left ) ) > 0 ) {
311
+ read_byte += ( size_t ) readsiz;
312
+ write_head += readsiz;
313
+ buffer_left = PATH_MAX - read_byte;
314
+ }
315
+ close( fd );
316
+
317
+ // convert cmdline to argv format
318
+ size_t argc = 0;
319
+ char **argv = xcalloc( 1, sizeof( char * ) );
320
+
321
+ char *token = buffer;
322
+ const char *buffer_end = buffer + read_byte;
323
+ while ( token <= buffer_end ) {
324
+ size_t token_len = strlen( token );
325
+ if ( token_len > 0 ) {
326
+ ++argc;
327
+ char **new_argv = xmalloc( ( argc + 1 ) * sizeof( char * ) );
328
+ for ( size_t i = 0; i < argc - 1; ++i ) {
329
+ new_argv[ i ] = argv[ i ];
330
+ }
331
+ xfree( argv );
332
+ argv = new_argv;
333
+ argv[ argc - 1 ] = token;
334
+ argv[ argc ] = NULL;
335
+ }
336
+ else {
337
+ if ( *( token + 1 ) == '\0' ) {
338
+ // "\0\0", end of cmdline
339
+ break;
340
+ }
341
+ }
342
+ token += token_len + 1;
343
+ }
344
+
345
+ const struct option long_options[] = {
346
+ { "name", 1, NULL, 'n' },
347
+ { NULL, 0, NULL, 0 },
348
+ };
349
+ const char short_options[] = "n:";
350
+ int c;
351
+ optind = 0;
352
+ opterr = 0;
353
+ const char *service_name = basename( argv[ 0 ] );
354
+ while ( ( c = getopt_long( ( int )argc, argv, short_options, long_options, NULL ) ) != -1 ){
355
+ switch ( c ) {
356
+ case 'n':
357
+ service_name = optarg;
358
+ break;
359
+ }
360
+ }
361
+
362
+ if ( strcmp( name, service_name ) == 0 ) {
363
+ xfree( argv );
364
+ xfree( buffer );
365
+ return pid;
366
+ }
367
+ else {
368
+ warn( "Failed to check process name %s.", name );
369
+ xfree( argv );
370
+ xfree( buffer );
371
+ return -1;
372
+ }
299
373
  }
300
374
 
301
375
 
@@ -1763,6 +1763,35 @@ delete_openflow_messages( uint64_t datapath_id ) {
1763
1763
  }
1764
1764
 
1765
1765
 
1766
+ bool
1767
+ disconnect_switch( uint64_t datapath_id ) {
1768
+ debug( "Disconnecting a switch ( datapath_id = %#" PRIx64 " ).", datapath_id );
1769
+
1770
+ maybe_init_openflow_application_interface();
1771
+ assert( openflow_application_interface_initialized );
1772
+
1773
+ size_t service_name_length = strlen( service_name ) + 1;
1774
+ size_t length = sizeof( openflow_service_header_t ) + service_name_length;
1775
+ buffer *buf = alloc_buffer_with_length( length );
1776
+ openflow_service_header_t *header = append_back_buffer( buf, sizeof( openflow_service_header_t ) );
1777
+ header->datapath_id = htonll( datapath_id );
1778
+ header->service_name_length = htons( ( uint16_t ) service_name_length );
1779
+ char *name = append_back_buffer( buf, service_name_length );
1780
+ memcpy( name, service_name, service_name_length );
1781
+
1782
+ char remote_service_name[ MESSENGER_SERVICE_NAME_LENGTH ];
1783
+ snprintf( remote_service_name, sizeof( remote_service_name ),
1784
+ "switch.%#" PRIx64, datapath_id );
1785
+
1786
+ bool ret = send_message( remote_service_name, MESSENGER_OPENFLOW_DISCONNECT_REQUEST,
1787
+ buf->data, buf->length );
1788
+
1789
+ free_buffer( buf );
1790
+
1791
+ return ret;
1792
+ }
1793
+
1794
+
1766
1795
  /*
1767
1796
  * Local variables:
1768
1797
  * c-basic-offset: 2
@@ -341,6 +341,13 @@ bool send_list_switches_request( void *user_data );
341
341
  bool delete_openflow_messages( uint64_t datapath_id );
342
342
 
343
343
 
344
+ /********************************************************************************
345
+ * Function for disconnecting a switch
346
+ ********************************************************************************/
347
+
348
+ bool disconnect_switch( uint64_t datapath_id );
349
+
350
+
344
351
  #endif // OPENFLOW_APPLICATION_INTERFACE_H
345
352
 
346
353
 
data/src/lib/trema.c CHANGED
@@ -373,7 +373,7 @@ die_unless_initialized() {
373
373
  }
374
374
 
375
375
 
376
- static void
376
+ void
377
377
  finalize_trema() {
378
378
  die_unless_initialized();
379
379
 
@@ -632,35 +632,28 @@ init_trema( int *argc, char ***argv ) {
632
632
  }
633
633
 
634
634
 
635
+ static void
636
+ create_pid_file() {
637
+ write_pid( get_trema_pid(), get_trema_name() );
638
+ }
639
+
640
+
635
641
  /**
636
642
  * Runs the main loop.
637
643
  */
638
644
  void
639
645
  start_trema() {
640
- start_trema_up();
641
- start_event_handler();
642
- start_trema_down();
643
- }
644
-
645
-
646
- void
647
- start_trema_up() {
648
646
  pthread_mutex_lock( &mutex );
649
647
 
650
648
  die_unless_initialized();
651
-
652
- debug( "Starting %s ... ( TREMA_HOME = %s )", get_trema_name(), get_trema_home() );
649
+ debug( "Starting %s ... (TREMA_HOME = %s)", get_trema_name(), get_trema_home() );
653
650
 
654
651
  maybe_daemonize();
655
- write_pid( get_trema_pid(), get_trema_name() );
652
+ create_pid_file();
656
653
  trema_started = true;
657
-
658
654
  start_messenger();
659
- }
660
-
655
+ start_event_handler();
661
656
 
662
- void
663
- start_trema_down() {
664
657
  finalize_trema();
665
658
 
666
659
  pthread_mutex_unlock( &mutex );
@@ -723,11 +716,17 @@ get_executable_name() {
723
716
 
724
717
 
725
718
  pid_t
726
- get_trema_process_from_name( const char *name ) {
719
+ get_pid_by_trema_name( const char *name ) {
727
720
  return read_pid( get_trema_pid(), name );
728
721
  }
729
722
 
730
723
 
724
+ pid_t
725
+ get_trema_process_from_name( const char *name ) {
726
+ return get_pid_by_trema_name( name );
727
+ }
728
+
729
+
731
730
  bool
732
731
  terminate_trema_process( pid_t pid ) {
733
732
  assert( pid > 0 );
data/src/lib/trema.h CHANGED
@@ -53,16 +53,16 @@ static const char DEFAULT_DUMP_SERVICE_NAME[] = "dump_service";
53
53
 
54
54
  void init_trema( int *argc, char ***argv );
55
55
  void start_trema( void );
56
- void start_trema_up();
57
- void start_trema_down();
58
56
  void stop_trema( void );
57
+ void finalize_trema( void );
59
58
  void flush( void );
60
59
  const char *get_trema_home( void );
61
60
  const char *get_trema_tmp( void );
62
61
  void set_trema_name( const char *name );
63
62
  const char *get_trema_name( void );
64
63
  const char *get_executable_name( void );
65
- pid_t get_trema_process_from_name( const char *name );
64
+ pid_t get_pid_by_trema_name( const char *name );
65
+ pid_t get_trema_process_from_name( const char *name ) __attribute__ ((deprecated));
66
66
  bool terminate_trema_process( pid_t pid );
67
67
  __attribute__( ( weak ) ) void usage( void );
68
68
 
@@ -131,7 +131,7 @@ service_recv_from_application( uint16_t message_type, buffer *buf ) {
131
131
  uint16_t service_name_length;
132
132
  char *service_name;
133
133
 
134
- if ( buf->length < sizeof( openflow_service_header_t ) + sizeof( struct ofp_header ) ) {
134
+ if ( buf->length < sizeof( openflow_service_header_t ) ) {
135
135
  error( "Too short openflow application message(%zu).", buf->length );
136
136
  free_buffer( buf );
137
137
 
@@ -399,7 +399,7 @@ switch_event_recv_featuresreply( struct switch_info *sw_info, uint64_t *dpid ) {
399
399
  snprintf( new_service_name, new_service_name_len, "%s%#" PRIx64, SWITCH_MANAGER_PREFIX, sw_info->datapath_id );
400
400
 
401
401
  // checking duplicate service
402
- pid_t pid = get_trema_process_from_name( new_service_name );
402
+ pid_t pid = get_pid_by_trema_name( new_service_name );
403
403
  if ( pid > 0 ) {
404
404
  // duplicated
405
405
  if ( !terminate_trema_process( pid ) ) {
@@ -682,7 +682,11 @@ main( int argc, char *argv[] ) {
682
682
  error( "Failed to set connected state." );
683
683
  return -1;
684
684
  }
685
- flush_secure_channel( &switch_info );
685
+ ret = flush_secure_channel( &switch_info );
686
+ if ( ret < 0 ) {
687
+ error( "Failed to flush secure channel. Terminating %s.", argv[ 0 ] );
688
+ return -1;
689
+ }
686
690
 
687
691
  start_trema();
688
692
 
data/trema.gemspec CHANGED
@@ -26,10 +26,10 @@ Gem::Specification.new do | gem |
26
26
  gem.extra_rdoc_files = [ "README.md" ]
27
27
  gem.test_files = `git ls-files -- {spec,features}/*`.split( "\n" )
28
28
 
29
- gem.add_dependency "bundler", "~> 1.2.3"
29
+ gem.add_dependency "bundler"
30
30
  gem.add_dependency "gli", "~> 2.5.4"
31
31
  gem.add_dependency "rake", "~> 10.0.3"
32
- gem.add_dependency "rdoc", "~> 3.12.1"
32
+ gem.add_dependency "rdoc", "~> 4.0.0"
33
33
  end
34
34
 
35
35
 
@@ -658,59 +658,6 @@ test_read_pid_fail_if_readlink_fail() {
658
658
  }
659
659
 
660
660
 
661
- static void
662
- test_read_pid_fail_if_strcmp_fail() {
663
- // Test if correctly access.
664
- char path[] = "/home/yasuhito/trema/tmp/chess.pid";
665
- expect_string( mock_access, pathname, path );
666
- expect_value( mock_access, mode, R_OK );
667
- will_return( mock_access, 0 );
668
-
669
- // Test if correctly opened.
670
- int pid_file_fd = 111;
671
- expect_string( mock_open, pathname, path );
672
- expect_value( mock_open, flags, O_RDONLY );
673
- expect_value( mock_open, mode, 0 );
674
- will_return( mock_open, pid_file_fd );
675
-
676
- // Test if correctly read.
677
- expect_value( mock_read, fd, pid_file_fd );
678
- expect_not_value( mock_read, buf, NULL );
679
- expect_value( mock_read, count, 10 - 1 );
680
- char valid_pid_string[] = "123\n";
681
- pid_t valid_pid = 123;
682
- read_buffer = valid_pid_string;
683
- read_length = strlen( valid_pid_string );
684
- will_return( mock_read, read_length );
685
-
686
- // Test if correctly kill.
687
- expect_value( mock_kill, pid, valid_pid );
688
- expect_value( mock_kill, sig, 0 );
689
- will_return( mock_kill, 0 );
690
-
691
- // Test if correctly close.
692
- expect_value( mock_close, fd, pid_file_fd );
693
-
694
- // Test if correctly readlink.
695
- char proc_path[] = "/proc/123/exe";
696
- expect_string( mock_readlink, path, proc_path );
697
- expect_not_value( mock_readlink, buf, NULL );
698
- expect_value( mock_readlink, bufsiz, PATH_MAX - 1 );
699
- char INVALID_exe_path[] = "/home/yasuhito/trema/bin/chess2";
700
- link_buffer = INVALID_exe_path;
701
- link_length = strlen( INVALID_exe_path );
702
- will_return( mock_readlink, link_length );
703
-
704
- // Test if correctly basename.
705
- expect_string( mock_basename, path, INVALID_exe_path );
706
- will_return( mock_basename, strdup( "chess2" ) );
707
-
708
- // Go
709
- pid_t pid = read_pid( "/home/yasuhito/trema/tmp", "chess" );
710
- assert_true( pid == -1 );
711
- }
712
-
713
-
714
661
  static void
715
662
  test_rename_pid_successed() {
716
663
  // Test if correctly unlink.
@@ -781,7 +728,6 @@ main() {
781
728
  unit_test( test_read_pid_fail_if_kill_fail_with_ESRCH ),
782
729
  unit_test( test_read_pid_fail_if_kill_fail_with_EPERM ),
783
730
  unit_test( test_read_pid_fail_if_readlink_fail ),
784
- unit_test( test_read_pid_fail_if_strcmp_fail ),
785
731
 
786
732
  // rename_pid() tests.
787
733
  unit_test( test_rename_pid_successed ),
@@ -3476,6 +3476,52 @@ test_delete_openflow_messages_if_clear_send_queue_fails() {
3476
3476
  }
3477
3477
 
3478
3478
 
3479
+ /********************************************************************************
3480
+ * disconnect_switch() tests.
3481
+ ********************************************************************************/
3482
+
3483
+ static void
3484
+ test_disconnect_switch() {
3485
+ size_t expected_length = ( size_t ) ( sizeof( openflow_service_header_t ) + strlen( SERVICE_NAME ) + 1 );
3486
+ void *expected_data = xcalloc( 1, expected_length );
3487
+ openflow_service_header_t *header = expected_data;
3488
+ header->datapath_id = htonll( DATAPATH_ID );
3489
+ header->service_name_length = htons( ( uint16_t ) ( strlen( SERVICE_NAME ) + 1 ) );
3490
+ memcpy( ( char * ) expected_data + sizeof( openflow_service_header_t ), SERVICE_NAME, strlen( SERVICE_NAME ) + 1 );
3491
+
3492
+ expect_string( mock_send_message, service_name, REMOTE_SERVICE_NAME );
3493
+ expect_value( mock_send_message, tag32, MESSENGER_OPENFLOW_DISCONNECT_REQUEST );
3494
+ expect_value( mock_send_message, len, expected_length );
3495
+ expect_memory( mock_send_message, data, expected_data, expected_length );
3496
+ will_return( mock_send_message, true );
3497
+
3498
+ assert_true( disconnect_switch( DATAPATH_ID ) );
3499
+
3500
+ xfree( expected_data );
3501
+ }
3502
+
3503
+
3504
+ static void
3505
+ test_disconnect_switch_if_send_message_fails() {
3506
+ size_t expected_length = ( size_t ) ( sizeof( openflow_service_header_t ) + strlen( SERVICE_NAME ) + 1 );
3507
+ void *expected_data = xcalloc( 1, expected_length );
3508
+ openflow_service_header_t *header = expected_data;
3509
+ header->datapath_id = htonll( DATAPATH_ID );
3510
+ header->service_name_length = htons( ( uint16_t ) ( strlen( SERVICE_NAME ) + 1 ) );
3511
+ memcpy( ( char * ) expected_data + sizeof( openflow_service_header_t ), SERVICE_NAME, strlen( SERVICE_NAME ) + 1 );
3512
+
3513
+ expect_string( mock_send_message, service_name, REMOTE_SERVICE_NAME );
3514
+ expect_value( mock_send_message, tag32, MESSENGER_OPENFLOW_DISCONNECT_REQUEST );
3515
+ expect_value( mock_send_message, len, expected_length );
3516
+ expect_memory( mock_send_message, data, expected_data, expected_length );
3517
+ will_return( mock_send_message, false );
3518
+
3519
+ assert_false( disconnect_switch( DATAPATH_ID ) );
3520
+
3521
+ xfree( expected_data );
3522
+ }
3523
+
3524
+
3479
3525
  /********************************************************************************
3480
3526
  * Run tests.
3481
3527
  ********************************************************************************/
@@ -3650,6 +3696,10 @@ main() {
3650
3696
  // delete_openflow_messages() tests.
3651
3697
  unit_test_setup_teardown( test_delete_openflow_messages, init, cleanup ),
3652
3698
  unit_test_setup_teardown( test_delete_openflow_messages_if_clear_send_queue_fails, init, cleanup ),
3699
+
3700
+ // disconnect_switch() tests.
3701
+ unit_test_setup_teardown( test_disconnect_switch, init, cleanup ),
3702
+ unit_test_setup_teardown( test_disconnect_switch_if_send_message_fails, init, cleanup ),
3653
3703
  };
3654
3704
  return run_tests( tests );
3655
3705
  }
@@ -833,11 +833,11 @@ test_get_executable_name() {
833
833
 
834
834
 
835
835
  /********************************************************************************
836
- * get_trema_process_from_name() tests.
836
+ * get_pid_by_trema_name() tests.
837
837
  *******************************************************************************/
838
838
 
839
839
  static void
840
- test_get_trema_process_from_name() {
840
+ test_get_pid_by_trema_name() {
841
841
  char NAME[] = "test_name";
842
842
  char TEMP_DIRECTORY[] = "/tmp";
843
843
  char PID_DIRECTORY[] = "/tmp/pid";
@@ -848,7 +848,7 @@ test_get_trema_process_from_name() {
848
848
  will_return( mock_read_pid, PID );
849
849
 
850
850
  // Go
851
- pid_t pid = get_trema_process_from_name( NAME );
851
+ pid_t pid = get_pid_by_trema_name( NAME );
852
852
  assert_true( pid == PID );
853
853
  unset_trema_tmp();
854
854
  }
@@ -990,8 +990,8 @@ main() {
990
990
  // get_executable_name() test.
991
991
  unit_test_setup_teardown( test_get_executable_name, reset_trema, reset_trema ),
992
992
 
993
- // get_trema_process_from_name() test.
994
- unit_test_setup_teardown( test_get_trema_process_from_name, reset_trema, reset_trema ),
993
+ // get_pid_by_trema_name() test.
994
+ unit_test_setup_teardown( test_get_pid_by_trema_name, reset_trema, reset_trema ),
995
995
 
996
996
  // terminate_trema_process() test.
997
997
  unit_test_setup_teardown( test_terminate_trema_process_when_was_found, reset_trema, reset_trema ),
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trema
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 14
10
- version: 0.3.14
9
+ - 15
10
+ version: 0.3.15
11
11
  platform: ruby
12
12
  authors:
13
13
  - Yasuhito Takamiya
@@ -15,27 +15,23 @@ autorequire:
15
15
  bindir: .
16
16
  cert_chain: []
17
17
 
18
- date: 2013-02-18 00:00:00 Z
18
+ date: 2013-03-04 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- prerelease: false
22
- name: bundler
23
21
  version_requirements: &id001 !ruby/object:Gem::Requirement
24
22
  none: false
25
23
  requirements:
26
- - - ~>
24
+ - - ">="
27
25
  - !ruby/object:Gem::Version
28
- hash: 25
26
+ hash: 3
29
27
  segments:
30
- - 1
31
- - 2
32
- - 3
33
- version: 1.2.3
28
+ - 0
29
+ version: "0"
30
+ name: bundler
31
+ prerelease: false
34
32
  type: :runtime
35
33
  requirement: *id001
36
34
  - !ruby/object:Gem::Dependency
37
- prerelease: false
38
- name: gli
39
35
  version_requirements: &id002 !ruby/object:Gem::Requirement
40
36
  none: false
41
37
  requirements:
@@ -47,11 +43,11 @@ dependencies:
47
43
  - 5
48
44
  - 4
49
45
  version: 2.5.4
46
+ name: gli
47
+ prerelease: false
50
48
  type: :runtime
51
49
  requirement: *id002
52
50
  - !ruby/object:Gem::Dependency
53
- prerelease: false
54
- name: rake
55
51
  version_requirements: &id003 !ruby/object:Gem::Requirement
56
52
  none: false
57
53
  requirements:
@@ -63,22 +59,24 @@ dependencies:
63
59
  - 0
64
60
  - 3
65
61
  version: 10.0.3
62
+ name: rake
63
+ prerelease: false
66
64
  type: :runtime
67
65
  requirement: *id003
68
66
  - !ruby/object:Gem::Dependency
69
- prerelease: false
70
- name: rdoc
71
67
  version_requirements: &id004 !ruby/object:Gem::Requirement
72
68
  none: false
73
69
  requirements:
74
70
  - - ~>
75
71
  - !ruby/object:Gem::Version
76
- hash: 53
72
+ hash: 63
77
73
  segments:
78
- - 3
79
- - 12
80
- - 1
81
- version: 3.12.1
74
+ - 4
75
+ - 0
76
+ - 0
77
+ version: 4.0.0
78
+ name: rdoc
79
+ prerelease: false
82
80
  type: :runtime
83
81
  requirement: *id004
84
82
  description: Trema is a full-stack, easy-to-use framework for developing OpenFlow controllers in Ruby and C.
@@ -108,6 +106,7 @@ files:
108
106
  - cruise.rb
109
107
  - features/.nav
110
108
  - features/README.md
109
+ - features/core/get_pid_by_trema_name.feature
111
110
  - features/core/packetin_filter.feature
112
111
  - features/core/switch_manager.feature
113
112
  - features/core/trema-config.feature
@@ -182,6 +181,9 @@ files:
182
181
  - ruby/trema/controller.rb
183
182
  - ruby/trema/custom-switch.rb
184
183
  - ruby/trema/daemon.rb
184
+ - ruby/trema/default-logger.c
185
+ - ruby/trema/default-logger.h
186
+ - ruby/trema/default-logger.rb
185
187
  - ruby/trema/desc-stats-reply.rb
186
188
  - ruby/trema/dsl.rb
187
189
  - ruby/trema/dsl/configuration.rb
@@ -232,9 +234,6 @@ files:
232
234
  - ruby/trema/link.rb
233
235
  - ruby/trema/list-switches-reply.c
234
236
  - ruby/trema/list-switches-reply.h
235
- - ruby/trema/logger.c
236
- - ruby/trema/logger.h
237
- - ruby/trema/logger.rb
238
237
  - ruby/trema/mac.rb
239
238
  - ruby/trema/match.c
240
239
  - ruby/trema/match.h
@@ -338,6 +337,7 @@ files:
338
337
  - spec/trema/barrier-request_spec.rb
339
338
  - spec/trema/cli_spec.rb
340
339
  - spec/trema/controller_spec.rb
340
+ - spec/trema/default-logger_spec.rb
341
341
  - spec/trema/dsl/configuration_spec.rb
342
342
  - spec/trema/dsl/link_spec.rb
343
343
  - spec/trema/dsl/run_spec.rb
@@ -363,7 +363,6 @@ files:
363
363
  - spec/trema/ip_spec.rb
364
364
  - spec/trema/link_spec.rb
365
365
  - spec/trema/list-switches-reply_spec.rb
366
- - spec/trema/logger_spec.rb
367
366
  - spec/trema/mac_spec.rb
368
367
  - spec/trema/match_spec.rb
369
368
  - spec/trema/open-vswitch_spec.rb