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.


Avoid strict-aliasing related issues when compiling with optimization
[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 (typicaly (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 }
114
115 $mem = 1024;
116
117 print "How much memory (in MB) do you want to initially allocate for Palacios? [$mem] : ";
118 $mem = get_user($mem);
119
120 $devmem='y';
121
122 print "Do you need userspace access to your VMs' physical memory? [$devmem] : ";
123 $devmem = get_user($devmem);
124
125 $qemu='n';
126 $qemudir=$pdir."/linux_usr/qemu";
127
128 $hostdev = get_palacios_core_feature($pdir,"V3_CONFIG_HOST_DEVICE");
129
130 if ($hostdev eq "y") { 
131    print "Your Palacios configuration includes the host device interface.\n";
132    print "You can use it to interface with QEMU devices if you have a\n";
133    print "patched version of QEMU (see linux_usr/qemu for more info)\n\n";
134    print "Do you plan to use QEMU devices? [n] : ";
135    $qemu = get_user($qemu);
136    if ($qemu eq "y") {
137     while (1) { 
138         print "What is the path to your patched version of QEMU ? [$qemudir] : ";
139         $qemudir = get_user($qemudir);
140         last if -e "$qemudir/bin/qemu-system-x86_64";
141         print "$qemudir/bin/qemu-system-x86_64 cannot be found\n";
142       } 
143     }
144 }
145
146 print <<END2
147
148 Parameters
149    Palacios Direcotry:          $pdir
150    Kernel Configs Directory:    $kdir
151    Initial Palacios Memory (MB) $mem
152    Can Hot Remove:              $canhotremove
153    Will Hot Remove:             $hotremove
154    Enforce 4 GB Limit:          $gb4
155    Compiled Memory Block Size:  $compmemblocksize
156    Override Memory Block Size:  $override_memblocksize
157    Actual Memory Block Size:    $memblocksize
158    Allow Devmem:                $devmem
159    Support QEMU devices:        $qemu
160    QEMU directory:              $qemudir
161
162 END2
163 ;
164
165
166 #
167 #
168 #
169 #
170 print "Writing ./ENV\n";
171 open(ENV,">ENV");
172 print ENV "export PALACIOS_DIR=$pdir\n";
173 if ($qemu eq "y") { 
174   print ENV "export PALACIOS_QEMU_DIR=$qemudir\n";
175 }
176 print ENV "export PATH=$pdir/linux_usr:\$PATH\n";
177 close(ENV);
178 `chmod 644 ENV`;
179
180 print "Writing ./v3_init\n";
181 open(INIT,">v3_init");
182 print INIT "#!/bin/sh\n";
183 print INIT "source $pdir/ENV\n";  # just in case
184
185 # this file will track memory allocations
186 # made at user level so that they can be recovered later
187 # v3_mem will append to it
188 print INIT "rm -f $pdir/.v3offlinedmem\n";
189
190 print INIT "\n\n# insert the module\n";
191 $cmd = "insmod $pdir/v3vee.ko";
192 $cmd.= " allow_devmem=1 " if $devmem eq 'y';
193 $cmd.= " options=\"mem_block_size=$memblocksize\" " if $override_memblocksize eq 'y';
194 print INIT $cmd, "\n";
195
196 %numa = get_numa_data();
197
198 if (defined($numa{numnodes})) {
199   $numnodes=$numa{numnodes};
200 } else {
201   $numnodes=1;
202 }
203
204 if (defined($numa{numcores})) { 
205   $numcores=$numa{numcores};
206   $numcorespalacios = get_palacios_core_feature($pdir,"V3_CONFIG_MAX_CPUS");
207   if (defined($numcorespalacios) && $numcores>$numcorespalacios) { 
208     print "WARNING: Your Palacios configuration is configured to support\n";
209     print " a maximum of $numcorespalacios cores, but this machine has $numcores cores.\n";
210     print " Your Palacios will work on this machine, but will not be able to use\n";
211     print " the additional cores.\n";
212     if ($numnodes>1) {
213        print " This is also a NUMA machine, so this will also affect the initial\n";
214        print " allocation of memory in the NUMA nodes produced by this script.\n";
215        print " We highly recommend you reconfigure Palacios with at least $numcores cores and rebuild it.\n";
216      }
217   }
218
219
220
221
222 $chunk = $memblocksize / (1024 * 1024) ;
223 $numchunks = $mem / $chunk;
224 $chunkspernode  = $numchunks / $numnodes;
225
226 print "The initial memory allocation will be:\n\n";
227 print "  Total memory:       $mem MB\n";
228 print "  Memory block size:  $chunk MB\n";
229 print "  Number of blocks:   $numchunks\n";
230 print "  Number of nodes:    $numnodes\n";
231 print "  Blocks/node:        $chunkspernode\n";
232 print "  32 bit limit?       $gb4\n";
233 print "  Hot-removed?        $hotremove\n";
234
235 if ($numnodes*$chunkspernode*$chunk != $mem) { 
236   print "\nWARNING: The memory is not evenly divided among nodes or blocks.\n";
237   print " This means that LESS memory is allocated than requested.\n\n";
238 }
239
240 $cmd = "v3_mem -a";
241 $cmd.= " -k " if $hotremove eq 'n';
242 $cmd.= " -l " if $gb4 eq 'y';
243
244 for ($i=0;$i<$numnodes;$i++) {
245   for ($j=0;$j<$chunkspernode;$j++) { 
246     if ($numnodes>1) { 
247       print INIT "$cmd -n $i $chunk\n";
248     } else {
249       print INIT "$cmd $chunk\n";
250     }
251   }
252 }
253 close(INIT);
254 `chmod 755 v3_init`;
255
256 print "Writing ./v3_deinit\n";
257 open(DEINIT,">v3_deinit");
258 print DEINIT "#!/bin/sh\n";
259 # bring any offlined memory back to the kernel
260 print DEINIT "v3_mem -r offline\n";
261 # a side effect here is that the offline file will be empty
262 # the rmmod will free any in-kernel allocated memory
263 print DEINIT "rmmod v3vee\n";
264 close(DEINIT);
265 `chmod 755 v3_deinit`;
266 print "Done.\n";
267
268
269
270 sub get_user {
271   my $def = shift;
272   
273   my $inp = <STDIN>; chomp($inp);
274   
275   if ($inp eq "") { 
276     return $def;
277   } else {
278     return $inp;
279   }
280 }
281
282 sub get_kernel_feature {
283   my $dir=shift;
284   my $feature=shift;
285   my $x;
286
287   $x=`grep $feature $dir/config-\`uname -r\``;
288
289   if ($x=~/^\s*\#/) {
290     return undef;
291   } else {
292     if ($x=~/\s*$feature\s*=\s*(\S*)\s*$/) {
293       return $1;
294     } else {
295       return undef;
296     }
297   }
298 }
299   
300 sub get_palacios_core_feature {
301   my $dir=shift;
302   my $feature=shift;
303   my $x;
304
305   $x=`grep $feature= $dir/.config`;
306
307   if ($x=~/^\s*\#/) {
308     return undef;
309   } else {
310     if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
311       return $1;
312     } else {
313       return undef;
314     }
315   }
316 }
317
318
319 sub powerof2  {
320   my $x = shift;
321   my $exp;
322   
323   $exp = log($x) /log(2);
324
325   return $exp==int($exp);
326 }
327
328 sub get_numa_data() {
329   my $line;
330   my $maxnode=0;
331   my $maxcpu=0;
332   my %numa;
333
334   open (N, "numactl --hardware |");
335   while ($line=<N>) { 
336     if ($line=~/^node\s+(\d+)\s+cpus:\s+(.*)$/) { 
337       my $node=$1;
338       my @cpus = split(/\s+/,$2);
339       my $cpu;
340       if ($node>$maxnode) { $maxnode=$node; }
341       foreach $cpu (@cpus) { 
342         if ($cpu>$maxcpu) { $maxcpu=$cpu; }
343       }
344       $numa{"node$node"}{cores}=\@cpus;
345     }
346   }
347   $numa{numnodes}=$maxnode+1;
348   $numa{numcores}=$maxcpu+1;
349   return %numa;
350 }