6 Welcome. The purpose of this tool is to simplify the creation of
7 common forms of guests for the V3VEE environment on a Linux system.
8 These guests *should* work for any host embedding (e.g., Kitten) but
9 there may be hidden Linux assumptions.
11 The tool assumes you have already built Palacios, the Linux embedding,
12 and the Linux user-space tools. If you haven't done this, hit CTRL-C
13 now, configure and build Palacios, the user-space tools, and run
16 This tool also assumes that you have the environment produced by
17 v3_config_v3vee.pl sourced:
21 What this tool builds is a directory that contains a guest
22 configuration file (the ".pal" file) and its dependent files. Note
23 that lots of additional functionality is possible beyond what can be
24 configured with this tool. The precise functionality depends on the
25 version and branch of Palacios, and what was configured into it when
26 it was built. To access such functionality, you need to write your
27 own .pal file, or use one generated by this tool as a basis.
29 Any .pal guest configuration file is instantiated as a VM in the
33 v3_create -b guest.pal name_of_guest
35 Any files (disk images) that your guest configuration depends on
36 must be accessible when v3_create is run.
38 Once the VM is instantiated, you can then launch it:
40 v3_launch /dev/v3-vmN (N is given by the v3_create command)
42 We will configure your guest via a sequence of questions.
47 $pdir = $ENV{PALACIOS_DIR};
49 if (!defined($pdir)) {
50 print "Please set PALACIOS_DIR (you probably have not sourced ENV) and try again\n";
54 $otherbios = get_palacios_core_feature($pdir,"V3_CONFIG_OTHERBIOS");
55 $otherbios = !defined($otherbios) ? 0 : $otherbios eq "y" ? 1: 0;
57 print "Your Palacios installation is set up for a custom BIOS. \n";
58 print "You probably do NOT want to use this tool... Continue ? [n] : ";
59 if (get_user("n") eq "n") { exit -1; }
64 print "What is the name of your guest? [$name] : ";
65 $name = get_user($name);
68 print "What is the directory into which we will put your guest? [$dir] : ";
69 $dir = get_user($dir);
71 print "Unable to create the directory\n";
75 $config{numcores} = quant_question("How many cores will your guest have?", 1);
77 $config{mem} = quant_question("How much memory should it have in MB?", 256);
79 if ($config{numcores}>1) {
80 print "Do you want to to produce a NUMA configuration and mapping for your guest? [n] : ";
81 if (get_user("n") eq "y") {
82 do_numa_config(\%config,$pdir);
87 print "We will give your guest the default performance tuning characteristics\n";
88 $config{perftune_block} .= <<PERFTUNE
90 <strategy>friendly</strategy>
91 <threshold>1000</threshold>
97 print "We will give your guest the default host scheduler interaction characteristics\n";
98 $config{schedule_hz_block} .= " <schedule_hz>100</schedule_hz>\n";
101 $config{telemetry} = yn_question("Do you want telemetry (information about guest exits) ?", "y", "enable", "disable");
104 $config{paging_mode} = yn_question("Do you want to use nested paging if possible on your hardware?\n This will often (but not always) perform faster than shadow paging. ", "y", "nested", "shadow");
106 $config{large_pages} = yn_question("Do you want to use large pages if possible on your hardware?\n This will often (but not always) perform faster. ", "n", "true", "false");
108 print "We will give your guest the default shadow paging strategy for when shadow paging is used.\n";
109 $config{shadow_strategy} = "VTLB";
112 $config{memmap_block} = " <!-- there are no passthrough memory regions, but you can add them using\n".
113 " the <memmap> syntax described in the manual -->\n";
115 if (is_palacios_core_feature_enabled($pdir, "V3_CONFIG_EXT_VMWARE")) {
116 print "We will include the VMware Personality Extension since your Palacios build has it enabled\n";
117 $config{extensions_block} .= " <extension name=\"VMWARE_IFACE\"></extension>\n";
123 do_device(\%config, $pdir, "V3_CONFIG_BOCHS_DEBUG", "BOCHS_DEBUG", "bios_debug");
124 do_device(\%config, $pdir, "V3_CONFIG_OS_DEBUG", "OS_DEBUG", "os_debug");
130 do_device(\%config, $pdir, "V3_CONFIG_PIC", "8259A", "PIC", 1); # must have
131 if ($config{numcores}==1 && is_palacios_core_feature_enabled($pdir,"V3_CONFIG_BOCHSBIOS")) {
132 print "This is a single core guest and your Palacios setup uses the legacy BOCHS BIOS.\n";
133 print " Do you want to have only the legacy (pre-APIC) interrupt controller logic? [n] :";
134 if (get_user("n") eq "y") {
138 do_device(\%config, $pdir, "V3_CONFIG_APIC", "LAPIC", "apic", 1); # must have
139 do_device(\%config, $pdir, "V3_CONFIG_IO_APIC", "IOAPIC", "ioapic", 1, undef, " <apic>apic</apic>\n");
143 # PCI buses and north/south bridge - all must haves
145 do_device(\%config, $pdir, "V3_CONFIG_PCI", "PCI", "pci0",1); # must have
146 do_device(\%config, $pdir, "V3_CONFIG_I440FX", "i440FX", "northbridge",1, undef, " <bus>pci0</bus>\n"); #must have
147 do_device(\%config, $pdir, "V3_CONFIG_PIIX3", "PIIX3", "southbridge",1, undef, " <bus>pci0</bus>\n"); #must have
150 # MPTABLE for legacy BIOS. Innocuous for SEABIOS or OTHERBIOS
153 if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_MPTABLE")) {
154 print "We will include a classic MPTABLE constructor to describe your machine to the guest\n";
155 add_device(\%config, "MPTABLE", "mptable");
157 if ($config{numcores}>1 && is_palacios_core_feature_enabled($pdir,"V3_CONFIG_BOCHSBIOS")) {
158 print "This is a multicore guest, and your Palacios configuration uses the classic BOCHS BIOS\n".
159 "but does not have the MPTABLE constructor enabled... This guest will almost\n".
160 "certainly fail to work. Do you want to continue anyway? [n] :";
161 if (get_user("n") eq "n") {
171 do_device(\%config, $pdir, "V3_CONFIG_PIT", "8254_PIT", "PIT",1); # must have
174 # Keyboard and mouse (PS/2 controller)
176 do_device(\%config, $pdir, "V3_CONFIG_KEYBOARD", "KEYBOARD", "keyboard",1); #must have
180 # Displays, Consoles, Serial
182 print "\nWe will now consider consoles and serial ports.\n\n";
183 do_consoles_and_ports(\%config, $pdir);
187 # Storage controllers and devices (attached to PCI bus)
190 print "\nWe will now consider storage controllers and devices.\n\n";
191 do_storage(\%config, $pdir, $dir, $name, "pci0", "southbridge");
197 # Note: do_storage *must* have placed an IDE named ide0 in order for this to work
199 do_device(\%config, $pdir, "V3_CONFIG_NVRAM", "NVRAM", "nvram", 1, undef, " <storage>ide0</storage>\n"); #must have
203 # Network interfaces (attached to PCI bus)
206 print "\nWe will now consider network interfaces.\n\n";
207 do_network(\%config, $pdir, $dir, $name, "pci0", "southbridge");
212 # Generic Catch-all Device
214 do_generic(\%config, $pdir);
217 open(PAL,">$dir/$name.pal") or die "Cannot open $dir/$name.pal\n";
221 print $target "<vm class=\"PC\">\n\n";
222 print $target file_setup(\%config), "\n";
223 print $target memory_setup(\%config), "\n";
224 print $target paging_setup(\%config), "\n";
225 print $target memmap_setup(\%config), "\n";
226 print $target numa_setup(\%config), "\n";
227 print $target core_setup(\%config), "\n";
228 print $target schedule_setup(\%config), "\n";
229 print $target perftune_setup(\%config), "\n";
230 print $target telemetry_setup(\%config), "\n";
231 print $target extensions_setup(\%config), "\n";
232 print $target device_setup(\%config), "\n";
233 print $target "</vm>\n";
237 print "\n\nYour guest is now ready in the directory $dir\n\n";
238 print "To run it, do:\n\n";
240 print " v3_create -b $name.pal $name\n";
241 print " v3_launch /dev/v3-vmN (N given by v3_create\n\n";
242 print "Other useful tools:\n\n";
243 print " v3_console (CGA console)\n";
244 print " v3_stream (connect to stream, for example, serial port)\n\n";
250 my ($ques, $default) = @_;
252 print $ques." [$default] : ";
254 return get_user($default);
258 my ($ques, $default, $yans, $nans) = @_;
262 print $ques." [$default] : ";
263 $ans = get_user($default);
265 if (substr($ans,0,1) eq 'y' || substr($ans,0,1) eq 'Y') {
287 %numa = get_numa_data();
289 $numvcores = $cr->{numcores};
291 print "NUMA configuration involves the following:\n";
292 print " 1. Definition of virtual NUMA nodes and their corresponding regions of guest physical memory\n";
293 print " 2. Mapping of virtual NUMA nodes to physical NUMA nodes\n";
294 print " 3. Mapping of virtual cores to virtual NUMA nodes\n";
295 print " 4. Mapping of virtual cores to physical cores\n";
296 print "Your guest contains ".$numvcores." virtual cores.\n";
297 print "This host contains ".$numa{numcores}." physical cores and ".$numa{numnodes}." physical nodes.\n";
298 print "How many physical NUMA nodes does your target hardware have? [".$numa{numnodes}."] ? ";
299 $numpnodes=get_user($numa{numnodes});
300 $canauto=0 if ($numpnodes > $numa{numnodes});
301 print "How many physical cores does your target hardware have? [".$numa{numcores}."] ? ";
302 $numpcores=get_user($numa{numcores});
303 $canauto=0 if ($numpcores > $numa{numcores});
305 print "How many virtual NUMA nodes do you want? (up to $numvcores) for auto) [2] : ";
306 $numvnodes=get_user("2");
307 } while ($numvnodes<=0 || $numvnodes>$numvcores);
308 $cr->{numnodes} = $numvnodes;
309 $pernode = int(($cr->{mem}*1024*1024)/$numvnodes);
310 $lastnode = $pernode + ($cr->{mem}*1024*1024)-$pernode*$numvnodes;
311 print "Your guest has ".$cr->{mem}." MB of RAM, which we have defined and mapped like this:\n";
312 for ($i=0;$i<$numvnodes;$i++) {
313 my $start=$i*$pernode;
314 my $end=(($i==($numvnodes-1)) ? $start+$lastnode : $start+$pernode);
315 my $pnode = $i % $numpnodes;
316 $vnodemap[$i]=$pnode;
317 $start=sprintf("0x%x",$start);
318 $end=sprintf("0x%x",$end);
319 print "vnode $i : GPA $start to GPA $end : pnode $pnode\n";
320 push @{$cr->{nodes}}, { start=>$start, end=>$end, vnode=>$i, pnode=>$pnode};
324 print "We can now automatically map virtual cores to virtual NUMA nodes and physical CPUs using strided assignment\n";
325 print "assuming *this host's* NUMA configuration. Or you can enter the assignments manually. \n";
326 print " Which would you prefer {auto,manual} [auto] ? : ";
327 $doauto=1 if (get_user("auto") eq "auto");
329 print "Automatic mapping of virtual cores to virtual NUMA nodes and physical CPUs is not possible\n";
330 print "given your host configuration. Please configure manually below.\n";
334 for ($i=0;$i<$numvcores;$i++) {
335 my $vnode = $i % $numvnodes;
336 my $pnode = $vnodemap[$vnode];
337 my $pcores = $numa{"node$pnode"}{cores};
338 my $numpcores_per_pnode = $#{$pcores}+1; # assumes identical number on each node...
339 my $pcore = $numa{"node$pnode"}{cores}->[int($i/$numpnodes) % $numpcores_per_pnode];
340 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
341 $cr->{"core$i"}{pcore} = $pcore;
342 $cr->{"core$i"}{vnode} = $vnode;
345 for ($i=0;$i<$numvcores;$i++) {
346 print "What is the virtual NUMA node for virtual core $i ? [] : ";
347 my $vnode = get_user("");
348 my $pnode = $vnodemap[$vnode];
349 print "That maps to physical NUMA node $pnode.\n";
350 print "What is the physical core for virtual core $i ? [] : ";
351 my $pcore = get_user("");
352 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
353 $cr->{"core$i"}{pcore} = $pcore;
354 $cr->{"core$i"}{vnode} = $vnode;
361 sub get_numa_data() {
367 open (N, "numactl --hardware |");
369 if ($line=~/^node\s+(\d+)\s+cpus:\s+(.*)$/) {
371 my @cpus = split(/\s+/,$2);
373 if ($node>$maxnode) { $maxnode=$node; }
374 foreach $cpu (@cpus) {
375 if ($cpu>$maxcpu) { $maxcpu=$cpu; }
377 $numa{"node$node"}{cores}=\@cpus;
380 $numa{numnodes}=$maxnode+1;
381 $numa{numcores}=$maxcpu+1;
386 my ($cr,$pdir,$feature, $class, $id, $hardfail, $optblob, $nestblob) =@_;
388 if (is_palacios_core_feature_enabled($pdir, $feature)) {
389 print "We will include a $class since your Palacios build has it enabled\n";
390 add_device(\%config, $class, $id, $optblob, $nestblob);
392 if (defined($hardfail) && $hardfail) {
393 print "Wow, your Palacios build doesn't have a $class... We can't live without that...\n";
396 print "Not configuring a $class since your Palacios build doesn't have it enabled\n";
401 sub do_consoles_and_ports {
402 my ($cr, $pdir) = @_;
404 my $cga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CGA");
405 my $curses = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CURSES_CONSOLE");
406 my $cons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CONSOLE");
407 my $cancga = $cga && $curses && $cons;
408 my $vga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VGA");
409 my $gcons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_GRAPHICS_CONSOLE");
410 my $canvga = $vga && $gcons;
411 my $serial = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_SERIAL_UART");
412 my $charstream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CHAR_STREAM");
413 my $stream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_STREAM");
414 my $canserial = $serial && $charstream && $stream;
415 my $virtioconsole = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_CONSOLE");
416 my $canvirtioconsole = $virtioconsole; # probably need to verify frontend
417 my $paragraph = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_PARAGRAPH");
418 my $canparagraph = $paragraph && $gcons;
420 print "Your Palacios configuration allows the following options:\n";
421 print " * CGA: classic 80x25 text-only PC console (common option): ".($cancga ? "available\n" : "NOT AVAILABLE\n");
422 print " * VGA: classic 640x480 graphical PC console (uncommon option): ".($canvga ? "available\n" : "NOT AVAILABLE\n");
423 print " * SERIAL: classic PC serial ports (common option): ".($canserial ? "available\n" : "NOT AVAILABLE\n");
424 print " * VIRTIO: Linux Virtio Console (uncommon option): ".($canvirtioconsole ? "available\n" : "NOT AVAILABLE\n");
425 print " * PARAGRAPH: Paravirtualized graphics card (uncommon option): ".($canparagraph ? "available\n" : "NOT AVAILABLE\n");
426 print "The CGA and VGA options are mutually exclusive\n";
427 print "THe VGA and PARAGRAPH options are mutually exclusive\n";
429 if (!($cancga || $canvga || $canserial || $canvirtioconsole)) {
430 print "Hmm... No console mechanism is enabled in your Palacios build...\n";
431 print " This is probably not what you want...\n";
436 print "Do you want to use CGA as a console? [y] : ";
437 if (get_user("y") eq "y") {
438 add_device(\%config, "CGA_VIDEO", "cga", "passthrough=\"disable\"");
439 add_device(\%config, "CURSES_CONSOLE", "console", undef,
440 " <frontend tag=\"cga\" />\n".
441 " <tty>user</tty>\n");
447 if ($canvga && !$didcga) {
448 print "Do you want to use VGA as a console? [n] : ";
449 if (get_user("n") eq "y") {
450 add_device(\%config, "VGA", "vga", "passthrough=\"disable\" hostframebuf=\"enable\"");
451 # there is no gconsole device
458 print "You can include serial ports whether you use them for a console or not\n";
459 print "Note that you must configure your guest to place its console onto a serial port\n";
460 print "for it to be visible\n";
461 print "Do you want to include the serial ports (COM1..4) ? [y] : ";
462 if (get_user("y") eq "y") {
463 add_device(\%config,"SERIAL","serial");
464 add_device(\%config,"CHAR_STREAM","stream1","name=\"com1\"", " <frontend tag=\"serial\" com_port=\"1\" />\n");
465 add_device(\%config,"CHAR_STREAM","stream2","name=\"com2\"", " <frontend tag=\"serial\" com_port=\"2\" />\n");
466 add_device(\%config,"CHAR_STREAM","stream3","name=\"com3\"", " <frontend tag=\"serial\" com_port=\"3\" />\n");
467 add_device(\%config,"CHAR_STREAM","stream4","name=\"com4\"", " <frontend tag=\"serial\" com_port=\"4\" />\n");
474 if ($canvirtioconsole) {
475 print "Do you want to add a VIRTIO console? [n] : ";
476 if (get_user("n") eq "y") {
477 add_device(\%config,"LNX_VIRTIO_CONSOLE","virtio-cons",undef," <bus>pci0</bus>\n");
478 print "NOTE: no backend for the VIRTIO console is currently configured\n";
484 if ($canparagraph && !$didvga) {
485 print "Do you want to add a PARAGRAPH graphics card? [n] : ";
486 if (get_user("n") eq "y") {
487 add_device(\%config, "PARAGRAPH", "paragraph", undef,
488 " <bus>pci0</bus>\n".
489 " <mode>gcons_mem</bus>\n");
494 if (!($didcga || $didvga || $didserial || $didvirtioconsole || $didparagraph)) {
495 print "You have configured your guest without any obvious way of interacting with it....\n";
496 print " This is probably not what you want...\n";
502 my ($cr,$pdir,$dir,$name, $pcibus)=@_;
503 my $canvnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET");
504 my $canbridge = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NIC_BRIDGE");
505 my $canoverlay = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET_NIC") && $canvnet;
506 my $canvirtio = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_NET");
507 my $canvirtiovnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_VNET"); # not sure...
508 my $canne2k = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NE2K");
509 my $canrtl8139 = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_RTL8139");
518 push @devs, "virtio" if $canvirtio;
519 push @devs, "rtl8139" if $canrtl8139;
520 push @devs, "ne2000" if $canne2k;
522 push @backends, "bridge" if $canbridge;
523 push @backends, "vnet" if $canoverlay;
526 print "You have no network device implementations enabled in your Palacios build, so we are skipping networking\n";
530 if ($#backends==-1) {
531 print "You have no network device backends enabled in your Palacios build, so we are skipping networking\n";
538 last if (!yn_question("Do you want to add ".($num==0 ? "a" : "another")." network device?","n",1,0));
539 print "This requires the addition of the frontend device (the NIC) and a backend device.\n";
540 print "Frontends in Palacios include:\n";
541 print " * Virtio NIC (paravirtualized - common) : ".($canvirtio? "available" : "UNAVAILABLE")."\n";
542 print " * RTL8139 NIC (uncommon) : ".($canrtl8139? "available" : "UNAVAILABLE")."\n";
543 print " * NE2000 NIC (uncommon) : ".($canne2k? "available" : "UNAVAILABLE")."\n";
544 print "Which frontend do you want to add? {".join(", ", @devs)."} : ";
545 $front = get_user("");
546 @test = grep { /^$front$/ } @devs;
548 print "Unknown frontend\n";
551 print "Backends in Palacios include:\n";
552 print " * Bridge (direct attach to host NIC - common) : ".($canbridge? "available" : "UNAVAILABLE")."\n";
553 print " * VNET overlay (uncommon) : ".($canoverlay ? "available" : "UNAVAILABLE")."\n";
554 print "Which backend do you want to add? {".join(", ", @backends)."} : ";
555 $back = get_user("");
556 @test = grep { /^$back/ } @backends;
558 print "Unknown backend\n";
562 print "What MAC address do you want your NIC to have? [$mac] : ";
564 if ($front eq "virtio") {
565 add_device($cr,"LNX_VIRTIO_NIC","net$num",undef,
566 " <bus>$pcibus</bus>\n".
567 " <mac>$mac</mac>\n".
568 " <model mode=\"guest-driven\" />\n");
569 print "The device is configured with default guest-driven operation\n";
571 if ($front eq "rtl8139") {
572 add_device($cr,"RTL8139","net$num",undef,
573 " <bus>$pcibus</bus>\n".
574 " <mac>$mac</mac>\n");
576 if ($front eq "ne2000") {
577 add_device($cr,"NE2000","net$num",undef,
578 " <bus>$pcibus</bus>\n".
579 " <mac>$mac</mac>\n");
582 if ($back eq "bridge") {
584 print "What is the name of the host NIC you want to bridge to? [eth0] : ";
585 $host=get_user("eth0");
586 add_device($cr,"NIC_BRIDGE","net$num-back",undef,
587 " <frontend tag=\"net$num\" />\n".
588 " <hostnic name=\"$host\" />\n");
591 if ($back eq "vnet") {
592 add_device($cr,"VNET_NIC","net$num-back",undef,
593 " <frontend tag=\"net$num\" />\n");
594 print "Important: In order to use the VNET overlay, you must also create routes at run-time via /proc/v3vee/vnet\n";
602 return sprintf("%02X:%02X:%02X:%02X:%02X:%02X",
613 my ($cr,$pdir,$dir,$name,$pcibus,$controller)=@_;
618 do_device($cr, $pdir, "V3_CONFIG_IDE", "IDE", "ide0",1,undef,
619 " <bus>$pcibus</bus>\n".
620 " <controller>$controller</controller>\n" ); # must have
621 print "You can attach up to four storage devices to the storage controller \"ide\"\n";
622 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_0",
623 " <bus_num>0</bus_num>\n".
624 " <drive_num>0</drive_num>\n");
625 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_1",
626 " <bus_num>0</bus_num>\n".
627 " <drive_num>1</drive_num>\n");
628 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_0",
629 " <bus_num>1</bus_num>\n".
630 " <drive_num>0</drive_num>\n");
631 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_1",
632 " <bus_num>1</bus_num>\n".
633 " <drive_num>1</drive_num>\n");
635 if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_BLOCK")) {
636 print "You can attach VIRTIO block devices. How many do you need? [0] : ";
637 my $num = get_user("0");
639 for ($i=0;$i<$num;$i++) {
640 add_device($cr,"LNX_VIRTIO_BLK","virtioblk$i",undef," <bus>$pcibus</bus>\n");
641 do_storage_backend($cr, $pdir, $dir, $name, "virtioblk$i", "data$i", "");
647 sub do_storage_backend {
648 my ($cr, $pdir, $dir, $name, $frontend, $loc, $frontendblock) = @_;
649 my ($canramdisk, $canfiledisk, $cannetdisk, $cantmpdisk);
650 my @devs=("cd","hd","nothing");
657 $canramdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_RAMDISK");
658 $canfiledisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_FILEDISK");
659 $cannetdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_NETDISK");
660 $cantmpdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_TMPDISK");
661 push @disks, "ramdisk" if $canramdisk;
662 push @disks, "filedisk" if $canramdisk;
663 push @disks, "netdisk" if $cannetdisk;
664 push @disks, "tmpdisk" if $cantmpdisk;
667 if (!$canramdisk && !$canfiledisk && !$cannetdisk && !$cantmpdisk) {
668 print "You have no storage implementations enabled in your Palacios build, so it is impossible\n";
669 print "to add anything to storage controller \"$frontend\" location \"$loc\"\n";
675 print "What do you want to attach to storage controller \"$frontend\" location \"$loc\"\n";
676 print " Your options are {".join(", ",@devs)."} [nothing] : ";
677 $what = get_user("nothing");
678 @test = grep { /^$what$/ } @devs;
680 if ($what eq "nothing") {
683 print "A storage device requires one of the following implementations\n";
684 print " * RAMDISK - the data is kept in memory (common) : ".($canramdisk ? "available" : "UNAVAILABLE")."\n";
685 print " * FILEDISK - the data is kept in a host file (common) : ".($canfiledisk ? "available" : "UNAVAILABLE")."\n";
686 print " * NETDISK - the data is accessed via the network (uncommon) : ".($cannetdisk ? "available" : "UNAVAILABLE")."\n";
687 print " * TMPDISK - the data is kept in memory and discarded (common) : ".($cantmpdisk ? "available" : "UNAVAILABLE")."\n";
689 print "Which option do you want for this device? {".join(", ",@disks)."} [] : ";
690 $type = get_user("");
691 my @test = grep {/^$type$/} @disks;
695 if ($type eq "filedisk" || $type eq "ramdisk") {
696 print "$type requires a file (.iso for example). Do you have one? [y] : ";
697 if (get_user("y") eq "y") {
699 print "What is its path? [] : ";
700 $file = get_user("");
702 print "$file does not exist\n";
705 if (system("cp $file $dir/$frontend\_$loc.dat")) {
706 print "Unable to copy $file\n";
712 print "We will make one. How big should it be in MB? [64] : ";
713 $size = get_user("64");
714 gen_image_file("$dir/$frontend\_$loc.dat",$size);
716 $attach=" <frontend tag=\"$frontend\">\n";
718 $attach.=" <model>V3VEE CDROM</model>\n".
719 " <type>CDROM</type>\n".$frontendblock;
721 $attach.=" <model>V3VEE HD</model>\n".
722 " <type>HD</type>\n".$frontendblock;
724 $attach.=" </frontend>\n";
726 if ($type eq "ramdisk") {
727 add_device($cr,"RAMDISK","$frontend\_$loc", undef,
728 " <file>$frontend\_$loc</file>\n".$attach);
729 add_file($cr, "$frontend\_$loc", "$frontend\_$loc.dat");
731 add_device($cr,"FILEDISK","$frontend\_$loc", $what eq "hd" ? "writable=\"1\"" : undef,
732 " <path>$frontend\_$loc.dat</path>\n".$attach);
736 print "$type is not currently supported\n";
748 <!-- DMA 1 registers -->
751 <mode>PRINT_AND_IGNORE</mode>
754 <!-- DMA 2 registers -->
757 <mode>PRINT_AND_IGNORE</mode>
760 <!-- DMA 1 page registers -->
763 <mode>PRINT_AND_IGNORE</mode>
766 <!-- DMA 2 page registers -->
769 <mode>PRINT_AND_IGNORE</mode>
772 <!-- DMA 1 Misc Registers -->
775 <mode>PRINT_AND_IGNORE</mode>
778 <!-- DMA 2 Misc Registers -->
781 <mode>PRINT_AND_IGNORE</mode>
787 <mode>PRINT_AND_IGNORE</mode>
793 <mode>PRINT_AND_IGNORE</mode>
799 <mode>PRINT_AND_IGNORE</mode>
803 my @dev = find_devices_by_class($cr,"PARALLEL");
807 <!-- Parallel Port -->
810 <mode>PRINT_AND_IGNORE</mode>
815 my @par = find_devices_by_class($cr,"SERIAL");
819 <!-- Serial COM 1 -->
822 <mode>PRINT_AND_IGNORE</mode>
825 <!-- Serial COM 2 -->
828 <mode>PRINT_AND_IGNORE</mode>
831 <!-- Serial COM 3 -->
834 <mode>PRINT_AND_IGNORE</mode>
837 <!-- Serial COM 4 -->
840 <mode>PRINT_AND_IGNORE</mode>
846 do_device($cr, $pdir, "V3_CONFIG_GENERIC", "GENERIC", "generic", 1, undef, $block);
850 my ($cr, $name, $file) = @_;
852 push @{$cr->{files}}, { name=>$name, file=>$file};
857 my ($cr, $class, $id, $optblob, $nestblob) = @_;
859 push @{$cr->{devices}}, { class=>$class, id=>$id, opt=>$optblob, nest=>$nestblob };
862 sub find_devices_by_class {
864 return grep { $_->{class} eq $c } @{$cr->{devices}};
872 if (!defined($cr->{numa})) {
875 $s.=" <mem_layout vnodes=\"".($#{$cr->{nodes}}+1)."\" >\n";
876 foreach $vnode (@{$cr->{nodes}}) {
877 $s.=" <region start_addr=\"".$vnode->{start}."\" end_addr=\"".$vnode->{end}."\" vnode=\"".$vnode->{vnode}."\" node=\"".$vnode->{pnode}."\" />\n";
879 $s.=" </mem_layout>\n";
890 $s.= " <cores count=\"".$cr->{numcores}."\">\n";
891 if (!defined($cr->{numa})) {
894 for ($i=0;$i<$cr->{numcores};$i++) {
895 $s.= " <core target_cpu=\"".$cr->{"core$i"}{pcore}."\" vnode=\"".$cr->{"core$i"}{vnode}."\" />\n";
907 return " <memory>".$cr->{mem}."</memory>\n";
914 $s.= " <paging mode=\"".$cr->{paging_mode}."\">\n";
915 $s.= " <large_pages>".$cr->{large_pages}."</large_pages>\n";
916 $s.= " <strategy>".$cr->{shadow_strategy}."</strategy>\n";
925 return $cr->{memmap_block};
931 return $cr->{schedule_hz_block};
938 if (defined($cr->{perftune_block})) {
940 $s.= $cr->{perftune_block};
941 $s.=" </perftune>\n";
946 sub extensions_setup {
949 if (defined($cr->{extensions_block})) {
950 $s.=" <extensions>\n";
951 $s.= $cr->{extensions_block};
952 $s.=" </extensions>\n";
957 sub telemetry_setup {
959 return " <telemetry>".$cr->{telemetry}."</telemetry>\n";
967 if (!defined($cr->{files})) {
968 return " <!-- this configuration contains no files -->\n";
973 foreach $cf (@{$cr->{files}}) {
974 $s.=" <file id=\"".$cf->{name}."\" filename=\"".$cf->{file}."\" />\n";
988 foreach $cd (@{$cr->{devices}}) {
989 $s.=" <device class=\"".$cd->{class}."\" id=\"".$cd->{id}."\"";
990 if (defined($cd->{opt})) {
993 if (!defined($cd->{nest})) {
1002 $s.=" </devices>\n";
1013 my $inp = <STDIN>; chomp($inp);
1022 sub get_kernel_feature {
1027 $x=`grep $feature= $dir/config-\`uname -r\``;
1032 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1040 sub get_palacios_core_feature {
1045 $x=`grep $feature= $dir/.config`;
1050 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1058 sub is_palacios_core_feature_enabled {
1059 my $out = get_palacios_core_feature(@_);
1060 return !defined($out) ? 0 : $out eq "y";
1068 $exp = log($x) /log(2);
1070 return $exp==int($exp);
1074 sub gen_image_file {
1075 my ($name, $size_mb) = @_;
1077 if (system("dd if=/dev/zero of=$name bs=1048576 count=$size_mb")) {