blog.lobraun.de Linux

Grub on MSI GS43VR (UEFI)

UEFI laptops sometimes want some massaging before they are willing to boot up the GRUB boot manager. Many postings show different ways to setup the boot manager.

Several UEFI-capable devices can be configured using efivars, to store which Boot Manager should be used by default (e.g. the Windows Boot Manager, Grub, ...). They then offer an option during startup to pick the appropriate boot manager. The MSI GS43VR does not support efivars. So in order to make sure that grub is used as your default boot manager, you have to do the following:

First follow the instructions of your distro to setup the boot manager. Afterwards, identify the UEFI boot partition, and mount it to your system:

# mount /dev/<your_uefi_partition> /boot/efi/

Then identify the location that your distro used to store the file grubx64.efi:

# find /boot/efi/ -name grubx64.efi
/boot/efi/EFI/debian/grubx64.efi

Make a copy of your old Boot loader from MSI:

# cp /bin/efi/EFI/Boot/bootx64.efi /bin/efi/EFI/Boot/bootx64_msi_orig.efi

Copy your distros grubx64.efi over the bootx64.efi loader:

# cp /boot/efi/EFI/<distro_folder>/grubx64.efi /boot/efi/EFI/Boot/bootx64.efi

The reason for this is simple: The MSI will boot the image EFI/Boot/bootx64.efi as the default image. By copying the grub loader to this location, the MSI loader will automatically load the grub loader as its only loader.

You have redo this step every time grub updates its grubx64.efi file. You also have to redo this step if you decide to change your preferred distro. The grubx64.efi of one distro is unlikely to be able to load the further stages that are provided by another distro and you will be put into a grub rescue prompt.

Xorg -configure: Number of created screens does not match number of detected devices. Configuration failed.

Configuring an Xserver used to be a task that required fiddling with the X server configuration files, and you needed to perform this every time you set up a new system. Today, the X server will often automagically detect all available hardware and come up with some reasonable settings without any configuration file at all.

You only need to create an xorg.conf if you want to modify some of the defaults. Most of the time, this just means running

Xorg -configure 

And to copy the configuration file to your /etc/X11 directory. If you system has two graphic cards, then the configuration might abort with the following error message:

Number of created screens does not match number of detected devices. Configuration failed.

Xorg -configure does create a xorg.conf, which contains a two Monitor sections, two Screen sections, and two Device sections. An example output might look like this:

Section "ServerLayout"
    Identifier     "X.org Configured"
    Screen      0  "Screen0" 0 0
    Screen      1  "Screen1" RightOf "Screen0"
    InputDevice    "Mouse0" "CorePointer"
    InputDevice    "Keyboard0" "CoreKeyboard"
EndSection

Section "Files"
    ModulePath   "/usr/lib/xorg/modules"
    FontPath     "/usr/share/fonts/X11/misc"
    FontPath     "/usr/share/fonts/X11/cyrillic"
    FontPath     "/usr/share/fonts/X11/100dpi/:unscaled"
    FontPath     "/usr/share/fonts/X11/75dpi/:unscaled"
    FontPath     "/usr/share/fonts/X11/Type1"
    FontPath     "/usr/share/fonts/X11/100dpi"
    FontPath     "/usr/share/fonts/X11/75dpi"
    FontPath     "built-ins"
EndSection

Section "Module"
	Load  "glx" 
EndSection

Section "InputDevice"
	Identifier  "Keyboard0"
	Driver      "kbd"
EndSection

Section "InputDevice"
    Identifier  "Mouse0"
    Driver      "mouse"
    Option	    "Protocol" "auto"
    Option	    "Device" "/dev/input/mice"
    Option	    "ZAxisMapping" "4 5 6 7"
EndSection

Section "Monitor"
	Identifier   "Monitor0"
	VendorName   "Monitor Vendor"
	ModelName    "Monitor Model"
EndSection

Section "Monitor"
	Identifier   "Monitor1"
	VendorName   "Monitor Vendor"
	ModelName    "Monitor Model"
EndSection

Section "Device"
    ### Available Driver options are:-
    ### Values: <i>: integer, <f>: float, <bool>: "True"/"False",
    ### <string>: "String", <freq>: "<f> Hz/kHz/MHz",
    ### <percent>: "<f>%"
    ### [arg]: arg optional
    #Option     "SWcursor"           	# [<bool>]
    #Option     "HWcursor"           	# [<bool>]
    #Option     "NoAccel"            	# [<bool>]
    #Option     "ShadowFB"           	# [<bool>]
    #Option     "VideoKey"           	# <i>
    #Option     "WrappedFB"          	# [<bool>]
    #Option     "GLXVBlank"          	# [<bool>]
    #Option     "ZaphodHeads"        	# <str>
    #Option     "PageFlip"           	# [<bool>]
    #Option     "SwapLimit"          	# <i>
    #Option     "AsyncUTSDFS"        	# [<bool>]
    #Option     "AccelMethod"        	# <str>
    #Option     "DRI"                	# <i>
	Identifier  "Card0"
	Driver      "nouveau"
	BusID       "PCI:1:0:0"
EndSection

Section "Device"
    ### Available Driver options are:-
    ### Values: <i>: integer, <f>: float, <bool>: "True"/"False",
    ### <string>: "String", <freq>: "<f> Hz/kHz/MHz",
    ### <percent>: "<f>%"
    ### [arg]: arg optional
    #Option     "ShadowFB"           	# [<bool>]
    #Option     "DefaultRefresh"     	# [<bool>]
    #Option     "ModeSetClearScreen" 	# [<bool>]
    Identifier  "Card1"
    Driver      "vesa"
    BusID       "PCI:0:2:0"
EndSection

Section "Screen"
	Identifier "Screen0"
	Device     "Card0"
	Monitor    "Monitor0"
	SubSection "Display"
		Viewport   0 0
		Depth     1
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     4
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     8
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     15
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     16
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     24
	EndSubSection
EndSection

Section "Screen"
	Identifier "Screen1"
	Device     "Card1"
	Monitor    "Monitor1"
	SubSection "Display"
		Viewport   0 0
 		Depth     1
    EndSubSection
    SubSection "Display"
    	Viewport   0 0
    	Depth     4
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     8
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     15
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     16
	EndSubSection
	SubSection "Display"
		Viewport   0 0
		Depth     24
	EndSubSection
EndSection

If you can decide which graphic card should be used in the configuration, you can simply delete the other irrelevant sections from you configuration file. If I only want to have the nouveau driver running, then I remove all references to Monitor1, Screen1, and Card1 from the configuration. Make sure to adopt the ServerLayout section as well.

CIFS

Most Linux distributions provide their pre-compiled kernels with most options enabled as kernel modules. When self-compiling the kernel, you sometimes miss modules because you did not care to enable all available modules. That can sometimes lead to problems, such as when mounting SMB shares:

# mount -t cifs //<myhost>/<myshare> /mnt/myshare
mount error: cifs filesystem not supported by the system
mount error(19): No such device
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)

These problems can be overcome by providing and loading the CIFS kernel module under:

File Systems ---> 
    Network File Systems --->
       <M> CIFS support (advanced network filesystems, SMBFS successor)

Compile and install your kernel and kernel modules. The kernel module should be loaded when trying to mount a share. If it is not loaded automatically on mount, then load the module manually:

# modprobe cifs

Hibernate/Suspend with Nvidia Drivers on Gentoo

The proprietary Nvidia drivers from x11-drivers/nvidia-drivers contain the closed-sources drivers from Nvidia for Linux. On my laptop, the current version show problems when hibernating/suspending. Several people found that the resume operations do not properly bring up the X-sessions. The same problem occurs on my GTX 1060 laptop. None of the helpful tips found on the Internet would allow me to hibernate/resume when the drivers are loaded.

The only solution that worked for me, is to unload the drivers before going into hibernate and to load them after the resume operation is completed. If you configured your hibernate using this tutorial, and are using sys-power/pm-utils and sys-power/upower-pm-utils, then you can place the following script in /etc/pm/sleep.d/ to unload and load the drivers:

#!/bin/sh
#
# 01nvidia_drivers: unloads and loads nvidia drivers before and after suspend operations

function unload_if_loaded() {
    MODULE=$1
    if lsmod | grep "$MODULE" &>/dev/null; then
        rmmod $MODULE
    fi
}

case "$1" in
   hibernate|suspend)
       unload_if_loaded nvidia_drm
       unload_if_loaded nvidia_modeset
       unload_if_loaded nvidia
   ;;
   thaw|resume)
       modprobe nvidia_drm
   ;;
   *) exit $NA
   ;;
esac

You can place the script to /etc/pm/sleep.d/01nvidia_drivers and make sure it is executable.

chmod +x /etc/pm/sleep.d/01nvidia_drivers

Afterwards, you should be able to hibernate/resume properly.

Silent startup failure for MongoDB on Raspberry Pi (and other systems)

Yesterday I tried to install mongodb on my Raspberry Pi. Raspbian Jessie ships with a default mongo 2.4 package, so the installation should be pretty straightforward:

apt-get install mongodb

However, after the installation finished, the service did not start:

service mongodb start

did not result in a started mongod process. No log files in /var/log/mongodb were produced, indicating that the process stops before the logging is initialized. If the mongodb server is started manually, a very early crash can be observed:

sudo -u mongodb /usr/bin/mongod  --config /etc/mongodb.conf
Sun Mar 27 07:48:45.296 terminate() called, printing stack (if implemented for platform):
 0x664160 0x16d954 0x767ea9a0
 /usr/bin/mongod(_ZN5mongo15printStackTraceERSo+0x1c) [0x664160]
 /usr/bin/mongod(_ZN5mongo11myterminateEv+0x54) [0x16d954]
 /usr/lib/arm-linux-gnueabihf/libstdc++.so.6(+0x4a9a0) [0x767ea9a0]
Sun Mar 27 07:48:45.299 Got signal: 6 (Aborted).
 
Sun Mar 27 07:48:45.302 Backtrace:
0x664160 0x16e370 0x765be180 0x765bcf70
 /usr/bin/mongod(_ZN5mongo15printStackTraceERSo+0x1c) [0x664160]
 /usr/bin/mongod(_ZN5mongo10abruptQuitEi+0x2a0) [0x16e370]
 /lib/arm-linux-gnueabihf/libc.so.6(__default_sa_restorer_v2+0) [0x765be180]
 /lib/arm-linux-gnueabihf/libc.so.6(gsignal+0x38) [0x765bcf70]

Stracing the syscalls shows that the error is generated shortly after mongod tries to load locales:

munmap(0x76f24000, 4096)                = 0
open("/usr/lib/locale/en_GB.UTF-8/LC_NUMERIC", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_GB.utf8/LC_NUMERIC", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_GB/LC_NUMERIC", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en.UTF-8/LC_NUMERIC", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en.utf8/LC_NUMERIC", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en/LC_NUMERIC", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
gettimeofday({1459065376, 950211}, NULL) = 0
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=118, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f24000
read(4, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\1\0\0\0\0"..., 4096) = 118
_llseek(4, -6, [112], SEEK_CUR)         = 0
read(4, "\nUTC0\n", 4096)               = 6
close(4)                                = 0
munmap(0x76f24000, 4096)                = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f24000
write(1, "Sun Mar 27 07:56:16.950 ", 24Sun Mar 27 07:56:16.950 ) = 24
write(1, "terminate() called, printing sta"..., 65terminate() called, printing stack (if implemented for platform):) = 65
write(1, "\n", 1
)                       = 1
futex(0x7667e5d8, FUTEX_WAKE_PRIVATE, 2147483647) = 0
write(1, "0x664160 0x16d954 0x7679a9a0 \n", 300x664160 0x16d954 0x7679a9a0
) = 30
write(1, " /usr/bin/mongod(_ZN5mongo15prin"..., 65 /usr/bin/mongod(_ZN5mongo15printStackTraceERSo+0x1c) [0x664160]
) = 65
write(1, " /usr/bin/mongod(_ZN5mongo11myte"..., 59 /usr/bin/mongod(_ZN5mongo11myterminateEv+0x54) [0x16d954]
) = 59
write(1, " /usr/lib/arm-linux-gnueabihf/li"..., 68 /usr/lib/arm-linux-gnueabihf/libstdc++.so.6(+0x4a9a0) [0x7679a9a0]
) = 68

It turns out that I did not change the default locale on my installation (which was en_GB.UTF-8), and did not make sure a proper locale was generated for this setting.

To fix the error, first make sure you pick the right locale. This can be changed by running

dpkg-reconfigure locales

There, you can first pick the locales that should be generated:

Afterwards, you can pick the locale that should be used on the system:

dpkg-reconfigure will then generate the locales that are supported. The changes will be applied after the next reboot. Make sure they are actually used in your current session by running

export LANG=*<YOUR_LOCALE_SELECTION>*

Afterwards, mongodb should start just fine.

If you are not on a debian system, you can make sure that the proper locales are generated by editing

/etc/locale.gen

and uncommenting all locales that you need. Afterwards you need to generate

locale-gen

which will generate the locale files. Setting the LANG environment variable is something that is distribution specific. Check your manual on where you can find the proper place to configure the locale. On debian-based systems, you can find it in

/etc/default/locale

on Gentoo, check your

/etc/env.d/02locale