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 # Network interfaces (attached to PCI bus)
200 print "\nWe will now consider network interfaces.\n\n";
201 do_network(\%config, $pdir, $dir, $name, "pci0", "southbridge");
205 # Sanity-check - is there something bootable?
208 if (!($config{havecd} && !($config{havehd}))) {
209 print "The guest's storage configuration does not have either a CD or an HD. \n";
210 print "This means the guest BIOS will have nothing local to boot. \n";
211 if (!($config{havenic})) {
212 print "The guest also does does not have a NIC, which means the BIOS cannot\n";
213 print "do a network boot.\n";
215 print "The guest does have a NIC, so a network boot is possible, if the\n";
216 print "BIOS supports it.\n";
218 print "If this is not your intent, you probably want to CTRL-C and try again.\n";
221 print "The BIOS boot sequence will be set to CD,HD. If you need to change this\n";
222 print "later, edit the <bootseq> block within the NVRAM device.\n";
227 # Note: do_storage *must* have placed an IDE named ide0 in order for this to work
229 do_device(\%config, $pdir, "V3_CONFIG_NVRAM", "NVRAM", "nvram", 1, undef, " <storage>ide0</storage>\n <bootseq>cd,hd</bootseq>\n"); #must have
233 # Generic Catch-all Device
235 do_generic(\%config, $pdir);
238 open(PAL,">$dir/$name.pal") or die "Cannot open $dir/$name.pal\n";
242 print $target "<vm class=\"PC\">\n\n";
243 print $target file_setup(\%config), "\n";
244 print $target memory_setup(\%config), "\n";
245 print $target paging_setup(\%config), "\n";
246 print $target memmap_setup(\%config), "\n";
247 print $target numa_setup(\%config), "\n";
248 print $target core_setup(\%config), "\n";
249 print $target schedule_setup(\%config), "\n";
250 print $target perftune_setup(\%config), "\n";
251 print $target telemetry_setup(\%config), "\n";
252 print $target extensions_setup(\%config), "\n";
253 print $target device_setup(\%config), "\n";
254 print $target "</vm>\n";
258 print "\n\nYour guest is now ready in the directory $dir\n\n";
259 print "To run it, do:\n\n";
261 print " v3_create -b $name.pal $name\n";
262 print " v3_launch /dev/v3-vmN (N given by v3_create)\n\n";
263 print "Other useful tools:\n\n";
264 print " v3_console (CGA console)\n";
265 print " v3_stream (connect to stream, for example, serial port)\n\n";
271 my ($ques, $default) = @_;
273 print $ques." [$default] : ";
275 return get_user($default);
279 my ($ques, $default, $yans, $nans) = @_;
283 print $ques." [$default] : ";
284 $ans = get_user($default);
286 if (substr($ans,0,1) eq 'y' || substr($ans,0,1) eq 'Y') {
308 %numa = get_numa_data();
310 $numvcores = $cr->{numcores};
312 print "NUMA configuration involves the following:\n";
313 print " 1. Definition of virtual NUMA nodes and their corresponding regions of guest physical memory\n";
314 print " 2. Mapping of virtual NUMA nodes to physical NUMA nodes\n";
315 print " 3. Mapping of virtual cores to virtual NUMA nodes\n";
316 print " 4. Mapping of virtual cores to physical cores\n";
317 print "Your guest contains ".$numvcores." virtual cores.\n";
318 print "This host contains ".$numa{numcores}." physical cores and ".$numa{numnodes}." physical nodes.\n";
319 print "How many physical NUMA nodes does your target hardware have? [".$numa{numnodes}."] ? ";
320 $numpnodes=get_user($numa{numnodes});
321 $canauto=0 if ($numpnodes > $numa{numnodes});
322 print "How many physical cores does your target hardware have? [".$numa{numcores}."] ? ";
323 $numpcores=get_user($numa{numcores});
324 $canauto=0 if ($numpcores > $numa{numcores});
326 print "How many virtual NUMA nodes do you want? (up to $numvcores) for auto) [2] : ";
327 $numvnodes=get_user("2");
328 } while ($numvnodes<=0 || $numvnodes>$numvcores);
329 $cr->{numnodes} = $numvnodes;
330 $pernode = int(($cr->{mem}*1024*1024)/$numvnodes);
331 $lastnode = $pernode + ($cr->{mem}*1024*1024)-$pernode*$numvnodes;
332 print "Your guest has ".$cr->{mem}." MB of RAM, which we have defined and mapped like this:\n";
333 for ($i=0;$i<$numvnodes;$i++) {
334 my $start=$i*$pernode;
335 my $end=(($i==($numvnodes-1)) ? $start+$lastnode : $start+$pernode);
336 my $pnode = $i % $numpnodes;
337 $vnodemap[$i]=$pnode;
338 $start=sprintf("0x%x",$start);
339 $end=sprintf("0x%x",$end);
340 print "vnode $i : GPA $start to GPA $end : pnode $pnode\n";
341 push @{$cr->{nodes}}, { start=>$start, end=>$end, vnode=>$i, pnode=>$pnode};
345 print "We can now automatically map virtual cores to virtual NUMA nodes and physical CPUs using strided assignment\n";
346 print "assuming *this host's* NUMA configuration. Or you can enter the assignments manually. \n";
347 print " Which would you prefer {auto,manual} [auto] ? : ";
348 $doauto=1 if (get_user("auto") eq "auto");
350 print "Automatic mapping of virtual cores to virtual NUMA nodes and physical CPUs is not possible\n";
351 print "given your host configuration. Please configure manually below.\n";
355 for ($i=0;$i<$numvcores;$i++) {
356 my $vnode = $i % $numvnodes;
357 my $pnode = $vnodemap[$vnode];
358 my $pcores = $numa{"node$pnode"}{cores};
359 my $numpcores_per_pnode = $#{$pcores}+1; # assumes identical number on each node...
360 my $pcore = $numa{"node$pnode"}{cores}->[int($i/$numpnodes) % $numpcores_per_pnode];
361 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
362 $cr->{"core$i"}{pcore} = $pcore;
363 $cr->{"core$i"}{vnode} = $vnode;
366 for ($i=0;$i<$numvcores;$i++) {
367 print "What is the virtual NUMA node for virtual core $i ? [] : ";
368 my $vnode = get_user("");
369 my $pnode = $vnodemap[$vnode];
370 print "That maps to physical NUMA node $pnode.\n";
371 print "What is the physical core for virtual core $i ? [] : ";
372 my $pcore = get_user("");
373 print "vcore $i : vnode $vnode : pnode $pnode : pcore $pcore\n";
374 $cr->{"core$i"}{pcore} = $pcore;
375 $cr->{"core$i"}{vnode} = $vnode;
382 sub get_numa_data() {
388 open (N, "numactl --hardware |");
390 if ($line=~/^node\s+(\d+)\s+cpus:\s+(.*)$/) {
392 my @cpus = split(/\s+/,$2);
394 if ($node>$maxnode) { $maxnode=$node; }
395 foreach $cpu (@cpus) {
396 if ($cpu>$maxcpu) { $maxcpu=$cpu; }
398 $numa{"node$node"}{cores}=\@cpus;
401 $numa{numnodes}=$maxnode+1;
402 $numa{numcores}=$maxcpu+1;
407 my ($cr,$pdir,$feature, $class, $id, $hardfail, $optblob, $nestblob) =@_;
409 if (is_palacios_core_feature_enabled($pdir, $feature)) {
410 print "We will include a $class since your Palacios build has it enabled\n";
411 add_device(\%config, $class, $id, $optblob, $nestblob);
413 if (defined($hardfail) && $hardfail) {
414 print "Wow, your Palacios build doesn't have a $class... We can't live without that...\n";
417 print "Not configuring a $class since your Palacios build doesn't have it enabled\n";
422 sub do_consoles_and_ports {
423 my ($cr, $pdir) = @_;
425 my $cga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CGA");
426 my $curses = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CURSES_CONSOLE");
427 my $cons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CONSOLE");
428 my $cancga = $cga && $curses && $cons;
429 my $vga = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VGA");
430 my $gcons = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_GRAPHICS_CONSOLE");
431 my $canvga = $vga && $gcons;
432 my $serial = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_SERIAL_UART");
433 my $charstream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_CHAR_STREAM");
434 my $stream = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_STREAM");
435 my $canserial = $serial && $charstream && $stream;
436 my $virtioconsole = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_CONSOLE");
437 my $canvirtioconsole = $virtioconsole; # probably need to verify frontend
438 my $paragraph = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_PARAGRAPH");
439 my $canparagraph = $paragraph && $gcons;
441 print "Your Palacios configuration allows the following options:\n";
442 print " * CGA: classic 80x25 text-only PC console (common option): ".($cancga ? "available\n" : "NOT AVAILABLE\n");
443 print " * VGA: classic 640x480 graphical PC console (uncommon option): ".($canvga ? "available\n" : "NOT AVAILABLE\n");
444 print " * SERIAL: classic PC serial ports (common option): ".($canserial ? "available\n" : "NOT AVAILABLE\n");
445 print " * VIRTIO: Linux Virtio Console (uncommon option): ".($canvirtioconsole ? "available\n" : "NOT AVAILABLE\n");
446 print " * PARAGRAPH: Paravirtualized graphics card (uncommon option): ".($canparagraph ? "available\n" : "NOT AVAILABLE\n");
447 print "The CGA and VGA options are mutually exclusive\n";
448 print "THe VGA and PARAGRAPH options are mutually exclusive\n";
450 if (!($cancga || $canvga || $canserial || $canvirtioconsole)) {
451 print "Hmm... No console mechanism is enabled in your Palacios build...\n";
452 print " This is probably not what you want...\n";
457 print "Do you want to use CGA as a console? [y] : ";
458 if (get_user("y") eq "y") {
459 add_device(\%config, "CGA_VIDEO", "cga", "passthrough=\"disable\"");
460 add_device(\%config, "CURSES_CONSOLE", "console", undef,
461 " <frontend tag=\"cga\" />\n".
462 " <tty>user</tty>\n");
468 if ($canvga && !$didcga) {
469 print "Do you want to use VGA as a console? [n] : ";
470 if (get_user("n") eq "y") {
471 add_device(\%config, "VGA", "vga", "passthrough=\"disable\" hostframebuf=\"enable\"");
472 # there is no gconsole device
479 print "You can include serial ports whether you use them for a console or not\n";
480 print "Note that you must configure your guest to place its console onto a serial port\n";
481 print "for it to be visible\n";
482 print "Do you want to include the serial ports (COM1..4) ? [y] : ";
483 if (get_user("y") eq "y") {
484 add_device(\%config,"SERIAL","serial");
485 add_device(\%config,"CHAR_STREAM","stream1","name=\"com1\"", " <frontend tag=\"serial\" com_port=\"1\" />\n");
486 add_device(\%config,"CHAR_STREAM","stream2","name=\"com2\"", " <frontend tag=\"serial\" com_port=\"2\" />\n");
487 add_device(\%config,"CHAR_STREAM","stream3","name=\"com3\"", " <frontend tag=\"serial\" com_port=\"3\" />\n");
488 add_device(\%config,"CHAR_STREAM","stream4","name=\"com4\"", " <frontend tag=\"serial\" com_port=\"4\" />\n");
495 if ($canvirtioconsole) {
496 print "Do you want to add a VIRTIO console? [n] : ";
497 if (get_user("n") eq "y") {
498 add_device(\%config,"LNX_VIRTIO_CONSOLE","virtio-cons",undef," <bus>pci0</bus>\n");
499 print "NOTE: no backend for the VIRTIO console is currently configured\n";
505 if ($canparagraph && !$didvga) {
506 print "Do you want to add a PARAGRAPH graphics card? [n] : ";
507 if (get_user("n") eq "y") {
508 add_device(\%config, "PARAGRAPH", "paragraph", undef,
509 " <bus>pci0</bus>\n".
510 " <mode>gcons_mem</bus>\n");
515 if (!($didcga || $didvga || $didserial || $didvirtioconsole || $didparagraph)) {
516 print "You have configured your guest without any obvious way of interacting with it....\n";
517 print " This is probably not what you want...\n";
524 my ($cr,$pdir,$dir,$name, $pcibus)=@_;
525 my $canvnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET");
526 my $canbridge = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NIC_BRIDGE");
527 my $canoverlay = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_VNET_NIC") && $canvnet;
528 my $canvirtio = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_NET");
529 my $canvirtiovnet = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_VNET"); # not sure...
530 my $canne2k = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_NE2K");
531 my $canrtl8139 = is_palacios_core_feature_enabled($pdir,"V3_CONFIG_RTL8139");
540 push @devs, "virtio" if $canvirtio;
541 push @devs, "rtl8139" if $canrtl8139;
542 push @devs, "ne2000" if $canne2k;
544 push @backends, "bridge" if $canbridge;
545 push @backends, "vnet" if $canoverlay;
548 print "You have no network device implementations enabled in your Palacios build, so we are skipping networking\n";
552 if ($#backends==-1) {
553 print "You have no network device backends enabled in your Palacios build, so we are skipping networking\n";
560 last if (!yn_question("Do you want to add ".($num==0 ? "a" : "another")." network device?","n",1,0));
561 print "This requires the addition of the frontend device (the NIC) and a backend device.\n";
562 print "Frontends in Palacios include:\n";
563 print " * Virtio NIC (paravirtualized - common) : ".($canvirtio? "available" : "UNAVAILABLE")."\n";
564 print " * RTL8139 NIC (uncommon) : ".($canrtl8139? "available" : "UNAVAILABLE")."\n";
565 print " * NE2000 NIC (uncommon) : ".($canne2k? "available" : "UNAVAILABLE")."\n";
566 print "Which frontend do you want to add? {".join(", ", @devs)."} : ";
567 $front = get_user("");
568 @test = grep { /^$front$/ } @devs;
570 print "Unknown frontend\n";
573 print "Backends in Palacios include:\n";
574 print " * Bridge (direct attach to host NIC - common) : ".($canbridge? "available" : "UNAVAILABLE")."\n";
575 print " * VNET overlay (uncommon) : ".($canoverlay ? "available" : "UNAVAILABLE")."\n";
576 print "Which backend do you want to add? {".join(", ", @backends)."} : ";
577 $back = get_user("");
578 @test = grep { /^$back/ } @backends;
580 print "Unknown backend\n";
584 print "What MAC address do you want your NIC to have? [$mac] : ";
586 if ($front eq "virtio") {
587 add_device($cr,"LNX_VIRTIO_NIC","net$num",undef,
588 " <bus>$pcibus</bus>\n".
589 " <mac>$mac</mac>\n".
590 " <model mode=\"guest-driven\" />\n");
591 print "The device is configured with default guest-driven operation\n";
593 if ($front eq "rtl8139") {
594 add_device($cr,"RTL8139","net$num",undef,
595 " <bus>$pcibus</bus>\n".
596 " <mac>$mac</mac>\n");
598 if ($front eq "ne2000") {
599 add_device($cr,"NE2000","net$num",undef,
600 " <bus>$pcibus</bus>\n".
601 " <mac>$mac</mac>\n");
604 if ($back eq "bridge") {
606 print "What is the name of the host NIC you want to bridge to? [eth0] : ";
607 $host=get_user("eth0");
608 add_device($cr,"NIC_BRIDGE","net$num-back",undef,
609 " <frontend tag=\"net$num\" />\n".
610 " <hostnic name=\"$host\" />\n");
613 if ($back eq "vnet") {
614 add_device($cr,"VNET_NIC","net$num-back",undef,
615 " <frontend tag=\"net$num\" />\n");
616 print "Important: In order to use the VNET overlay, you must also create routes at run-time via /proc/v3vee/vnet\n";
628 return sprintf("%02X:%02X:%02X:%02X:%02X:%02X",
639 my ($cr,$pdir,$dir,$name,$pcibus,$controller)=@_;
644 do_device($cr, $pdir, "V3_CONFIG_IDE", "IDE", "ide0",1,undef,
645 " <bus>$pcibus</bus>\n".
646 " <controller>$controller</controller>\n" ); # must have
647 print "You can attach up to four storage devices to the storage controller \"ide\"\n";
648 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_0",
649 " <bus_num>0</bus_num>\n".
650 " <drive_num>0</drive_num>\n");
651 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "0_1",
652 " <bus_num>0</bus_num>\n".
653 " <drive_num>1</drive_num>\n");
654 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_0",
655 " <bus_num>1</bus_num>\n".
656 " <drive_num>0</drive_num>\n");
657 do_storage_backend($cr, $pdir, $dir, $name, "ide0", "1_1",
658 " <bus_num>1</bus_num>\n".
659 " <drive_num>1</drive_num>\n");
661 if (is_palacios_core_feature_enabled($pdir,"V3_CONFIG_LINUX_VIRTIO_BLOCK")) {
662 print "You can attach VIRTIO block devices. How many do you need? [0] : ";
663 my $num = get_user("0");
665 for ($i=0;$i<$num;$i++) {
666 add_device($cr,"LNX_VIRTIO_BLK","virtioblk$i",undef," <bus>$pcibus</bus>\n");
667 do_storage_backend($cr, $pdir, $dir, $name, "virtioblk$i", "data$i", "");
675 sub do_storage_backend {
676 my ($cr, $pdir, $dir, $name, $frontend, $loc, $frontendblock) = @_;
677 my ($canramdisk, $canfiledisk, $cannetdisk, $cantmpdisk);
678 my @devs=("cd","hd","nothing");
685 $canramdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_RAMDISK");
686 $canfiledisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_FILEDISK");
687 $cannetdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_NETDISK");
688 $cantmpdisk = is_palacios_core_feature_enabled($pdir, "V3_CONFIG_TMPDISK");
689 push @disks, "ramdisk" if $canramdisk;
690 push @disks, "filedisk" if $canramdisk;
691 push @disks, "netdisk" if $cannetdisk;
692 push @disks, "tmpdisk" if $cantmpdisk;
695 if (!$canramdisk && !$canfiledisk && !$cannetdisk && !$cantmpdisk) {
696 print "You have no storage implementations enabled in your Palacios build, so it is impossible\n";
697 print "to add anything to storage controller \"$frontend\" location \"$loc\"\n";
703 print "What do you want to attach to storage controller \"$frontend\" location \"$loc\"\n";
704 print " Your options are {".join(", ",@devs)."} [nothing] : ";
705 $what = get_user("nothing");
706 @test = grep { /^$what$/ } @devs;
708 if ($what eq "nothing") {
711 print "A storage device requires one of the following implementations\n";
712 print " * RAMDISK - the data is kept in memory (common) : ".($canramdisk ? "available" : "UNAVAILABLE")."\n";
713 print " * FILEDISK - the data is kept in a host file (common) : ".($canfiledisk ? "available" : "UNAVAILABLE")."\n";
714 print " * NETDISK - the data is accessed via the network (uncommon) : ".($cannetdisk ? "available" : "UNAVAILABLE")."\n";
715 print " * TMPDISK - the data is kept in memory and discarded (common) : ".($cantmpdisk ? "available" : "UNAVAILABLE")."\n";
717 print "Which option do you want for this device? {".join(", ",@disks)."} [] : ";
718 $type = get_user("");
719 my @test = grep {/^$type$/} @disks;
723 if ($type eq "filedisk" || $type eq "ramdisk") {
724 print "$type requires a file (.iso for example). Do you have one? [y] : ";
725 if (get_user("y") eq "y") {
727 print "What is its path? [] : ";
728 $file = get_user("");
730 print "$file does not exist\n";
733 if (system("cp $file $dir/$frontend\_$loc.dat")) {
734 print "Unable to copy $file\n";
740 print "We will make one. How big should it be in MB? [64] : ";
741 $size = get_user("64");
742 gen_image_file("$dir/$frontend\_$loc.dat",$size);
744 $attach=" <frontend tag=\"$frontend\">\n";
746 $attach.=" <model>V3VEE CDROM</model>\n".
747 " <type>CDROM</type>\n".$frontendblock;
750 $attach.=" <model>V3VEE HD</model>\n".
751 " <type>HD</type>\n".$frontendblock;
754 $attach.=" </frontend>\n";
756 if ($type eq "ramdisk") {
757 add_device($cr,"RAMDISK","$frontend\_$loc", undef,
758 " <file>$frontend\_$loc</file>\n".$attach);
759 add_file($cr, "$frontend\_$loc", "$frontend\_$loc.dat");
761 add_device($cr,"FILEDISK","$frontend\_$loc", $what eq "hd" ? "writable=\"1\"" : undef,
762 " <path>$frontend\_$loc.dat</path>\n".$attach);
766 print "$type is not currently supported\n";
778 <!-- DMA 1 registers -->
781 <mode>PRINT_AND_IGNORE</mode>
784 <!-- DMA 2 registers -->
787 <mode>PRINT_AND_IGNORE</mode>
790 <!-- DMA 1 page registers -->
793 <mode>PRINT_AND_IGNORE</mode>
796 <!-- DMA 2 page registers -->
799 <mode>PRINT_AND_IGNORE</mode>
802 <!-- DMA 1 Misc Registers -->
805 <mode>PRINT_AND_IGNORE</mode>
808 <!-- DMA 2 Misc Registers -->
811 <mode>PRINT_AND_IGNORE</mode>
817 <mode>PRINT_AND_IGNORE</mode>
823 <mode>PRINT_AND_IGNORE</mode>
829 <mode>PRINT_AND_IGNORE</mode>
833 my @dev = find_devices_by_class($cr,"PARALLEL");
837 <!-- Parallel Port -->
840 <mode>PRINT_AND_IGNORE</mode>
845 my @par = find_devices_by_class($cr,"SERIAL");
849 <!-- Serial COM 1 -->
852 <mode>PRINT_AND_IGNORE</mode>
855 <!-- Serial COM 2 -->
858 <mode>PRINT_AND_IGNORE</mode>
861 <!-- Serial COM 3 -->
864 <mode>PRINT_AND_IGNORE</mode>
867 <!-- Serial COM 4 -->
870 <mode>PRINT_AND_IGNORE</mode>
876 do_device($cr, $pdir, "V3_CONFIG_GENERIC", "GENERIC", "generic", 1, undef, $block);
880 my ($cr, $name, $file) = @_;
882 push @{$cr->{files}}, { name=>$name, file=>$file};
887 my ($cr, $class, $id, $optblob, $nestblob) = @_;
889 push @{$cr->{devices}}, { class=>$class, id=>$id, opt=>$optblob, nest=>$nestblob };
892 sub find_devices_by_class {
894 return grep { $_->{class} eq $c } @{$cr->{devices}};
902 if (!defined($cr->{numa})) {
905 $s.=" <mem_layout vnodes=\"".($#{$cr->{nodes}}+1)."\" >\n";
906 foreach $vnode (@{$cr->{nodes}}) {
907 $s.=" <region start_addr=\"".$vnode->{start}."\" end_addr=\"".$vnode->{end}."\" vnode=\"".$vnode->{vnode}."\" node=\"".$vnode->{pnode}."\" />\n";
909 $s.=" </mem_layout>\n";
920 $s.= " <cores count=\"".$cr->{numcores}."\">\n";
921 if (!defined($cr->{numa})) {
924 for ($i=0;$i<$cr->{numcores};$i++) {
925 $s.= " <core target_cpu=\"".$cr->{"core$i"}{pcore}."\" vnode=\"".$cr->{"core$i"}{vnode}."\" />\n";
937 return " <memory>".$cr->{mem}."</memory>\n";
944 $s.= " <paging mode=\"".$cr->{paging_mode}."\">\n";
945 $s.= " <large_pages>".$cr->{large_pages}."</large_pages>\n";
946 $s.= " <strategy>".$cr->{shadow_strategy}."</strategy>\n";
955 return $cr->{memmap_block};
961 return $cr->{schedule_hz_block};
968 if (defined($cr->{perftune_block})) {
970 $s.= $cr->{perftune_block};
971 $s.=" </perftune>\n";
976 sub extensions_setup {
979 if (defined($cr->{extensions_block})) {
980 $s.=" <extensions>\n";
981 $s.= $cr->{extensions_block};
982 $s.=" </extensions>\n";
987 sub telemetry_setup {
989 return " <telemetry>".$cr->{telemetry}."</telemetry>\n";
997 if (!defined($cr->{files})) {
998 return " <!-- this configuration contains no files -->\n";
1003 foreach $cf (@{$cr->{files}}) {
1004 $s.=" <file id=\"".$cf->{name}."\" filename=\"".$cf->{file}."\" />\n";
1018 foreach $cd (@{$cr->{devices}}) {
1019 $s.=" <device class=\"".$cd->{class}."\" id=\"".$cd->{id}."\"";
1020 if (defined($cd->{opt})) {
1023 if (!defined($cd->{nest})) {
1032 $s.=" </devices>\n";
1043 my $inp = <STDIN>; chomp($inp);
1052 sub get_kernel_feature {
1057 $x=`grep $feature= $dir/config-\`uname -r\``;
1062 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1070 sub get_palacios_core_feature {
1075 $x=`grep $feature= $dir/.config`;
1080 if ($x=~/\s*$feature=\s*(\S*)\s*$/) {
1088 sub is_palacios_core_feature_enabled {
1089 my $out = get_palacios_core_feature(@_);
1090 return !defined($out) ? 0 : $out eq "y";
1098 $exp = log($x) /log(2);
1100 return $exp==int($exp);
1104 sub gen_image_file {
1105 my ($name, $size_mb) = @_;
1107 if (system("dd if=/dev/zero of=$name bs=1048576 count=$size_mb")) {