Ubuntu/Linux: systemd-resolved[2344]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP.

In one of my systems the system log was reporting every 2-3 minutes the following error message:

Sep  3 13:43:57 tux1 systemd-resolved[2344]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP.
Sep  3 13:45:34 tux1 systemd-resolved[2344]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP.
Sep  3 13:48:58 tux1 systemd-resolved[2344]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP.
Sep  3 13:50:34 tux1 systemd-resolved[2344]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP.
Sep  3 13:53:56 tux1 systemd-resolved[2344]: Server returned error NXDOMAIN, mitigating potential DNS violation DVE-2018-0001, retrying transaction with reduced feature level UDP.

This was caused by a mismatch between the systemd configuration and /etc/resolv.conf.

/etc/resolv.conf should be a symbolic link pointing to the systemd DNS configuration in /run/systemd/resolve/resolv.conf

You can check if this is in place just by listing the file.

$ ls -l /etc/resolv.conf

If it isn’t pointing to the right file (and you are using systemd) you can fix it:

# rm /etc/resolv.conf
# ln -s /etc/resolv.conf  /run/systemd/resolve/resolv.conf

The errors stopped after this fix.

$ cat /var/log/syslog | grep -i error | grep -i dns



Ubuntu/GRUB: Error: invalid environment block

After a recent system update I got the following error message:

Error: invalid environment block

Press any key to continue...

Luckily the system would boot up but ignoring errors isn’t best practice. This error is caused by a faulty GRUB2 environment block. This is a file located in /boot/grub/grubenv.

You can easily regenerate it with the following commands. It is advisable to make a backup copy the file just in case you need to revert.

# grub-editenv grubenv create
# grub-editenv grubenv set default=
# grub-editenv grubenv list
# update-grub

After rebooting the message should have disappeared.

If you can’t boot from your system drive you can use a Live CD and then mount your system’s boot partition and apply the same commands.

I haven’t tested this part personally but maybe the commands will help as a reference. Details are scarce on purpose, check what the commands do before doing anything.

# mount /dev/sda1 /mnt/boot/efi
or
# mount /dev/sda1 /mnt/boot/

# grub-editenv /mnt/boot/grub/grubenv grubenv create 
# grub-editenv /mnt/boot/grub/grubenv grubenv set default=
# grub-editenv /mnt/boot/grub/grubenv grubenv list
# grub-mkconfig  -o /mnt/boot/grub/grub.cfg

The other approach, also untested by me, could involve chroot.

# mount /dev/sda2 /target
# mount --bind /dev /target/dev
# mount --bind /dev/pts /target/dev/pts
# mount --bind /sys /target/sys
# mount --bind /proc /target/proc
# mount /dev/sda1 /target/boot

chroot /target

# grub-editenv grubenv create
# grub-editenv grubenv set default=
# grub-editenv grubenv list
# update-grub



Ubuntu 20.04: Install Ubuntu with ZFS and encryption

Ubuntu 20.04 offers installing ZFS as the default filesystem. This has lots of advantages. My favourite is being able to revert the system and home partitions (simultaneously or individually) to a previous state through the boot menu.

One major drawback for me is the lack of an option to encrypt the filesystem during the installation.

You have the option to use LUKS and ext4 but there isn’t an encryption option in the installer for ZFS.

Some people have used LUKS and ZFS in the past, but that solution didn’t quite work for me. The tutorials I saw were using LUKS1 instead of LUKS2 and it also felt that the approach was cumbersome now that ZFS on Linux supports native encryption.

The more you deviate from a standard installation the more complicated it will be to do any troubleshooting if anything breaks in the future. Keep it simple.

The ZFS on Linux version included with the 20.04 installer is 0.8.3.

The installation of Ubuntu 20.04 on ZFS will create two pools: bpool and rpool.

bpool contains the boot partition and rpool all the other mountpoints in several datasets.

In a very security minded world both pools should be encrypted, but I prefer not encrypt the boot partition. Adding that extra layer of security might make a system recovery that much more difficult or impossible.

The default partitioning during the install creates four partitions and two ZFS pools, using all the storage in the installation disk:

/boot/efi 512MiB EFI System Partition (vfat)
SWAP 2GiB Linux Swap Partition (swap)
bpool 2GiB ZFS/Solaris boot partition (zfs)
rpool all remaining space ZFS/Solaris root partition (zfs)

To encrypt the rpool we will need to edit the installation script.

Steps

  • Click the “Try Ubuntu” button.
  • Open a terminal window.
  • Edit /usr/share/ubiquity/zsys-setup
# vim /usr/share/ubiquity/zsys-setup

This script is responsible for setting up ZFS. We can modify the default options for rpool.

  • Edit the rpool section from this:
# Pools
        # rpool
        zpool create -f \
                -o ashift=12 \
                -O compression=lz4 \
                -O acltype=posixacl \
                -O xattr=sa \
                -O relatime=on \
                -O normalization=formD \
                -O mountpoint=/ \
                -O canmount=off \
                -O dnodesize=auto \
                -O sync=disabled \
                -O mountpoint=/ -R "${target}" rpool "${partrpool}"

to this:

# Pools
        # rpool
        echo PASSWORD | zpool create -f \
                -o ashift=12 \
                -O compression=lz4 \
                -O acltype=posixacl \
                -O xattr=sa \
                -O relatime=on \
                -O normalization=formD \
                -O mountpoint=/ \
                -O canmount=off \
                -O dnodesize=auto \
                -O sync=disabled \
                -O recordsize=1M \
                -O encryption=aes-256-gcm \
                -O keylocation=prompt \
                -O keyformat=passphrase \
                -O mountpoint=/ -R "${target}" rpool "${partrpool}"
  • Replace PASSWORD with the encryption password you want to use. You will be prompted to type this at boot time.
  • Save the changes to the file and exit.
  • Launch the installer:
# ubiquity
  • Install Ubuntu as you would.
    In the storage section:
  • Select “Use entire disk”
  • Select ZFS (Experimental)

The system will be installed with the encryption options set on the script and on boot it will prompt you with the password you setup.


Some comments on the options for reference:

-o ashift=12
This is the default setting that means that your disk’s block size is 4,096 bytes (2^12=4,096). Valid values are:

0 for autodetect sector size
9 for 512 bytes
10 for 1,024 bytes
11 for 2,048
12 for 4,096
13 for 8,192
14 for 16,384
15 for 32,768
16 for 65,536

You can output the physical sector size with lsblk -t, although values of 512 might be simulated. You should check the specifications if the drive is SSD.

Alternative ways to retrieve physical sector sizes are:

$ cat /sys/block/sd*/queue/physical_block_size
# hdparm -I /dev/sda | grep Sector

A value of 12 will work just fine, even on 512 sector drives and likely being the reason for Canonical setting up as the default.

If set too low this can have a huge and negative impact on performance.

-O recordsize=1M
Other tutorials suggest creating this entry. According to Oracle’s documentation this parameter is used for databases and I have read that it can also be used for certain types of VMs.

The default value is 128k. You can tune it for your individual use by changing the record size of an existing pool. Any new files created will use the new record size value. You can cp/rm files to force them to be rewritten with the new value.

You can change this value later on with:

# zfs set recordsize=128k rpool

or

# zfs set recordsize=128k rpool/filesystem

-O encryption=aes-256-gcm
AES with key lengths of 128, 192 and 256 bits in CCM and GCM operation modes are supported natively.
0.8.4 comes with a fix that improves performance with AES-GCM and should hopefully be included in an update to Ubuntu soon.

-O keylocation=prompt
Valid options are prompt or file:// </absolute/file/path>

Prompt will ask you to type the password, in this case during boot.
File will point to the location of the decryption key, but on a portable system it would defy its purpose.

-O keyformat=passphrase
Options are raw, hex or passphrase.
When using passphrase the password can be between 8 and 512 bytes in length.


Additional information

Reference sites
Debian ZFS site
Ubuntu ZFS reference
FreeBSD ZFS reference

ZFS on Linux website / Admin documentation
ZFS on Linux manpage
OpenZFS System Administration
OpenZFS FAQ

Oracle ZFS Admin guide (not necessarily in line with ZFS on Linux)
Archlinux ZFS wiki
Alpine Linux with root on ZFS with native encryption wiki

Ars Technica intro to ZFS

Interesting articles on ZFS tuning:
Tuning ZFS recordsize (Oracle blog)
ZFS record size (Joyent blog)
OpenZFS performance tuning wiki




Ubuntu: Ubuntu 20.4 installing NVIDIA drivers breaks built-in audio on laptop

On a new laptop I couldn’t get the external HDMI monitor to work with the nouveau drivers, so I installed the NVIDIA drivers (version 440).

The NVIDIA drivers worked perfectly and the external monitor could be configured, but it didn’t take too long to notice that the built-in audio wasn’t working.

Audio would only play through HDMI. Disconnecting the monitor wouldn’t make the built-in audio work again.

No audio from the built-in speakers or headphones on a laptop isn’t good.

Reverting to the nouveau drivers wouldn’t fix the audio. I have to say that I have become a fan of the ZFS rollback feature on 20.04 in a flash. You can revert the system to how it was before any update that borks things. You can try different troubleshooting solutions and go back if needed. Big fan.

So, how to get the audio to work again?

First find the audio driver being used. There are several ways to find what audio driver you are using:

$ inxi -iF
[...]
Audio:
  Device-1: Intel Cannon Lake PCH cAVS driver: snd_hda_intel 
  Device-2: NVIDIA TU106 High Definition Audio driver: snd_hda_intel 
  Sound Server: ALSA v: k5.4.0-28-generic 
[...]
$ lshw -c multimedia
  *-multimedia              
       description: Audio device
       product: TU106 High Definition Audio Controller
       vendor: NVIDIA Corporation
       physical id: 0.1
       bus info: pci@0000:01:00.1
       version: a1
       width: 32 bits
       clock: 33MHz
       capabilities: bus_master cap_list
       configuration: driver=snd_hda_intel latency=0
       resources: irq:17 memory:b4000000-b4003fff
  *-multimedia
       description: Audio device
       product: Cannon Lake PCH cAVS
       vendor: Intel Corporation
       physical id: 1f.3
       bus info: pci@0000:00:1f.3
       version: 10
       width: 64 bits
       clock: 33MHz
       capabilities: bus_master cap_list
       configuration: driver=snd_hda_intel latency=32
       resources: irq:150 memory:b4618000-b461bfff memory:b4200000-b42fffff
$ lspci -v
[...]
00:1f.3 Audio device: Intel Corporation Cannon Lake PCH cAVS (rev 10)
        Subsystem: CLEVO/KAPOK Computer Cannon Lake PCH cAVS
        Flags: bus master, fast devsel, latency 32, IRQ 150
        Memory at b4618000 (64-bit, non-prefetchable) [size=16K]
        Memory at b4200000 (64-bit, non-prefetchable) [size=1M]
        Capabilities: <access denied>
        Kernel driver in use: snd_hda_intel
        Kernel modules: snd_hda_intel, snd_sof_pci
[...]
01:00.1 Audio device: NVIDIA Corporation TU106 High Definition Audio Controller (rev a1)
        Subsystem: CLEVO/KAPOK Computer TU106 High Definition Audio Controller
        Flags: bus master, fast devsel, latency 0, IRQ 17
        Memory at b4000000 (32-bit, non-prefetchable) [size=16K]
        Capabilities: <access denied>
        Kernel driver in use: snd_hda_intel
        Kernel modules: snd_hda_intel
[...]

From the above we can see that the audio driver being used is snd_hda_intel, which is quite common.

Second, find out the audio codecs in use:

$ cat /proc/asound/card0/codec*

The output after installing the NVIDIA drivers that stopped the audio from working shows a lot of UNKNOWN and N/A entries:

Codec: Realtek ALC1220
Address: 0
AFG Function Id: 0x1 (unsol 1)
Vendor Id: 0x10ec1220
Subsystem Id: 0x155896e1
Revision Id: 0x100003
No Modem Function Group found
Default PCM:
N/A
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
State of AFG node 0x01:
  Power: setting=UNKNOWN, actual=UNKNOWN, Error, Clock-stop-OK, Setting-reset
Invalid AFG subtree
Codec: Intel Kabylake HDMI
Address: 2
AFG Function Id: 0x1 (unsol 0)
Vendor Id: 0x8086280b
Subsystem Id: 0x80860101
Revision Id: 0x100000
No Modem Function Group found
Default PCM:
N/A
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
State of AFG node 0x01:
  Power: setting=UNKNOWN, actual=UNKNOWN, Error, Clock-stop-OK, Setting-reset
Invalid AFG subtree

But a normal/working output would be similar to this:

Codec: Realtek ALC1220
Address: 0
AFG Function Id: 0x1 (unsol 1)
Vendor Id: 0x10ec1220
Subsystem Id: 0x155896e1
Revision Id: 0x100003
No Modem Function Group found
Default PCM:
    rates [0x5f0]: 32000 44100 48000 88200 96000 192000
    bits [0xe]: 16 20 24
    formats [0x1]: PCM
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
State of AFG node 0x01:
  Power states: D0 D1 D2 D3 D3cold CLKSTOP EPSS
  Power: setting=D0, actual=D0
GPIO: io=8, o=0, i=0, unsolicited=1, wake=0
  IO[0]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[1]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[2]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[3]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[4]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[5]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[6]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
  IO[7]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0
Node 0x02 [Audio Output] wcaps 0x41d: Stereo Amp-Out
  Control: name="Line Out Playback Volume", index=0, device=0
 [...]

From all of the above we can determine that the audio driver used is snd_hda_intel and that the codec is Realtek ALC1220.

It is very likely that your driver will be the same but the codec might vary. If using snd_hda_intel you can lookup what model variant you need searching the codec name in this list:

https://www.infradead.org/~mchehab/rst_conversion/sound/hd-audio/models.html

For the ALC1220 the model name to use seems to be dual-codecs.

Edit your ALSA configuration file:

# vim /etc/modprobe.d/alsa-base.conf

and add this to the end of the file:

# Manual entry to allow audio via headphones because NVIDIA drivers break the built-in audio
options snd-hda-intel model=clevo-p950
options snd-hda-intel probe_mask=0x1

I used the wrong model name by mistake. I meant to use dual-codecs but I used the model name just below in the list: clevo-p950. It worked and as it worked I haven’t gone back to edit it.

After updating your alsa configuration file reboot.

Just be more careful than me and choose the model name that matches your system.

After rebooting the audio from the built-in speakers and headphones were working.

You can change the output being used from your settings or using PulseAudio‘s volume control.




SNFS/Xsan: Changing a volume name

In the past it used to be a very straightforward process. You would rename the volume configuration file and run cvfsck.

With newer versions if you try to do that you will get an error message.

To make the name change you can use the cvupdatefs command.

If you have more than one volume running, the below instructions will allow you to rename one volume while the rest are still running, minimising downtime.

Stopping the file system

Stop the file system

# cvadmin -e 'stop oldname_volume1'

Check that it hasn't failed over.

# cvadmin -e 'select'

If it has failed over to another server just run the first command again until the volume you want to rename isn't running.

Check the filesystem

# cvfsck -j oldname_volume1
# cvfsck -nvvvvv oldname_volume1

If errors are shown at the above you need to fix them. Ideally you want to dump inode information before any big repair but that is for another article.

You can fix the errors with:

# cvfsck -vvvvv

Run the above command until there are no errors shown.

Changing the volume name

You can now change the volume name.

# cvupdatefs -R newname_volume2 oldname_volume1

Update the name of the volume in fmslist.

SNFS
# vim /usr/cvfs/config/fsmlist

Xsan
# vim /Library/Preferences/Xsan/fsmlist

In Xsan you need to push the changes to the second metadata server.

# xsanctl pushConfigUpdate

In Xsan you might need to check that the name isn’t referenced in any other configuration file (/Library/Preferences/Xsan), but you can run grep and see where you might need to make changes.

Also in Xsan, if needed, copy the configuration file to the second metadata server. Be aware that Xsan Admin does very often fail to make a good copy of the configuration to the second server. Run a file checksum on both ends and copy the volume configuration file manually if it doesn’t match.

This issue with Xsan Admin will in the best case not allow a volume to fail over, and in the worst case, cause data loss.

In SNFS/Linux you should check for any references of the old name in /usr/cvfs/config/

Also in SNFS/Linux, make sure that the changed files are also updated on the second metadata server.

Remounting the filesystem

In Xsan you don’t need to issue a new profile for the clients to mount the new volume. Just mount it once from the CLI and it will automount on restart:

# xsanctl mount newname_volume2

On Linux clients update entries in /etc/vstab or /etc/fstab to automount the volume on boot.

On Windows clients you will need to use the SNFS configuration tool to mount the newly named volume.

For HA environments Quantum has published an article with the above steps for their systems.




Covid19

I hope that my very scarce readership and their relatives and friends are well. These are going to be very trying times.

It is because of this that spreading rumours and messages that aren’t contrasted has to be discouraged.

Rumours kill people.

Please, consult official and trusted sources of information. Spreading rumours, however well-meant, might have unintended consequences on already scarce resources.

There are are already shortage of food in supermarkets due to panic buying even though the supply chain hasn’t been disrupted.

Think of others. Think of the people that are in the front-line and are struggling to buy food and other basic items.

There is enough for everyone. Don’t get more than what you need. Keep your distance. Avoid the spread. Stay home and stay healthy.

You can get updated information in the below links:

https://www.bing.com/covid

https://www.ft.com/coronavirus-latest

https://www.theguardian.com/world/series/coronavirus-live

https://www.gov.uk/coronavirus

Other interesting links:

https://quarantinechat.com/

There are some free online offerings for those of you on quarantine. There are people keeping lists of those events so my list is meagre and not meant to be up to date. Send me a message and I can share more if needed.

https://artsandculture.google.com/partner?hl=en

https://www.gog.com/games?page=1&sort=popularity&price=free

Keep safe!




Ubuntu/Debian: Not enough free space on disk ‘/boot’ when updating the OS

My /boot partition is only 512MB and I get this error message every now and then when updating:

Not enough free space

The upgrade needs a total of xx.x M free space on disk ‘/boot’. Please free at least an additional xx.x M of disk space on ‘/boot’. You can remove old kernels using ‘sudo apt autoremove’, and you could set COMPRESS=xz in /etc/initramfs-tools/initramfs.conf to reduce the size of your initramfs.

The obvious process is to expand /boot to be at least 1GB and be more careful in the future when partitioning during the OS installation.

Luckily there are a couple of things to try before repartitioning.

Try cleaning old kernels automatically:

# apt autoremove

Compress your initramfs by editing /etc/initramfs-tools/initramfs.conf

# vim /etc/initramfs-tools/initramfs.conf

and change the COMPRESS entry to:

COMPRESS=xz

You might need to rebuild your initramfs for the compression to start applying.

If after doing the above you still don’t have enough free space you can manually delete old kernels.

First check which Linux kernel you are on:

# uname -r

4.15.0-76-generic

In the example above the current kernel is 4.15.0-76. It is really important that the current used kernel is left untouched on the system. Under no circumstances should it be removed.

Check which kernels are on your system:

# dpkg -l | grep linux-image

rc  linux-image-4.15.0-55-generic              4.15.0-55.60                                     amd64        Signed kernel image generic
rc  linux-image-4.15.0-58-generic              4.15.0-58.64                                     amd64        Signed kernel image generic
rc  linux-image-4.15.0-60-generic              4.15.0-60.67                                     amd64        Signed kernel image generic
rc  linux-image-4.15.0-62-generic              4.15.0-62.69                                     amd64        Signed kernel image generic
rc  linux-image-4.15.0-64-generic              4.15.0-64.73                                     amd64        Signed kernel image generic
rc  linux-image-4.15.0-65-generic              4.15.0-65.74                                     amd64        Signed kernel image generic
rc  linux-image-4.15.0-66-generic              4.15.0-66.75                                     amd64        Signed kernel image generic
rc  linux-image-4.15.0-69-generic              4.15.0-69.78                                     amd64        Signed kernel image generic
rc  linux-image-4.15.0-70-generic              4.15.0-70.79                                     amd64        Signed kernel image generic
ii  linux-image-4.15.0-72-generic              4.15.0-72.81                                     amd64        Signed kernel image generic
ii  linux-image-4.15.0-74-generic              4.15.0-74.84                                     amd64        Signed kernel image generic
ii  linux-image-4.15.0-76-generic              4.15.0-76.86                                     amd64        Signed kernel image generic
ii  linux-image-generic                        4.15.0.76.78                                     amd64        Generic Linux kernel image

The first column of the output provides a 2-3 letter code with useful information on the status of each package.

For reference this is their meaning:

First letter. Desired package state:

u ... unknown
i ... install
r ... remove/deinstall
p ... purge (remove including config files)
h ... hold

Second letter. Current package state:

n ... not-installed
i ... installed
c ... config-files (only config files are installed)
U ... unpacked
F ... half-configured (configuration failed for some reason)
h ... half-installed (installation failed for some reason)
W ... triggers-awaited (package is waiting for a trigger from another package)
t ... triggers-pending (package has been triggered)

Third letter. Error state:

R ... reinstallation-required (package broken, reinstallation required)

From the previous output we know that there are some config files left around (rc header), and that several kernel images are still installed (ii header).

The ii ones are the ones consuming the space we need to free up. We need to remove some of those.

We have to keep the current kernel version and at least one or two previous versions as good practice.

So based on all of the above and in this example:

To remove
linux-image-4.15.0-55-generic
linux-image-4.15.0-58-generic
linux-image-4.15.0-60-generic
linux-image-4.15.0-62-generic
linux-image-4.15.0-64-generic
linux-image-4.15.0-65-generic
linux-image-4.15.0-66-generic
linux-image-4.15.0-69-generic
linux-image-4.15.0-70-generic
linux-image-4.15.0-72-generic

To keep
linux-image-4.15.0-74-generic (previous)
linux-image-4.15.0-76-generic (current)

You can remove them one by one:

# apt purge linux-image-4.15.0-55-generic
# apt purge linux-image-4.15.0-58-generic
# apt purge linux-image-4.15.0-60-generic
.
.
.

Or all of them in one go with:

# apt purge linux-image-4.15.0-{55,58,60,62,64,65,66,69,60,72}-generic

This will free up enough space of /boot until you repartition.




macOS: Spotlight results not showing applications

Sometimes if your system restarts unexpectedly Spotlight stops working as expected. In this particular case it won’t show any Applications on the results despite the settings on System Preferences.

This will happen even if you disable and re-enable Spotlight through the GUI. The solution is do it via the CLI.

Stop Spotlight indexing:

# mdutil -a -i off
[...]
/Volumes/Untitled:
2020-01-26 10:59:42.019 mdutil[13212:548120] mdutil disabling Spotlight: /Volumes/Untitled -> kMDConfigSearchLevelFSSearchOnly
	Indexing disabled.

Stop Spotlight:

# launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist

Start Spotlight:

# launchctl load -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist

Start Spotlight indexing:

# mdutil -a -i on
[...]
/Volumes/Untitled:
	Indexing enabled.

The results should now show applications.




KVM/QEMU: Reduce the size of your VM files

When virt-manager creates new images by default they will take the full size assigned to the virtual storage on the VM.

If your host system is using a filesystem with built-in compression like ZFS or BTRFS it won’t affect the amount of free space left on the host.

But if you aren’t or want to copy the VM to another host, then you would like to reduce its size.

You can remove unneeded files/defragment/zero the empty space of the filesystem depending on the OS the VM is running before to help the file reduction.

For comparison purposes you can check the internal disk size before the optimisation and also after with the following command:

# qemu-img info linux-vm.qcow2
image: linux-vm.qcow2
file format: qcow2
virtual size: 20G (21474836480 bytes)
disk size: 1.6G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

Stop the VM and then process the VM file:

# qemu-img convert -O qcow2 linux-vm.qcow2 linux-vm-compressed.qcow2

Depending on the size of the image and the machine running the command it can be time consuming, but the size reduction is worth it.

An alternative way of reducing the VM size is by using virt-sparsify.

Install the libguestfs-tools package.

[CentOS 7]
yum install libguestfs-tools

[CentOS 8]
dnf install libguestfs-tools

[Ubuntu/Debian]
# apt install libguestfs-tools

Stop the VM and then process it with:

# virt-sparsify --in-place linux-vm.qcow2

The –in-place option won’t create a new file and will compress the existing one.




Linux: Configure locale and keyboard layout when remotely accessing from a Mac

At work I have to remote into several different Linux systems from a Mac and there is always the pain of having to handle different keyboard layouts if using Synergy or VMs.

The conversion from a Mac keyboard layout doesn’t translate correctly when the Linux system has the keyboard configured as a PC.

First find out what the current configuration is.

$ localectl

The output in a British system is:

  System Locale: LANG=en_GB.UTF-8
                 LANGUAGE=en_GB:en
     VC Keymap : n/a
     X11 Layout: gb
      X11 Model: pc105
    X11 Options: terminate:ctrl_alt_bksp

Note that the last line might not show in Ubuntu systems.

Unfortunately if you are accessing from a Mac this layout will not work and basic things like |pipe| will not be easy to find.

You can edit the locale and keyboard layout of the system you are accessing so the mapping matches your Mac keyboard layout.

The ideal configuration should be like this:

  System Locale: LANG=en_GB.UTF-8
                 LANGUAGE=en_GB:en
     VC Keymap : n/a
     X11 Layout: gb
      X11 Model: macintosh
    X11 Variant: mac
    X11 Options: lv3:alt_switch

Ubuntu 18.04 / Ubuntu 20.04 / Debian 9 / Debian 10

Edit the following file:

/etc/default/keyboard

With these entries:

XKBMODEL="macintosh"
XKBLAYOUT="gb"
XKBVARIANT="mac"
XKBOPTIONS="lv3:alt_switch"

The XKBOPTIONS I have here are for Synergy to keep the Control and Alt keys on the Mac working the same on the Linux systems. You might not need or want it. Just remove it from the commands if that is the case.

You can also do a text GUI configuration of the keyboard with:

# dpkg-reconfigure keyboard-configuration

If your environment isn’t in English the menus won’t be either. You can force the language output of the application launched to be in the default one. That would be English in most cases. The same command as above but forcing the output to be in English:

# LC_ALL=C dpkg-reconfigure keyboard-configuration

An internet search of LC_ALL will show you more languages and options if needed.

CentOS 6

I have only been able to change the keyboard to a British layout, the Mac layout doesn’t seem to work.

Edit the following file:

/etc/sysconfig/i18n

with the following:

LANG="en_GB.UTF-8"
SYSFONT="latarcyrheb-sun16"
SUPPORTED="en_GB.UTF-8:en_GB:en"

Or type the following command:

# loadkeys uk

You might need to restart if editing i18n, but the change should be automatic with loadkeys.

CentOS 7

Edit the following file:

/etc/locale.conf

with the following:

LANG="en_GB.UTF-8"

Or type the following command:

# localectl set-locale LANG=en_GB.UTF-8

Set the keymap:

# localectl set-x11-keymap gb macintosh mac lv3:alt_switch

In CentOS 7 it isn’t necessary to reboot, the above command automatically loads the key mappings.

CentOS 8

The same commands used for CentOS 7 fail. I suspect that there is a file or folder with the keyboard mappings that has been moved. It might be a bug or a deprecated feature.

Just in case I opened a bug report with CentOS.

Regardless, the following will set the locale and the keyboard mappings correctly:

# localectl set-locale LANG=en_GB.UTF-8
# localectl set-keymap gb-mac

There is no need to reboot.