Preparing for Offspring

Status report

Okay, so now you've had the fun of creating a virtual machine. (Hey, even if it didn't seem entertaining, it was probably a lot less frustrating than what some people consider to be fun. Check out what an operating system developer identifies as fun!)

Soon, this guide will have the user working with a network of multiple “virtual machines”. The good news is that these extra machines are going to be created by essentially copying the progress that has been made so far. Instead of needing to replicate all of the required work that has already been poured into the creation of a single machine, that investment will become useful time and time again.

First, though, there are some steps worth taking to polish up the state of the current machine so that it will become even more worthwhile to copy.

Backup

Some of this stuff, like deleting files, is a bit destructive. Making a backup copy of the virtual machine's disk may be relatively quick and easy, and be something you're quite thankful for later. (In truth, this might be skipped if data storage is slightly limited, like storing an 8-16GB disk image on a 32GB SDHC card. However, if space is super-abundant, such as multi-terabyte hard drives, then this process is recommended, despite the minor hassle of needing to shut down the virtual machine.)

If the correct earlier steps of this guide have been followed, then the following may be used to shut down the virtual machine.

echo VMDirBas=${VMDirBas} VMGenNam=${VMGenNam} VMLILNAM=${VMLILNAM}
${VMDirBas}/execbin/${VMGenNam}/${VMLILNAM}/sysstop/stop_${VMLILNAM}
Backing up first drive

Make a copy of the main disk. For example, first, run:

echo VMCrDsNm=${VMCrDsNm} VMDskSml=${VMDskSml} VMDskBeg=${VMDskBeg} VMDskEnd=${VMDskEnd}
export VMCrDsNm=1
export VMDskSml=${VMLILNAM}${VMCrDsNm}-pre-parent.qc2
unset VMDskBeg VMDskEnd

Then,

Clean-up recently made file
sudo mv -i ${VMDskBeg} ${VMDskDir}/old/${VMLILNAM}${VMCrDsNm}-pre-parent-uncompressed-child.qc2

...

Clean-up older file
sudo mv -i ${VMDskDir}/${VMLILNAM}${VMCrDsNm}-after-first-packages.qc2 ${VMDskDir}/old/.
Childing first drive

You can start to use a child image too, if you want. (This guide is currently written, assuming that is done.)

echo VMDsCrNm=${VMDsCrNm}
export VMCrDsNm=1
export VMDskMom=${VMDskEnd}
VM: Mk Kid Disk: Common Steps
Handling second drive
echo VMCrDsNm=${VMCrDsNm} VMDskSml=${VMDskSml} VMDskBeg=${VMDskBeg} VMDskEnd=${VMDskEnd}
export VMCrDsNm=2
export VMDskSml=${VMLILNAM}${VMCrDsNm}-pre-parent.qc2
Safe process
Backing up second drive
unset VMDskBeg VMDskEnd

Then,

Clean-up recently made file
sudo mv -i ${VMDskBeg} ${VMDskDir}/old/${VMLILNAM}${VMCrDsNm}-pre-parent-uncompressed-child.qc2
Childing second drive

You can start to use a child image too, if you want. (This guide is currently written, assuming that is done.)

echo VMDsCrNm=${VMDsCrNm}
export VMCrDsNm=2
export VMDskMom=${VMDskEnd}
VM: Mk Kid Disk: Common Steps
Alternative

Then, the safe process is to re-perform all of compressing a virtual machine disk.

  • Alternatively, some steps can probably be skipped. As long as things work (like not running out of disk space), some time may be saved by skipping all of the steps before running the “time sudo qemu-img convert ...” that worked. However, don't skip that step (nor the later ones).
Copying the system

This guide then has people follow the steps at:

Commentary

Note that this is a rather improper copy:

  • The identification files have been duplicated; ideally they should be made unique.
    • The current plan is to just not worry about this, because these “identification files” will be deleted in the near-ish future, anyway.
  • Ideally, the new system and the demo system would have unique IP addresses
    • During the creation of the demo system, simplicity was desired, and this guide chose to use the common IP address for a firewall/gateway. That seemed sensible, to help make such an address seem more familiar. If the “demo” system ever gets used again, adjusting its IP addresses (maybe to end with “4”) may be the preferred way to handle it.

In the long term, these issues end up being insignificant if the “demo” system doesn't get used again, so this guide isn't going to worry about them. Just remember that there are some items that should be addressed if the “demo” system gets used at the same time as the new “parent” system.

Finally, go ahead and start the new machine.

${VMDirBas}/execbin/${VMGenNam}/${VMLILNAM}/sysstart/exc_${VMLILNAM}
Starting the virtual machine
Interacting with the new system

At this point, if the TCP port forwarding isn't active, you might not need to set it up, because there may be little need to start using Qemu's built-in VNC server. Instead, if you simply wait a few minutes, you may find you can SSH into a known IP address.

(That said, seeing the system via VNC isn't a bad thing, and setting that up may be a satisfying task to perform while the system boots up. If the system ends up NOT getting any anticipated IP address, then having that functional VNC may be useful.)

Keep in mind that if you do try to use the Qemu monitor, it may now be using a different TCP port number, because the “virtual machine” startup script (exc_${VMLILNAM}) uses a TCP port number based on the value of ${VMNUM}.

Logging in

Presumably, one can log into the new “virtual machine” using the same “user account” name that worked to log into the old “virtual machine”.

Customizations to make
Identities

Right now, there are two computers (one of which is presumably powered off) that basically look identical. The hard drives are identical, so any identities stored on the hard drives will look identical. It is good to change that ASAP, to help diminish/prevent potential confusion ASAP. This way, a person can easily identify a system while making other sorts of changes (like networking addresses). If an administrator is making changes without correctly identifying which system is being used, then it is easy for changes to be made to on the wrong systems (or for required changes to be skipped).

Details may be OS-specific. For Unix, the “ hostname ” command may be helpful to get the hostname to be viewed, and changed temporarily. However, there may be another location where the hostname needs to be changed, which is a detail that may vary somewhat commonly.

Setting the hostname in OpenBSD
hostname
cat /etc/myname
cpytobak /etc/myname
echo newname.domainname.zz| sudo -n tee /etc/myname

(This is a case where this guide is intentionally using the tee command, but is not using the -a option for that command. We want the info to replace the old data. We're not deleting the old file first, simply to eliminate a short time where the system doesn't have a name in this file.

sudo hostname $( cat /etc/myname )
hostname
hostname -s
Networking

After that, setting up networking may be the highest priority, so that SSH can start to be used.

Butchering the customizations

Log into the system. (If the system is still stopped, go ahead and start it up.)

Some effort may have been made to set up certain functionality. Part of the reason to make things work may have simply been to verify functionality, as a test. For instance, setting DNS settings can help to verify that network communications are routing sufficiently. (There may be other advantages, like being able to easily install softare.) However, some of those settings may be changed, breaking functionality (temporarily).

At this point, the goal is going to be to try to make this system seem, as much as possible, like a generic system.

Some of these following instructions may have been made under the assumption that the first/demo/example system has been copied, and that a copy named mom/parent is being used. Some instructions, like changing the system name, might not make quite as much sense. (If you change the system's hostname in the “virtual machine”'s “operating system”, but then don't change other names, you could have one or more naming mismatches. Other names include the names of the scripts that are used to start up the system and shut down the system, the disk image names, the directory names, and so forth. So, only change the name if it makes sense to do so...)

System host name

What is the disk image going to be used for? If this disk image will be used for computers that are part of a specific organization, or a specific project, then it makes sense to make the system's name reflect that. (If you are doing the same project as other students in a classroom, then your copy of the project name might include an identifier that identifies each of the virtual machines as being as one of your computers. So, including an identifier, like your name or initials or ID number, may be sensible. In a formalized training, there may be some sort of standard that people are encouraged or expected to be following, so follow the guidance provided by class documentation.)

It may also make sense to give the machine a name that reflects that this is the parent image.

OpenBSD
hostname
sudo cpytobak /etc/myname
echo basedisk.project.example.net.zz| sudo -n tee -a /etc/myname
sudo hostname $( cat /etc/myname )

(It appears that last line might be unnecessary... Or that simply running hostname with no parameters might refresh the hostname based on what is in the file?)

Login name

(This step is of rather limited usefulness, as long as appropriate measures (like disabling login credentials that may be used elsewhere) are taken. So, for now, this guide is recommending to skip this step.)

Rationale

If this is a parent image, it may be nice to use some sort of custom login name, along with keys that are used for the purpose of logging into newly created systems. If those SSH are different than the SSH keys that will be used for regular maintenance, then a person can keep the regular SSH out of the parent image. That way, if a person (who might not have authorization) creates a new child image, that action doesn't give them access to a copy of the key files that are in regular use.

To summarize that: the idea here is to create a new user account that will be used for logging in the first time.

For instance: maybe I've been using an account name like netadmin, sysadmin, admin, boxruler, or something along those lines. However, we'll create a new account named “firstlog”.

Later, after a child image is created, the firstlog account will be used for the first login. That account will be used to provide the desired authentication for another account that may use another name (like netadmin) which is preferred for long term usage.

sudo adduser

This user needs to be given administrator access to this computer. That way, when a child image is created, this account can be used to grant administrator access to an account that will be used in the long term. If the SSH is currently set up for another user, it may be possible to copy or move the existing configuration. For instance:

sudo ls -l ~firstlog/.ssh/authorized_keys
sudo mv -i ~netadmin/.ssh/authorized_keys ~firstlog/.ssh/
sudo chown firstlog:firstlog ~firstlog/.ssh/authorized_keys

From now on, just plan to use the firstlog account on this machine, until the “child” disk images are being used.

(end of section)

NIC addresses
ls -lF /etc/hostname.*
cat /etc/hostname.nic#

e.g.:

ls -lF /etc/hostname.*
cat /etc/hostname.em0
Protect yourself

Note that if the system wasn't using automatic addressing before, then, by doing this, you may lose the ability for the system's networking to function as expected when the system reboots. It may be a great idea to document the current configuration, so that you can quickly know how to manually fix the networking if a reboot becomes needed. This information might not need to be stored in long term documentation. Storing this in a seperate file, which is intended to be a temporary file for scratch notes, may be a fine approach.

Simply run this:

ifconfig em0

And then jot down the important information (most especially: the IP addresses).

Auto addressing

If automatic addressing will be used by most of the systems that will be using this disk image, then this file should be changed to use automatic addressing. For example:

sudo rm -i /etc/hostname.em0
echo !echo Initializing \${if}...| sudo -n tee -a /etc/hostname.em0
echo \# IPv4 auto-config| sudo -n tee -a /etc/hostname.em0
echo dhcp| sudo -n tee -a /etc/hostname.em0
echo \# Set the UP flag.  Doing this before IPv6 router advertisements| sudo -n tee -a /etc/hostname.em0
echo up| sudo -n tee -a /etc/hostname.em0
stuff to skip for now

(This example mentions rtsol and autoconf, but such automated IPv6 technologies are not intended to be part of the current version of this guide. To have things work smoothly, instead of possibly using configurations that are not fully supported (perhaps because not every required system is supporting the standard for now), this guide is currently recommending to skip those lines for now.)

echo \# Send Router Solicitation for IPv6 auto address assignment| sudo -n tee -a /etc/hostname.em0
echo !ifconfig \${if} inet6 autoconf| sudo -n tee -a /etc/hostname.em0
echo rtsol| sudo -n tee -a /etc/hostname.em0

And then, with this command...

ls -l /etc/hostname.em0

You can see the “insecure” permissions(or does it say "not secure"?). (When /etc/netstart runs on this interface, it will change the permissions from the default, “-rw-r--r--”, to “-rw-r-----”.)

Static

If most systems will be using static addressing, then it may make sense to set the address to something that is clearly, obviously wrong. That way, if anybody (such as yourself... or another administrator who, in the future, may be authorized to work on this system) ends up forgetting to customize the address, and they see the address, then they will quickly know that address needs to be customized.

sudo rm -i /etc/hostname.em0
echo !echo Initializing \${if}...| sudo -n tee -a /etc/hostname.em0
echo \# IPv4 static config| sudo -n tee -a /etc/hostname.em0
echo inet 192.0.2.2 255.255.255.0 NONE description ""| sudo -n tee -a /etc/hostname.em0
echo \# Set IPv6 static address assignment| sudo -n tee -a /etc/hostname.em0
echo inet6 2001:db8::1 64| sudo -n tee -a /etc/hostname.em0
echo \# Routing info...| sudo -n tee -a /etc/hostname.em0
echo !route add 0.0.0.0/0 192.0.2.1| sudo -n tee -a /etc/hostname.em0
echo !route add ::/0 2001:db8::1| sudo -n tee -a /etc/hostname.em0
echo \# Set the UP flag.  Doing this before IPv6 router advertisements| sudo -n tee -a /etc/hostname.em0
echo up| sudo -n tee -a /etc/hostname.em0
  • (This is an unusual case where this guide recommends actually placing the example IP addresses, from 2001:db8:: and IPv4 192.0.2/24, directly onto a system without replacement. The text shown above can be copied as “literal text”. Those network addresses will need to be customized, but they are best to customize at a *later* part of the process.)
Update

To clarify, here is the current recommendation:

cpytobak /etc/hostname.em0
sudo rm -i /etc/hostname.em0

Do it!

echo !echo Initializing \${if}...| sudo -n tee -a /etc/hostname.em0
echo \# IPv4 auto-config| sudo -n tee -a /etc/hostname.em0
echo dhcp| sudo -n tee -a /etc/hostname.em0
echo \# Set the UP flag.  Doing this before IPv6 router advertisements| sudo -n tee -a /etc/hostname.em0
echo up| sudo -n tee -a /etc/hostname.em0
echo \# Set IPv6 static address assignment| sudo -n tee -a /etc/hostname.em0
echo inet6 2001:db8:1::ffff 64| sudo -n tee -a /etc/hostname.em0
echo \# Routing info...| sudo -n tee -a /etc/hostname.em0
echo \# IPv4 routing is expected to be handled by DHCP...| sudo -n tee -a /etc/hostname.em0
echo !route add ::/0 2001:db8:1::1| sudo -n tee -a /etc/hostname.em0
echo up| sudo -n tee -a /etc/hostname.em0
echo ${VISUAL}
sudoedit /etc/hostname.em0
  • It is NOT intended that the IPv6 address matches the IPv6 routing address
    • Actually, it is intended that they both be customized.
  • Subnets should have been chosen by now. If not, decide on the subnets because they are going to start being used.
  • Update the IPv6 address to refer to a non-sense/example address, or a reserved address.
    • Recommended: Make it an address that is reserved for new systems. This way, new systems can be remotely accessed relatively easy. Make a policy that changing the address should be a very early step for new systems (along with other early actions, like changing an administrator password, and changing the identification (e.g., hostname) of the system). (For example, upcoming instructions have this be done in Early actions for “child” virtual machines: Network Configuration.)
  • Have the IPv6 address be on the vmSvrs subnet. (See: Sample subnets (used by this guide).)
  • Have the IPv6 routing address (on the “!route” line) be the gateway address for the vmSvrs subnet. This will end up being an address used by a NIC (the second NIC) on the “virtual machine” which is a firewall.
Use local servers
Rationale

Have computers use local resources. Go ahead and specify the addresses of local servers, even if those local servers don't exist yet.

The point here is that the configuration files are being altered for default settings. If *most* of the computers will be using those local servers, then those local servers should be the defaults that get used over the long term, even if those servers aren't functional yet. If the servers aren't functional yet, that little detail is expected to cause no problems or few problems, and those few problems can be worked around relatively well.

So, as a more specific example, if most computers will be using a DNS server of 192.0.2.4, then go ahead and set the configuration to use 192.0.2.4 as the DNS server. It doesn't matter if the DNS server at 192.0.2.4 hasn't been set up yet. If a server isn't currently operational, that is presumably a rather temporary, short-term scenario. The goal here is to change the configuration files to use values that will work best in most cases over the long term.

Having a plan

However, before you do this, you really ought to have a good idea of what network addresses the systems will be using. (This includes identifying what subnet they will be using.) Otherwise, work is likely to be used ineffectively.

  • If this network is being created as part of a project, check the project documentation
  • If your project is going to be connecting to an existing local network, you may wish to become familiar with some of the services provided by the rest of the local network. If such services are not documented, contact the network administrators to see what is available.
  • If you are creating a brand new network from scratch, such servers might not exist yet. Still, it makes sense to design a network with the idea that such services will exist. Usage of Network Addresses for individual hardware/software maybe a resource for helping to apply a bunch of numbers to a bunch of systems.

Definitely know what subnet is going to be used. Have a very good idea (it is best to completely know) what addresses will be getting used for some key services.

Remember to be in the good habit of backing up files before making changes.

Use local DNS servers
Using local DNS/IPv4 servers

If using DHCP/IPv4 then no manual DNS configuration needs to be done at this time. Instead, the child images can use the DNS configuration details that are provided when the DHCP/IPv4 communications occur.

Using local DNS/IPv6 servers

This guide is not currently providing extensive detailed steps for IPv6.

(Using FEC0:0:0:ffff::/126 in a new deployment would violate the rules, and the intent, of RFC 3879 section 4, though that text does say the addresses “MAY” be used by some networks, so using these addresses is unlikely to break things. They may also be supported by some devices.)

So, at this time, no steps are generally required for this section. However, if you are using a custom design, and you know better, then go ahead and provide the custom settings that you use.

These instructions don't really say how to do this... That doesn't really matter too much, because DHCP commonly overrides these settings. (Still, some applicable details would be appropriate.)

system addressing plan: initial/early addresses has DNS servers at .4 and .5 so placing addresses to the vmSvrs subnet, ending with those partial addresses, may be appropriate.

cpytobak /etc/resolv.conf
echo ${VISUAL}
Use local NTP servers
Rationale

The rationale for choosing a NTP server (like not getting banned) is described by choosing an NTP server.

Using DHCP
This should be an option. (There are no details, tested at the time of this writing, currently here...) BOOTP/DHCP option 42 might be related. http://www.openbsd.org/faq/faq6.html#DHCPclient seems to indicate that dhclient places info in resolv.conf (Info about DHCP option 42 is documented elsewhere in this guide, on the NTP page, and the DHCP page ( vmdhcpd4.htm). Cross-hyperlinking may be done. For now, simply ignore this option, and see the section about manually specifying private servers.)
Manually specifying private servers

Choose an address to be a time server. (Or, more than one.) (As an example, Usage of Network Addresses for individual hardware/software: “A more exhaustive plan” uses 14 as a number for a network address related to time. That's not a widespread formal standard.)

ls -lF /etc/ntpd.conf*
echo listen on \*| sudo -n tee -a /etc/ntpd.conf.privsvr
echo server 192.0.2.14| sudo -n tee -a /etc/ntpd.conf.privsvr
echo servers ntpsvr.private.localnet.zz| sudo -n tee -a /etc/ntpd.conf.privsvr
echo \# DISABLED: constraints from \"https://www.google.com/\"| sudo -n tee -a /etc/ntpd.conf.privsvr
ls -lF /etc/ntpd.conf*
  • This guide is temporarily recommending against using the “constraints”.
    • It seemed to have a significant impact of not letting peers be detected as valid.
      • Perhaps the issues in communication were related to some strict firewall rules that were in place. Further research may be warranted. For now, initial testing indicated that removing contraints did seem to make things work better. Therefore, that line is being commented out, for now.
  • If constraints are being used, there are multiple syntaxes shown at OpenBSD Journal @ Undeadly.org: s2k15: Authenticated TLS 'constraints' in ntpd(8). One syntax shows an entire URL within quotes, and another shows a domain name that is not in quotes.

(The above example shows an IP address and a DNS name, both of which are simply examples pointing to existing resources.)

(The guideline, which is being used in that example, is to use “server ” for IP addresses, and “servers ” for DNS names. That “rule of thumb” is not an official rule that must be strictly followed because of some technical limitations by the people who created the software. Rather, that is just a guideline that is being followed; this guideline is discussed further in a section of the guide about time setting with automated methods.)

Multiple “server(s)” lines may be specified, in order to specify multiple servers.

If you'd like to review/customize that file:

ls -lF /etc/ntpd.conf*
cpytobak /etc/ntpd.conf*
echo ${VISUAL}
sudoedit /etc/ntpd.conf.privsvr

Also, have the /etc/ntpd.conf.local file to use private servers.

Part one:

ls -lF /etc/ntpd.conf*
sudo cpytobak /etc/ntpd.conf.local
sudo rm -i /etc/ntpd.conf.local

And, say “yes” before moving onto part two:

sudo ln -s /etc/ntpd.conf.privsvr /etc/ntpd.conf.local
ls -lF /etc/ntpd.conf*
Alter shutdown process

Find out if this file exists. If so, then the operating system probably runs this script when the system shuts down. So, you may wish to become familiar with what the script does:

ls -l /etc/rc.shutdown
${PAGER} /etc/rc.shutdown

As a side note, there may be an example...

ls -l /etc/examples/rc.shutdown

Backup before changing:

sudo cpytobak /etc/examples/rc.shutdown

Then, use one of the following techniques:

Using a text editor...
sudoedit /etc/rc.shutdown

Insert the following text (or whatever portion of this text doesn't already exist).

#!/bin/sh

# Run code from second drive before shutting down.

[ -x /srv/hddcfg/hddcfgdn ] && /srv/hddcfg/hddcfgdn
[ -f /srv/hddcfg/hddcfgdn.sh ] && . /srv/hddcfg/hddcfgdn.sh

(Then, since that text was inserted, the prior contents can exist after the text that has been inserted.)

...or, using a command line

This provides an approximation of what is shown in the text editor section. (The current version, shown here, is less precise/pretty.)

echo \#!/bin/sh|sudo -n tee -a /etc/rc.shutdown
echo . /srv/hddcfg/hddcfgdn.sh|sudo -n tee -a /etc/rc.shutdown
echo /srv/hddcfg/hddcfgdn|sudo -n tee -a /etc/rc.shutdown
Any other adjustments

Soon, the parent image will be done. If there are any other changes desired, now is just about the last chance to do them.

For example, what shell do you wish to use? This guide is perfectly happy to have people use “OpenBSD's ksh”. However, if you wish to proceed with a difference choice, you can specify an alternative using the chsh command. If this change is desired, or any other changes are desired, now may be about the time to do so.

last-minute thought: /etc/*tty* secured further?

Delete identity files
Removing Identity Files
Changes to do towards very end
wrapping up base image changes
Shut down

If logged into the system:

sudo halt -p
Why SSH won't work

Normally, to shut down a system, you could also try to use a device that has the relevant private key...

ssh -i keyfile -l _endsys -p 22 sysname-or-IPaddress

However, SSH is probably broken since the key files were deleted.)

Compressing and childing
echo VMDirBas=${VMDirBas} VMGenNam=${VMGenNam} VMLILNAM=${VMLILNAM}

verifying variables related to virtual machines

Verify what filenames are expected to be used by the virtual machine.

grep -i " -hd" ${VMDirBas}/execbin/${VMGenNam}/${VMLILNAM}/sysstart/exc_${VMLILNAM}

View the files in that location

ls -l ${VMDirBas}/diskimgs/baseimgs/${VMGenNam}/${VMLILNAM}/
Compress the first disk
echo ${VMCrDsNm}
export VMCrDsNm=1
echo ${VMDskSml}
export VMDskSml=${VMLILNAM}${VMCrDsNm}-parent-compressed.qc2
unset VMDskBeg VMDskEnd

... and then, follow the steps at: virtual disk small

Make sure not to skip this step:

sudo chmod a-w ${VMDskEnd}
ls -Fltr ${VMDskDir}
echo ${VMCrDsNm}
export VMCrDsNm=1

Also, perform clean-up:

sudo mkdir ${VMDskDir}/old/
ls -l ${VMDskDir}
ls -l ${VMDskEnd}
ls -l ${VMDskBeg}
sudo mv -i ${VMDskBeg} ${VMDskDir}/old/${VMLILNAM}${VMCrDsNm}-parent-uncompressed.qc2
sudo mv -i ${VMDskDir}/${VMLILNAM}${VMCrDsNm}-pre-parent.qc2 ${VMDskDir}/old/.
Childing the first disk

(This first command is probably unnecessary, but is mentioned to help people to not accidentally perform only part of the needed instructions.)

export VMCrDsNm=1

Specify the parent image that the child image will require...

Here is one advantage to childing a disk right after compressing the disk (instead of moving on to compressing the next disk)... the name of the desired parent image is still convenient stored in a variable.

export VMDskMom=${VMDskEnd}

(Presumably that is currently pointing to ${VMDskDir}/${VMLILNAM}${VMCrDsNm}-parent-compressed.qc2 file.)

VM: Mk Kid Disk: Common Steps

Then, the child disk doesn't really need to be written to further. (That will be explained further in upcoming text. For now, just perform the following step to help protect the file.)

sudo chmod a-w ${VMDskKid}
ls -Fltr ${VMDskDir}
Compress the second disk
echo ${VMCrDsNm}
export VMCrDsNm=2
echo ${VMDskSml}
export VMDskSml=${VMLILNAM}${VMCrDsNm}-parent-compressed.qc2
unset VMDskBeg VMDskEnd

... and then, follow the steps at: virtual disk small

Make sure not to skip this step:

sudo chmod a-w ${VMDskEnd}
ls -Fltr ${VMDskDir}

The VMCrDsNm variable should not be cleared off quite yet. If it was, re-assign its value.

echo ${VMCrDsNm}
export VMCrDsNm=2

Also, perform clean-up:

ls -l ${VMDskDir}
ls -l ${VMDskEnd}
ls -l ${VMDskBeg}
sudo mv -i ${VMDskBeg} ${VMDskDir}/old/${VMLILNAM}${VMCrDsNm}-parent-uncompressed.qc2
sudo mv -i ${VMDskDir}/${VMLILNAM}${VMCrDsNm}-pre-parent.qc2 ${VMDskDir}/old/.
Childing the second disk

(This first command is probably unnecessary, but is mentioned to help people to not accidentally perform only part of the needed instructions.)

export VMCrDsNm=2

Specify the parent image that the child image will require...

export VMDskMom=${VMDskEnd}

VM: Mk Kid Disk: Common Steps

Then, the child disk doesn't really need to be written to further. (That will be explained further in upcoming text. For now, just perform the following step to help protect the file.)

sudo chmod a-w ${VMDskKid}
ls -Fltr ${VMDskDir}
Overview...
ls -Fltr ${VMDskDir}

At this point, each of the remaining images should be read-only. After compressing a disk, most systems will want to have the new “child image” be writable. However, this system is meant as a parent image.

At this point, the compressed copies of the image should not need to be updated. Hopefully there won't be any need to adjust the parent image. If there is, then there is a set of instructions that can be followed. However, the instructions for adjusting the base image is a rather time-consuming process, including the need to re-create any children (or carefully preserve the old image for existing “child disks” to be able to use).