trema 0.3.14 → 0.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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