4 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
5 # This file is part of openvim
8 # Licensed under the Apache License, Version 2.0 (the "License"); you may
9 # not use this file except in compliance with the License. You may obtain
10 # a copy of the License at
12 # http://www.apache.org/licenses/LICENSE-2.0
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17 # License for the specific language governing permissions and limitations
20 # For those usages not covered by the Apache License, Version 2.0 please
21 # contact with: nfvlabs@tid.es
24 #Get configuration of a host for using it as a compute node
28 echo -e "\nUsage: $0 --user-name <user> --ip=<X.X.X.X> --cores=<core_number> --huge-pages-1G=<huga_pages_number> --nb-10GB-interfaces==<interface_number>"
29 echo -e "Generate a develop host yaml to be used for openvim host-add\n"
30 echo -e " --user-name -u <user>* Server OAM Ip"
31 echo -e " --ip -i <ip>* Server hostname"
32 echo -e " --cores -c <cores> Numa Cores available must be an odd number and bigger or equal to 4."
33 echo -e " --huge-pages-1G -hp <huge_pages_number> Must be an odd number and bigger or equal to 16. 4GiB of memory will be reserved for the host OS, the rest will be used by VM."
34 echo -e " --nb-10GB-interfaces -ni <nb-10GB-interfaces> Dataplane interfaces must be an odd number and bigger or equal to 4."
35 echo -e " * Mandatory arguments"
37 echo -e "The output will be a server descriptor with two numas and resources (memory, cores and interfaces) equally distributed between them."
38 echo -e "Each interface (physical funtion) will have defined 8 SR-IOV (virtual functions)."
43 function get_hash_value
() { echo `eval echo $\{\`echo $USER[$IP]\
`\}`; }
47 b1
=$
((seed
%16)); seed
=$
((seed
/16))
48 b2
=$
((seed
%16)); seed
=$
((seed
/16))
49 b3
=$
((seed
%16)); seed
=$
((seed
/16))
50 b4
=$
((seed
%16)); seed
=$
((seed
/16))
51 b5
=$
((seed
%16)); seed
=$
((seed
/16))
52 mac
=`printf "%02X:%02X:%02X:%02X:%02X:%02X" 2 $b5 $b4 $b3 $b2 $b1`
56 function _parse_opts
(){
59 if [ -n "$option_help" ];
65 [ -z "$option_user_name" ] && echo -e "ERROR: User argument is mandatory, --user-name=<user>\n" && usage
66 USER_NAME
=${option_user_name}
68 [ -z "$option_ip" ] && echo -e "ERROR: OAM IP argument is mandatory, --ip=<X.X.X.X>\n" && usage
71 #TODO to be checl diference between real cores an numa cores
73 REAL_CORES
=$
(grep -c "^processor" "/proc/cpuinfo")
74 if [ -z "$option_cores" ] ; then
80 #Ensure the core user input is big enough
81 ([ $
((CORES
%2)) -ne 0 ]) && echo -e "ERROR: Wrong number of cores\n" && usage
83 MEMORY
=$
(($
(grep MemTotal
/proc
/meminfo |
awk '{print $2}') /1024/1024))
84 if [ -z "$option_huge_pages_1G" ] ; then
87 HUGE_PAGES_MEMORY
=${option_huge_pages_1G}
89 #Ensure the memory user input is big enough
90 #([ $((MEMORY%2)) -ne 0 ] || [ $MEMORY -lt 16 ] ) && echo -e "ERROR: Wrong number of memory\n" && usage
92 #nb_10GB_interfaces argument
93 if [ -z "$nb_10GB_interfaces" ] ; then
96 INTERFACES
=${nb_10GB_interfaces}
98 ([ $
((INTERFACES
%2)) -ne 0 ] ||
[ $INTERFACES -lt 4 ] ) && echo -e "ERROR: Wrong number of interfaces\n" && usage
100 # Parameter by default
102 ([ $
((NUMAS
%2)) -ne 0 ]) && NUMAS
=1
105 function _generate_compute_develope_yaml
(){
109 FEATURES_LIST
="lps,dioc,hwsv,tlbps,ht,lps,64b,iommu"
111 #Generate a cpu topology for 4 numas with hyperthreading
112 #in this developing/fake server all cores can be used
113 #TODO check if this calculation is correct
114 echo2file
"#This file was created by $0"
115 echo2file
"#for adding this compute node to openvim"
116 echo2file
"#copy this file to openvim controller and run"
117 echo2file
"#openvim host-add <this>"
120 echo2file
" name: $HOST_NAME"
121 echo2file
" user: $USER_NAME"
122 echo2file
" ip_name: $IP"
123 echo2file
"host-data:"
124 echo2file
" name: $HOST_NAME"
125 echo2file
" user: $USER_NAME"
126 echo2file
" ip_name: $IP"
127 echo2file
" ranking: 100"
128 echo2file
" description: $HOST_NAME"
129 echo2file
" features: $FEATURES_LIST"
136 while [ $numa -lt $NUMAS ]
139 HUGE_PAGES
=$
((HUGE_PAGES_MEMORY
/2-2))
140 ([ ${HUGE_PAGES} -lt -1 ]) && HUGE_PAGES
=0
142 echo2file
" - numa_socket: $numa"
144 echo2file
" hugepages: $((HUGE_PAGES))"
145 echo2file
" memory: $((MEMORY/$NUMAS))"
149 for((n_core
=0;n_core
<$REAL_CORES;n_core
++))
151 THREAD_ID
=$
(($n_core+1))
152 CORE_ID
=$
(($
((${n_core}+${numa}))/2))
153 echo2file
" - core_id: ${CORE_ID}"
154 echo2file
" thread_id: ${THREAD_ID}"
155 [ $CORE_ID -eq 0 ] && echo2file
" status: noteligible"
157 thread_counter
=$
((thread_counter
+1))
159 # GENERATE INTERFACES INFORMATION AND PRINT IT
161 echo2file
" interfaces:"
162 for ((iface
=0;iface
<$INTERFACES;iface
+=2))
164 name
="iface$iface_counter"
165 bus
=$
((iface
+last_iface
))
167 pci
=`printf "0000:%02X:00.0" $bus`
171 echo2file
" - source_name: $name"
172 echo2file
" Mbps: 10000"
173 echo2file
" pci: \"$pci\""
174 echo2file
" mac: \"$mac\""
178 for((nb_sriov
=0;nb_sriov
<8;nb_sriov
++))
180 #PCI_COUNTER=$((PCI_COUNTER+2))
181 #echo2file "nb_sriov "$nb_sriov
182 #echo2file "PCI_COUNTER "$PCI_COUNTER
184 pci
=`printf "0000:%02X:10.%i" $bus $nb_sriov`
187 echo2file
" - source_name: eth$nb_sriov"
188 echo2file
" mac: \"$mac\""
189 echo2file
" pci: \"$pci\""
191 iface_counter
=$
((iface_counter
+1))
193 last_iface
=$
(((numa
+1)*127/NUMAS
+5)) #made-up formula for more realistic pci numbers
198 function _yaml_init
(){
199 echo -n > host-develope.yaml
202 function echo2file
(){
204 echo "${1}" >> host-develope.yaml
215 for option_group
in $options
217 _name
=${option_group%%:*}
220 eval option_
${_name}='""'
227 if [[ -n $get_argument ]]
229 [[ ${argument:0:1} == "-" ]] && echo "option '-$option' requires an argument" >&2 && return 1
230 eval ${get_argument}='"$argument"'
231 #echo option $get_argument with argument
238 if [[ ${argument:0:1} == "-" ]] && [[ ${argument:1:1} != "-" ]] && [[ ${#argument} -ge 2 ]]
241 while index
=$
((index
+1)) && [[ $index -lt ${#argument} ]]
243 option
=${argument:$index:1}
245 for option_group
in $options
248 for o
in $
(echo $option_group |
tr ":=" " ")
250 [[ -z "$_name" ]] && _name
=${o//-/_}
251 #echo option $option versus $o
252 if [[ "$option" == "${o}" ]]
254 eval option_
${_name}='${option_'${_name}'}-'
256 if [[ ${option_group:${#option_group}-1} != "=" ]]
260 if [[ ${#argument} -gt $((index+1)) ]]
262 eval option_${_name}='"${argument:$((index+1))}"'
265 get_argument=option_${_name}
266 #echo next should be argument $argument
273 [[ $bad_option == y ]] && echo "invalid argument '-$option'? Type -h for help" >&2 && return 1
275 elif [[ ${argument:0:2} == "--" ]] && [[ ${#argument} -ge 3 ]]
278 option_argument=${option#*=}
279 option_name=${option%%=*}
280 [[ "$option_name" == "$option" ]] && option_argument=""
282 for option_group in $options
285 for o in $(echo $option_group | tr ":=" " ")
287 [[ -z "$_name" ]] && _name=${o//-/_}
288 #echo option $option versus $o
289 if [[ "$option_name" == "${o}" ]]
292 if [[ ${option_group:${#option_group}-1} != "=" ]]
293 then #not an argument
294 [[ -n "${option_argument}" ]] && echo "option '--${option%%=*}' do not accept an argument " >&2 && return 1
295 eval option_${_name}='"${option_'${_name}'}-"'
296 elif [[ -n "${option_argument}" ]]
298 eval option_
${_name}='"${option_argument}"'
300 get_argument
=option_
${_name}
301 #echo next should be argument $argument
307 [[ $bad_option == y
]] && echo "invalid argument '-$option'? Type -h for help" >&2 && return 1
308 elif [[ ${argument:0:2} == "--" ]]
314 if [[ "$o" == "--" ]]
321 [[ $bad_option == y
]] && echo "invalid argument '--'? Type -h for help" >&2 && return 1
324 params
="$params ${argument}"
329 [[ -n "$get_argument" ]] && echo "option '-$option' requires an argument" >&2 && return 1
334 DIRNAME
=$
(readlink
-f ${BASH_SOURCE[0]})
335 DIRNAME
=$
(dirname $DIRNAME)
337 #source ${DIRNAME}/get-options.sh "help:h user:u= ip:i= cores:c= huge-pages-1G:hp= nb-10GB-interfaces:ni=" $*
338 _get_opts
"help:h user-name:u= ip:i= cores:c= huge-pages-1G:hp= nb-10GB-interfaces:ni=" $
* ||
exit 1
341 #check root privileges
342 [ "${USER}" != "root" ] && echo "Needed root privileges" >&2 && exit 2
343 #check root privileges and non a root user behind
346 HOST_NAME
=`cat /etc/hostname`
348 _generate_compute_develope_yaml