PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/bin
Viewing File: /usr/bin/bond2team
#!/bin/bash # # Translate tool from bonding configuration to team. # # Copyright (C) 2013 Flavio Leitner <fbl@redhat.com> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License, version 2, # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # VERSION="0.97" PR_QUIET=0 PR_ERR=1 PR_WARN=2 PR_INFO=3 PR_DBG=4 #defaults ARGC=$# FORMAT_IFCFG=0 FORMAT_JANSSON=1 OUTPUT_FORMAT=${FORMAT_IFCFG} MODE_IFCFG=0 MODE_NOIFCFG=1 MODE=${MODE_IFCFG} OUTPUT_FILE= RENAME= DEVICE= BOND_MASTER= STDOUT=1 BONDING_OPTS= CONFIGDIR="/etc/sysconfig/network-scripts" PR_LVL=3 OUTPUT_DIR= OUTPUT_TMP_DIR= TMP_FILES=() RUNNER_OPTS=() LWATCH_OPTS=() # array: ( 'port ifname', 'opt1', 'opt2', 'optn', 'opt4', 'port ifname', ... ) PORT_LIST= PORTS_OPTS=() PRIMARY= PRIMARY_RESELECT= # building file scratch memory area VFILE= show_examples() { cat << EOF The following commands will deliver the ifcfg files into a temporary directory. You can review the files and copy to the right location. Add the following argument to the commands below to print the output to the screen instead of writing to files. --stdout Add the following arguments to the commands below to set the destination directory for the output files. --outputdir </path/to/dir> Add the following argument to the commands below to output the files in teamd format (JSON) instead of the default ifcfg format. --json To convert the current "bond0" ifcfg configuration to team ifcfg: # $0 --master bond0 To convert the current "bond0" ifcfg configuration out of the standard ifcfg-: # $0 --master bond0 --configdir </path/to/ifcfg> To convert the current "bond0" ifcfg configuration to team ifcfg renaming the interface name to "team0". (carefull: firewall rules, aliases interfaces, etc., will break after the renaming because the tool will only change the ifcfg file, nothing else) # $0 --master bond0 --rename team0 To convert given bonding parameters without any ifcfg: # $0 --bonding_opts "mode=1 miimon=500" To convert given bonding parameters without any ifcfg with ports: # $0 --bonding_opts "mode=1 miimon=500 primary=eth1 primary_reselect-0" \\ --port eth1 --port eth2 --port eth3 --port eth4 EOF } usage() { cat << EOF usage: $0 [options] This tool translates bonding configuration to team. See bond2team(1) for detailed information. OPTIONS: --master <interface> set the master interface name or ifcfg --rename <iface> rename the master interface to <iface> --ifcfg set the output format to ifcfg style --json set the output format to teamd style --bonding_opts pass the bonding options instead of reading from the ifcfg- file --port <iface> add the interface to the port's list --configdir <dir> set where the ifcfg- files are default: /etc/sysconfig/network-scripts --outputdir <dir> set the output diretory default: temporary diretory --stdout print to stdout instead of modify the system's files. --debug increase debug level --quiet no messages --version show the tool version --help this screen --examples show command examples EOF } # Output Functions pr() { if [ $1 -le $PR_LVL ]; then shift; echo "$*" > /dev/stderr fi } pr_error() { pr ${PR_ERR} "ERROR: " $* } pr_warn() { pr ${PR_WARN} "WARNING: " $* } pr_info() { pr ${PR_INFO} "INFO: " $* } pr_dbg() { pr ${PR_DBG} "DEBUG: " $* } to_stdout() { return ${STDOUT} } create_output_file() { local f=$1 if [ ! -d "${OUTPUT_TMP_DIR}" ]; then OUTPUT_TMP_DIR=$(LANG=C mktemp -d /tmp/bond2team.XXXXXX) fi if [ ! -d "${OUTPUT_TMP_DIR}" ]; then pr_error "${FUNCNAME} can't create dir ${OUTPUT_TMP_DIR}" return 1 fi local tmpfile=${OUTPUT_TMP_DIR}/${f} touch ${tmpfile} if [ ! -f ${tmpfile} ]; then pr_error "${FUNCNAME} can't create file ${tmpfile}" return 1 fi local pos=${#TMP_FILES[*]} TMP_FILES[${pos}]="${tmpfile}" OUTPUT_FILE=${tmpfile} } show_output_files() { echo "" echo "Resulted files:" for tmpf in $(seq 0 $((${#TMP_FILES[@]} - 1))) do echo " ${TMP_FILES[$tmpf]}" done } clean_up() { pr_dbg "${FUNCNAME} $*" for tmpf in $(seq 0 $((${#TMP_FILES[@]} - 1))) do pr_dbg "rm -f ${TMP_FILES[$tmpf]}" rm -f ${TMP_FILES[$tmpf]} done if [ -d "{OUTPUT_TMP_DIR}" ]; then rmdir ${OUTPUT_TMP_DIR} fi } ifcfg_get_device() { local ifcfg=$1 if [ ! -f ${ifcfg} ]; then pr_error "file not found: ${ifcfg}" return 1 fi DEVICE=`LANG=C sed -n \ "s@^[[:space:]]*DEVICE=[\"]*\(.*\)\([[:space:]#]\|\"\|$\)@\1@p" \ $ifcfg` if [ -z "${DEVICE}" ]; then pr_error "ifcfg file not supported: ${ifcfg}" return 1 fi } ifcfg_get_master_file() { local dev=${1} MASTER="${dev}" if [ "${MODE}" -eq "${MODE_NOIFCFG}" ]; then return 0 fi if [ ! -f ${MASTER} ]; then MASTER="${CONFIGDIR}/ifcfg-${dev}" if [ -f ${MASTER} ]; then return 0 fi if [ -n "${BONDING_OPTS}" ]; then # options provided, set noifcfg MODE=${MODE_NOIFCFG} MASTER=${dev} return 0 fi pr_error "Can't find ifcfg file for ${dev}" return 1 fi return 0 } ifcfg_overwrite_files() { pr_dbg "${FUNCNAME} $*" /bin/cp -f ${OUTPUT_TMP_DIR}/ifcfg* ${OUTPUT_DIR} } ifcfg_get_bond_opts() { pr_dbg "${FUNCNAME} $*" local ifcfg=$1 if [ -n "${BONDING_OPTS}" ]; then pr_dbg "${FUNCNAME} bonding_opts=${BONDING_OPTS}" return 0 fi if [ ! -f ${ifcfg} ]; then pr_error "File not found: ${ifcfg}" return 1 fi BONDING_OPTS=`LANG=C sed -n \ "s@^[[:space:]]*BONDING_OPTS=[\"]*\(.*\)\([[:space:]#]\|\"\|$\)@\1@p" \ $ifcfg` if [ -z "${BONDING_OPTS}" ]; then pr_error "ifcfg file not supported: ${MASTER}" return 1 fi pr_dbg "${FUNCNAME} bonding_opts=${BONDING_OPTS}" return 0 } vfile_reset() { VFILE=() } vfile_load_ifcfg() { pr_dbg "${FUNCNAME} $*" local ifcfg=$1 vfile_reset if [ ${MODE} -eq ${MODE_NOIFCFG} ]; then return 0 fi # filter out bonding and team options and # don't break lines with spaces oIFS="$IFS" IFS=$'\n' VFILE=( $(LANG=C \ grep -iv 'BONDING_OPTS\|SLAVE\|MASTER\|DEVICETYPE\|TEAM' \ $ifcfg )) IFS="$oIFS" } vfile_write_to_file() { pr_dbg "${FUNCNAME} $*" local output=$1 for ln in $(seq 0 $((${#VFILE[@]} - 1))) do echo "${VFILE[$ln]}" >> $output done return 0 } ifcfg_dump_stdout() { local dev="${1}" local ifcfg="ifcfg-${dev}" if [ -z "${dev}" ]; then ifcfg="ifcfg-<interface name>" fi for ln in $(seq 0 $((${#VFILE[@]} - 1))) do [ $ln -eq 0 ] && echo "---8<--- ${ifcfg} ---8<---" echo "${VFILE[$ln]}" done echo "---8<--- ${ifcfg} ---8<---" echo "" return 0 } vfile_get_device() { pr_dbg "${FUNCNAME} $*" if [ ${MODE} -eq ${MODE_NOIFCFG} ]; then pr_dbg "${FUNCNAME} using DEVICE=${MASTER}" DEVICE=${MASTER} return 0 fi for ln in $(seq 0 $((${#VFILE[@]} - 1))) do local line=${VFILE[$ln]} if [ "${line%%=*}" = "DEVICE" ]; then local name_line="${line##*=}" local name="${name_line%%[ # ]*}" DEVICE=${name} pr_dbg "${FUNCNAME} from file: DEVICE=${DEVICE}" return 0 fi done pr_error "Failed to find the device's name" return 1 } vfile_get_ipaddr() { for ln in $(seq 0 $((${#VFILE[@]} - 1))) do local line=${VFILE[$ln]} if [ "${line%%=*}" = "IPADDR" ]; then local ipaddr_line="${line##*=}" local ipaddr="${ipaddr_line%%[ # ]*}" echo "${ipaddr}" fi done } vfile_add_line() { pr_dbg "${FUNCNAME} $*" local pos=${#VFILE[*]} VFILE[${pos}]="$1" } ifcfg_device_rename() { local device=$1 local rename=$2 # neither device nor rename was provided if [ -z "${rename}" ]; then return 0 fi # renaming with no ifcfg? if [ ${MODE} -eq ${MODE_NOIFCFG} ]; then return 0 fi for ln in $(seq 0 $((${#VFILE[@]} - 1))) do local line=${VFILE[$ln]} if [ "${line%%=*}" = "DEVICE" ]; then newdev="${line/${device}/${rename}}" VFILE[$ln]="$newdev" TEAM_MASTER=${rename} return 0 fi done pr_error "Failed to rename $device to $rename" return 1 } team_port_set_devtype() { pr_dbg "${FUNCNAME} $*" local master=$1 vfile_add_line "DEVICETYPE=\"TeamPort\"" vfile_add_line "TEAM_MASTER=\"$master\"" } team_port_set_config() { pr_dbg "${FUNCNAME} $*" local port=$1 local team_port_config="" if [ "${PRIMARY}" == "$port" ]; then team_port_config="'{ \"prio\" : -10" else team_port_config="'{ \"prio\" : -100" fi if [ -n "${PRIMARY_RESELECT}" ]; then if [ "${PRIMARY}" == "$port" ]; then if [ -z "${team_port_config}" ]; then team_port_config="'{ \"sticky\" : true }'" else team_port_config="${team_port_config}, \"sticky\" : true }'" fi else if [ -z "${team_port_config}" ]; then team_port_config="{ \"sticky\" : false }'" else team_port_config="${team_port_config}, \"sticky\" : false }'" fi fi else if [ -n "${team_port_config}" ]; then team_port_config="${team_port_config} }'" fi fi if [ -n "$team_port_config" ]; then vfile_add_line "TEAM_PORT_CONFIG=$team_port_config" fi } team_port_ifcfg_create() { local dev=$1 vfile_load_ifcfg $dev if ! vfile_get_device; then return 1 fi team_port_set_devtype ${TEAM_MASTER} team_port_set_config ${DEVICE} return 0 } team_master_set_devtype() { pr_dbg "${FUNCNAME} $*" vfile_add_line "DEVICETYPE=\"Team\"" } team_master_set_config() { pr_dbg "${FUNCNAME} $*" local team_config="'{ \"runner\" : { " local nr_opt=0 nr_opt=${#RUNNER_OPTS[@]} if [ $nr_opt -eq 0 ]; then # default to miimon/ethtool team_config="${team_config} \"name\" : \"roundrobin\" }" else # add runner options for pos in $(seq 0 $((${#RUNNER_OPTS[@]} - 1))) do if [ $pos -ne 0 ]; then team_config="${team_config}, " fi team_config="${team_config} ${RUNNER_OPTS[$pos]}" done team_config="${team_config} }" fi nr_opt=${#LWATCH_OPTS[@]} if [ $nr_opt -eq 0 ]; then # default to miimon/ethtool team_config="${team_config}, \"link_watch\" : { \"name\" : \"ethtool\" }" else team_config="${team_config}, \"link_watch\" : { " # add linkwatch options for pos in $(seq 0 $(($nr_opt - 1))) do if [ $pos -ne 0 ]; then team_config="${team_config}, " fi team_config="${team_config} ${LWATCH_OPTS[$pos]}" done team_config="${team_config} }" fi team_config="${team_config} }'" pr_dbg "built team_config=${team_config}" vfile_add_line "TEAM_CONFIG=${team_config}" return 0 } team_ifcfg_dump_stdout() { pr_dbg "${FUNCNAME} $*" local dev=$1 if ! ifcfg_dump_stdout ${dev}; then return 1 fi return 0 } team_ifcfg_write_file() { pr_dbg "${FUNCNAME} $*" local dev=$1 OUTPUT_FILE= local filenm="ifcfg-${dev}" if [ -z "${dev}" ]; then filenm="ifcfg" fi create_output_file ${filenm} if [ ! -f "${OUTPUT_FILE}" ]; then return 1 fi if ! vfile_write_to_file ${OUTPUT_FILE}; then return 1 fi return 0 } team_master_ifcfg_create() { pr_dbg "${FUNCNAME} $*" if ! team_master_set_devtype; then return 1 fi if ! team_master_set_config; then return 1 fi return 0 } team_ifcfg_write() { pr_dbg "${FUNCNAME} $*" local dev=${1} if to_stdout; then team_ifcfg_dump_stdout ${dev} || return 1 else team_ifcfg_write_file ${dev} || return 1 fi return 0 } team_ifcfg_deliver() { pr_dbg "${FUNCNAME} $*" if ! to_stdout; then return 0 fi if [ -z "${OUTPUT_DIR}" ]; then show_output_files else ifcfg_overwrite_files clean_up fi return 0 } teamd_config_create() { vfile_reset vfile_add_line "{" # add runner options vfile_add_line " \"device\" : \"${DEVICE}\"," vfile_add_line " \"runner\" : {" local runner_nr=${#RUNNER_OPTS[@]} if [ ${runner_nr} -eq 0 ]; then # default roundrobin vfile_add_line " \"runner\" : \"roundrobin\" " else local last_pos=$((${runner_nr} - 1)) for pos in $(seq 0 ${last_pos}) do if [ $pos -eq ${last_pos} ]; then vfile_add_line " ${RUNNER_OPTS[$pos]}" else vfile_add_line " ${RUNNER_OPTS[$pos]}," fi done fi vfile_add_line " }," vfile_add_line " \"link_watch\" : {" local lwatch_nr=${#LWATCH_OPTS[@]} if [ ${lwatch_nr} -eq 0 ]; then # default to miimon lwatch_add_opt "\"name\" : \"ethtool\"" else for pos in $(seq 0 ${last_pos}) do last_pos=$((${lwatch_nr} - 1)) if [ $pos -eq ${last_pos} ]; then vfile_add_line " ${LWATCH_OPTS[$pos]}" else vfile_add_line " ${LWATCH_OPTS[$pos]}," fi done fi vfile_add_line " }," return 0 } teamd_config_close() { vfile_add_line "}" return 0 } teamd_dump_stdout() { for ln in $(seq 0 $((${#VFILE[@]} - 1))) do [ $ln -eq 0 ] && echo "---8<--- teamd.conf ---8<---" echo "${VFILE[$ln]}" done echo "---8<--- teamd.conf ---8<---" echo "" return 0 } teamd_write_file() { pr_dbg "${FUNCNAME} $*" local dev=$1 OUTPUT_FILE= create_output_file "teamd.conf" if [ ! -f "${OUTPUT_FILE}" ]; then return 1 fi if ! vfile_write_to_file ${OUTPUT_FILE}; then return 1 fi return 0 } teamd_config_write() { pr_dbg "${FUNCNAME} $*" if to_stdout; then teamd_dump_stdout || return 1 else teamd_write_file ${dev} || return 1 show_output_files fi return 0 } teamd_port_create() { vfile_add_line " \"ports\" : {" return 0 } teamd_port_close() { vfile_add_line " }" return 0 } teamd_port_add() { pr_dbg "${FUNCNAME} $*" local dev=${1} local lastone=${2} if [ -n "${PORT_LIST}" ]; then DEVICE=${dev} else if ! ifcfg_get_device ${dev}; then return 1 fi fi vfile_add_line " \"${DEVICE}\" : {" if [ "${PRIMARY}" == "${DEVICE}" ]; then vfile_add_line " \"prio\" : -10," else vfile_add_line " \"prio\" : -100," fi if [ -n "${PRIMARY_RESELECT}" ]; then if [ "${PRIMARY}" == "$port" ]; then vfile_add_line " \"sticky\" : true " else vfile_add_line " \"sticky\" : false " fi else vfile_add_line " \"sticky\" : false " fi if [ ${lastone} -eq 1 ]; then vfile_add_line " }" else vfile_add_line " }," fi return 0 } # Runner Functions runner_add_opt() { pr_dbg "${FUNCNAME} $*" local pos=${#RUNNER_OPTS[*]} RUNNER_OPTS[${pos}]="$1" } runner_parse_adselect() { pr_dbg "${FUNCNAME} $*" local value=$1 case $value in "0"|"stable") runner_add_opt "\"agg_select_policy\" : \"bandwidth\"" || return 1 ;; "1"|"bandwidth") runner_add_opt "\"agg_select_policy\" : \"bandwidth\"" || return 1 ;; "2"|"count") runner_add_opt "\"agg_select_policy\" : \"count\"" || return 1 ;; *) pr_error "parameter ad_select=$value is not supported" return 1 esac } runner_parse_failovermac() { pr_dbg "${FUNCNAME} $*" local value=$1 case $value in "0") runner_add_opt "\"hwaddr_policy\" : \"same_all\"" || return 1 ;; "1"|"active") runner_add_opt "\"hwaddr_policy\" : \"by_active\"" || return 1 ;; "2"|"follow") runner_add_opt "\"hwaddr_policy\" : \"only_active\"" || return 1 ;; *) pr_error "parameter fail_over_mac $value is not supported" return 1 ;; esac } runner_parse_lacprate() { pr_dbg "${FUNCNAME} $*" local value=$1 case $value in "slow"|"0") runner_add_opt "\"fast_rate\" : 0" || return 1 ;; "fast"|"1") runner_add_opt "\"fast_rate\" : 1" || return 1 ;; *) pr_error "parameter lacp_rate=$value is not supported" return 1 ;; esac } runner_parse_xmit_policy() { pr_dbg "${FUNCNAME} $*" local value=$1 case $value in "layer2") runner_add_opt "\"tx_hash\" : [ \"eth\" ]" || return 1 ;; "layer2+3") runner_add_opt "\"tx_hash\" : [ \"eth\", \"l3\" ]" || return 1 ;; "layer3+4") runner_add_opt "\"tx_hash\" : [ \"l3\", \"l4\" ]" || return 1 ;; *) pr_error "parameter xmit_hash_policy=$value is not supported" return 1 esac } runner_parse_mode() { pr_dbg "${FUNCNAME} $*" local value=$1 case $value in "0"|"balance-rr") runner_add_opt "\"name\" : \"roundrobin\"" || return 1 ;; "1"|"active-backup") runner_add_opt "\"name\" : \"activebackup\"" || return 1 ;; "2"|"balance-xor") # FIXME runner_add_opt "\"name\" : \"loadbalance\"" || return 1 ;; "3"|"broadcast") runner_add_opt "\"name\" : \"broadcast\"" || return 1 ;; "4"|"802.3ad") runner_add_opt "\"name\" : \"lacp\"" || return 1 ;; "5"|"balance-tlb") runner_add_opt "\"name\" : \"loadbalance\"" || return 1 ;; "6"|"balance-alb") pr_error "parameter mode=$value is not supported" return 1 ;; *) pr_error "parameter mode=$value is not supported" return 1 ;; esac } runner_parse_opt() { pr_dbg "${FUNCNAME} $*" local param=$1 local value=$2 case $param in "ad_select") runner_parse_adselect $value || return 1 ;; "fail_over_mac") runner_parse_failovermac $value || return 1 ;; "lacp_rate") runner_parse_lacprate $value || return 1 ;; "min_links") runner_add_opt "\"min_ports\" : $value" || return 1 ;; "mode") runner_parse_mode $value || return 1 ;; "xmit_hash_policy") runner_parse_xmit_policy $value || return 1 ;; esac } # Link Watch functions lwatch_add_opt() { pr_dbg "${FUNCNAME} $*" local pos=${#LWATCH_OPTS[*]} LWATCH_OPTS[${pos}]="$1" } lwatch_parse_arp_validate() { pr_dbg "${FUNCNAME} $*" local value=$1 case $value in "0"|"none") ;; "1"|"active") lwatch_add_opt "\"validate_active\" : 1" || return 1 ;; "2"|"backup") lwatch_add_opt "\"validate_inactive\" : 1" || return 1 ;; "3"|"all") lwatch_add_opt "\"validate_active\" : 1" || return 1 lwatch_add_opt "\"validate_inactive\" : 1" || return 1 ;; *) pr_error "parameter arp_validate=$value is not supported" return 1 ;; esac } lwatch_parse_arpiptarget() { #FIXME: supports only one arp_ip_target address. # otherwise a new linkwatch section must be create pr_dbg "${FUNCNAME} $*" local ip_addrs=$1 local ip_list=${ip_addrs//,/ } local ip_array=($ip_list) if [ ${#ip_array[*]} -ne 1 ]; then pr_error "parameter arp_ip_target= with multiple IP addresses is not supported" return 1 fi for addr in ${ip_list} do lwatch_add_opt "\"target_host\" : \"$addr\"" done } lwatch_parse_opt() { pr_dbg "${FUNCNAME} $*" local param=$1 local value=$2 case $param in "arp_interval") lwatch_add_opt "\"interval\" : $value" ;; "arp_ip_target") lwatch_add_opt "\"name\" : \"arp_ping\"" if ! lwatch_parse_arpiptarget $value; then return 1 fi ;; "arp_validate") lwatch_parse_arp_validate $value ;; "downdelay") lwatch_add_opt "\"delay_down\" : $value" ;; "miimon") lwatch_add_opt "\"name\" : \"ethtool\"" ;; "updelay") lwatch_add_opt "\"delay_up\" : $value" ;; *) pr_error "parameter $param=$value is not supported" return 1 ;; esac } port_parse_opt() { pr_dbg "${FUNCNAME} $*" local param=$1 local value=$2 case $param in "primary") PRIMARY="$value" ;; "primary_reselect") case $value in "0"|"always") PRIMARY_RESELECT=1 ;; "1"|"better") ;; "2"|"failure") ;; *) pr_error "parameter $param=$value is not supported" return 1 esac ;; *) pr_error "parameter $param=$value is not supported" return 1 ;; esac } convert_bond_opts() { local bonding_opts=$1 pr_dbg "${FUNCNAME} $*" for arg in $bonding_opts do key=${arg%%=*}; value=${arg##*=}; pr_dbg "parsing $key=$value" case "$key" in "active_slave"|"max_bonds"|"use_carrier") pr_info "parameter $key not supported, ignoring" continue ;; "all_slaves_active"|"resend_igmp"|"num_grat_arp"|"num_unsol_na") pr_error "parameter $key not supported, aborting" return 1 ;; "ad_select"|"fail_over_mac"|"lacp_rate"|"min_links"|"mode"|"xmit_hash_policy") runner_parse_opt $key $value || return 1 ;; "arp_interval"|"arp_ip_target"|"arp_validate"|"downdelay"|"miimon"|"updelay") lwatch_parse_opt $key $value || return 1 ;; "primary"|"primary_reselect") port_parse_opt $key $value || return 1 ;; *) pr_error "unknown parameter $key=$value, aborting" return 1 ;; esac done } # Parse command line options while :; do case "$1" in "--master") MASTER="$2" shift 2 ;; "--bonding_opts") BONDING_OPTS="$2" shift 2 ;; "--ifcfg") OUTPUT_FORMAT=${FORMAT_IFCFG} shift ;; "--json") OUTPUT_FORMAT=${FORMAT_JANSSON} shift ;; "--quiet") PR_LVL=${PR_QUIET} shift ;; "--debug") PR_LVL=`expr ${PR_LVL} + 1` shift ;; "--outputdir") OUTPUT_DIR="$2" shift 2 ;; "--configdir") CONFIGDIR="$2" shift 2 ;; "--rename") [ -n "${RENAME}" ] && usage && exit 1 RENAME="$2" shift 2 ;; "--stdout") STDOUT=0 shift ;; "--port") PORT_LIST="${PORT_LIST} $2" shift 2 ;; "--version") echo "$VERSION" exit 0 ;; "--help") usage exit 0 ;; "--examples") show_examples exit 0 ;; *) if [ -z "$1" ]; then break fi pr_error "unknown parameter: $1" usage exit 1 ;; esac done if [ -n "${OUTPUT_DIR}" -a ! -d "${OUTPUT_DIR}" ]; then pr_error "Invalid output diretory: ${OUTPUT_DIR}" usage exit 1 fi if [ -z "${MASTER}" -a -z "${BONDING_OPTS}" ]; then pr_error "No master interface or bonding options specified" usage exit 1 fi # no master means no ifcfg to read if [ -z "${MASTER}" ]; then MODE=${MODE_NOIFCFG} fi if [ ${OUTPUT_FORMAT} -eq ${FORMAT_JANSSON} -a -z "${MASTER}" ]; then MASTER="team0" fi if ! ifcfg_get_master_file ${MASTER}; then exit 1 fi # load the ifcfg file if ! vfile_load_ifcfg ${MASTER}; then exit 1 fi # get the bonding options if ! ifcfg_get_bond_opts ${MASTER}; then exit 1 fi if ! convert_bond_opts "${BONDING_OPTS}"; then exit 1 fi if ! vfile_get_device; then exit 1 fi TEAM_MASTER=${DEVICE} if ! ifcfg_device_rename ${DEVICE} ${RENAME}; then exit 1 fi BOND_MASTER=${DEVICE} if [ ${OUTPUT_FORMAT} -eq ${FORMAT_IFCFG} ]; then if ! team_master_ifcfg_create; then exit 1 fi if ! team_ifcfg_write ${TEAM_MASTER}; then clean_up exit 1 fi # process all ports for portcfg in $(LANG=C grep -s -l "^[[:space:]]*MASTER=\"\?${BOND_MASTER}\"\?\([[:space:]#]\|$\)" ${CONFIGDIR}/ifcfg-*) do if ! team_port_ifcfg_create $portcfg; then clean_up exit 1 fi if ! team_ifcfg_write ${DEVICE}; then clean_up exit 1 fi done team_ifcfg_deliver else if ! teamd_config_create; then exit 1 fi if ! teamd_port_create; then exit 1 fi if [ -n "${PORT_LIST}" ]; then portcfg_list=${PORT_LIST} else portcfg_list=$(LANG=C grep -s -l "^[[:space:]]*MASTER=\"\?${BOND_MASTER}\"\?\([[:space:]#]\|$\)" ${CONFIGDIR}/ifcfg-*) fi # count number of ports portcfg_total=0 for portcfg in ${portcfg_list} do portcfg_total=$((${portcfg_total} + 1)) done # process all ports portcfg_nr=0 lastone=0 for portcfg in ${portcfg_list} do portcfg_nr=$((${portcfg_nr} + 1)) if [ ${portcfg_nr} -eq ${portcfg_total} ]; then lastone=1 fi if ! teamd_port_add ${portcfg} ${lastone}; then exit 1 fi done if ! teamd_port_close; then exit 1 fi if ! teamd_config_close; then exit 1 fi if ! teamd_config_write; then exit 1 fi fi