Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


fix potential overflow condition in VMX assist
[palacios.git] / v3_config_v3vee.pl
1 #!/usr/bin/perl -w
2
3
4 print <<END
5
6 Welcome.  The purpose of this tool is to simplify configuration
7 of the V3VEE environment on a Linux system.   It assumes you
8 have already built Palacios, the Linux embedding, and the Linux
9 user-sapce tools.   If you haven't, hit CTRL-C now and do the
10 at least the following:
11
12   make menuconfig 
13      [choose your options]
14   make
15   cd linux_usr
16   make
17   cd ..
18   ./v3_config_v3vee.pl
19
20
21 This tool will create (or overwrite) the following for you:
22
23   ./ENV       An environment file that you can source
24   ./v3_init   A script that will insert Palacios with
25               relevant options and with appropriate memory
26               allocations.
27   ./v3_deinit A script that will free memory and remove 
28               Palacios.
29
30 After these are created, you can insert Palacio in the following way:
31
32   source ./ENV
33   ./v3_init
34
35 Then create and run VMs:
36
37   v3_create image_file name
38   v3_launch /dev/v3-vmN
39   v3_stop /dev/v3-vmN
40   v3_free /dev/v3-vmN
41
42 And you can remove Palacios and free memory it is using.
43
44   ./v3_deinit
45
46
47 We begin with a set of questions.
48
49 END
50 ;
51
52 $pdir = `pwd`; chomp($pdir);
53
54 print "What is your Palacios directory? [$pdir] : ";
55
56 $pdir = get_user($pdir);
57
58 $kdir = "/boot";
59
60 print "Where are your Linux kernel config files? [$kdir] : ";
61
62 $kdir = get_user($kdir);
63
64 $hotremove = get_kernel_feature($kdir, "CONFIG_MEMORY_HOTREMOVE");
65
66 if (!defined($hotremove)) { 
67   $hotremove="n";
68 }
69
70 $canhotremove=$hotremove;
71
72 $memblocksize = get_palacios_core_feature($pdir,"V3_CONFIG_MEM_BLOCK_SIZE");
73
74 if (!defined($memblocksize)) { 
75   print "Cannot determine your memory block size from your Palacios configuration.\n";
76   exit -1;
77 }
78
79 if (!powerof2($memblocksize)) { 
80   print "Cannot handle a memory block size that is not a power of two ($memblocksize)...\n";
81   exit -1;
82 }
83
84 $compmemblocksize = $memblocksize;
85
86 $maxalloc = 4194304;
87
88 print "What is your kernel's maximum contiguous page allocation size in bytes (typically 2^(MAX_ORDER-1)*4096) [$maxalloc] : ";
89
90 $maxalloc = get_user($maxalloc);
91
92 $gb4 = 'n';
93
94 print "Do you need to use features that require 4GB enforcement of page allocation? [$gb4] : ";
95
96 $gb4 = get_user($gb4);
97
98 if ($hotremove eq "y") {
99   print "Your kernel supports hot remove.  Do you want to use it? [$hotremove] : ";
100   $hotremove = get_user($hotremove);
101 }
102
103
104 $override_memblocksize = 'n';
105
106 if ($hotremove eq "n") {
107   do  { 
108      $override_memblocksize = 'y';
109      print "You are not using hot-remove, so we will adjust memory block size\n";
110      print "Desired memory block size? [$maxalloc or less, power of 2] : ";
111      $memblocksize = get_user($maxalloc);
112   } while ($memblocksize>$maxalloc && !powerof2($memblocksize));
113   do  { 
114      print "You are not using hot-remove, so we can adjust the allocation size\n";
115      print "Typically, you want this as large as possible (up to what your\n";
116      print "kernel allows, but for special purposes, for example cache\n";
117      print "partitioning, you want this to be as small as possible (just\n";
118      print "larger than the largest contiguous allocation your guests will need.)\n";
119      print "Desired allocation size? [$maxalloc or less, power of 2] : ";
120      $allocsize = get_user($maxalloc);
121   } while ($allocsize>$maxalloc && !powerof2($allocsize));
122 } else {
123   $allocsize=$memblocksize;
124 }
125
126 $mem = 1024;
127
128 print "How much memory (in MB) do you want to initially allocate for Palacios? [$mem] : ";
129 $mem = get_user($mem);
130
131 $devmem='y';
132
133 print "Do you need userspace access to your VMs' physical memory? [$devmem] : ";
134 $devmem = get_user($devmem);
135
136 $qemu='n';
137 $qemudir=$pdir."/linux_usr/qemu";
138
139 $hostdev = get_palacios_core_feature($pdir,"V3_CONFIG_HOST_DEVICE");
140
141 if ($hostdev eq "y") { 
142    print "Your Palacios configuration includes the host device interface.\n";
143    print "You can use it to interface with QEMU devices if you have a\n";
144    print "patched version of QEMU (see linux_usr/qemu for more info)\n\n";
145    print "Do you plan to use QEMU devices? [n] : ";
146    $qemu = get_user($qemu);
147    if ($qemu eq "y") {
148     while (1) { 
149         print "What is the path to your patched version of QEMU ? [$qemudir] : ";
150         $qemudir = get_user($qemudir);
151         last if -e "$qemudir/bin/qemu-system-x86_64";
152         print "$qemudir/bin/qemu-system-x86_64 cannot be found\n";
153       } 
154     }
155 }
156
157 print <<END2
158
159 Parameters
160    Palacios Direcotry:          $pdir
161    Kernel Configs Directory:    $kdir
162    Initial Palacios Memory (MB) $mem
163    Can Hot Remove:              $canhotremove
164    Will Hot Remove:             $hotremove
165    Enforce 4 GB Limit:          $gb4
166    Compiled Memory Block Size:  $compmemblocksize
167    Override Memory Block Size:  $override_memblocksize
168    Actual Memory Block Size:    $memblocksize
169    Allocation Block Size:       $allocsize
170    Allow Devmem:                $devmem
171    Support QEMU devices:        $qemu
172    QEMU directory:              $qemudir
173
174 END2
175 ;
176
177
178 #
179 #
180 #
181 #
182 print "Writing ./ENV\n";
183 open(ENV,">ENV");
184 print ENV "export PALACIOS_DIR=$pdir\n";
185 if ($qemu eq "y") { 
186   print ENV "export PALACIOS_QEMU_DIR=$qemudir\n";
187 }
188 print ENV "export PATH=$pdir/linux_usr:\$PATH\n";
189 close(ENV);
190 `chmod 644 ENV`;
191
192 print "Writing ./v3_init\n";
193 open(INIT,">v3_init");
194 print INIT "#!/bin/sh\n";
195 print INIT "source $pdir/ENV\n";  # just in case
196
197 # this file will track memory allocations
198 # made at user level so that they can be recovered later
199 # v3_mem will append to it
200 print INIT "rm -f $pdir/.v3offlinedmem\n";
201
202 print INIT "\n\n# insert the module\n";
203 $cmd = "insmod $pdir/v3vee.ko";
204 $cmd.= " allow_devmem=1 " if $devmem eq 'y';
205 $cmd.= " options=\"mem_block_size=$memblocksize\" " if $override_memblocksize eq 'y';
206 print INIT $cmd, "\n";
207
208 %numa = get_numa_data();
209
210 if (defined($numa{numnodes})) {
211   $numnodes=$numa{numnodes};
212 } else {
213   $numnodes=1;
214 }
215
216 if (defined($numa{numcores})) { 
217   $numcores=$numa{numcores};
218   $numcorespalacios = get_palacios_core_feature($pdir,"V3_CONFIG_MAX_CPUS");
219   if (defined($numcorespalacios) && $numcores>$numcorespalacios) { 
220     print "WARNING: Your Palacios configuration is configured to support\n";
221     print " a maximum of $numcorespalacios cores, but this machine has $numcores cores.\n";
222     print " Your Palacios will work on this machine, but will not be able to use\n";
223     print " the additional cores.\n";
224     if ($numnodes>1) {
225        print " This is also a NUMA machine, so this will also affect the initial\n";
226        print " allocation of memory in the NUMA nodes produced by this script.\n";
227        print " We highly recommend you reconfigure Palacios with at least $numcores cores and rebuild it.\n";
228      }
229   }
230
231
232
233
234 $chunk = $allocsize / (1024 * 1024) ;
235 $numchunks = $mem / $chunk;
236 $chunkspernode  = $numchunks / $numnodes;
237
238 print "The initial memory allocation will be:\n\n";
239 print "  Total memory:       $mem MB\n";
240 print "  Memory block size:  $chunk MB\n";
241 print "  Number of blocks:   $numchunks\n";
242 print "  Number of nodes:    $numnodes\n";
243 print "  Blocks/node:        $chunkspernode\n";
244 print "  32 bit limit?       $gb4\n";
245 print "  Hot-removed?        $hotremove\n";
246
247 if ($numnodes*$chunkspernode*$chunk != $mem) { 
248   print "\nWARNING: The memory is not evenly divided among nodes or blocks.\n";
249   print " This means that LESS memory is allocated than requested.\n\n";
250 }
251
252 $cmd = "v3_mem -a";
253 $cmd.= " -k " if $hotremove eq 'n';
254 $cmd.= " -l " if $gb4 eq 'y';
255
256 for ($i=0;$i<$numnodes;$i++) {
257   for ($j=0;$j<$chunkspernode;$j++) { 
258     if ($numnodes>1) { 
259       print INIT "$cmd -n $i $chunk\n";
260     } else {
261       print INIT "$cmd $chunk\n";
262     }
263   }
264 }
265 close(INIT);
266 `chmod 755 v3_init`;
267
268 print "Writing ./v3_deinit\n";
269 open(DEINIT,">v3_deinit");
270 print DEINIT "#!/bin/sh\n";
271 # bring any offlined memory back to the kernel
272 print DEINIT "v3_mem -r offline\n";
273 # a side effect here is that the offline file will be empty
274 # the rmmod will free any in-kernel allocated memory
275 print DEINIT "rmmod v3vee\n";
276 close(DEINIT);
277 `chmod 755 v3_deinit`;
278 print "Done.\n";
279
280
281
282 sub get_user {
283   my $def = shift;
284   
285   my $inp = <STDIN>; chomp($inp);
286   
287   if ($inp eq "") { 
288     return $def;
289   } else {
290     return $inp;
291   }
292 }
293
294 sub get_kernel_feature {
295   my $dir=shift;
296   my $feature=shift;
297   my $x;
298
299   $x=`grep $feature $dir/config-\`uname -r\``;
300
301   if ($x=~/^\s*\#/) {
302     return undef;
303   } else {
304     if ($x=~/\s*$feature\s*=\s*(\S*)\s*$/) {
305       return $1;
306     } else {
307       return undef;
308     }
309   }
310 }
311   
312 sub get_palacios_core_feature {
313   my $dir=shift;
314   my $feature=shift;
315   my $x;
316
317   $x=`grep $feature= $dir/.config`;
318
319   if ($x=~/^\s*\#/) {
320     return undef;
321   } else {
322     if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
323       return $1;
324     } else {
325       return undef;
326     }
327   }
328 }
329
330
331 sub powerof2  {
332   my $x = shift;
333   my $exp;
334   
335   $exp = log($x) /log(2);
336
337   return $exp==int($exp);
338 }
339
340 sub get_numa_data() {
341   my $line;
342   my $maxnode=0;
343   my $maxcpu=0;
344   my %numa;
345
346   open (N, "numactl --hardware |");
347   while ($line=<N>) { 
348     if ($line=~/^node\s+(\d+)\s+cpus:\s+(.*)$/) { 
349       my $node=$1;
350       my @cpus = split(/\s+/,$2);
351       my $cpu;
352       if ($node>$maxnode) { $maxnode=$node; }
353       foreach $cpu (@cpus) { 
354         if ($cpu>$maxcpu) { $maxcpu=$cpu; }
355       }
356       $numa{"node$node"}{cores}=\@cpus;
357     }
358   }
359   $numa{numnodes}=$maxnode+1;
360   $numa{numcores}=$maxcpu+1;
361   return %numa;
362 }