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);
86 do_swapping(\%config, $pdir);
88 print "We will give your guest the default performance tuning characteristics\n";
89 $config{perftune_block} .= <<PERFTUNE
91 <strategy>friendly</strategy>
92 <threshold>1000</threshold>
98 print "We will give your guest the default host scheduler interaction characteristics\n";
99 $config{schedule_hz_block} .= " <schedule_hz>100</schedule_hz>\n";
102 $config{telemetry} = yn_question("Do you want telemetry (information about guest exits) ?", "y", "enable", "disable");
105 $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");
107 $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");
109 print "We will give your guest the default shadow paging strategy for when shadow paging is used.\n";
110 $config{shadow_strategy} = "VTLB";
113 $config{memmap_block} = " <!-- there are no passthrough memory regions, but you can add them using\n".
114 " the <memmap> syntax described in the manual -->\n";
116 if (is_palacios_core_feature_enabled($pdir, "V3_CONFIG_EXT_VMWARE")) {
117 print "We will include the VMware Personality Extension since your Palacios build has it enabled\n";
118 $config{extensions_block} .= " <extension name=\"VMWARE_IFACE\"></extension>\n";
124 do_device(\%config, $pdir, "V3_CONFIG_BOCHS_DEBUG", "BOCHS_DEBUG", "bios_debug");
125 do_device(\%config, $pdir, "V3_CONFIG_OS_DEBUG", "OS_DEBUG", "os_debug");
131 do_device(\%config, $pdir, "V3_CONFIG_PIC", "8259A", "PIC", 1); # must have
132 if ($config{numcores}==1 && is_palacios_core_feature_enabled($pdir,"V3_CONFIG_BOCHSBIOS")) {
133 print "This is a single core guest and your Palacios setup uses the legacy BOCHS BIOS.\n";
134 print " Do you want to have only the legacy (pre-APIC) interrupt controller logic? [n] :";
135 if (get_user("n") eq "y") {
139 do_device(\%config, $pdir, "V3_CONFIG_APIC", "LAPIC", "apic", 1); # must have
140 do_device(\%config, $pdir, "V3_CONFIG_IO_APIC", "IOAPIC", "ioapic", 1, undef, " <apic>apic</apic>\n");
144 # PCI buses and north/south bridge - all must haves
146 do_device(\%config, $pdir, "V3_CONFIG_PCI", "PCI", "pci0",1); # must have
147 do_device(\%config, $pdir, "V3_CONFIG_I440FX", "i440FX", "northbridge",1, undef, " <bus>pci0</bus>\n"); #must have
148 do_device(\%config, $pdir, "V3_CONFIG_PIIX3", "PIIX3", "southbridge",1, undef, " <bus>pci0</bus>\n"); #must have
151 # MPTABLE for legacy BIOS. Innocuous for SEABIOS or OTHERBIOS
154 if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_MPTABLE")) {
155 print "We will include a classic MPTABLE constructor to describe your machine to the guest\n";
156 add_device(\%config, "MPTABLE", "mptable");
158 if ($config{numcores}>1 && is_palacios_core_feature_enabled($pdir,"V3_CONFIG_BOCHSBIOS")) {
159 print "This is a multicore guest, and your Palacios configuration uses the classic BOCHS BIOS\n".
160 "but does not have the MPTABLE constructor enabled... This guest will almost\n".
161 "certainly fail to work. Do you want to continue anyway? [n] :";
162 if (get_user("n") eq "n") {
172 do_device(\%config, $pdir, "V3_CONFIG_PIT", "8254_PIT", "PIT",1); # must have
175 # Keyboard and mouse (PS/2 controller)
177 do_device(\%config, $pdir, "V3_CONFIG_KEYBOARD", "KEYBOARD", "keyboard",1); #must have
181 # Displays, Consoles, Serial
183 print "\nWe will now consider consoles and serial ports.\n\n";
184 do_consoles_and_ports(\%config, $pdir);
188 # Storage controllers and devices (attached to PCI bus)
191 print "\nWe will now consider storage controllers and devices.\n\n";
192 do_storage(\%config, $pdir, $dir, $name, "pci0", "southbridge");
198 # Network interfaces (attached to PCI bus)
201 print "\nWe will now consider network interfaces.\n\n";
202 do_network(\%config, $pdir, $dir, $name, "pci0", "southbridge");
206 # Sanity-check - is there something bootable?
209 if (!($config{havecd} && !($config{havehd}))) {
210 print "The guest's storage configuration does not have either a CD or an HD. \n";
211 print "This means the guest BIOS will have nothing local to boot. \n";
212 if (!($config{havenic})) {
213 print "The guest also does does not have a NIC, which means the BIOS cannot\n";
214 print "do a network boot.\n";
216 print "The guest does have a NIC, so a network boot is possible, if the\n";
217 print "BIOS supports it.\n";
219 print "If this is not your intent, you probably want to CTRL-C and try again.\n";
222 print "The BIOS boot sequence will be set to CD,HD. If you need to change this\n";
223 print "later, edit the <bootseq> block within the NVRAM device.\n";
228 # Note: do_storage *must* have placed an IDE named ide0 in order for this to work
230 do_device(\%config, $pdir, "V3_CONFIG_NVRAM", "NVRAM", "nvram", 1, undef, " <storage>ide0</storage>\n <bootseq>cd,hd</bootseq>\n"); #must have
234 # Generic Catch-all Device
236 do_generic(\%config, $pdir);
239 open(PAL,">$dir/$name.pal") or die "Cannot open $dir/$name.pal\n";
243 print $target "<vm class=\"PC\">\n\n";
244 print $target file_setup(\%config), "\n";
245 print $target memory_setup(\%config), "\n";
246 print $target swapping_setup(\%config), "\n";
247 print $target paging_setup(\%config), "\n";
248 print $target memmap_setup(\%config), "\n";
249 print $target numa_setup(\%config), "\n";
250 print $target core_setup(\%config), "\n";
251 print $target schedule_setup(\%config), "\n";
252 print $target perftune_setup(\%config), "\n";
253 print $target telemetry_setup(\%config), "\n";
254 print $target extensions_setup(\%config), "\n";
255 print $target device_setup(\%config), "\n";
256 print $target "</vm>\n";
260 print "\n\nYour guest is now ready in the directory $dir\n\n";
261 print "To run it, do:\n\n";
263 print " v3_create -b $name.pal $name\n";
264 print " v3_launch /dev/v3-vmN (N given by v3_create)\n\n";
265 print "Other useful tools:\n\n";
266 print " v3_console (CGA console)\n";
267 print " v3_stream (connect to stream, for example, serial port)\n\n";
273 my ($ques, $default) = @_;
275 print $ques." [$default] : ";
277 return get_user($default);
281 my ($ques, $default, $yans, $nans) = @_;
285 print $ques." [$default] : ";
286 $ans = get_user($default);
288 if (substr($ans,0,1) eq 'y' || substr($ans,0,1) eq 'Y') {
310 %numa = get_numa_data();
312 $numvcores = $cr->{numcores};
314 print "NUMA configuration involves the following:\n";
315 print " 1. Definition of virtual NUMA nodes and their corresponding regions of guest physical memory\n";
316 print " 2. Mapping of virtual NUMA nodes to physical NUMA nodes\n";
317 print " 3. Mapping of virtual cores to virtual NUMA nodes\n";
318 print " 4. Mapping of virtual cores to physical cores\n";
319 print "Your guest contains ".$numvcores." virtual cores.\n";
320 print "This host contains ".$numa{numcores}." physical cores and ".$numa{numnodes}." physical nodes.\n";
321 print "How many physical NUMA nodes does your target hardware have? [".$numa{numnodes}."] ? ";
322 $numpnodes=get_user($numa{numnodes});
323 $canauto=0 if ($numpnodes > $numa{numnodes});
324 print "How many physical cores does your target hardware have? [".$numa{numcores}."] ? ";
325 $numpcores=get_user($numa{numcores});
326 $canauto=0 if ($numpcores > $numa{numcores});
328 print "How many virtual NUMA nodes do you want? (up to $numvcores) for auto) [2] : ";
329 $numvnodes=get_user("2");
330 } while ($numvnodes<=0 || $numvnodes>$numvcores);
331 $cr->{numnodes} = $numvnodes;
332 $pernode = int(($cr->{mem}*1024*1024)/$numvnodes);
333 $lastnode = $pernode + ($cr->{mem}*1024*1024)-$pernode*$numvnodes;
334 print "Your guest has ".$cr->{mem}." MB of RAM, which we have defined and mapped like this:\n";
335 for ($i=0;$i<$numvnodes;$i++) {
336 my $start=$i*$pernode;
337 my $end=(($i==($numvnodes-1)) ? $start+$lastnode : $start+$pernode);
338 my $pnode = $i % $numpnodes;
339 $vnodemap[$i]=$pnode;
340 $start=sprintf("0x%x",$start);
341 $end=sprintf("0x%x",$end);
342 print "vnode $i : GPA $start to GPA $end : pnode $pnode\n";
343 push @{$cr->{nodes}}, { start=>$start, end=>$end, vnode=>$i, pnode=>$pnode};
347 print "We can now automatically map virtual cores to virtual NUMA nodes and physical CPUs using strided assignment\n";
348 print "assuming *this host's* NUMA configuration. Or you can enter the assignments manually. \n";
349 print " Which would you prefer {auto,manual} [auto] ? : ";
350 $doauto=1 if (get_user("auto") eq "auto");
352 print "Automatic mapping of virtual cores to virtual NUMA nodes and physical CPUs is not possible\n";
353 print "given your host configuration. Please configure manually below.\n";
357 for ($i=0;$i<$numvcores;$i++) {
358 my $vnode = $i % $numvnodes;
359 my $pnode = $vnodemap[$vnode];
360 my $pcores = $numa{"node$pnode"}{cores};
361 my $numpcores_per_pnode = $#{$pcores}+1; # assumes identical number on each node...
362 my $pcore = $numa{"node$pnode"}{cores}->[int($i/$numpnodes) % $numpcores_per_pnode];
363 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
364 $cr->{"core$i"}{pcore} = $pcore;
365 $cr->{"core$i"}{vnode} = $vnode;
368 for ($i=0;$i<$numvcores;$i++) {
369 print "What is the virtual NUMA node for virtual core $i ? [] : ";
370 my $vnode = get_user("");
371 my $pnode = $vnodemap[$vnode];
372 print "That maps to physical NUMA node $pnode.\n";
373 print "What is the physical core for virtual core $i ? [] : ";
374 my $pcore = get_user("");
375 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
376 $cr->{"core$i"}{pcore} = $pcore;
377 $cr->{"core$i"}{vnode} = $vnode;
384 sub get_numa_data() {
390 open (N, "numactl --hardware |");
392 if ($line=~/^node\s+(\d+)\s+cpus:\s+(.*)$/) {
394 my @cpus = split(/\s+/,$2);
396 if ($node>$maxnode) { $maxnode=$node; }
397 foreach $cpu (@cpus) {
398 if ($cpu>$maxcpu) { $maxcpu=$cpu; }
400 $numa{"node$node"}{cores}=\@cpus;
403 $numa{numnodes}=$maxnode+1;
404 $numa{numcores}=$maxcpu+1;
410 my ($cr, $pdir) = @_;
412 my $canswap = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_SWAPPING");
413 my $mem = $cr->{mem};
417 $cr->{swapping} = yn_question("Do you want to use swapping?", "n", "y", "n");
419 if ($cr->{swapping} eq "y") {
420 $cr->{swap_alloc} = quant_question("How much memory do you want to allocate [MB] ?", $mem/2);
421 print "We will use the default swapping strategy.\n";
422 $cr->{swap_strat} = "default";
423 print "What file do you want to swap to? [./swap.bin] ";
424 $cr->{swap_file} = get_user("./swap.bin");
431 my ($cr,$pdir,$feature, $class, $id, $hardfail, $optblob, $nestblob) =@_;
433 if (is_palacios_core_feature_enabled($pdir, $feature)) {
434 print "We will include a $class since your Palacios build has it enabled\n";
435 add_device(\%config, $class, $id, $optblob, $nestblob);
437 if (defined($hardfail) && $hardfail) {
438 print "Wow, your Palacios build doesn't have a $class... We can't live without that...\n";
441 print "Not configuring a $class since your Palacios build doesn't have it enabled\n";
446 sub do_consoles_and_ports {
447 my ($cr, $pdir) = @_;
449 my $cga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CGA");
450 my $curses = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CURSES_CONSOLE");
451 my $cons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CONSOLE");
452 my $cancga = $cga && $curses && $cons;
453 my $vga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VGA");
454 my $gcons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_GRAPHICS_CONSOLE");
455 my $canvga = $vga && $gcons;
456 my $serial = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_SERIAL_UART");
457 my $charstream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CHAR_STREAM");
458 my $stream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_STREAM");
459 my $canserial = $serial && $charstream && $stream;
460 my $virtioconsole = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_CONSOLE");
461 my $canvirtioconsole = $virtioconsole; # probably need to verify frontend
462 my $paragraph = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_PARAGRAPH");
463 my $canparagraph = $paragraph && $gcons;
465 print "Your Palacios configuration allows the following options:\n";
466 print " * CGA: classic 80x25 text-only PC console (common option): ".($cancga ? "available\n" : "NOT AVAILABLE\n");
467 print " * VGA: classic 640x480 graphical PC console (uncommon option): ".($canvga ? "available\n" : "NOT AVAILABLE\n");
468 print " * SERIAL: classic PC serial ports (common option): ".($canserial ? "available\n" : "NOT AVAILABLE\n");
469 print " * VIRTIO: Linux Virtio Console (uncommon option): ".($canvirtioconsole ? "available\n" : "NOT AVAILABLE\n");
470 print " * PARAGRAPH: Paravirtualized graphics card (uncommon option): ".($canparagraph ? "available\n" : "NOT AVAILABLE\n");
471 print "The CGA and VGA options are mutually exclusive\n";
472 print "THe VGA and PARAGRAPH options are mutually exclusive\n";
474 if (!($cancga || $canvga || $canserial || $canvirtioconsole)) {
475 print "Hmm... No console mechanism is enabled in your Palacios build...\n";
476 print " This is probably not what you want...\n";
481 print "Do you want to use CGA as a console? [y] : ";
482 if (get_user("y") eq "y") {
483 add_device(\%config, "CGA_VIDEO", "cga", "passthrough=\"disable\"");
484 add_device(\%config, "CURSES_CONSOLE", "console", undef,
485 " <frontend tag=\"cga\" />\n".
486 " <tty>user</tty>\n");
492 if ($canvga && !$didcga) {
493 print "Do you want to use VGA as a console? [n] : ";
494 if (get_user("n") eq "y") {
495 add_device(\%config, "VGA", "vga", "passthrough=\"disable\" hostframebuf=\"enable\"");
496 # there is no gconsole device
503 print "You can include serial ports whether you use them for a console or not\n";
504 print "Note that you must configure your guest to place its console onto a serial port\n";
505 print "for it to be visible\n";
506 print "Do you want to include the serial ports (COM1..4) ? [y] : ";
507 if (get_user("y") eq "y") {
508 add_device(\%config,"SERIAL","serial");
509 add_device(\%config,"CHAR_STREAM","stream1","name=\"com1\"", " <frontend tag=\"serial\" com_port=\"1\" />\n");
510 add_device(\%config,"CHAR_STREAM","stream2","name=\"com2\"", " <frontend tag=\"serial\" com_port=\"2\" />\n");
511 add_device(\%config,"CHAR_STREAM","stream3","name=\"com3\"", " <frontend tag=\"serial\" com_port=\"3\" />\n");
512 add_device(\%config,"CHAR_STREAM","stream4","name=\"com4\"", " <frontend tag=\"serial\" com_port=\"4\" />\n");
519 if ($canvirtioconsole) {
520 print "Do you want to add a VIRTIO console? [n] : ";
521 if (get_user("n") eq "y") {
522 add_device(\%config,"LNX_VIRTIO_CONSOLE","virtio-cons",undef," <bus>pci0</bus>\n");
523 print "NOTE: no backend for the VIRTIO console is currently configured\n";
529 if ($canparagraph && !$didvga) {
530 print "Do you want to add a PARAGRAPH graphics card? [n] : ";
531 if (get_user("n") eq "y") {
532 add_device(\%config, "PARAGRAPH", "paragraph", undef,
533 " <bus>pci0</bus>\n".
534 " <mode>gcons_mem</bus>\n");
539 if (!($didcga || $didvga || $didserial || $didvirtioconsole || $didparagraph)) {
540 print "You have configured your guest without any obvious way of interacting with it....\n";
541 print " This is probably not what you want...\n";
548 my ($cr,$pdir,$dir,$name, $pcibus)=@_;
549 my $canvnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET");
550 my $canbridge = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NIC_BRIDGE");
551 my $canoverlay = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET_NIC") && $canvnet;
552 my $canvirtio = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_NET");
553 my $canvirtiovnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_VNET"); # not sure...
554 my $canne2k = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NE2K");
555 my $canrtl8139 = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_RTL8139");
564 push @devs, "virtio" if $canvirtio;
565 push @devs, "rtl8139" if $canrtl8139;
566 push @devs, "ne2000" if $canne2k;
568 push @backends, "bridge" if $canbridge;
569 push @backends, "vnet" if $canoverlay;
572 print "You have no network device implementations enabled in your Palacios build, so we are skipping networking\n";
576 if ($#backends==-1) {
577 print "You have no network device backends enabled in your Palacios build, so we are skipping networking\n";
584 last if (!yn_question("Do you want to add ".($num==0 ? "a" : "another")." network device?","n",1,0));
585 print "This requires the addition of the frontend device (the NIC) and a backend device.\n";
586 print "Frontends in Palacios include:\n";
587 print " * Virtio NIC (paravirtualized - common) : ".($canvirtio? "available" : "UNAVAILABLE")."\n";
588 print " * RTL8139 NIC (uncommon) : ".($canrtl8139? "available" : "UNAVAILABLE")."\n";
589 print " * NE2000 NIC (uncommon) : ".($canne2k? "available" : "UNAVAILABLE")."\n";
590 print "Which frontend do you want to add? {".join(", ", @devs)."} : ";
591 $front = get_user("");
592 @test = grep { /^$front$/ } @devs;
594 print "Unknown frontend\n";
597 print "Backends in Palacios include:\n";
598 print " * Bridge (direct attach to host NIC - common) : ".($canbridge? "available" : "UNAVAILABLE")."\n";
599 print " * VNET overlay (uncommon) : ".($canoverlay ? "available" : "UNAVAILABLE")."\n";
600 print "Which backend do you want to add? {".join(", ", @backends)."} : ";
601 $back = get_user("");
602 @test = grep { /^$back/ } @backends;
604 print "Unknown backend\n";
608 print "What MAC address do you want your NIC to have? [$mac] : ";
610 if ($front eq "virtio") {
611 add_device($cr,"LNX_VIRTIO_NIC","net$num",undef,
612 " <bus>$pcibus</bus>\n".
613 " <mac>$mac</mac>\n".
614 " <model mode=\"guest-driven\" />\n");
615 print "The device is configured with default guest-driven operation\n";
617 if ($front eq "rtl8139") {
618 add_device($cr,"RTL8139","net$num",undef,
619 " <bus>$pcibus</bus>\n".
620 " <mac>$mac</mac>\n");
622 if ($front eq "ne2000") {
623 add_device($cr,"NE2000","net$num",undef,
624 " <bus>$pcibus</bus>\n".
625 " <mac>$mac</mac>\n");
628 if ($back eq "bridge") {
630 print "What is the name of the host NIC you want to bridge to? [eth0] : ";
631 $host=get_user("eth0");
632 add_device($cr,"NIC_BRIDGE","net$num-back",undef,
633 " <frontend tag=\"net$num\" />\n".
634 " <hostnic name=\"$host\" />\n");
637 if ($back eq "vnet") {
638 add_device($cr,"VNET_NIC","net$num-back",undef,
639 " <frontend tag=\"net$num\" />\n");
640 print "Important: In order to use the VNET overlay, you must also create routes at run-time via /proc/v3vee/vnet\n";
652 return sprintf("%02X:%02X:%02X:%02X:%02X:%02X",
663 my ($cr,$pdir,$dir,$name,$pcibus,$controller)=@_;
668 do_device($cr, $pdir, "V3_CONFIG_IDE", "IDE", "ide0",1,undef,
669 " <bus>$pcibus</bus>\n".
670 " <controller>$controller</controller>\n" ); # must have
671 print "You can attach up to four storage devices to the storage controller \"ide\"\n";
672 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_0",
673 " <bus_num>0</bus_num>\n".
674 " <drive_num>0</drive_num>\n");
675 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_1",
676 " <bus_num>0</bus_num>\n".
677 " <drive_num>1</drive_num>\n");
678 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_0",
679 " <bus_num>1</bus_num>\n".
680 " <drive_num>0</drive_num>\n");
681 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_1",
682 " <bus_num>1</bus_num>\n".
683 " <drive_num>1</drive_num>\n");
685 if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_BLOCK")) {
686 print "You can attach VIRTIO block devices. How many do you need? [0] : ";
687 my $num = get_user("0");
689 for ($i=0;$i<$num;$i++) {
690 add_device($cr,"LNX_VIRTIO_BLK","virtioblk$i",undef," <bus>$pcibus</bus>\n");
691 do_storage_backend($cr, $pdir, $dir, $name, "virtioblk$i", "data$i", "");
699 sub do_storage_backend {
700 my ($cr, $pdir, $dir, $name, $frontend, $loc, $frontendblock) = @_;
701 my ($canramdisk, $canfiledisk, $cannetdisk, $cantmpdisk);
702 my @devs=("cd","hd","nothing");
709 $canramdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_RAMDISK");
710 $canfiledisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_FILEDISK");
711 $cannetdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_NETDISK");
712 $cantmpdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_TMPDISK");
713 push @disks, "ramdisk" if $canramdisk;
714 push @disks, "filedisk" if $canramdisk;
715 push @disks, "netdisk" if $cannetdisk;
716 push @disks, "tmpdisk" if $cantmpdisk;
719 if (!$canramdisk && !$canfiledisk && !$cannetdisk && !$cantmpdisk) {
720 print "You have no storage implementations enabled in your Palacios build, so it is impossible\n";
721 print "to add anything to storage controller \"$frontend\" location \"$loc\"\n";
727 print "What do you want to attach to storage controller \"$frontend\" location \"$loc\"\n";
728 print " Your options are {".join(", ",@devs)."} [nothing] : ";
729 $what = get_user("nothing");
730 @test = grep { /^$what$/ } @devs;
732 if ($what eq "nothing") {
735 print "A storage device requires one of the following implementations\n";
736 print " * RAMDISK - the data is kept in memory (common) : ".($canramdisk ? "available" : "UNAVAILABLE")."\n";
737 print " * FILEDISK - the data is kept in a host file (common) : ".($canfiledisk ? "available" : "UNAVAILABLE")."\n";
738 print " * NETDISK - the data is accessed via the network (uncommon) : ".($cannetdisk ? "available" : "UNAVAILABLE")."\n";
739 print " * TMPDISK - the data is kept in memory and discarded (common) : ".($cantmpdisk ? "available" : "UNAVAILABLE")."\n";
741 print "Which option do you want for this device? {".join(", ",@disks)."} [] : ";
742 $type = get_user("");
743 my @test = grep {/^$type$/} @disks;
747 if ($type eq "filedisk" || $type eq "ramdisk") {
748 print "$type requires a file (.iso for example). Do you have one? [y] : ";
749 if (get_user("y") eq "y") {
751 print "What is its path? [] : ";
752 $file = get_user("");
754 print "$file does not exist\n";
757 if (system("cp $file $dir/$frontend\_$loc.dat")) {
758 print "Unable to copy $file\n";
764 print "We will make one. How big should it be in MB? [64] : ";
765 $size = get_user("64");
766 gen_image_file("$dir/$frontend\_$loc.dat",$size);
768 $attach=" <frontend tag=\"$frontend\">\n";
770 $attach.=" <model>V3VEE CDROM</model>\n".
771 " <type>CDROM</type>\n".$frontendblock;
774 $attach.=" <model>V3VEE HD</model>\n".
775 " <type>HD</type>\n".$frontendblock;
778 $attach.=" </frontend>\n";
780 if ($type eq "ramdisk") {
781 add_device($cr,"RAMDISK","$frontend\_$loc", undef,
782 " <file>$frontend\_$loc</file>\n".$attach);
783 add_file($cr, "$frontend\_$loc", "$frontend\_$loc.dat");
785 add_device($cr,"FILEDISK","$frontend\_$loc", $what eq "hd" ? "writable=\"1\"" : undef,
786 " <path>$frontend\_$loc.dat</path>\n".$attach);
790 print "$type is not currently supported\n";
802 <!-- DMA 1 registers -->
805 <mode>PRINT_AND_IGNORE</mode>
808 <!-- DMA 2 registers -->
811 <mode>PRINT_AND_IGNORE</mode>
814 <!-- DMA 1 page registers -->
817 <mode>PRINT_AND_IGNORE</mode>
820 <!-- DMA 2 page registers -->
823 <mode>PRINT_AND_IGNORE</mode>
826 <!-- DMA 1 Misc Registers -->
829 <mode>PRINT_AND_IGNORE</mode>
832 <!-- DMA 2 Misc Registers -->
835 <mode>PRINT_AND_IGNORE</mode>
841 <mode>PRINT_AND_IGNORE</mode>
847 <mode>PRINT_AND_IGNORE</mode>
853 <mode>PRINT_AND_IGNORE</mode>
857 my @dev = find_devices_by_class($cr,"PARALLEL");
861 <!-- Parallel Port -->
864 <mode>PRINT_AND_IGNORE</mode>
869 my @par = find_devices_by_class($cr,"SERIAL");
873 <!-- Serial COM 1 -->
876 <mode>PRINT_AND_IGNORE</mode>
879 <!-- Serial COM 2 -->
882 <mode>PRINT_AND_IGNORE</mode>
885 <!-- Serial COM 3 -->
888 <mode>PRINT_AND_IGNORE</mode>
891 <!-- Serial COM 4 -->
894 <mode>PRINT_AND_IGNORE</mode>
900 do_device($cr, $pdir, "V3_CONFIG_GENERIC", "GENERIC", "generic", 1, undef, $block);
904 my ($cr, $name, $file) = @_;
906 push @{$cr->{files}}, { name=>$name, file=>$file};
911 my ($cr, $class, $id, $optblob, $nestblob) = @_;
913 push @{$cr->{devices}}, { class=>$class, id=>$id, opt=>$optblob, nest=>$nestblob };
916 sub find_devices_by_class {
918 return grep { $_->{class} eq $c } @{$cr->{devices}};
926 if (!defined($cr->{numa})) {
929 $s.=" <mem_layout vnodes=\"".($#{$cr->{nodes}}+1)."\" >\n";
930 foreach $vnode (@{$cr->{nodes}}) {
931 $s.=" <region start_addr=\"".$vnode->{start}."\" end_addr=\"".$vnode->{end}."\" vnode=\"".$vnode->{vnode}."\" node=\"".$vnode->{pnode}."\" />\n";
933 $s.=" </mem_layout>\n";
944 $s.= " <cores count=\"".$cr->{numcores}."\">\n";
945 if (!defined($cr->{numa})) {
948 for ($i=0;$i<$cr->{numcores};$i++) {
949 $s.= " <core target_cpu=\"".$cr->{"core$i"}{pcore}."\" vnode=\"".$cr->{"core$i"}{vnode}."\" />\n";
961 return " <memory>".$cr->{mem}."</memory>\n";
968 $s.= " <paging mode=\"".$cr->{paging_mode}."\">\n";
969 $s.= " <large_pages>".$cr->{large_pages}."</large_pages>\n";
970 $s.= " <strategy>".$cr->{shadow_strategy}."</strategy>\n";
979 return $cr->{memmap_block};
985 return $cr->{schedule_hz_block};
992 if (defined($cr->{perftune_block})) {
994 $s.= $cr->{perftune_block};
995 $s.=" </perftune>\n";
1000 sub extensions_setup {
1003 if (defined($cr->{extensions_block})) {
1004 $s.=" <extensions>\n";
1005 $s.= $cr->{extensions_block};
1006 $s.=" </extensions>\n";
1011 sub swapping_setup {
1013 if (defined($cr->{swapping}) && $cr->{swapping} eq "y") {
1014 return " <swapping enable=\"y\">\n <allocated>".$cr->{swap_alloc}."</allocated>\n <file>".$cr->{swap_file}."</file>\n <strategy>".$cr->{swap_strat}."</strategy>\n </swapping>\n";
1016 return " <!-- there is no swapping configuration, but you can add one manually -->\n";
1019 sub telemetry_setup {
1021 return " <telemetry>".$cr->{telemetry}."</telemetry>\n";
1029 if (!defined($cr->{files})) {
1030 return " <!-- this configuration contains no files -->\n";
1035 foreach $cf (@{$cr->{files}}) {
1036 $s.=" <file id=\"".$cf->{name}."\" filename=\"".$cf->{file}."\" />\n";
1050 foreach $cd (@{$cr->{devices}}) {
1051 $s.=" <device class=\"".$cd->{class}."\" id=\"".$cd->{id}."\"";
1052 if (defined($cd->{opt})) {
1055 if (!defined($cd->{nest})) {
1064 $s.=" </devices>\n";
1075 my $inp = <STDIN>; chomp($inp);
1084 sub get_kernel_feature {
1089 $x=`grep $feature= $dir/config-\`uname -r\``;
1094 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1102 sub get_palacios_core_feature {
1107 $x=`grep $feature= $dir/.config`;
1112 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1120 sub is_palacios_core_feature_enabled {
1121 my $out = get_palacios_core_feature(@_);
1122 return !defined($out) ? 0 : $out eq "y";
1130 $exp = log($x) /log(2);
1132 return $exp==int($exp);
1136 sub gen_image_file {
1137 my ($name, $size_mb) = @_;
1139 if (system("dd if=/dev/zero of=$name bs=1048576 count=$size_mb")) {