Context
You are asked to install a GNU software package from source code.
Task
First, configure the software package at ~/bool with all default settings.
The software package has been unpacked and all tools required for a configuration have been pre-installed for your convenience.
Next, build the software package at ~/bool.
All tools and dependent libraries required for compilation have been pre-installed for your convenience.
Finally, install the built software package.
See the complete solution in Explanation.
Objective: Configure, compile, and install the GNU software package already extracted into ~/bool, using its default build and installation settings.
The standard GNU build procedure consists of three main commands, executed in this exact order:
/configure
make
sudo make install
The official GNU Autoconf and Automake documentation confirms this sequence for packages using the GNU build system.
Step 1: Connect to the correct Linux server.
The task is associated with host lfcs00102.
From the candidate terminal, execute:
ssh lfcs00102
This establishes an SSH session with the server where the source-code package must be configured, compiled, and installed.
All subsequent commands must be executed on this host.
Step 2: Navigate to the software source directory.
Execute:
cd ~/bool
cd changes the working directory.
~ represents the current user's home directory.
bool is the directory containing the extracted software source code.
Verify the current directory:
pwd
Expected structure:
/home/candidate/bool
The actual home directory depends on the account used on the host.
Step 3: Inspect the extracted source files.
Execute:
ls -la
A GNU Autotools-based source package commonly contains files such as:
configure
Makefile.am
Makefile.in
configure.ac
README
INSTALL
src/
These are examples of commonly encountered files; the actual directory contents may differ.
The critical file for the first stage is:
configure
The task explicitly states that the package has already been unpacked and the required development tools are installed.
Therefore, there is no need to download another source archive, extract additional files, or install development packages.
Step 4: Verify that the configuration script exists.
Execute:
ls -l ./configure
Then check whether it is executable:
test -x ./configure
echo $?
Expected exit code:
0
If the file is readable but lacks execution permission, you can inspect its permissions:
stat -c '%A %a %n' ./configure
Before changing permissions, confirm that the file is the actual generated configuration script.
If necessary, a readable configure shell script can also be executed with:
sh ./configure
However, the normal and preferred invocation for this task is ./configure.
Step 5: Configure the software package using all default settings.
Execute:
/configure
This is the first essential command.
The configure script examines the system and prepares the source tree for compilation.
Typical checks include:
Operating system and processor architecture.
Available C compiler.
Compiler capabilities and flags.
Required libraries and header files.
Build utilities and dependencies.
Installation directory configuration.
Generation of Makefiles.
An illustrative output might include:
checking for gcc... gcc
checking whether the C compiler works... yes
checking for stdio.h... yes
checking for stdlib.h... yes
checking for make... make
configure: creating ./config.status
config.status: creating Makefile
The output will differ according to the source package.
Important: The task requires all default settings. Therefore, do not specify configuration arguments such as:
/configure --prefix=/opt/bool
or:
/configure --disable-shared
unless explicitly requested.
Using plain ./configure ensures that the package's own default configuration options are selected.
GNU Autoconf documents that the default installation prefix is commonly /usr/local, although packages can choose another default.
Step 6: Verify that configuration completed successfully.
Immediately after ./configure finishes, execute:
echo $?
Expected:
0
Exit status 0 indicates that the configuration script completed successfully.
Next, verify the generated Makefile:
ls -l Makefile
You can also check for the configuration status file:
ls -l config.status
For a standard Autoconf package, these files indicate that configuration generated the instructions required for compilation.
If configuration reports a missing dependency or another error, investigate that specific error before proceeding to the build stage.
Do not assume that configuration succeeded merely because some files were generated.
Step 7: Inspect the generated Makefile.
Execute:
ls -lh Makefile
The Makefile contains the instructions that GNU Make uses to build and install the software.
You can inspect the default installation prefix:
grep -E '^prefix[[:space:]]*=' Makefile
A typical result is:
prefix = /usr/local
This means that the package is configured to install files under /usr/local, unless it defines different destinations.
Common GNU installation directories include:
Directory
Typical purpose
/usr/local/bin
User executables
/usr/local/sbin
Administration executables
/usr/local/lib
Program libraries
/usr/local/include
Header files
/usr/local/share
Architecture-independent data
Do not modify the installation prefix because the task requires the default settings.
Step 8: Build the software package.
Execute the second essential command:
make
This instructs GNU Make to build the software using the generated Makefile.
During compilation, Make may perform operations such as:
Reading the Makefile.
Identifying source files and dependencies.
Invoking the compiler.
Compiling source files into object files.
Linking object files with required libraries.
Producing executable programs or library files.
For a package written in C, an illustrative compilation sequence may look like:
gcc -DHAVE_CONFIG_H -I. -c main.c -o main.o
gcc -DHAVE_CONFIG_H -I. -c util.c -o util.o
gcc -o program main.o util.o
These commands are examples. The actual compilation operations depend on the package.
GNU Make normally builds the default target when invoked without arguments. For standard GNU packages, this is equivalent to the all target.
Step 9: Understand why make should normally run without sudo.
The recommended command is:
make
Not:
sudo make
Building as the normal user is preferable because it avoids creating root-owned intermediate files inside the source directory.
Administrative privileges are generally necessary only when installing files into protected system directories.
Since the task states that all build dependencies are already installed, the compilation should not require additional package installation.
Step 10: Verify that compilation completed successfully.
Immediately after make finishes, execute:
echo $?
Expected output:
0
This confirms that the Make process returned a successful exit status.
If compilation fails, the terminal normally reports an error, such as:
make: *** [Makefile:150: all] Error 2
Such output indicates a failed build.
Investigate the preceding compiler or linker error before continuing.
Do not attempt to install a package that has not built successfully.
Step 11: Confirm the build target is up to date.
You can run:
make
again after a successful build.
If no source files have changed, Make may display:
make: Nothing to be done for 'all'.
Alternatively, it may run a small number of checks or other build commands.
This is expected behavior: Make determines which targets need rebuilding based on its rules and dependencies.
A second build is optional and does not replace checking the first command's exit status.
Step 12: Run the package tests if supported.
Many GNU software packages provide an optional test target:
make check
This runs tests defined by the package's build system.
The official GNU Automake documentation defines make check as the conventional test-suite target.
However, the task does not explicitly require running tests.
Therefore, this step is optional. Use it only if the package provides the target and running the tests is appropriate.
If tests are run, verify their outcome:
echo $?
Expected successful status:
0
Do not confuse make check with make install. Tests validate a build but do not necessarily install it.
Step 13: Install the compiled software package.
After a successful build, execute:
sudo make install
This is the third essential command.
sudo provides administrative privileges.
make executes the build system's specified target.
install invokes the Makefile's installation rules.
The command installs the compiled software into its configured destinations.
Depending on the package, installation may include:
Copying executable binaries.
Installing shared or static libraries.
Installing header files.
Installing documentation and manual pages.
Installing additional package data.
The installation location follows the settings selected during ./configure.
GNU Automake confirms that make install copies the required built files into their installation directories.
Step 14: Do not change the installation destination.
The task specifically requests the default configuration.
Therefore, avoid commands such as:
sudo make install prefix=/opt/custom
Also avoid reconfiguring the package using:
/configure --prefix=/opt/custom
These would change the normal installation destinations.
The appropriate installation command remains:
sudo make install
Step 15: Verify that installation completed successfully.
Immediately after sudo make install finishes, execute:
echo $?
Expected:
0
A zero exit code indicates that the installation target completed successfully.
If installation fails with a permissions error, verify whether administrative privileges were applied correctly and inspect the affected directory.
If a build or dependency error occurs during installation, resolve that error before treating the task as complete.
Step 16: Verify the installation destination.
Inspect the installation prefix recorded in the Makefile:
grep -E '^prefix[[:space:]]*=' Makefile
If the prefix is /usr/local, the installed files will typically be placed in appropriate directories beneath that prefix.
You can inspect standard executable locations:
ls -lt /usr/local/bin/
And, where appropriate:
ls -lt /usr/local/lib/
These commands can help identify newly installed files, but they are not conclusive on their own because other software may already exist in those directories.
For more precise verification, inspect the package's Makefile installation rules or any installation manifest it produces.
Step 17: Verify the installed executable if applicable.
If the package installs an executable, first determine its actual command name from the package's documentation or installation output.
Then execute:
command -v ACTUAL_EXECUTABLE_NAME
For example, if a package installs an executable called example-program:
command -v example-program
You can then check its version if that option is supported:
example-program --version
These commands are illustrative. The directory name bool does not prove that the installed executable is also named bool.
Do not invent an executable name when validating the installation.
Step 18: Run installation checks if the package supports them.
Some GNU packages provide the following target:
make installcheck
This runs checks against installed software rather than files within the build tree.
GNU Automake documents installcheck as an optional target for validating installed programs and libraries.
It is not mandatory for this question.
The task requires configuration, compilation and installation. A successful sudo make install operation satisfies the installation stage.
Step 19: Understand why the three commands must be executed in order.
Order
Command
Purpose
1
/configure
Detects the build environment and prepares Makefiles using default settings
2
make
Compiles and links the source code
3
sudo make install
Installs the built software into the configured system directories
Each stage depends on the preceding stage.
Running make before a successful configuration might fail because the necessary Makefile has not been generated.
Running make install without a successful build may also fail or cause the installation target to attempt compilation. That does not replace the explicitly required build step.
For the LFCS simulation, execute each required stage separately and verify success before continuing.
Step 20: Perform the final verification.
From the source directory:
cd ~/bool
Check the generated Makefile:
test -f Makefile & & echo "Makefile exists"
Check the configuration status file if the package uses Autoconf:
test -f config.status & & echo "Configuration completed"
Confirm the configured prefix:
grep -E '^prefix[[:space:]]*=' Makefile
Check that the build is up to date:
make
Finally, verify the installed files or executable using the actual package name and installation output.
A successful result must satisfy all requirements:
Requirement
Expected result
Correct host
lfcs00102
Source directory
~/bool
Configure with defaults
Successful
Build package
Successful
Install package
Successful
Custom configure options
None
Source extraction
Already completed
Dependency installation
Already completed
Final Solution
The complete essential command sequence is:
Copy commands
# Connect to the designated host
ssh lfcs00102
# Navigate to the extracted source package
cd ~/bool
# Inspect the source files
ls -la
ls -l ./configure
# Step 1: Configure with default settings
/configure
# Step 2: Build the software package
make
# Step 3: Install the built package
sudo make install
To verify the exit status of each stage reliably, use the following alternative, which stops if a required stage fails:
cd ~/bool || exit 1
/configure & &
make & &
sudo make install
This short sequence is appropriate when the provided tools and dependencies are already available, as specified in the task.
Technical Verification and References
The solution has been validated against the official GNU build-system documentation.
GNU Autoconf Manual — Explains the generated configure script and default configuration settings.
GNU Make Manual — Explains compilation using Makefiles and Make targets.
GNU Automake — Standard Targets — Documents make, make check, make install and make installcheck.
Expected result: The GNU software package located at ~/bool is successfully configured using its default settings, compiled using GNU Make, and installed through its Makefile's installation target.
Verification limitation: The prescribed sequence is supported by official GNU documentation. Whether the commands successfully complete on lfcs00102 must be confirmed from their actual terminal output and exit statuses; the supplied recording does not establish an independently tested successful installation.
Task
First, inspect the system and identify the block device under heavy write load and which user process is causing the load.
Next, kill the process causing the load and unmount the device to prevent causing issues to the storage system in case this process runs again.
See the complete solution in Explanation.
Objective: Identify which Linux block device is experiencing excessive write activity, determine the user process generating that activity, terminate the offending process, and unmount the affected filesystem.
The solution requires four main operations:
Examine block-device read/write statistics.
Identify the process responsible for the heavy disk writes.
Terminate the identified process.
Unmount the filesystem associated with the affected block device.
The video provides useful evidence about the responsible process.
Findings from the video
Required host
lfcs00099
Process generating heavy writes
batches
Observed process ID
891
Process owner
root
Observed write rate Approximately 1,200 KiB/s in one sample
Mountpoint acted on in video
/media/batches
The recording shows batches as the principal writer and the candidate subsequently unmounting /media/batches. However, the original block-device name is not established clearly enough to quote as an exact device path. The solution below includes the commands needed to confirm that mapping.
Step 1: Connect to the correct Linux server.
The video specifies host lfcs00099.
Execute:
ssh lfcs00099
All diagnostic commands, process termination and unmounting must be performed on this host.
Step 2: Examine all available block devices.
Execute:
lsblk
For a more informative output:
lsblk -p -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINTS
Column
Purpose
NAME
Absolute block-device path
TYPE
Disk, partition, or logical device
SIZE
Device capacity
FSTYPE
Filesystem type
MOUNTPOINTS
Where the device's filesystem is mounted
An illustrative output might be:
NAME TYPE SIZE FSTYPE MOUNTPOINTS
/dev/sda disk 40G
└─/dev/sda1 part 40G ext4 /
/dev/sdb disk 10G
└─/dev/sdb1 part 10G ext4 /media/batches
/dev/sdc disk 20G
└─/dev/sdc1 part 20G ext4 /media/data
This output is an example, not confirmed device assignments from the video.
Do not assume that /dev/sdb1 is the affected device until the actual machine's storage configuration is inspected.
Step 3: Identify the block device experiencing excessive writes.
Use iostat, which is part of the sysstat utilities.
Execute:
iostat -dx 1 5
-d displays block-device activity.
-x enables extended I/O statistics.
1 specifies a one-second sampling interval.
5 requests five reports.
The command displays measurements for each block device.
Pay particular attention to:
Metric
Meaning
w/s
Write requests completed per second
wkB/s
Kilobytes written per second
w_await
Average time spent completing write requests
%util
Percentage of elapsed time during which the device had I/O requests
A device with unusually high sustained write throughput compared with the other devices is a candidate for the problematic storage workload.
An illustrative comparison:
Device r/s w/s rkB/s wkB/s %util
sda 2.00 1.00 8.00 4.00 1.00
sdb 0.00 250.00 0.00 1200.00 95.00
sdc 1.00 4.00 4.00 16.00 3.00
In this example, sdb deserves investigation.
High %util by itself does not establish a device fault, especially on modern parallel-I/O storage. Evaluate write throughput, latency and workload together. The official sysstat documentation defines these metrics.
GitHub
Step 4: Identify which user process is causing the write load.
The recording uses iotop to monitor process-level disk activity.
Execute:
sudo iotop
For a view restricted to processes currently performing I/O:
sudo iotop -oP
-o shows processes actively performing I/O.
-P presents process-level information rather than individual threads.
iotop displays process IDs, owners, disk-read rates, disk-write rates and command names.
The important columns are:
TID PRIO USER DISK READ DISK WRITE COMMAND
The task concerns heavy writes, so focus on DISK WRITE, not DISK READ.
The official iotop manual confirms that these measurements represent process-level I/O activity.
Linux manual page
Step 5: Identify the offending process from the video.
At approximately 32:45–33:25 in the recording, the terminal shows iotop output with processes including:
PID USER DISK READ DISK WRITE COMMAND
891 root 0 B/s ~1200 KiB/s batches
927 root ~1200 KiB/s 0 B/s ingest
909 root ~20 KiB/s ~20 KiB/s data
944 root ~20 KiB/s ~20 KiB/s export
These are rounded observations from the displayed sampling interval, not fixed process characteristics.
The important distinction is that ingest is responsible mainly for read activity in the observed samples, whereas batches is the dominant writer.
Therefore, the process to investigate and terminate is batches, observed as PID 891.
PIDs are assigned dynamically and must be checked on the live system before termination.
Step 6: Verify the identity of the process.
On the exam host, execute:
ps -p 891 -o pid,ppid,user,comm,args
For the recorded session, the command should identify batches if PID 891 is still assigned to the same process.
The ps output displays:
PID: process identifier.
PPID: parent process identifier.
USER: account that owns the process.
COMMAND/ARGS: executable name and command-line arguments.
If the PID is different in a fresh session, substitute the PID obtained from iotop.
Do not terminate PID 891 blindly on another system.
Step 7: Verify the process's actual write activity.
Linux exposes per-process I/O statistics through:
/proc/PID/io
For the observed PID:
sudo cat /proc/891/io
The output includes fields such as:
rchar:
wchar:
syscr:
syscw:
read_bytes:
write_bytes:
cancelled_write_bytes:
The write_bytes field reports bytes attributed to the process as writes to the storage layer.
You can inspect the relevant fields:
sudo grep -E 'read_bytes|write_bytes' /proc/891/io
Take two measurements several seconds apart to determine whether write activity is increasing.
The Linux kernel's /proc/PID/io documentation describes these counters and their limitations.
Linux manual page
Step 8: Identify the filesystem being written to by batches.
Execute:
sudo lsof -p 891
lsof lists open files associated with the selected process.
Look for open files located under the affected mountpoint.
For example, paths might begin with:
/media/batches/
If the process has an open writable file on /media/batches, that supports the connection between the observed write activity and this filesystem.
Be aware that lsof lists open resources; not every open file is necessarily responsible for the observed write rate.
Cross-check with block-device I/O measurements.
Step 9: Identify the actual block device mounted at /media/batches.
Execute:
findmnt --mountpoint /media/batches
For concise output:
findmnt -no SOURCE,FSTYPE,TARGET --mountpoint /media/batches
This displays the filesystem source and mountpoint.
For example:
/dev/sdb1 ext4 /media/batches
If this is the output, the block-device path is /dev/sdb1.
This is illustrative. The actual block device must come from the exam host.
Also verify the mapping through:
lsblk -p -o NAME,TYPE,FSTYPE,MOUNTPOINTS
The official findmnt(8) manual documents using --mountpoint to inspect the filesystem mounted at a particular directory.
Linux manual page
Step 10: Confirm that the identified device is responsible for the heavy write activity.
Compare the block device reported by findmnt with the output of:
iostat -dx 1 5
You should now have both pieces of information required by the first part of the task:
The block device experiencing the heavy writes.
The responsible process.
For the recorded scenario, the process evidence points to batches, and the candidate's selected target is /media/batches.
If the block-device statistics instead identify another device, investigate the discrepancy before terminating anything.
Step 11: Check whether the offending process is still running.
Execute:
ps -p 891
Or, using the PID obtained from the current investigation:
ps -p PID -o pid,user,comm,args
Replace PID with the actual current process ID.
Confirm the command name and owner one final time immediately before sending a termination signal.
Step 12: Terminate the process gracefully.
The recommended first attempt is:
sudo kill -TERM 891
This sends SIGTERM to the observed process.
SIGTERM requests an orderly shutdown and allows applications to perform cleanup operations.
Check whether the process has stopped:
ps -p 891
The official Linux kill(1) manual recommends attempting SIGTERM before SIGKILL when possible.
Linux manual page
Step 13: Forcefully terminate the process only if required.
The candidate in the video uses:
sudo kill -9 891
This sends SIGKILL, which terminates the process without allowing it to handle the signal.
The equivalent named-signal command is:
sudo kill -KILL 891
This is technically valid if the process cannot be stopped normally.
However, it is preferable to attempt SIGTERM first, because abruptly killing a writer may interrupt in-progress writes or application cleanup.
For the recorded process, PID 891 is the primary target. The video additionally shows the candidate killing PIDs 909 and 944, but those processes display much lower write activity. Their termination is not justified solely by the task evidence.
Step 14: Verify the offending process has stopped.
Execute:
ps -p 891 -o pid,comm
If the process has fully exited, it should no longer appear as an active process.
You can also inspect:
sudo iotop -oP
The batches process should no longer be generating disk writes.
If the process has restarted automatically with a new PID, investigate its parent process or service rather than relying on the original PID.
Step 15: Inspect remaining users of the affected filesystem.
Before unmounting, execute:
sudo fuser -vm /media/batches
This identifies processes accessing files on the filesystem.
The options mean:
-v: display verbose information.
-m: identify processes accessing the specified mounted filesystem.
The fuser documentation describes this behavior.
Linux manual page
Review the output.
If unrelated processes still need the filesystem, determine whether they can safely stop accessing it. Do not kill every listed process indiscriminately.
Step 16: Unmount the affected filesystem.
Once the offending process has stopped and the filesystem is no longer busy, execute:
sudo umount /media/batches
This is the unmount operation shown in the recording.
sudo provides administrative privileges.
umount detaches a mounted filesystem from the Linux directory hierarchy.
/media/batches identifies the target mountpoint.
The official umount(8) manual confirms that specifying the mountpoint is the normal way to unmount a filesystem.
Linux manual page
Step 17: Handle a busy filesystem if necessary.
If the command reports:
umount: /media/batches: target is busy
it means the filesystem is still being used.
Recheck:
sudo fuser -vm /media/batches
Also inspect:
sudo lsof +f -- /media/batches
A process may have open files, memory mappings, or its working directory on that filesystem.
Close those references appropriately and retry:
sudo umount /media/batches
Do not immediately force or lazily unmount the filesystem.
A lazy unmount can hide an ongoing problem by detaching the mountpoint while references to the filesystem remain. The official umount documentation warns about this distinction.
Linux manual page
Step 18: Verify the filesystem is unmounted.
Execute:
findmnt --mountpoint /media/batches
A successful unmount should result in no matching mount being displayed.
For an additional check:
mountpoint -q /media/batches
echo $?
A nonzero exit status indicates that the directory is not currently a mountpoint.
Also inspect:
lsblk -p -o NAME,TYPE,FSTYPE,MOUNTPOINTS
The affected filesystem should no longer list /media/batches as an active mountpoint.
Step 19: Verify that the excessive write activity has stopped.
Execute:
iostat -dx 1 5
Compare the affected device's write statistics against the measurements recorded before termination.
Also execute:
sudo iotop -oP
Confirm that the original heavy-writing process is no longer active.
Other normal system processes may continue performing I/O. The requirement is to eliminate the problematic workload and unmount its affected device, not to reduce all system writes to zero.
Step 20: Avoid unnecessary modifications to other devices.
The video shows the candidate issuing additional commands involving /media/data and other processes.
Those actions should not automatically be repeated.
The task asks for the block device under heavy write load and the process causing that load.
Unless measurements establish that several devices are affected, there is no reason to unmount unrelated filesystems.
In particular, do not use:
sudo umount -a
This attempts to unmount multiple filesystems and is inappropriate for a targeted storage operation.
Also do not reformat, repartition or remove the affected block device.
Unmounting does not delete the data stored on the filesystem.
Step 21: Consider whether automatic remounting is configured.
Unmounting /media/batches changes the current mounted state, but it does not necessarily prevent the filesystem from being mounted again after a reboot.
For example, the filesystem may be configured through /etc/fstab or a systemd mount unit.
Inspect relevant configuration if the requirement is specifically to keep the device unmounted across restarts:
findmnt --fstab
However, the task instructs you to unmount the device, not explicitly to remove persistent mount configuration.
Do not alter /etc/fstab or disable unrelated services without a demonstrated requirement.
Step 22: Perform final verification.
Execute:
ps -p 891 -o pid,comm
findmnt --mountpoint /media/batches
lsblk -p -o NAME,TYPE,FSTYPE,MOUNTPOINTS
iostat -dx 1 3
If PID 891 is the same offending process observed in the recording and /media/batches is confirmed as its affected filesystem, the expected result is:
Requirement
Expected result
Correct host
lfcs00099
Heavily written block device
Identified using iostat and lsblk
Responsible process
batches
Observed PID
891
Process owner
root
Process terminated
Yes
Affected mountpoint
/media/batches
Filesystem unmounted
Yes
Original excessive write activity
No longer present
Final Solution
The following is the focused command sequence for the scenario shown in the video.
# Connect to the designated server
ssh lfcs00099
# Inspect block devices and mounted filesystems
lsblk -p -o NAME,TYPE,SIZE,FSTYPE,MOUNTPOINTS
# Identify the device under heavy write load
iostat -dx 1 5
# Identify the process generating disk writes
sudo iotop -oP
# Confirm the process identity
# Video PID 891; verify the live PID before proceeding
ps -p 891 -o pid,ppid,user,comm,args
# Inspect files opened by the process
sudo lsof -p 891
# Confirm the affected block-device mapping
findmnt -no SOURCE,FSTYPE,TARGET \
--mountpoint /media/batches
# Request orderly termination
sudo kill -TERM 891
# Confirm the process stopped
ps -p 891
# Check remaining filesystem users
sudo fuser -vm /media/batches
# Unmount the affected filesystem
sudo umount /media/batches
# Verify the filesystem is no longer mounted
findmnt --mountpoint /media/batches
# Verify block-device mount status
lsblk -p -o NAME,TYPE,FSTYPE,MOUNTPOINTS
# Check write activity again
iostat -dx 1 3
If normal termination fails and the process is still confirmed to be the same offending workload, use:
sudo kill -KILL 891
Then recheck the process state and retry the unmount.
Technical Verification and References
The procedure has been checked against the following upstream Linux and sysstat documentation:
sysstat iostat Manual
— Measuring block-device I/O activity and write throughput.
Linux iotop(8)
— Identifying processes performing heavy disk I/O.
Linux findmnt(8)
— Identifying filesystem sources and mountpoints.
Linux kill(1)
— Terminating processes using signals.
Linux fuser(1)
— Identifying processes using mounted filesystems.
Linux umount(8)
— Safely detaching filesystems.
Video verification findings
At approximately 32:40–34:15, Question 16 appears on host lfcs00099. The recording shows iotop identifying batches (PID 891, owned by root) as the process producing the dominant write activity.
The candidate then runs:
sudo kill -9 891
sudo umount /media/batches
Both commands are technically valid for their respective operations. However, the recording does not provide a sufficiently clear device-to-mountpoint mapping to certify the actual block-device path. It also shows additional process terminations and unmounts that are not established as necessary by the write measurements.
Expected result: The high-write-load block device is identified, the batches process responsible for the excessive writes is terminated, and its associated filesystem at /media/batches is unmounted after confirming the device mapping. Unrelated processes and storage devices remain unaffected.
next last task now please
Worked for 2m 32s
Task
Set the "number of processes" hard limit for the existing user james to 32768 and the soft limit to 16384.
Ensure that changes are made persistently.
See the complete solution in Explanation.
Objective: Configure persistent Linux resource limits for the existing user james, ensuring that:
The hard process limit is 32768.
The soft process limit is 16384.
The limits are applied when the user starts a new PAM-managed login session.
The configuration remains available after a system reboot.
The appropriate solution uses Linux-PAM's resource-limit configuration, typically in /etc/security/limits.d/.
The official Linux-PAM documentation specifies the configuration syntax and confirms that nproc is the resource identifier for process limits.
Step 1: Connect to the correct Linux server.
The video specifies host lfcs00089.
From the candidate terminal, execute:
ssh lfcs00089
This establishes an SSH session with the designated server.
All subsequent configuration changes must be performed on this host.
Step 2: Verify that the user james exists.
Execute:
id james
This displays the user's UID, primary group and supplementary group memberships.
Example output:
uid=1001(james) gid=1001(james) groups=1001(james)
The numeric identifiers may differ on the actual server.
You can also check the account database:
getent passwd james
The task specifies an existing user, so there is no need to create a new account or modify the user's password.
Step 3: Understand soft and hard process limits.
Linux implements process-related resource restrictions using RLIMIT_NPROC.
Limit
Required value
Purpose
Soft
16384
Default process/thread creation limit enforced for the user's processes
Hard
32768
Maximum value to which an unprivileged user may raise the soft limit
The hard limit must be at least as large as the soft limit. Here:
\[ 16384 \leq 32768 \]
Therefore, the requested configuration is valid.
On Linux, RLIMIT_NPROC actually accounts for processes and threads associated with the real user ID, subject to kernel privilege exceptions. It is not a separate allowance for every running application.
Step 4: Inspect any existing persistent limits.
Before changing the system, execute:
sudo cat /etc/security/limits.conf
Then list any existing supplemental configuration files:
sudo ls -la /etc/security/limits.d/
Search specifically for process-limit settings:
sudo grep -RnsE \
'^[[:space:]]*([^#[:space:]] +[[:space:]]+)+(soft|hard|-)[[:space:]] +nproc' \
/etc/security/limits.conf /etc/security/limits.d/ 2 > /dev/null
Also check for any existing entries concerning james:
sudo grep -RnsE '^[[:space:]]*james[[:space:]] ' \
/etc/security/limits.conf /etc/security/limits.d/ 2 > /dev/null
These checks help identify existing user-specific limits and avoid contradictory configuration entries.
Step 5: Understand the persistent configuration locations.
The primary resource-limit configuration file is:
/etc/security/limits.conf
Additional administrator-defined limits can be stored under:
/etc/security/limits.d/
Both locations are supported by Linux-PAM.
The configuration format is:
< domain > < type > < item > < value >
For this task:
Field
Required value
Description
Domain
james
Existing username
Type
soft or hard
Which resource limit to configure
Item
nproc
Number of processes/threads
Value
16384 or 32768
Required limit
A dedicated configuration file is preferable because it keeps the account-specific policy separate from the system's general resource-limit settings.
Step 6: Create the persistent configuration file.
Execute:
sudo nano /etc/security/limits.d/90-james-nproc.conf
This opens a new configuration file.
If the file already exists, inspect its contents before modifying it.
Step 7: Add the required soft and hard process limits.
Insert the following two lines:
james soft nproc 16384
james hard nproc 32768
This is the exact configuration required for the task.
Explanation of the first line:
james soft nproc 16384
james selects the target user.
soft specifies the default soft resource limit.
nproc refers to the process/thread limit.
16384 establishes the required soft value.
Explanation of the second line:
james hard nproc 32768
james selects the same user.
hard specifies the hard resource limit.
nproc identifies the resource.
32768 establishes the maximum hard value.
These settings apply specifically to james rather than all users.
The Linux-PAM manual explicitly supports user-specific soft and hard nproc entries.
Step 8: Save the configuration.
If using Nano:
Press Ctrl + O to save.
Press Enter to confirm the filename.
Press Ctrl + X to exit.
If using Vim:
Press Esc.
Type :wq.
Press Enter.
The file should be located at:
/etc/security/limits.d/90-james-nproc.conf
Step 9: Verify the saved configuration.
Execute:
sudo cat /etc/security/limits.d/90-james-nproc.conf
Expected output:
james soft nproc 16384
james hard nproc 32768
Check the file permissions:
ls -l /etc/security/limits.d/90-james-nproc.conf
A typical configuration file has permissions of 644 and is owned by root.
If the file permissions are incorrect, restore appropriate permissions:
sudo chmod 644 /etc/security/limits.d/90-james-nproc.conf
The file should be readable by the PAM module when login sessions are established.
Step 10: Verify that PAM applies resource limits.
The settings are interpreted by the PAM module:
pam_limits.so
Check whether the module is configured:
sudo grep -Rns 'pam_limits.so' /etc/pam.d/
A relevant configuration entry resembles:
session required pam_limits.so
session identifies the PAM session-management phase.
required means the module must succeed for the relevant PAM operation to succeed.
pam_limits.so applies the configured resource limits when the session is established.
The official Linux-PAM documentation confirms that this module applies resource limits to user sessions.
On Ubuntu, inspect the PAM configuration used by the relevant login method, including sshd, login, su, and any referenced common-session files.
Do not blindly add duplicate pam_limits.so entries. If the module is absent from the actual login path, configure it appropriately before testing.
Step 11: Understand when the changes take effect.
The limits defined in /etc/security/limits.d/90-james-nproc.conf are persistent settings, but they are not automatically applied to every currently running process.
Linux-PAM applies these limits when an applicable new login session begins.
Therefore:
Existing sessions may retain their previous limits.
New PAM-managed sessions can receive the new values.
Changes survive reboot because the configuration is stored on disk.
There is no need to restart the entire operating system simply to load the configuration.
The Linux-PAM manual specifically explains that configured resource limits are applied per login session.
Step 12: Start a fresh session as james.
If you have administrative access, you can attempt to create a new login session with:
sudo su - james
This starts a login-style shell using the su PAM service, provided that service is configured to apply PAM resource limits.
Alternatively, open a new SSH login as james, using the account's existing credentials if permitted:
ssh james@localhost
A fresh SSH login is particularly useful if the actual login service is the intended target of the configuration.
Check the active user:
whoami
Expected:
james
Do not assume that simply running sudo -u james ulimit ... is a valid test. ulimit is a shell builtin, and changing the execution user does not necessarily create a PAM session or apply its resource-limit policy.
Step 13: Verify the soft process limit.
Inside the new login session belonging to james, execute:
ulimit -Su
ulimit displays or controls process resource limits.
-S selects the soft limit.
-u selects the maximum process/thread resource limit.
Expected output:
16384
This confirms that the session received the required soft limit.
Step 14: Verify the hard process limit.
In the same session, execute:
ulimit -Hu
-H selects the hard limit.
-u selects the process/thread resource limit.
Expected output:
32768
The GNU Bash manual confirms that -S and -H distinguish soft and hard limits, and that -u refers to the maximum number of processes available to a user.
Step 15: Verify both limits together.
Execute:
printf 'Soft limit: '
ulimit -Su
printf 'Hard limit: '
ulimit -Hu
Expected output:
Soft limit: 16384
Hard limit: 32768
This is the most direct practical verification of the two requested values.
Step 16: Verify the kernel's process-limit information.
Linux also exposes resource limits through the /proc filesystem.
Inside the new james session, execute:
cat /proc/self/limits
Find the line:
Max processes
The relevant values should be:
Limit Soft Limit Hard Limit
Max processes 16384 32768
The displayed output contains additional columns and other resource limits, but the Max processes entry is the one relevant to this task.
For a more concise check, execute:
grep 'Max processes' /proc/self/limits
Expected values:
Max processes 16384 32768
You can also use:
prlimit --pid $$
This displays resource limits for the current shell process.
Step 17: Check for conflicting limits if the values are incorrect.
If the new session does not show the required values, investigate rather than repeatedly adding duplicate configuration entries.
First, inspect user-specific rules:
sudo grep -Rns 'james' \
/etc/security/limits.conf /etc/security/limits.d/
Next, inspect all process-limit rules:
sudo grep -Rns 'nproc' \
/etc/security/limits.conf /etc/security/limits.d/
Then check whether pam_limits.so is active in the login method used for testing.
Potential reasons for an unexpected value include an overriding limits configuration, a session started without PAM resource-limit processing, or resource limits imposed by a systemd-managed service.
If the user runs an application under a systemd service, systemd's LimitNPROC= setting may also be relevant. However, configuring a systemd service is not required by the task.
Step 18: Verify persistence.
The persistent configuration resides at:
/etc/security/limits.d/90-james-nproc.conf
Execute:
sudo cat /etc/security/limits.d/90-james-nproc.conf
Expected:
james soft nproc 16384
james hard nproc 32768
Because this configuration is stored under /etc, it remains present after the system reboots unless it is changed or removed.
For end-to-end verification, start a fresh login session after reboot and repeat:
ulimit -Su
ulimit -Hu
Expected:
16384
32768
A reboot is not necessary for normal verification, and should not be performed unnecessarily during the LFCS exam.
Step 19: Confirm that unrelated users remain unchanged.
The file contains rules for:
james
It does not use the wildcard:
*
Therefore, this particular configuration does not apply indiscriminately to all users.
Avoid adding entries such as:
* soft nproc 16384
* hard nproc 32768
Those would impose the specified limits more broadly, instead of targeting the user named in the task.
Step 20: Perform final verification.
The final configuration must satisfy all requirements:
Requirement
Expected result
Existing user
james
Resource type
nproc
Soft limit
16384
Hard limit
32768
Persistent configuration
Present
Fresh login session
Correct limits applied
Other users
No unnecessary changes
Final Solution
The essential commands are:
Copy commands
# Connect to the correct server
ssh lfcs00089
# Verify the user exists
id james
# Create the persistent resource-limit configuration
printf '%s\n' \
'james soft nproc 16384' \
'james hard nproc 32768' | \
sudo tee /etc/security/limits.d/90-james-nproc.conf
# Verify the configuration
sudo cat /etc/security/limits.d/90-james-nproc.conf
# Confirm PAM resource-limit integration
sudo grep -Rns 'pam_limits.so' /etc/pam.d/
# Start a new PAM-managed login session
# (provided the su PAM stack applies pam_limits)
sudo su - james
# Verify the soft limit
ulimit -Su
# Verify the hard limit
ulimit -Hu
# Verify through procfs
grep 'Max processes' /proc/self/limits
The required configuration is:
james soft nproc 16384
james hard nproc 32768
Technical Verification and References
Linux-PAM limits.conf(5) — Confirms the configuration file syntax and nproc resource identifier.
Linux-PAM pam_limits(8) — Explains how limits are applied when PAM sessions are established.
GNU Bash — ulimit — Documents soft and hard resource-limit verification.
Linux getrlimit(2) — Defines the kernel's process-limit behavior.
Video verification finding: At approximately 29:01–29:05, Question 9 appears with host lfcs00089. The recording shows the full task statement but does not demonstrate the required configuration being completed. The solution above is independently validated against Linux-PAM documentation.
Expected result: User james receives a soft process limit of 16384 and a hard process limit of 32768 in applicable new login sessions. The settings are stored persistently and remain configured after reboot.
Task
Configure the system to enable the IP forwarding kernel feature persistently.
See the complete solution in Explanation.
Objective: Enable IPv4 packet forwarding on the Linux server and ensure that the setting remains enabled after a system reboot.
In Linux, IPv4 forwarding is controlled by the kernel parameter:
net.ipv4.ip_forward
This parameter determines whether the Linux kernel can forward IPv4 packets between network interfaces.
Value
Meaning
0
IPv4 forwarding disabled
1
IPv4 forwarding enabled
The task requires a persistent configuration, not merely a temporary runtime change.
The official Linux kernel documentation confirms that setting net.ipv4.ip_forward to 1 enables forwarding of IPv4 packets.
Step 1: Connect to the correct Linux server.
The video specifies that this task must be completed on host lfcs00081.
From the candidate terminal, execute:
ssh lfcs00081
This establishes an SSH session with the designated server.
All remaining commands must be executed on this host.
Step 2: Inspect the current IP forwarding configuration.
Execute:
sysctl net.ipv4.ip_forward
This displays the current value of the IPv4 forwarding parameter.
If forwarding is disabled, the output is:
net.ipv4.ip_forward = 0
If forwarding is already enabled, the output is:
net.ipv4.ip_forward = 1
You can also inspect the corresponding kernel interface directly:
cat /proc/sys/net/ipv4/ip_forward
Expected output when forwarding is disabled:
0
The /proc/sys/ hierarchy provides an interface for viewing and modifying runtime kernel parameters.
Step 3: Check the existing persistent configuration.
Before modifying anything, check whether the parameter is already configured elsewhere.
Execute:
sudo grep -RnsE '^[[:space:]]*net\.ipv4\.ip_forward[[:space:]] *=' \
/etc/sysctl.conf /etc/sysctl.d/ \
/run/sysctl.d/ /usr/lib/sysctl.d/ 2 > /dev/null
This searches the relevant sysctl configuration files.
For example, the output might include:
/etc/sysctl.conf:28:net.ipv4.ip_forward=0
This indicates that the existing configuration explicitly disables IPv4 forwarding.
If the parameter appears in multiple files, inspect the effective configuration order before changing it.
Step 4: Enable IPv4 forwarding immediately.
Execute:
sudo sysctl -w net.ipv4.ip_forward=1
sudo executes the command with administrative privileges.
sysctl reads or modifies kernel parameters.
-w writes a new value to a kernel parameter.
net.ipv4.ip_forward=1 enables IPv4 forwarding.
Expected output:
net.ipv4.ip_forward = 1
This change takes effect immediately.
However, this command alone does not guarantee persistence after reboot.
Therefore, additional configuration is required.
Step 5: Create a persistent sysctl configuration file.
The preferred method on a systemd-based Linux system is to create a dedicated file in:
/etc/sysctl.d/
Execute:
sudo nano /etc/sysctl.d/99-lfcs-ip-forward.conf
Add this exact line:
net.ipv4.ip_forward = 1
Save the file.
The complete file should contain:
net.ipv4.ip_forward = 1
Why this works:
/etc/sysctl.d/ stores persistent administrator-defined kernel settings.
.conf files in this directory are read during system startup.
The filename prefix 99- normally positions the file after most package-provided configuration files.
The setting enables IPv4 forwarding whenever it is applied.
The systemd sysctl.d(5) documentation confirms that these configuration files are used to apply kernel parameters during boot.
Step 6: Check for settings that could override the new value.
A particularly important consideration is /etc/sysctl.conf.
On Ubuntu systems using the procps implementation, sysctl --system processes /etc/sysctl.conf after the configuration files in sysctl.d.
Therefore, an existing entry such as:
net.ipv4.ip_forward = 0
inside /etc/sysctl.conf could override the value in the new file when sysctl --system is executed.
Inspect it:
sudo grep -n 'net.ipv4.ip_forward' /etc/sysctl.conf
If an active, conflicting entry is present, edit it:
sudo nano /etc/sysctl.conf
Change:
net.ipv4.ip_forward = 0
to:
net.ipv4.ip_forward = 1
Alternatively, remove the duplicate active entry and rely on the dedicated /etc/sysctl.d/99-lfcs-ip-forward.conf file.
Do not modify unrelated sysctl parameters.
The official sysctl(8) manual documents how --system processes configuration files and how /etc/sysctl.conf can override earlier values.
Step 7: Apply the persistent configuration immediately.
Execute:
sudo sysctl --system
This loads the sysctl settings from the system configuration.
The relevant output should include:
net.ipv4.ip_forward = 1
Review the command output for conflicting settings or errors.
Check the command's exit status immediately:
echo $?
A successful execution should normally return:
0
Step 8: Verify that IPv4 forwarding is enabled in the running kernel.
Execute:
sysctl net.ipv4.ip_forward
Expected:
net.ipv4.ip_forward = 1
Verify through the kernel interface:
cat /proc/sys/net/ipv4/ip_forward
Expected:
1
These two commands confirm the same runtime kernel setting through different interfaces.
Step 9: Verify the persistent configuration file.
Execute:
cat /etc/sysctl.d/99-lfcs-ip-forward.conf
Expected output:
net.ipv4.ip_forward = 1
You can also confirm that the setting remains active after reapplying its configuration:
sudo sysctl --system
sysctl net.ipv4.ip_forward
The final result should remain:
net.ipv4.ip_forward = 1
This confirms both that the runtime setting is enabled and that the system configuration can reapply it successfully.
Step 10: Verify persistence after a reboot, if permitted.
The strongest practical verification is to reboot the server and check the parameter afterward.
Only perform this step if rebooting the exam host is permitted and you can reconnect safely.
Execute:
sudo reboot
After the server finishes restarting, reconnect:
ssh lfcs00081
Then execute:
sysctl net.ipv4.ip_forward
Expected:
net.ipv4.ip_forward = 1
If the value remains 1, IPv4 forwarding has been restored successfully during startup.
Important: A reboot is not necessary to apply the change. sudo sysctl --system is sufficient for immediate activation. Avoid an unnecessary reboot during an exam if the required state can already be verified.
Step 11: Understand why both runtime and persistent changes matter.
There are two separate requirements to consider:
Configuration method
Immediate effect
Persistent after reboot
sudo sysctl -w net.ipv4.ip_forward=1
Yes
No, by itself
Write 1 to /proc/sys/net/ipv4/ip_forward
Yes
No, by itself
Configure /etc/sysctl.d/*.conf
After loading
Yes
Configure /etc/sysctl.conf on the Ubuntu setup
After loading
Yes
sudo sysctl --system
Applies configured values
Does not itself create persistence
The correct solution must leave the runtime parameter enabled and store the configuration in a location that is processed at startup.
Step 12: Confirm that IPv4 forwarding does not require additional configuration for this task.
The question asks only to enable the IP forwarding kernel feature persistently.
It does not request:
Configuring network interfaces.
Creating routing tables.
Adding NAT or firewall rules.
Enabling IPv6 forwarding.
Installing a routing daemon.
Therefore, these additional changes are unnecessary.
Enabling the kernel's forwarding feature allows Linux to forward IPv4 packets, but successful routing between networks can still depend on interface configuration, routing tables, and firewall policies.
Those are separate operational concerns and are not part of the stated task.
Step 13: Perform the final verification.
Execute:
sysctl net.ipv4.ip_forward
Expected:
net.ipv4.ip_forward = 1
Then:
cat /proc/sys/net/ipv4/ip_forward
Expected:
1
Finally:
cat /etc/sysctl.d/99-lfcs-ip-forward.conf
Expected:
net.ipv4.ip_forward = 1
The resulting configuration must satisfy the following:
Requirement
Expected result
IPv4 forwarding enabled
Yes
Runtime kernel parameter
1
Persistent configuration
Present
Settings reapply successfully
Yes
Other kernel parameters
Unchanged unless affected by the kernel's forwarding transition
IPv4 forwarding after reboot
Enabled
Final Solution
Copy commands
# Connect to the correct server
ssh lfcs00081
# Check current IPv4 forwarding status
sysctl net.ipv4.ip_forward
# Enable IPv4 forwarding immediately
sudo sysctl -w net.ipv4.ip_forward=1
# Make the setting persistent
printf 'net.ipv4.ip_forward = 1\n' | \
sudo tee /etc/sysctl.d/99-lfcs-ip-forward.conf
# Check for a conflicting setting in /etc/sysctl.conf
sudo grep -n 'net.ipv4.ip_forward' /etc/sysctl.conf
# Resolve any active conflicting entry if present,
# then apply persistent settings
sudo sysctl --system
# Verify the effective kernel setting
sysctl net.ipv4.ip_forward
# Verify directly through procfs
cat /proc/sys/net/ipv4/ip_forward
# Verify the persistent configuration
cat /etc/sysctl.d/99-lfcs-ip-forward.conf
Alternative Solution — Method Demonstrated in the Video
The candidate in the recording edits:
sudo vim /etc/sysctl.conf
This is also a valid approach on the Ubuntu environment shown.
Inside the file, locate the IPv4 forwarding setting:
#net.ipv4.ip_forward=1
If the line is commented out, uncomment it so it reads:
net.ipv4.ip_forward=1
If an active entry is already set to 0, change it to 1 instead. Ensure there are no contradictory active entries.
Save and apply:
sudo sysctl -p /etc/sysctl.conf
Verify:
sysctl net.ipv4.ip_forward
Expected:
net.ipv4.ip_forward = 1
Both approaches are valid. A dedicated file under /etc/sysctl.d/ is preferable for keeping administrator-specific changes separate, whereas editing /etc/sysctl.conf closely follows the method attempted in the recording. Use one consistent configuration and ensure no conflicting setting overrides it.
Technical Verification and References
The solution has been checked against official Linux and systemd documentation:
Linux Kernel — IP Sysctl Documentation — Defines the IPv4 forwarding parameter and its behavior.
Linux sysctl(8) — Documents runtime modification and applying system configuration.
systemd sysctl.d(5) — Explains persistent kernel settings loaded during startup.
Video verification finding: At approximately 28:20–29:10, the recording shows Task 8 on host lfcs00081. The candidate edits /etc/sysctl.conf and executes a reboot. However, the visible recording does not establish the precise final contents of the file or show a successful post-reboot check of net.ipv4.ip_forward.
Expected result: The Linux system has IPv4 forwarding enabled with net.ipv4.ip_forward = 1, and the setting is configured to remain enabled after reboot.
Task
Using libvirt (virt-install), create a new virtual machine named cool-moray from an existing disk image at /vms/cool-moray/jammy-server-cloudimg-amd64.img with the following specifications:
Setting
Value
Memory in MB
1024
You must use --noautoconsole for the installation to complete and exit.
See the complete solution in Explanation.
Objective: Create a new virtual machine using the existing Ubuntu 22.04 disk image, allocate 1024 MiB of RAM, register the virtual machine with libvirt, and ensure virt-install exits without opening an interactive console.
The correct solution uses virt-install with the --import and --noautoconsole options. The --import option is essential because the task provides an existing operating system disk image rather than requesting a fresh installation.
Step 1: Connect to the correct Linux server.
The video specifies that this task must be completed on host lfcs00083.
From the candidate terminal, execute:
ssh lfcs00083
This connects to the virtualization host where the VM must be created.
All subsequent commands must be executed on this host.
Step 2: Verify that virtualization tools are available.
Check the virt-install utility:
virt-install --version
Check the virsh utility:
virsh --version
Also check the QEMU image-management utility:
qemu-img --version
These tools serve different purposes:
virt-install creates and configures virtual machines.
virsh manages and inspects virtual machines through libvirt.
qemu-img examines and manages virtual disk images.
The task states that libvirt must be used, so creating the VM directly with a standalone qemu-system command would not be the appropriate solution.
Step 3: Verify connectivity to the libvirt hypervisor.
Execute:
sudo virsh --connect qemu:///system list --all
virsh communicates with the libvirt virtualization manager.
--connect qemu:///system selects the system-wide QEMU/KVM connection.
list --all displays both running and stopped virtual machines.
An illustrative result is:
Id Name State
--------------------------------
1 existing-vm running
- test-vm shut off
The actual VM list will depend on the host.
If libvirt cannot be contacted, check the host's libvirt services and sockets:
sudo systemctl status libvirtd
Some systems use modular libvirt daemons such as virtqemud, so inspect the installed service arrangement rather than assuming libvirtd is always present.
Step 4: Check whether cool-moray already exists.
Execute:
sudo virsh --connect qemu:///system list --all
Look for a virtual machine named:
cool-moray
You can check directly:
sudo virsh --connect qemu:///system dominfo cool-moray
If libvirt reports that the domain does not exist, proceed.
If the domain already exists, inspect it before making changes. Do not delete or recreate an existing machine without establishing why it is present.
The --name option of virt-install requires a name unique to the target libvirt connection.
Step 5: Verify that the existing disk image is present.
The task specifies the exact disk image path:
/vms/cool-moray/jammy-server-cloudimg-amd64.img
Execute:
ls -lh /vms/cool-moray/jammy-server-cloudimg-amd64.img
If normal user permissions do not allow inspection:
sudo ls -lh /vms/cool-moray/jammy-server-cloudimg-amd64.img
The image must exist before creating the VM.
Do not create an empty virtual disk in its place. The requirement is to use the existing disk image.
Step 6: Inspect the existing virtual disk image.
Execute:
sudo qemu-img info /vms/cool-moray/jammy-server-cloudimg-amd64.img
An example of the resulting information is:
image: /vms/cool-moray/jammy-server-cloudimg-amd64.img
file format: qcow2
virtual size: 2 GiB
disk size: 650 MiB
These size values are illustrative.
qemu-img info identifies the image's format, virtual size, actual allocated storage, and any backing image relationship.
Ubuntu cloud images commonly use QCOW2, but verify the actual image format instead of assuming it from the .img extension.
The existing image must remain intact.
Step 7: Confirm the guest operating-system type.
The disk filename contains:
jammy-server-cloudimg-amd64.img
jammy refers to Ubuntu 22.04 LTS, and amd64 indicates the x86-64 architecture.
Check the installed OS profiles:
virt-install --osinfo list
To find Ubuntu 22.04 specifically:
virt-install --osinfo list | grep -i ubuntu22
If ubuntu22.04 is available, it can be selected using:
--osinfo ubuntu22.04
This provides appropriate guest operating-system metadata and configuration defaults.
If that profile is unavailable, the upstream Ubuntu cloud-image procedure supports using:
--osinfo generic
Do not install a new operating system or download a different disk image merely to complete the task.
Step 8: Create the virtual machine using virt-install.
Once the disk exists, the libvirt connection works and the Ubuntu profile is supported, execute:
sudo virt-install \
--connect qemu:///system \
--name cool-moray \
--memory 1024 \
--disk path=/vms/cool-moray/jammy-server-cloudimg-amd64.img \
--osinfo ubuntu22.04 \
--import \
--noautoconsole
This is the principal solution.
If ubuntu22.04 is not recognized by the installed libosinfo database, substitute --osinfo generic, following the official Ubuntu cloud-image instructions.
The command leaves CPU count, network configuration and other parameters at their supported defaults because the visible task does not prescribe specific values for them.
Step 9: Understand every parameter in the command.
Parameter
Explanation
sudo
Executes with administrative privileges
virt-install
Creates and defines a VM through libvirt
--connect qemu:///system
Targets the system-wide QEMU/KVM hypervisor
--name cool-moray
Assigns the required VM name
--memory 1024
Allocates 1024 MiB of guest memory
--disk path=...
Attaches the existing virtual disk image
--osinfo ubuntu22.04
Selects the Ubuntu 22.04 operating-system profile
--import
Boots an existing OS image without running an installer
--noautoconsole
Prevents automatic attachment to the guest console and allows the command to return
Three arguments are especially important.
--memory 1024
The task specifies memory of 1024 MB. The virt-install utility interprets this parameter in MiB.
Therefore:
--memory 1024
sets the guest's configured RAM to 1024 MiB, equivalent to 1 GiB.
--import
This tells virt-install to create the VM around an existing disk image and skip the operating-system installation process.
Without an appropriate installation method such as --import, virt-install may expect installation media or fail to determine how the guest should be created.
--noautoconsole
The task explicitly requires this flag.
It prevents virt-install from automatically connecting to the guest's graphical or text console. Official documentation states that it also allows virt-install to exit promptly rather than waiting on an interactive console session.
Step 10: Verify that the creation command succeeds.
When virt-install succeeds, it normally prints messages indicating that the VM has been created and the domain is being started.
An illustrative successful message could be:
Starting install...
Creating domain...
Domain creation completed.
Do not treat these example messages as an actual result from the video.
Immediately after the command completes, check the exit status:
echo $?
Expected successful exit status:
0
If the command fails, read the actual error before attempting it again.
Common failure conditions include an existing VM name, inaccessible image path, unsupported OS profile, missing virtualization support or an unavailable default network.
Step 11: Verify that the new virtual machine is registered.
Execute:
sudo virsh --connect qemu:///system list --all
The output should now contain:
cool-moray
For example:
Id Name State
---------------------------
2 cool-moray running
The domain ID and runtime state may differ.
This command verifies that libvirt recognizes the VM.
Step 12: Verify the virtual machine's assigned memory.
Execute:
sudo virsh --connect qemu:///system dominfo cool-moray
Inspect the memory information.
For a VM configured with 1024 MiB, an expected value is:
Max memory: 1048576 KiB
Calculation:
\[ 1024 \times 1024 = 1,048,576 \text{ KiB} \]
This confirms that libvirt has the required memory allocation.
Also verify the VM name and general status in the same output.
Step 13: Verify the attached virtual disk.
Execute:
sudo virsh --connect qemu:///system domblklist cool-moray --details
The output should identify a disk whose source is:
/vms/cool-moray/jammy-server-cloudimg-amd64.img
This verifies that the VM uses the exact existing image required by the task.
Do not confuse creating a new blank disk with attaching the existing disk. The latter is required.
Step 14: Inspect the VM's persistent configuration.
Execute:
sudo virsh --connect qemu:///system dumpxml cool-moray
This displays the libvirt domain definition in XML format.
Look for the guest name:
< name > cool-moray < /name >
Also inspect the memory setting and the disk source.
The relevant configuration should contain the equivalent of:
< memory unit='KiB' > 1048576 < /memory >
And a disk source referencing:
< source file='/vms/cool-moray/jammy-server-cloudimg-amd64.img'/ >
The actual XML may include additional attributes, devices, generated addresses and machine-specific settings.
Step 15: Verify the VM's runtime state.
Execute:
sudo virsh --connect qemu:///system domstate cool-moray
A successful initial launch should normally report:
running
If it reports shut off, investigate the reason:
sudo virsh --connect qemu:///system dominfo cool-moray
You can also inspect the appropriate libvirt/QEMU logs.
Importing a cloud image registers and starts a guest, but it does not automatically establish guest login credentials or configure cloud-init user data. Those operations are not requested by this task.
Step 16: Verify that virt-install has returned control to the terminal.
Because --noautoconsole was specified, the virt-install command should return to the shell after initiating VM creation.
For example, the terminal prompt should become available again:
candidate@lfcs00083:~$
The presence of the normal shell prompt indicates that the creation utility is no longer occupying the terminal.
This is separate from the VM's own runtime state: the virtual machine may continue running after virt-install exits.
Step 17: Perform final verification.
Execute:
sudo virsh --connect qemu:///system list --all
sudo virsh --connect qemu:///system dominfo cool-moray
sudo virsh --connect qemu:///system domblklist cool-moray --details
sudo virsh --connect qemu:///system domstate cool-moray
Confirm the following:
Requirement
Expected result
VM name
cool-moray
Existing disk image
/vms/cool-moray/jammy-server-cloudimg-amd64.img
Memory
1024 MiB
Installation method
Existing image imported
Mandatory option
--noautoconsole used
VM registration
Present in libvirt
VM initial startup
Successful
Terminal
Returns to shell after creation
Final Solution
The essential commands are:
# Connect to the designated server
ssh lfcs00083
# Verify the existing disk image
ls -lh /vms/cool-moray/jammy-server-cloudimg-amd64.img
# Inspect the image
sudo qemu-img info /vms/cool-moray/jammy-server-cloudimg-amd64.img
# Check the VM name is available
sudo virsh --connect qemu:///system list --all
# Confirm the guest OS profile exists
virt-install --osinfo list
# Create the VM
sudo virt-install \
--connect qemu:///system \
--name cool-moray \
--memory 1024 \
--disk path=/vms/cool-moray/jammy-server-cloudimg-amd64.img \
--osinfo ubuntu22.04 \
--import \
--noautoconsole
# Verify the new VM
sudo virsh --connect qemu:///system list --all
sudo virsh --connect qemu:///system dominfo cool-moray
sudo virsh --connect qemu:///system domblklist cool-moray --details
sudo virsh --connect qemu:///system domstate cool-moray
Technical Verification and References
The solution is based on the official virt-install, libvirt and Ubuntu cloud-image documentation.
Ubuntu virt-install(1) Manual — Describes the --memory, --disk, --import, --osinfo and --noautoconsole options.
libvirt virsh Command Reference — Documents VM inspection commands, including list, dominfo, domblklist and domstate.
Ubuntu — Launch QCOW Cloud Images Using libvirt — Provides a practical example of launching an existing Ubuntu cloud image with virt-install, --import and --noautoconsole.
Video verification finding: At approximately 28:30, the recording shows Question 7 and the required host lfcs00083. The candidate begins entering the SSH command but cancels it and moves to Question 8. The recording therefore does not demonstrate a successful VM creation. The solution above is independently documentation-validated, not confirmed as executed in that recording.
Expected result: A virtual machine named cool-moray is created and registered through libvirt using the existing Ubuntu image, with 1024 MiB RAM. The VM starts successfully, and virt-install exits without attaching to the VM's console.
Copyright © 2021-2026 CertsTopics. All Rights Reserved