Making First Virtual Machine

Getting needed software

These instructions will have you modify multiple text files on the machine that will be running the “virtual machine” software. If you're not familiar with an available “text editor”, then either learn how to use an available text editor efficiently, or install one that will be pleasant to use.


Here are some references to other sections of the site. Know that these other sections are not part of the tutorial, so they don't refer you back to this tutorial. After getting the information that is needed, remember to return to this tutorial (if you wish to be making further progress in this tutorial).

  • Some details, which may be helpful for choosing a text editor, are available from choosing a text editor.
  • Details about installing new software may be mentioned by the section about software installation. Naturally, installing software from a network may not be a feasible option if networking is not yet functional.

Install both:

  • “virtual machine” software,
  • and a desirable text editor

(There are two sub-sections here: “virtual machine” software, and “text editors”. If the first category has instructions that are specific to your operating system, don't forget to look for details for the second category.)

“virtual machine” software
OpenBSD details for installing “virtual machine” software
sudo pkg_add -ivv ftp://ftp.$(uname -s).org/pub/$(uname -s)/$(uname -r)/packages/$(uname -p)/qemu
Text editors
Editors for OpenBSD

Many people consider nano easy to use. To install that:

sudo pkg_add -ivv ftp://ftp.$(uname -s).org/pub/$(uname -s)/$(uname -r)/packages/$(uname -p)/nano

To use nano, just know that the caret (“^”) refers to the Ctrl key. So when nano's built-in help, at the bottom of the screen, says “^X”, that means Ctrl-X. (Having caret (“^”) refer to the Ctrl key is described in another section of this site. That section is not part of this tutorial, so it does not refer back to this tutorial. That section is at: Ctrl keyboard sequences.)


The editor named “ee” also provides an interface that is rather easy to learn well enough to accomplish the most basic of tasks. The key thing to know about that is that the Esc key (or Ctrl-[) pops up menus.

sudo pkg_add -ivv ftp://ftp.$(uname -s).org/pub/$(uname -s)/$(uname -r)/packages/$(uname -p)/ee

Many skilled professionals like the vi program, in part due to common availability, and in part due to having quite a bit of power. Fortunately (for such users), the vi program is pre-installed. Those wishing to dabble into using vi can check out: vi usage.

emacs (and/or similar)

The MicroEMACS program comes with the full operating system installation. The executable's filename is mg. A tutorial for this software is available at: MicroEMACS (mg)/emacs.

Specifying a default editor

Once you know which editor you like, you can specify a default editor. (If you haven't had a chance to try out the editors, either try them out now, or try them out as you continue on with the tutorial. However, if you don't specify the default now, at least remember that this can be done later.)

People using the Bourne shell, or compatible shells like the Korn shell (ksh) can use something like this:

export VISUAL="nano -w"

Users of other shells can follow whatever other process is appropriate. For example, setting environment variables mentions setenv.

Start some documentation

Depending on the size/scope/seriousness of the project, there might not have been any need to create documentation yet.

However, it is about to start getting to be useful. Create a file that can be used to store notes. Naming the file after a project is often a good idea.


A key reason to make this file is simply to verify that the file can be successfully created. Another reason is that entering information is quicker than needing to think about where to start storing the documentation.

If you don't just want an empty file, you can place the name of the project in the documentation. Simply makMake sure that you have access to be able to write to the file.

[#chsmchnm]: Determine the name of the machine
Determining the short name

Determine the name of the machine. If you are following instructions provided by someone else, check to see if provided instructions have this information available. If the computer/machine will belong to another person, checking with that person would probably be a very appropriate action.

It may be that the person who is setting up the machine has an opportunity to choose the name. In that case, make the choice. There are various methods for doing this, such as choosing a theme and then picking some names randomly or more purposefully.

Naming guidelines

There are some tips for creating names that will work well. This guide recommends reading those tips when selecting a name. However, realize that the references resources are not currently part of this guide. This means that the sections that are referenced will not redirect you back to this guide when you are done reading them. So, remember to return back to this guide after reading the information related to choosing a name.

Commonly used DNS names, which refers to IETF BCP 17, which provides some common names. These names may be excellent choices for machines that are dedicated to a single service that is described by one of those names.

For other machines, the section on host name rules/guidelines provides some information. One way it provides information is by referring to resources, including the “Commonly used DNS names” that was just referenced. However, in addition to that, another resource that gets referred to is DNS domain name rules, which refers to yet more resources. Reviewing those guidelines is a task that is recommended if choosing a new/unique name.

When choosing a name, keep this concept in mind: checking for expected standards for customizations. (Performing checks is recommended.)

When deciding on a name, it can be helpful to understand the purpose of the machine. This guide's first virtual machine may be intended to be a sample machine that can be used as a “base”/“template” that gets copied/mimicked when additional machines are created.

Other people

As a general rule when you are deploying a machine, if other people are using this machine, consider whether input/opinions/ideas should be obtained by the people who will be using the machine.

Test labs

Machines with a names containing phrases like “demo”, “sample”, or “example” might be appropriate.

Classroom setting

It may be appropriate for a machine name to contain a reference to the person who will be using the machine. That may be a student's name, a student ID number, or perhaps simply a number assigned to the desk where a student will be regularly sitting.

Do try to make the name unique. For example: If this computer will be used for project number 4, and will be used in room 7, on a desk that has a number “8” written on the desk, and will be the third machine in a group of machines that fits that description, then a phrase like “p4r7d8m3” could communicate those details. That name may look very cryptic to someone who is unfamiliar with the pattern. However, if everybody in an organization uses specific patterns, then those patterns can start to be recognized by experienced staff members.

Naming the machine after a very specific location is not recommended if the machine is expected to be mobile, or even if there is a good chance that the machine may move someday. Try to pick a name that is likely to remain accurate as long as the machine is used.

If the (virtual) machine is only intended to be used by a single person, then having the person's name may be used. This may make sense if a business will be letting an employee use a machine that the employee gets to keep if the employee leaves the company. Another case, when naming a computer after a person may make sense, is if a virtual machine is highly customized to a specific person, and the virtual machine is not going to be used after that person leaves the company. However, if the machine is only going to be used by a specific person/title, and the person who fulfills that role is likely to be replaced if that person leaves the company (whether voluntarily, or due to circumstances that could include hospitalization or death), then name the computer after the position. That way, if the person ever does get replaced, the name of the computer will remain appropriate.

There isn't just one particular name-choosing method that is clearly better than all other possible methods. However, within a specific organization, one method may have the noteworthy advantage of being a standard that is used throughout the organization. That is why checking for expected standards for customizations can be useful.

Additional name portion

Note: with modern operating systems, machines typically have a multi-part name. One part of the name will be the “short name” selected. Another part will be the name of the network. (This is presumably a detail that has already been chosen, in the previous step about the name of the network.)

Setting environment variables
Basic task

See: Setting environment variables related to virtual machines.


A previous step indicated that some documentation should have been started for this project. Update the project documentation to note the values of these variables.

Additional documentation

Documenting the system's name would seem like a good idea. However, particularly in the short term (before networking is fully operational), the name may be something that a person can easily figure out by looking at the values of the basic environment variables that were just customized. So, as long as those basic environment variables are documented, there may be little point to also documenting the name another way. That may be true until networking is set up (and DNS is operational).

However, if the system's name isn't documented by the environment variables that were just customized, then documenting the system's name may be an extremely sensible step to do here. (Preferably, document the long name. If the format of the name hasn't been finalized yet, at least document all of the details that would be used when choosing a name.)

[#creatdsk]: Create a disk image
Determine size requirements

An earlier step of determining requirements had some information about this. (See: Disk space for services and virtual machines.) Determine a size of disk space that can be used (both because that amount of disk space is available, and because that amount of disk space is sufficiently large). An earlier step specified that disk space requirements were supposed to be researched (as needed), so this sort of information may be quite readily available simply by checking a report that was created as a result of that research.

Make some disk images

Run these commands:

echo VMDirBas=${VMDirBas} VMGenNam=${VMGenNam} VMLILNAM=${VMLILNAM}
mkdir -p ${VMDirBas}/diskimgs/baseimgs/${VMGenNam}/${VMLILNAM}
qemu-img create -f qcow2 ${VMDirBas}/diskimgs/baseimgs/${VMGenNam}/${VMLILNAM}/${VMLILNAM}1.qc2 16G
qemu-img create -f qcow2 ${VMDirBas}/diskimgs/baseimgs/${VMGenNam}/${VMLILNAM}/${VMLILNAM}2.qc2 16G

Verify that the files exist:

ls -l ${VMDirBas}/diskimgs/baseimgs/${VMGenNam}/${VMLILNAM}/${VMLILNAM}?.qc2

At this point, if there is a nice “copy and paste” functionality available, documenting the output of qemu-img and documenting that can be nice.


Be absolutely sure to document the values of the three environment variables. That documentation is expected to be useful later. The best way to document this is to store the “export” command lines. Then, once a slick method for “copy and paste” functionality can be used (later on, if that feature is not already functional), setting those variables may be as easy and quick as using “copy and paste” insetad of needing to re-type those commands.

Actually, if copying and pasting allows this to be done easily, simply documenting the command lines and the resulting output from of all those recent commands (including the echo command, the usually-silent mkdir command, and the two qemu-img commands) is a nice idea. That will capture some details that may be nice later.

Note that the output might not show the entire commands. The qemu-img command lines may exceed 80 characters, which may cause some command line shells to truncate the visible portion of the commands. If the entire command isn't showing up in the output), then copy the command (from the instructions) to the system's documentation.

Creating a startup script

This puts the file where it is needed. This isn't creating the file from scratch. The file was manually hard coded, so if you want to see how it was made, just look over its contents.

Getting and placing the file


Essential updates to start script

Once the file is placed there, it will be getting to be time to edit the file.

Info gathering

First, do a bit of information gathering. Use a scratch pad (which could be a temporary section of the “long term” documentation file) to record this information, because there is about to be some benefit to having this information be readily available.

File paths

Once you know where the installation media is at, you may wish to document that as part of the system documentation. Similar to documentation of the creation of the disk images, this documentation may be less critical for most routine tasks. Typically the script file may not need to have that file after the operating system gets installed, so the detail of that file's exact location may be less critical for long term documentation. However, if there is ever a desire to access that disk image, then finding that detail in documentation may be more convenient than hunting for the disk image later. Also, in the cases where situation does arise where that disk image is desired, hunting for the disk image may commonly be a particularly unpleasant burden, so having that documentation can be nice.

  • If this task is being done as part of a project (such as a class) that has been assigned, see if there is documentation provided by the person who assigned the project. That documentation may state where the installation media is at.
  • If you are following this tutorial on your own, you may have downloaded the installation media yourself. In that case, it will be up to you to know where you downloaded the file. If you don't know this, check the web browser's “download history” (Ctrl-J in Mozilla Firefox or Google Chrome), or use a technique to find the file(s).
  • If you haven't obtained the necessary installation media yet, then, by all means, do get started on that. The installation media will be needed shortly.
Media Installation Notes

Here are some details that may be specific installation data related to certain operating system(s):


If the official CD-ROMs are being used, then the path will refer to will be the CD-ROM drive.

The other convenient option is generally to use an ISO image that has been downloaded. If you've downloaded a install##.iso file, then using that file is likely to use up less bandwidth than the cd##.iso file. So, if the install##.iso file is available, use it, unless you have a reason to prefer the cd##.iso file. (For example, if there is a desire to experience an installation that copies more data from a network during the installation process, someone may wish to use the cd##.iso file to have that experience.)

Environment variables

At this point, it may be nice to show the contents of some variables one more time:

echo VMDirBas=${VMDirBas} VMGenNam=${VMGenNam} VMLILNAM=${VMLILNAM}

The main point to showing these variable values, right now, is not to make sure they are set. Presumably, they probably are (if prior steps have just recently been performed). However, the key reason is that the values of ${VMGenNam} and ${VMLILNAM} will be useful to know while you're in a text editor. Make a note of what those values are.

Editing the file

In theory, general practice would recommend that the file should be backed up before making changes. However, if this file is currently an exact copy of a file that is easily retrievable, then there may be no need to make another backup.

After the virtual machine has been configured, there will probably not be a whole lot of need to update the script file. Therefore, requiring superuser access to edit the script file is probably a good idea. Hopefully the permissions are set to require that.

ls -l ${VMDirBas}/execbin/${VMGenNam}/${VMLILNAM}/sysstart/exc_${VMLILNAM}

Proceed to edit the file:

sudoedit ${VMDirBas}/execbin/${VMGenNam}/${VMLILNAM}/sysstart/exc_${VMLILNAM}

(Most of the following steps are probably described by tutorial on making virtual machines: “Essential customizations for the script file” section. A discussion on using a VM Number is avaiable at using a VMNUM.)

Virtual machine name

This step might seem optional, until you remember that the disk image is using the virtual machine's name. This is required so that the script can locate the disk image.

Prepare to search for text:

  • In nano, using Ctrl-sequences of ^W (the “WhereIs” functionality, to see “Where” some text “Is” at), or ^\ (Ctrl-Backslash is actually “Search and Replace”, but careful usage could be done to just search).
  • With vi, enter command mode and press /.

    Find the lines that say:

    #   VMLILNAM : a unique, and preferably short, name representing this system
    [ "X${VMLILNAM}" = "X" ]&&VMLILNAM=demomach

    Customize the part to the right of the second equal sign. Make this text file set VMLILNAM to use the same value as the environment variable (that was set by Handling environment variables: virtual machine environment). (If you forgot the value you set, you can either exit the text editor and check, or check the notes that you made when this guide recommended recording the value.)

Virtual Machine Number

Decide on a VMNUM (as noted by the 1st bullet point of the tutorial on making virtual machines: “Essential customizations for the script file” section). Two digit numbers are great.

This is really a rather important step. If the computer will be running multiple virtual machines, each MAC address should be unique. Because the script file uses this number for creating a MAC address, the virtual machine numbers should be unique.

Find the lines that say:

#   VMLILNAM : a unique, and preferably short, name representing this system
[ "X${VMNUM}" = "X" ]&&VMNUM=11

Customize the value after the second equal sign.

By the way: including this “virtual machine” number in the documentation (that covers this virtual machine) may be a great idea.

Specify script generation name
[ "X${VMScrGen}" = "X" ]&&VMScrGen=1

That should be set to a value of one. (The default file may already have that value set. Still, it is worth checking.)

Specify system generation name

Like the VMLILNAM variable, this VMGenNam variable is essential for finding the disk image. Admittedly, this is less critical, because the script file may simply use the pre-existing values of an environment. However, in case the environment is actually cleared, there is no benefit to having the script file contain a wrong default, so this information out to be updated.

Find the line that sets VMGenNam. (The line might be just above the line that sets the VMLILNAM variable, so start by looking a few lines above the last variable that was modified.) At the time of this writing, the exact line of text looked like this (before the customization that should occur).

[ "X${VMGenNam}" = "X" ] && export VMGenNam=erlytest

Make this text file set the variable to the same value as VMGenNam's current value (which was set by Handling environment variables: virtual machine environment). (This is on a line that contains the word export.) (If you forgot the value you set, you can either exit the text editor and check, or check the notes that you made when this guide recommended recording the value.)

So what you're doing is editing what comes after the equal sign.

Specify virtual machine locations

Update the VMDirBas.


Like the VMLILNAM variable, this VMDirBas variable is essential for finding the disk image. Admittedly, setting this variable within the file may be less critical, because the script file may simply use the pre-existing values of an environment. However, in case the environment is actually cleared, there is no benefit to having the script file contain a wrong default, so this information ought to be updated.

Find the line that sets the VMDirBas variable. It is the second non-commented line (which is the line that says export) in the following portion of quoted script code:

# VMDirBas : A place where this virtual machine (and perhaps others) store
#          related files. This does not need to be unique for this machine.
[ "X${VMDirBas}" = "X" ] || echo Using existing \${VMDirBas} of ${VMDirBas}

#          Only set if not pre-set. (Allows easy override.)
[ "X${VMDirBas}" = "X" ] && export VMDirBas=/srv/bigspace/myvm
# Note: this should NOT end with a slash. (If you really want to specify
#  the root directory, then specify a period after the slash ("/.") (without
#  the quotation marks).

Make the part after the equal sign be set to use the same value as the environment variable (that was set by Handling environment variables: virtual machine environment). (This is on a line that contains the word export.) (If you forgot the value you set, you can either exit the text editor and check, or check the notes that you made when this guide recommended recording the value.)

[ "X${VMDirBas}" = "X" ] && export VMDirBas=/srv/bigspace/myvm

Check the amount of memory. For instance, the script file may have a line that says “ -m 272 ” If that seems reasonable, then use it. Otherwise, customize it.

One thing to keep in mind, when determining the amount of memory, is how much memory is recommended by the operating system that the virtual machine will be using. Another factor is to determine how much memory is recommended for the software that will be getting used. Another factor to consider is how much memory is going to be available on the physical host that will be running the virtual machine.

Boot code location

Handle the options related to the code that will be booted.

File path

Find the lines that say:

# These are sane defaults, except the CD-ROM path should be customized.
#   If you don't like these defaults, consider changing: VMScrGen=2
[ "X${VMOptCDR}" = "X" ]&&VMOptCDR=" -cdrom /mypath/os_install.iso "
customize that path to point to another ISO image, if applicable

Place the correct file path in the -cdrom line. (A default “-cdrom /mypath/os_install.iso” line exists, pointing to a pre-typed filename. That filename likely needs to be corrected/updated.)

For instance, for OpenBSD version #.#, use the appropriate cd##.iso file.

Specify boot device

If your system uses a common simple setup of a single hard drive, and a boot file, then make sure that “boot” goes to the “d” drive (“-boot d”). (This is probably okay by default, but check it just to make sure. Such a check may be particularly useful if the script file was a copy of another file that may have already been customized.)

Escaping newlines
Old info

(This is old information, which hasn't been completely removed from this guide yet. However, it was based on an earlier version of the script, and is no longer applicable. Skip it.)

Near the -m and -cdrom options, many of the lines should end with a backslash. In the default script file that is provided by this guide, each of the lines between the “echo Now starting to run Qemu...” line, and the following echo statement, ought to have a backslash before each of the “newline” character. That means that the line should end with a backslash. If any of those backslashes were inadvertedly removed while customizing another line, then place them back.

Other/optional updates to start script


Output method

Qemu can be configured to implement a system's local display output by using a version of the “curses” terminal emulation library.

This step is optional. It involves a bit more work at this point of the process, but some people will like it.

Currently, this guide does NOT recommend using curses for people who are looking for the simplest possible experience, in case there are complications caused by multiple programs writing to a single terminal. Instead, this guide uses the route of using VNC, which is more steps, but less prone to cause some rather confusing situations. This guide does not currently have details of how to handle some potentially confusing situations that could arise when using the curses library. So, only do that at your own risk, if you are willing to deal with challenges related to using curses.

If you wish to have the virtual machine's output be sent directly to the terminal, see: Qemu display: curses for directions on setting that.

Final pre-run script content adjustments

By default, the script file performs some behaviors that some people may find are less than ideal. These items don't need to be changed, but people might desire some changes. Making the changes now, while still in the text editor that is editing the script file, may be a relatively convenient time to make these changes if desired.

  • This guide is not currently recommending any of the steps in this “Final pre-run script content adjustments” section. The adjustments are just mentioned as a reminder for people who do want to make such changes, because some people may wish to perform these steps. However, these are not necessary to perform at this time. (If you wish to skip the optional steps, proceed to the section about setting permissions.)
Display output

With the startup script that this guide points people to use, the default behavior is to send visual output to an internal display which is not immediately visible.

(Details have been moved to: Qemu display: curses.)

Virtual machine starts stopped

With the startup script that this guide points people to use, the end of the virtual machine's command line contains a -S option. This stops (pauses) the virtual machine as soon as the virtual machine software is started.

This can be nice, or may be viewed as an unpleasant nuisance. One nice part is that a person can make sure they can see the virtual machine before the virtual machine starts running. This lets the entire virtual machine process be visible. By pausing the machine, a person can take available time to perform an action like creating an SSH tunnel and then using software to create a VNC connection through that tunnel.

At some point, the -S option may be a nuisance for a machine that automatically starts. The option can simply be removed at a later time. Additionally, a person can elect to remove the -S option at this time, if desired.

With that, the content of the file will typically be sufficient for starting a machine. Actually, networking can be rather complex, but this guide delays networking to be a topic to address later. Admittedly, networking is important and may even be critical for successfully installing the operating system. (Or, networking might not be typically needed for installing the operating system. Some operating systems can download data over the network. If that is the process that is being used, then networking is critical for that to function.)

For now, this guide recommends trying to verify that the virtual machine can even start. That test helps to validate the actions already taken so far. The topic of networking will be re-visted later (soon).

Save changes

Save changes.

At this point, you'll probably want to get to a command prompt. So, if you are minimizing the number of command prompts that you use, then exit the text editor. (Otherwise, make a new available command prompt, if needed.)

Setting permissions
Standard variable check
echo VMDirBas=${VMDirBas} VMGenNam=${VMGenNam} VMLILNAM=${VMLILNAM}

See Set some initial variables to identify a script.

See: ][CyberPillar][ Overview: Outputting variables.

Set permissions:

ls -l ${VMDirBas}/execbin/${VMGenNam}/${VMLILNAM}/sysstart/exc_${VMLILNAM}
sudo chmod ug+x ${VMDirBas}/execbin/${VMGenNam}/${VMLILNAM}/sysstart/exc_${VMLILNAM}
ls -l ${VMDirBas}/execbin/${VMGenNam}/${VMLILNAM}/sysstart/exc_${VMLILNAM}

This should change the permissions from starting with “-rw-rw-” to starting with “-rwxrwx”. Those x's are related to permission to execute the file.