trema 0.4.3 → 0.4.4
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 +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
|
|