trema 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -0
- data/CONTRIBUTING.md +12 -0
- data/Gemfile +5 -3
- data/README.md +3 -3
- data/Rakefile +30 -14
- data/bin/trema +3 -0
- data/cruise.rb +1 -1
- data/features/examples/switch_monitor.feature +2 -2
- data/features/switch_event/add_forward_entry.feature +0 -1
- data/features/switch_event/delete_forward_entry.feature +0 -1
- data/features/switch_event/dump_forward_entries.feature +0 -1
- data/features/switch_event/set_forward_entries.feature +0 -1
- data/ruby/trema/command/run.rb +3 -0
- data/ruby/trema/dsl/runner.rb +1 -0
- data/ruby/trema/mac.rb +4 -145
- data/ruby/trema/match.c +8 -8
- data/ruby/trema/packet-in.c +12 -12
- data/ruby/trema/port-mod.c +7 -4
- data/ruby/trema/port.c +4 -1
- data/ruby/trema/set-eth-dst-addr.rb +3 -5
- data/ruby/trema/set-eth-src-addr.rb +5 -6
- data/ruby/trema/stats-reply.c +1 -1
- data/ruby/trema/switch-event.c +10 -10
- data/ruby/trema/trema.c +3 -0
- data/ruby/trema/version.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/trema/packet-in_spec.rb +2 -2
- data/spec/trema/set-eth-addr_spec.rb +5 -43
- data/src/examples/learning_switch/learning-switch.rb +2 -0
- data/src/lib/daemon.c +37 -22
- data/src/lib/log.c +31 -0
- data/src/lib/messenger.c +13 -5
- data/src/lib/trema.c +6 -5
- data/src/switch_manager/switch.c +178 -41
- data/src/switch_manager/switchinfo.h +6 -2
- data/trema.gemspec +3 -3
- data/unittests/lib/daemon_test.c +36 -36
- data/unittests/lib/trema_test.c +25 -8
- metadata +124 -96
- checksums.yaml +0 -7
- data/spec/trema/mac_spec.rb +0 -100
data/ruby/trema/packet-in.c
CHANGED
@@ -29,7 +29,7 @@ VALUE cPacketIn;
|
|
29
29
|
#define PACKET_IN_RETURN_MAC( packet_member ) \
|
30
30
|
{ \
|
31
31
|
VALUE ret = ULL2NUM( mac_to_uint64( get_packet_in_info( self )->packet_member ) ); \
|
32
|
-
return rb_funcall( rb_eval_string( "
|
32
|
+
return rb_funcall( rb_eval_string( "Pio::Mac" ), rb_intern( "new" ), 1, ret ); \
|
33
33
|
}
|
34
34
|
|
35
35
|
#define PACKET_IN_RETURN_IP( packet_member ) \
|
@@ -209,7 +209,7 @@ packet_in_reason( VALUE self ) {
|
|
209
209
|
/*
|
210
210
|
* The source MAC address.
|
211
211
|
*
|
212
|
-
* @return [
|
212
|
+
* @return [Mac] the value of source MAC address as a Mac object.
|
213
213
|
*/
|
214
214
|
static VALUE
|
215
215
|
packet_in_macsa( VALUE self ) {
|
@@ -220,7 +220,7 @@ packet_in_macsa( VALUE self ) {
|
|
220
220
|
/*
|
221
221
|
* The destination MAC address.
|
222
222
|
*
|
223
|
-
* @return [
|
223
|
+
* @return [Mac] the value of destination MAC address as a
|
224
224
|
* Trema::MAC object.
|
225
225
|
*/
|
226
226
|
static VALUE
|
@@ -373,8 +373,8 @@ packet_in_arp_oper( VALUE self ) {
|
|
373
373
|
/*
|
374
374
|
* The ARP source hardware address of a packet.
|
375
375
|
*
|
376
|
-
* @return [
|
377
|
-
* the value of the ARP source hardware address as a
|
376
|
+
* @return [Mac, nil]
|
377
|
+
* the value of the ARP source hardware address as a Mac object or nil
|
378
378
|
* if packet not an ARP.
|
379
379
|
*/
|
380
380
|
static VALUE
|
@@ -409,8 +409,8 @@ packet_in_arp_spa( VALUE self ) {
|
|
409
409
|
/*
|
410
410
|
* The ARP target hardware address of a packet.
|
411
411
|
*
|
412
|
-
* @return [
|
413
|
-
* the value of ARP target hardware address as a
|
412
|
+
* @return [Mac]
|
413
|
+
* the value of ARP target hardware address as a Mac object or nil if
|
414
414
|
* packet is not an ARP.
|
415
415
|
*/
|
416
416
|
static VALUE
|
@@ -504,8 +504,8 @@ packet_in_rarp_oper( VALUE self ) {
|
|
504
504
|
/*
|
505
505
|
* The RARP source hardware address of a packet.
|
506
506
|
*
|
507
|
-
* @return [
|
508
|
-
* the value of the RARP source hardware address as a
|
507
|
+
* @return [Mac, nil]
|
508
|
+
* the value of the RARP source hardware address as a Mac object or nil
|
509
509
|
* if packet not an RARP.
|
510
510
|
*/
|
511
511
|
static VALUE
|
@@ -540,8 +540,8 @@ packet_in_rarp_spa( VALUE self ) {
|
|
540
540
|
/*
|
541
541
|
* The RARP target hardware address of a packet.
|
542
542
|
*
|
543
|
-
* @return [
|
544
|
-
* the value of RARP target hardware address as a
|
543
|
+
* @return [Mac]
|
544
|
+
* the value of RARP target hardware address as a Mac object or nil if
|
545
545
|
* packet is not an RARP.
|
546
546
|
*/
|
547
547
|
static VALUE
|
@@ -1230,7 +1230,7 @@ void
|
|
1230
1230
|
Init_packet_in() {
|
1231
1231
|
rb_require( "rubygems" );
|
1232
1232
|
rb_require( "pio" );
|
1233
|
-
|
1233
|
+
|
1234
1234
|
mTrema = rb_eval_string( "Trema" );
|
1235
1235
|
cPacketIn = rb_define_class_under( mTrema, "PacketIn", rb_cObject );
|
1236
1236
|
rb_define_alloc_func( cPacketIn, packet_in_alloc );
|
data/ruby/trema/port-mod.c
CHANGED
@@ -57,7 +57,7 @@ port_mod_alloc( VALUE kclass ) {
|
|
57
57
|
* @param [Number] :port_no
|
58
58
|
* an index into datapath's ports list.
|
59
59
|
*
|
60
|
-
* @param [String,Number,
|
60
|
+
* @param [String,Number,Mac] :hw_addr
|
61
61
|
* the hardware address of a port.
|
62
62
|
* Unique for each port. Obtained from +OFPT_FEATURES_REPLY+ message.
|
63
63
|
* Can be supplied as a string, number or as a Mac object.
|
@@ -92,9 +92,9 @@ port_mod_init( int argc, VALUE *argv, VALUE self ) {
|
|
92
92
|
mac = hw_addr;
|
93
93
|
if ( rb_obj_is_kind_of( hw_addr, rb_cString ) == Qtrue ||
|
94
94
|
rb_obj_is_kind_of( hw_addr, rb_cInteger ) == Qtrue ) {
|
95
|
-
mac = rb_funcall( rb_eval_string( "
|
95
|
+
mac = rb_funcall( rb_eval_string( "Pio::Mac" ), rb_intern( "new" ), 1, hw_addr );
|
96
96
|
}
|
97
|
-
else if ( rb_obj_is_instance_of( hw_addr, rb_eval_string( "
|
97
|
+
else if ( rb_obj_is_instance_of( hw_addr, rb_eval_string( "Pio::Mac" ) ) == Qfalse ) {
|
98
98
|
rb_raise( rb_eArgError, "hw_addr must be a string or an integer or Mac object" );
|
99
99
|
}
|
100
100
|
ptr = ( uint8_t * ) dl_addr_to_a( mac, haddr );
|
@@ -159,7 +159,7 @@ port_mod_port_no( VALUE self ) {
|
|
159
159
|
|
160
160
|
|
161
161
|
/*
|
162
|
-
* Ethernet address converted and stored as a {
|
162
|
+
* Ethernet address converted and stored as a {Mac} object.
|
163
163
|
*
|
164
164
|
* @return [Mac] the value of hw_addr.
|
165
165
|
*/
|
@@ -208,6 +208,9 @@ port_mod_advertise( VALUE self ) {
|
|
208
208
|
*/
|
209
209
|
void
|
210
210
|
Init_port_mod() {
|
211
|
+
rb_require( "rubygems" );
|
212
|
+
rb_require( "pio" );
|
213
|
+
|
211
214
|
mTrema = rb_eval_string( "Trema" );
|
212
215
|
cPortMod = rb_define_class_under( mTrema, "PortMod", rb_cObject );
|
213
216
|
rb_define_alloc_func( cPortMod, port_mod_alloc );
|
data/ruby/trema/port.c
CHANGED
@@ -301,6 +301,9 @@ port_compare( VALUE self, VALUE other ) {
|
|
301
301
|
*/
|
302
302
|
void
|
303
303
|
Init_port() {
|
304
|
+
rb_require( "rubygems" );
|
305
|
+
rb_require( "pio" );
|
306
|
+
|
304
307
|
mTrema = rb_eval_string( "Trema" );
|
305
308
|
cPort = rb_define_class_under( mTrema, "Port", rb_cObject );
|
306
309
|
|
@@ -354,7 +357,7 @@ VALUE
|
|
354
357
|
port_from( const struct ofp_phy_port *phy_port ) {
|
355
358
|
VALUE attributes = rb_hash_new();
|
356
359
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "number" ) ), UINT2NUM( phy_port->port_no ) );
|
357
|
-
VALUE hw_addr = rb_funcall( rb_eval_string( "
|
360
|
+
VALUE hw_addr = rb_funcall( rb_eval_string( "Pio::Mac" ), rb_intern( "new" ), 1, ULL2NUM( mac_to_uint64( phy_port->hw_addr ) ) );
|
358
361
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "hw_addr" ) ), hw_addr );
|
359
362
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "name" ) ), rb_str_new2( phy_port->name ) );
|
360
363
|
rb_hash_aset( attributes, ID2SYM( rb_intern( "config" ) ), UINT2NUM( phy_port->config ) );
|
@@ -32,14 +32,12 @@ module Trema
|
|
32
32
|
# @example
|
33
33
|
# SetEthDstAddr.new("11:22:33:44:55:66")
|
34
34
|
# SetEthDstAddr.new(0x112233445566)
|
35
|
-
# SetEthDstAddr.new(
|
35
|
+
# SetEthDstAddr.new(Mac.new("11:22:33:44:55:66"))
|
36
|
+
# SetEthDstAddr.new(Mac.new(0x112233445566))
|
36
37
|
#
|
37
|
-
# @param [
|
38
|
+
# @param mac_address [#to_str, #to_int]
|
38
39
|
# the Ethernet address to create this action with.
|
39
40
|
#
|
40
|
-
# @raise [ArgumentError] if invalid format is detected.
|
41
|
-
# @raise [TypeError] if supplied argument is not a String or Integer or Mac.
|
42
|
-
#
|
43
41
|
end
|
44
42
|
|
45
43
|
|
@@ -25,21 +25,20 @@ module Trema
|
|
25
25
|
#
|
26
26
|
class SetEthSrcAddr < SetEthAddr
|
27
27
|
#
|
28
|
-
# Creates an action to modify the source Ethernet address of a
|
28
|
+
# Creates an action to modify the source Ethernet address of a
|
29
|
+
# packet.
|
29
30
|
#
|
30
31
|
# @overload initialize(mac_address)
|
31
32
|
#
|
32
33
|
# @example
|
33
34
|
# SetEthSrcAddr.new("11:22:33:44:55:66")
|
34
35
|
# SetEthSrcAddr.new(0x112233445566)
|
35
|
-
# SetEthSrcAddr.new(
|
36
|
+
# SetEthSrcAddr.new(Mac.new("11:22:33:44:55:66"))
|
37
|
+
# SetEthSrcAddr.new(Mac.new(0x112233445566))
|
36
38
|
#
|
37
|
-
# @param [
|
39
|
+
# @param mac_address [#to_str, #to_int]
|
38
40
|
# the Ethernet address to create this action with.
|
39
41
|
#
|
40
|
-
# @raise [ArgumentError] if invalid format is detected.
|
41
|
-
# @raise [TypeError] if supplied argument is not a String or Integer or Mac.
|
42
|
-
#
|
43
42
|
end
|
44
43
|
|
45
44
|
|
data/ruby/trema/stats-reply.c
CHANGED
@@ -213,7 +213,7 @@ get_action( const struct ofp_action_header *ah ) {
|
|
213
213
|
VALUE mac_address;
|
214
214
|
const struct ofp_action_dl_addr *action_dl_addr = ( const struct ofp_action_dl_addr * ) ah;
|
215
215
|
|
216
|
-
mac_address = rb_funcall( rb_eval_string( "
|
216
|
+
mac_address = rb_funcall( rb_eval_string( "Pio::Mac" ), rb_intern( "new" ), 1, ULL2NUM( mac_to_uint64( action_dl_addr->dl_addr ) ) );
|
217
217
|
if ( ah->type == OFPAT_SET_DL_SRC ) {
|
218
218
|
action = rb_funcall( rb_eval_string( "Trema::SetEthSrcAddr" ), rb_intern( "new" ), 1, mac_address );
|
219
219
|
}
|
data/ruby/trema/switch-event.c
CHANGED
@@ -110,7 +110,7 @@ add_forward_entry_to_all_switches( VALUE self, VALUE type, VALUE service_name )
|
|
110
110
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
111
111
|
cb->self = self;
|
112
112
|
cb->block = Qnil;
|
113
|
-
if ( rb_block_given_p()
|
113
|
+
if ( rb_block_given_p() ) {
|
114
114
|
cb->block = rb_block_proc();
|
115
115
|
}
|
116
116
|
bool succ = add_event_forward_entry_to_all_switches(
|
@@ -159,7 +159,7 @@ delete_forward_entry_from_all_switches( VALUE self, VALUE type,
|
|
159
159
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
160
160
|
cb->self = self;
|
161
161
|
cb->block = Qnil;
|
162
|
-
if ( rb_block_given_p()
|
162
|
+
if ( rb_block_given_p() ) {
|
163
163
|
cb->block = rb_block_proc();
|
164
164
|
}
|
165
165
|
bool succ = delete_event_forward_entry_to_all_switches(
|
@@ -235,7 +235,7 @@ add_forward_entry_to_switch( VALUE self, VALUE dpid, VALUE type,
|
|
235
235
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
236
236
|
cb->self = self;
|
237
237
|
cb->block = Qnil;
|
238
|
-
if ( rb_block_given_p()
|
238
|
+
if ( rb_block_given_p() ) {
|
239
239
|
cb->block = rb_block_proc();
|
240
240
|
}
|
241
241
|
bool succ = add_switch_event_forward_entry(
|
@@ -287,7 +287,7 @@ delete_forward_entry_from_switch( VALUE self, VALUE dpid, VALUE type,
|
|
287
287
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
288
288
|
cb->self = self;
|
289
289
|
cb->block = Qnil;
|
290
|
-
if ( rb_block_given_p()
|
290
|
+
if ( rb_block_given_p() ) {
|
291
291
|
cb->block = rb_block_proc();
|
292
292
|
}
|
293
293
|
bool succ = delete_switch_event_forward_entry(
|
@@ -345,7 +345,7 @@ set_forward_entries_to_switch( VALUE self, VALUE dpid, VALUE type,
|
|
345
345
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
346
346
|
cb->self = self;
|
347
347
|
cb->block = Qnil;
|
348
|
-
if ( rb_block_given_p()
|
348
|
+
if ( rb_block_given_p() ) {
|
349
349
|
cb->block = rb_block_proc();
|
350
350
|
}
|
351
351
|
bool succ = set_switch_event_forward_entries(
|
@@ -393,7 +393,7 @@ dump_forward_entries_from_switch( VALUE self, VALUE dpid, VALUE type ) {
|
|
393
393
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
394
394
|
cb->self = self;
|
395
395
|
cb->block = Qnil;
|
396
|
-
if ( rb_block_given_p()
|
396
|
+
if ( rb_block_given_p() ) {
|
397
397
|
cb->block = rb_block_proc();
|
398
398
|
}
|
399
399
|
bool succ = dump_switch_event_forward_entries(
|
@@ -443,7 +443,7 @@ add_forward_entry_to_switch_manager( VALUE self, VALUE type,
|
|
443
443
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
444
444
|
cb->self = self;
|
445
445
|
cb->block = Qnil;
|
446
|
-
if ( rb_block_given_p()
|
446
|
+
if ( rb_block_given_p() ) {
|
447
447
|
cb->block = rb_block_proc();
|
448
448
|
}
|
449
449
|
bool succ = add_switch_manager_event_forward_entry(
|
@@ -493,7 +493,7 @@ delete_forward_entry_from_switch_manager( VALUE self, VALUE type,
|
|
493
493
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
494
494
|
cb->self = self;
|
495
495
|
cb->block = Qnil;
|
496
|
-
if ( rb_block_given_p()
|
496
|
+
if ( rb_block_given_p() ) {
|
497
497
|
cb->block = rb_block_proc();
|
498
498
|
}
|
499
499
|
bool succ = delete_switch_manager_event_forward_entry(
|
@@ -549,7 +549,7 @@ set_forward_entries_to_switch_manager( VALUE self, VALUE type,
|
|
549
549
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
550
550
|
cb->self = self;
|
551
551
|
cb->block = Qnil;
|
552
|
-
if ( rb_block_given_p()
|
552
|
+
if ( rb_block_given_p() ) {
|
553
553
|
cb->block = rb_block_proc();
|
554
554
|
}
|
555
555
|
bool succ = set_switch_manager_event_forward_entries(
|
@@ -594,7 +594,7 @@ dump_forward_entries_from_switch_manager( VALUE self, VALUE type ) {
|
|
594
594
|
callback_info *cb = xcalloc( 1, sizeof( callback_info ) );
|
595
595
|
cb->self = self;
|
596
596
|
cb->block = Qnil;
|
597
|
-
if ( rb_block_given_p()
|
597
|
+
if ( rb_block_given_p() ) {
|
598
598
|
cb->block = rb_block_proc();
|
599
599
|
}
|
600
600
|
bool succ = dump_switch_manager_event_forward_entries(
|
data/ruby/trema/trema.c
CHANGED
@@ -79,6 +79,9 @@ Init_trema() {
|
|
79
79
|
rb_define_const( mTrema, "OFPAT_ENQUEUE", INT2NUM( OFPAT_ENQUEUE ) );
|
80
80
|
rb_define_const( mTrema, "OFPAT_VENDOR", INT2NUM( OFPAT_VENDOR ) );
|
81
81
|
|
82
|
+
rb_require( "rubygems" );
|
83
|
+
rb_require( "pio" );
|
84
|
+
rb_require( "trema/mac" );
|
82
85
|
rb_require( "trema/host" );
|
83
86
|
rb_require( "trema/openflow-switch" );
|
84
87
|
rb_require( "trema/path" );
|
data/ruby/trema/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -78,9 +78,9 @@ describe Trema::PacketIn do
|
|
78
78
|
expect( message.data ).to be_instance_of( String )
|
79
79
|
expect( message.buffered? ).to be_false
|
80
80
|
|
81
|
-
expect( message.macsa ).to be_instance_of(
|
81
|
+
expect( message.macsa ).to be_instance_of( Pio::Mac )
|
82
82
|
expect( message.macsa.to_s ).to eq( "00:00:00:00:00:01" )
|
83
|
-
expect( message.macda ).to be_instance_of(
|
83
|
+
expect( message.macda ).to be_instance_of( Pio::Mac )
|
84
84
|
expect( message.macda.to_s ).to eq( "00:00:00:00:00:02" )
|
85
85
|
|
86
86
|
expect( message.eth_type ).to eq( 0x0800 )
|
@@ -21,21 +21,16 @@ require "trema"
|
|
21
21
|
|
22
22
|
|
23
23
|
[ SetEthSrcAddr, SetEthDstAddr ].each do | klass |
|
24
|
-
describe klass, "
|
24
|
+
describe klass, ".new", :type => "actions" do
|
25
25
|
subject { klass.new( mac_address ) }
|
26
26
|
|
27
27
|
|
28
|
-
context
|
29
|
-
let( :mac_address ) { "52:54:00:a8:ad:8c" }
|
30
|
-
|
31
|
-
its( "mac_address.to_s" ) { should eq( "52:54:00:a8:ad:8c" ) }
|
32
|
-
its( :to_s ) { should eq( "#{ klass.to_s }: mac_address=52:54:00:a8:ad:8c" ) }
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
context "with mac_address (11:22:33:44:55:66)" do
|
28
|
+
context %{with "11:22:33:44:55:66"} do
|
37
29
|
let( :mac_address ) { "11:22:33:44:55:66" }
|
38
30
|
|
31
|
+
its( :mac_address ) { should eq "11:22:33:44:55:66" }
|
32
|
+
its( :to_s ) { should eq "#{ klass.to_s }: mac_address=11:22:33:44:55:66" }
|
33
|
+
|
39
34
|
context "when set as FlowMod's action", :sudo => true do
|
40
35
|
it "should insert a new flow with action (mod_dl_{src,dst}:11:22:33:44:55:66)" do
|
41
36
|
class TestController < Controller; end
|
@@ -56,39 +51,6 @@ require "trema"
|
|
56
51
|
end
|
57
52
|
end
|
58
53
|
end
|
59
|
-
|
60
|
-
|
61
|
-
context %q{with mac_address (Mac.new("52:54:00:a8:ad:8c"))} do
|
62
|
-
let( :mac_address ) { Mac.new("52:54:00:a8:ad:8c") }
|
63
|
-
|
64
|
-
its( "mac_address.to_s" ) { should eq( "52:54:00:a8:ad:8c" ) }
|
65
|
-
its( :to_s ) { should eq( "#{ klass.to_s }: mac_address=52:54:00:a8:ad:8c" ) }
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
|
-
context "with mac_address (0x525400a8ad8c)" do
|
70
|
-
let( :mac_address ) { 0x525400a8ad8c }
|
71
|
-
|
72
|
-
its( "mac_address.to_s" ) { should eq( "52:54:00:a8:ad:8c" ) }
|
73
|
-
its( :to_s ) { should eq( "#{ klass.to_s }: mac_address=52:54:00:a8:ad:8c" ) }
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
context %q{with invalid mac_address ("INVALID MAC STRING")} do
|
78
|
-
let( :mac_address ) { "INVALID MAC STRING" }
|
79
|
-
|
80
|
-
it { expect { subject }.to raise_error( ArgumentError ) }
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
context "with invalid mac_address ([1, 2, 3])" do
|
85
|
-
let( :mac_address ) { [ 1, 2, 3 ] }
|
86
|
-
|
87
|
-
it { expect { subject }.to raise_error( TypeError ) }
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
it_validates "option is within range", :mac_address, 0..0xffffffffffff
|
92
54
|
end
|
93
55
|
end
|
94
56
|
|
data/src/lib/daemon.c
CHANGED
@@ -34,6 +34,8 @@
|
|
34
34
|
|
35
35
|
#ifdef UNIT_TESTING
|
36
36
|
|
37
|
+
#define static
|
38
|
+
|
37
39
|
#ifdef die
|
38
40
|
#undef die
|
39
41
|
#endif
|
@@ -136,12 +138,6 @@ extern ssize_t mock_readlink( const char *path, char *buf, size_t bufsiz );
|
|
136
138
|
#define basename mock_basename
|
137
139
|
extern char *mock_basename( char *path );
|
138
140
|
|
139
|
-
#ifdef rename
|
140
|
-
#undef rename
|
141
|
-
#endif // rename
|
142
|
-
#define rename mock_rename
|
143
|
-
extern int mock_rename( const char *oldpath, const char *newpath );
|
144
|
-
|
145
141
|
#ifdef warn
|
146
142
|
#undef warn
|
147
143
|
#endif // warn
|
@@ -150,6 +146,9 @@ extern void mock_warn( const char *format, ... );
|
|
150
146
|
|
151
147
|
#endif // UNIT_TESTING
|
152
148
|
|
149
|
+
static const char SWITCH_DAEMON[] = "switch.";
|
150
|
+
static const char SWITCH_DAEMON_EXE_NAME[] = "switch";
|
151
|
+
|
153
152
|
|
154
153
|
void
|
155
154
|
daemonize( const char *home ) {
|
@@ -185,6 +184,8 @@ daemonize( const char *home ) {
|
|
185
184
|
|
186
185
|
static const int PID_STRING_LENGTH = 10;
|
187
186
|
|
187
|
+
static int locked_fd = -1;
|
188
|
+
|
188
189
|
void
|
189
190
|
write_pid( const char *directory, const char *name ) {
|
190
191
|
assert( directory != NULL );
|
@@ -194,22 +195,28 @@ write_pid( const char *directory, const char *name ) {
|
|
194
195
|
snprintf( path, PATH_MAX, "%s/%s.pid", directory, name );
|
195
196
|
path[ PATH_MAX - 1 ] = '\0';
|
196
197
|
|
197
|
-
|
198
|
-
|
198
|
+
if ( locked_fd > -1 ) {
|
199
|
+
close(locked_fd);
|
200
|
+
locked_fd = -1;
|
201
|
+
}
|
202
|
+
|
203
|
+
locked_fd = open( path, O_RDWR | O_CREAT, 0600 );
|
204
|
+
if ( locked_fd == -1 ) {
|
199
205
|
die( "Could not create a PID file: %s", path );
|
200
206
|
}
|
201
207
|
|
202
|
-
if ( lockf(
|
208
|
+
if ( lockf( locked_fd, F_TLOCK, 0 ) == -1 ) {
|
203
209
|
die( "Could not acquire a lock on a PID file: %s", path );
|
204
210
|
}
|
205
211
|
|
206
212
|
char str[ PID_STRING_LENGTH ];
|
207
213
|
snprintf( str, sizeof( str ), "%d\n", getpid() );
|
208
214
|
str[ sizeof( str ) - 1 ] = '\0';
|
209
|
-
ssize_t ret = write(
|
215
|
+
ssize_t ret = write( locked_fd, str, strlen( str ) );
|
210
216
|
if ( ret == -1 ) {
|
211
217
|
die( "Could not write a PID file: %s", path );
|
212
218
|
}
|
219
|
+
debug( "Write pid file ( file = %s, pid = %d )", path, getpid() );
|
213
220
|
}
|
214
221
|
|
215
222
|
|
@@ -224,8 +231,14 @@ unlink_pid( const char *directory, const char *name ) {
|
|
224
231
|
|
225
232
|
int ret = unlink( path );
|
226
233
|
if ( ret < 0 ) {
|
227
|
-
|
234
|
+
if ( errno == ENOENT ) {
|
235
|
+
warn( "PID file %s does not exist", path );
|
236
|
+
}
|
237
|
+
else {
|
238
|
+
die( "Could not remove a PID file: %s", path );
|
239
|
+
}
|
228
240
|
}
|
241
|
+
debug( "Unlink pid file ( file = %s, pid = %d )", path, getpid() );
|
229
242
|
}
|
230
243
|
|
231
244
|
|
@@ -295,6 +308,11 @@ read_pid( const char *directory, const char *name ) {
|
|
295
308
|
return pid;
|
296
309
|
}
|
297
310
|
|
311
|
+
if ( strncmp( name, SWITCH_DAEMON, strlen( SWITCH_DAEMON ) ) == 0 &&
|
312
|
+
strcmp( exe_name, SWITCH_DAEMON_EXE_NAME ) == 0 ) {
|
313
|
+
return pid;
|
314
|
+
}
|
315
|
+
|
298
316
|
// check if -n (service_name) option is used
|
299
317
|
sprintf( proc_path, "/proc/%d/cmdline", pid );
|
300
318
|
fd = open( proc_path, O_RDONLY, 0 );
|
@@ -379,18 +397,15 @@ rename_pid( const char *directory, const char *old, const char *new ) {
|
|
379
397
|
assert( old != NULL );
|
380
398
|
assert( new != NULL );
|
381
399
|
|
382
|
-
|
383
|
-
snprintf( old_path, PATH_MAX, "%s/%s.pid", directory, old );
|
384
|
-
old_path[ PATH_MAX - 1 ] = '\0';
|
385
|
-
char new_path[ PATH_MAX ];
|
386
|
-
snprintf( new_path, PATH_MAX, "%s/%s.pid", directory, new );
|
387
|
-
new_path[ PATH_MAX - 1 ] = '\0';
|
400
|
+
assert( locked_fd > -1 );
|
388
401
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
402
|
+
int old_locked_fd = locked_fd;
|
403
|
+
locked_fd = -1;
|
404
|
+
write_pid( directory, new );
|
405
|
+
close( old_locked_fd );
|
406
|
+
unlink_pid( directory, old );
|
407
|
+
|
408
|
+
debug( "Rename pid file ( old name = %s, new name = %s, pid = %d )", old, new, getpid() );
|
394
409
|
}
|
395
410
|
|
396
411
|
|