Eu gosto de usar os kernels mais recentes e compilar minhas próprias versões. Às vezes adiciono patches pra melhorar resposta de temporeal, às vezes um suporte pra AUFS no docker.
Atualmente estou com o 4.14-rc2, um pouco antigo nesse momento mas que me deu um uptime de 25 dias sem problemas até agora.
Linux elxaf7qtt32 4.14.0-rc2-helio #12 SMP PREEMPT Fri Sep 29 13:50:19 CEST 2017 x86_64 x86_64 x86_64 OSI/Linux
(é... troquei GNU/Linux por OSI/Linux... por diversão e usando sed na saída do uname)
E descobri que o VirtualBox versão 5.2 simplesmente não consegue rodar o comando /sbin/vboxconfig. Olhando o erro um pouco mais de perto pelo log:
gcc -Wp,-MD,/tmp/vbox.0/linux/.SUPR0IdcClient-linux.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/5/include -I./arch/x86/include -I./arch/x86/include/generated -I./include -
I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototyp
es -Wno-trigraphs -fno-strict-aliasing -fno-common -fshort-wchar -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -
mno-avx -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -
DCONFIG_X86_X32_ABI -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_SSSE3=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG
_AS_AVX2=1 -DCONFIG_AS_AVX512=1 -DCONFIG_AS_SHA1_NI=1 -DCONFIG_AS_SHA256_NI=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -fno-delete-null-pointer-checks -O2 --param=allow-
store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=1024 -fstack-protector-strong -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracki
ng-assignments -g -gdwarf-4 -pg -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-pro
totypes -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -include /tmp/vbox.0/include/VBox/SUPDrvMangling.h -fno-pie -I/lib/modules/4.14.0-rc2-helio/build/i
nclude -I/tmp/vbox.0/ -I/tmp/vbox.0/include -I/tmp/vbox.0/r0drv/linux -D__KERNEL__ -DMODULE -DRT_OS_LINUX -DIN_RING0 -DIN_RT_R0 -DIN_SUP_R0 -DVBOX -DRT_WITH_VBOX -DVBOX_WITH_HARDENING
-Wno-declaration-after-statement -DRT_ARCH_AMD64 -DVBOX_WITH_64_BITS_GUESTS -DMODULE -DKBUILD_BASENAME='"SUPR0IdcClient_linux"' -DKBUILD_MODNAME='"vboxnetflt"' -c -o /tmp/vbox.0/lin
ux/.tmp_SUPR0IdcClient-linux.o /tmp/vbox.0/linux/SUPR0IdcClient-linux.c
if [ "-pg" = "-pg" ]; then if [ /tmp/vbox.0/SUPR0IdcClient.o != "scripts/mod/empty.o" ]; then ./scripts/recordmcount "/tmp/vbox.0/SUPR0IdcClient.o"; fi; fi;
(cat /dev/null; echo kernel//tmp/vbox.0/vboxnetflt.ko;) > /tmp/vbox.0/modules.order
if [ "-pg" = "-pg" ]; then if [ /tmp/vbox.0/linux/SUPR0IdcClient-linux.o != "scripts/mod/empty.o" ]; then ./scripts/recordmcount "/tmp/vbox.0/linux/SUPR0IdcClient-linux.o"; fi; fi;
if [ "-pg" = "-pg" ]; then if [ /tmp/vbox.0/VBoxNetFlt.o != "scripts/mod/empty.o" ]; then ./scripts/recordmcount "/tmp/vbox.0/VBoxNetFlt.o"; fi; fi;
/tmp/vbox.0/linux/VBoxNetFlt-linux.c: In function ‘vboxNetFltLinuxSkBufFromSG’:
/tmp/vbox.0/linux/VBoxNetFlt-linux.c:741:24: error: ‘SKB_GSO_UDP’ undeclared (first use in this function)
fGsoType = SKB_GSO_UDP;
^
/tmp/vbox.0/linux/VBoxNetFlt-linux.c:741:24: note: each undeclared identifier is reported only once for each function it appears in
In file included from /tmp/vbox.0/include/iprt/types.h:29:0,
from /tmp/vbox.0/r0drv/linux/the-linux-kernel.h:34,
from /tmp/vbox.0/linux/VBoxNetFlt-linux.c:24:
/tmp/vbox.0/linux/VBoxNetFlt-linux.c: In function ‘vboxNetFltLinuxCanForwardAsGso’:
/tmp/vbox.0/linux/VBoxNetFlt-linux.c:1276:53: error: ‘SKB_GSO_UDP’ undeclared (first use in this function)
if (RT_UNLIKELY( skb_shinfo(pSkb)->gso_type & ~(SKB_GSO_UDP | SKB_GSO_DODGY | SKB_GSO_TCPV6 | SKB_GSO_TCPV4) ))
^
/tmp/vbox.0/include/iprt/cdefs.h:1616:53: note: in definition of macro ‘RT_UNLIKELY’
# define RT_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
^
/tmp/vbox.0/linux/VBoxNetFlt-linux.c: In function ‘vboxNetFltLinuxForwardToIntNetInner’:
/tmp/vbox.0/linux/VBoxNetFlt-linux.c:1526:47: error: ‘SKB_GSO_UDP’ undeclared (first use in this function)
if ( (skb_shinfo(pBuf)->gso_type & (SKB_GSO_UDP | SKB_GSO_TCPV6 | SKB_GSO_TCPV4))
^
scripts/Makefile.build:311: recipe for target '/tmp/vbox.0/linux/VBoxNetFlt-linux.o' failed
make[2]: *** [/tmp/vbox.0/linux/VBoxNetFlt-linux.o] Error 1
Makefile:1498: recipe for target '_module_/tmp/vbox.0' failed
make[1]: *** [_module_/tmp/vbox.0] Error 2
/tmp/vbox.0/Makefile.include.footer:97: recipe for target 'vboxnetflt' failed
Foi algo relacionado com a variável SKB_GSO_UDP, que parece não existir no kernel mais recente ou no VirtualBox.
Buscando pelo termo pude encontrar que realmente existe uma diferença entre ambos um patch precisa ser aplicado, descrito aqui:
Fonte: https://gist.github.com/herbmillerjr/039c129e9c25b047b906e19ad1f23a59
diff --git a/work/vboxnetflt/linux/VBoxNetFlt-linux.c b/work/vboxnetflt/linux/VBoxNetFlt-linux.c
index f824654..b61d82c 100644
--- work/vboxnetflt/linux/VBoxNetFlt-linux.c
+++ work/vboxnetflt/linux/VBoxNetFlt-linux.c
@@ -126,6 +126,10 @@ typedef struct VBOXNETFLTNOTIFIER *PVBOXNETFLTNOTIFIER;
# endif
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
+#define SKB_GSO_UDP 0
+#endif
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 20, 0)
# define VBOX_HAVE_SKB_VLAN
#else
diff --git a/work/vboxpci/linux/VBoxPci-linux.c b/work/vboxpci/linux/VBoxPci-linux.c
index 2dbf47f..e361ef3 100644
--- work/vboxpci/linux/VBoxPci-linux.c
+++ work/vboxpci/linux/VBoxPci-linux.c
@@ -353,12 +353,16 @@ static void vboxPciFileClose(struct file* file)
static int vboxPciFileWrite(struct file* file, unsigned long long offset, unsigned char* data, unsigned int size)
{
int ret;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
+ ret = kernel_write(file, data, size, &offset);
+#else
mm_segment_t fs_save;
fs_save = get_fs();
set_fs(get_ds());
ret = vfs_write(file, data, size, &offset);
set_fs(fs_save);
+#endif
if (ret < 0)
printk(KERN_DEBUG "vboxPciFileWrite: error %d\n", ret);
Mas como minha versão de VirtualBox não era exatamente a mesma que essa descrita, acabei fazendo o patch manualmente, que adiciona a variável SKB_GSO_UDP ao VirtualBox caso seja um kernel 4.14.0 ou superior. Os arquivos para serem modificados no Ubuntu (e possivelmente Debian) são:
- /usr/share/virtualbox/src/vboxhost/vboxnetflt/linux/VBoxNetFlt-linux.c
- /usr/share/virtualbox/src/vboxhost/vboxpci/linux/VBoxPci-linux.c
depois basta rodar novamente como root o comando /sbin/vboxconfig para criar os módulos de kernel necessários pro funcionamento do VirtualBox.
SKB_GSO_UDP
SKB: SocKet Buffer
GSO: Generic Segmentation Offloading
UDP: User Datagram Protocol
Não tenho idéia do que isso faz exatamente mas parece ser uma chamada de um pacote UDP encapsulado.
