diff --git a/chef/cookbooks/barclamp/libraries/nic.rb b/chef/cookbooks/barclamp/libraries/nic.rb index a3562a0cb0..698e99f0ac 100644 --- a/chef/cookbooks/barclamp/libraries/nic.rb +++ b/chef/cookbooks/barclamp/libraries/nic.rb @@ -605,6 +605,15 @@ def miimon=(millisecs) self end + def xmit_hash_policy + sysfs("bonding/xmit_hash_policy").split[0] + end + + def xmit_hash_policy=(xmit_hash_policy) + sysfs_put("bonding/xmit_hash_policy", xmit_hash_policy) + self + end + def down slaves.each{ |s|s.down } super @@ -625,7 +634,7 @@ def destroy nil end - def self.create(nic,mode=6,miimon=100) + def self.create(nic, mode=6, miimon=100, xmit_hash_policy="layer2") Chef::Log.info("Creating new bond #{nic}") if self.exists?(nic) raise ::ArgumentError.new("#{nic} already exists.") @@ -642,6 +651,7 @@ def self.create(nic,mode=6,miimon=100) iface = ::Nic.new(nic) iface.mode = mode iface.miimon = miimon + iface.xmit_hash_policy = xmit_hash_policy iface.up iface end diff --git a/chef/cookbooks/network/recipes/default.rb b/chef/cookbooks/network/recipes/default.rb index da6cef201c..5501423326 100644 --- a/chef/cookbooks/network/recipes/default.rb +++ b/chef/cookbooks/network/recipes/default.rb @@ -192,6 +192,12 @@ def get_datapath_id_for_ovsbridge(bridge) # We want a bond. Figure out what mode it should be. Default to 5 team_mode = conduit_map[conduit]["team_mode"] || (node["network"]["teaming"] && node["network"]["teaming"]["mode"]) || 5 + miimon = conduit_map[network.conduit]["team_miimon"] || + (node["network"]["teaming"] && + node["network"]["teaming"]["miimon"]) || 100 + xmit_hash_policy = conduit_map[network.conduit]["team_xmit_hash_policy"] || + (node["network"]["teaming"] && + node["network"]["teaming"]["xmit_hash_policy"]) || "layer2" # See if a bond that matches our specifications has already been created, # or if there is an empty bond lying around. bond = Nic::Bond.find(base_ifs) @@ -203,7 +209,7 @@ def get_datapath_id_for_ovsbridge(bridge) bond_names = (0..existing_bond_names.length).to_a.map{ |i| "bond#{i}" } new_bond_name = (bond_names - existing_bond_names).first - bond = Nic::Bond.create(new_bond_name, team_mode) + bond = Nic::Bond.create(new_bond_name, team_mode, miimon, xmit_hash_policy) Chef::Log.info("Creating bond #{bond.name} for network #{name}") end ifs[bond.name] ||= Hash.new @@ -217,6 +223,13 @@ def get_datapath_id_for_ovsbridge(bridge) end ifs[bond.name]["mode"] = team_mode ifs[bond.name]["type"] = "bond" + ifs[bond.name]["miimon"] = miimon + ifs[bond.name]["xmit_hash_policy"] = xmit_hash_policy + # Also save miimon and xmit_hash_policy to the NIC object, since that is + # safe to change on the fly, and will be used to write the configuration + # files. + bond.miimon = miimon + bond.xmit_hash_policy = xmit_hash_policy our_iface = bond node.set["crowbar"]["bond_list"] = {} if node["crowbar"]["bond_list"].nil? node.set["crowbar"]["bond_list"][bond.name] = ifs[bond.name]["slaves"] diff --git a/chef/cookbooks/network/templates/default/interfaces.erb b/chef/cookbooks/network/templates/default/interfaces.erb index 2b041fa20b..d2668ef809 100644 --- a/chef/cookbooks/network/templates/default/interfaces.erb +++ b/chef/cookbooks/network/templates/default/interfaces.erb @@ -43,7 +43,8 @@ iface <%= name %> inet manual pre-up test -f /sys/class/net/bonding_masters || modprobe bonding pre-up grep -qw <%=name%> /sys/class/net/bonding_masters || echo +<%=name%> >/sys/class/net/bonding_masters || true pre-up echo <%=i["mode"] %> >/sys/class/net/<%=name%>/bonding/mode || true - pre-up echo 100 >/sys/class/net/<%=name%>/bonding/miimon || true + pre-up echo <%=i["miimon"] %> >/sys/class/net/<%=name%>/bonding/miimon || true + pre-up echo <%=i["xmit_hash_policy"] %> >/sys/class/net/<%=name%>/bonding/xmit_hash_policy || true <% i["slaves"].each do |slave| -%> up ip link set <%=slave%> down up echo +<%=slave%> > /sys/class/net/<%=name%>/bonding/slaves || true diff --git a/chef/cookbooks/network/templates/default/redhat-cfg.erb b/chef/cookbooks/network/templates/default/redhat-cfg.erb index f182011eb3..b329fa806e 100644 --- a/chef/cookbooks/network/templates/default/redhat-cfg.erb +++ b/chef/cookbooks/network/templates/default/redhat-cfg.erb @@ -12,7 +12,7 @@ DELAY=<%=@nic.forward_delay%> STP=no <% end -%> <% when @nic.kind_of?(Nic::Bond) -%> -BONDING_OPTS="miimon=<%=@nic.miimon%> mode=<%=@nic.mode%>" +BONDING_OPTS="miimon=<%=@nic.miimon%> mode=<%=@nic.mode%> xmit_hash_policy=<%=@nic.xmit_hash_policy%>" <% when @nic.kind_of?(Nic::Vlan) -%> VLAN=yes <% when @nic.kind_of?(Nic) -%> @@ -35,4 +35,4 @@ PREFIX<%=(i == 0)?'':(i+1).to_s%>=<%=v4addrs[i].subnet%> <% end -%> <% if iface["gateway"] -%> GATEWAY=<%=iface["gateway"]%> -<% end -%> \ No newline at end of file +<% end -%> diff --git a/chef/cookbooks/network/templates/default/suse-cfg.erb b/chef/cookbooks/network/templates/default/suse-cfg.erb index 7668a86569..4b25ce0bd7 100644 --- a/chef/cookbooks/network/templates/default/suse-cfg.erb +++ b/chef/cookbooks/network/templates/default/suse-cfg.erb @@ -59,7 +59,7 @@ ETHERDEVICE=<%=quote(iface["parent"])%> # Settings specific to bond devices (ifcfg-bonding(5)) when @nic.kind_of?(Nic::Bond) -%> BONDING_MASTER=yes -BONDING_MODULE_OPTS=<%=quote("mode=#{@nic.mode} miimon=#{@nic.miimon}")%> +BONDING_MODULE_OPTS=<%=quote("mode=#{@nic.mode} miimon=#{@nic.miimon} xmit_hash_policy=#{@nic.xmit_hash_policy}")%> <% iface["slaves"].each_with_index do |slave,i| -%> BONDING_SLAVE_<%=i%>=<%=quote(slave)%> <% end -%> diff --git a/chef/data_bags/crowbar/migrate/network/022_add_bonding_miimon_xmit_hash_policy.rb b/chef/data_bags/crowbar/migrate/network/022_add_bonding_miimon_xmit_hash_policy.rb new file mode 100644 index 0000000000..058011398d --- /dev/null +++ b/chef/data_bags/crowbar/migrate/network/022_add_bonding_miimon_xmit_hash_policy.rb @@ -0,0 +1,19 @@ +def upgrade(ta, td, a, d) + unless a["teaming"].key? "miimon" + a["teaming"]["miimon"] = ta["teaming"]["miimon"] + end + unless a["teaming"].key? "xmit_hash_policy" + a["teaming"]["xmit_hash_policy"] = ta["teaming"]["xmit_hash_policy"] + end + return a, d +end + +def downgrade(ta, td, a, d) + unless ta["teaming"].key? "miimon" + a["teaming"].delete "miimon" + end + unless ta["teaming"].key? "xmit_hash_policy" + a["teaming"].delete "xmit_hash_policy" + end + return a, d +end diff --git a/chef/data_bags/crowbar/template-network.json b/chef/data_bags/crowbar/template-network.json index be91aaaa5b..c28dc2ebcb 100644 --- a/chef/data_bags/crowbar/template-network.json +++ b/chef/data_bags/crowbar/template-network.json @@ -8,7 +8,9 @@ "enable_tx_offloading": false, "mode": "single", "teaming": { - "mode": 1 + "mode": 1, + "miimon": 100, + "xmit_hash_policy": "layer2" }, "interface_map": [ { @@ -258,7 +260,7 @@ "network": { "crowbar-revision": 0, "crowbar-applied": false, - "schema-revision": 21, + "schema-revision": 22, "element_states": { "network": [ "readying", "ready", "applying" ] }, diff --git a/chef/data_bags/crowbar/template-network.schema b/chef/data_bags/crowbar/template-network.schema index 1ded181577..94bbbf5d28 100644 --- a/chef/data_bags/crowbar/template-network.schema +++ b/chef/data_bags/crowbar/template-network.schema @@ -20,7 +20,9 @@ "type": "map", "required": true, "mapping": { - "mode": { "type": "int", "required": true } + "mode": { "type": "int", "required": true }, + "miimon": { "type": "int", "required": true }, + "xmit_hash_policy": { "type": "str", "required": true, "pattern": "/^layer2$|^layer2\+3$|^layer3\+4$|^encap2\+3$|^encap3\+4$/" } } }, "interface_map": { @@ -57,6 +59,8 @@ "required": true, "mapping": { "team_mode": { "type": "int" }, + "team_miimon": { "type": "int" }, + "team_xmit_hash_policy": { "type": "str", "pattern": "/^layer2$|^layer2\+3$|^layer3\+4$|^encap2\+3$|^encap3\+4$/" }, "if_list": { "type": "seq", "required": true,