WSL2標準kernelでmodprobe

# カーネルモジュールを使う方法

[ここ](https://qiita.com/lin_n/items/624d34a12ede6f72f403)から下記引用:

:::note warn
\<m\>だとカーネルモジュールが生成され、ドライバが含まれないkernelが生成されてしまいます。
WSLではlinuxカーネルに必要なドライバを全部取り込む流儀があるようで、面倒事を避けるためにカーネルモジュール指定は止めておきましょう。
:::
あえてWSL2標準kernelでカーネルモジュールを使う方法。CBL-Mariner2.0でカーネルビルドをすれば良い。[USBマスストレージモジュールを例](https://qiita.com/qawsed477/items/11e4248861fdf8c6a585#usb%E3%83%9E%E3%82%B9%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)として説明。

# 環境
```
C:\Users\user>ver

Microsoft Windows [Version 10.0.22631.3085]

C:\Users\user>wsl.exe --version
WSL バージョン: 2.1.1.0
カーネル バージョン: 5.15.146.1-2
WSLg バージョン: 1.0.60
MSRDC バージョン: 1.2.5105
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22631.3085

```

# Overlayfs
[WSL2.1.1](https://github.com/microsoft/WSL/releases/tag/2.1.1)以降(カーネル[5.15.137.3-microsoft-standard-WSL2](https://github.com/microsoft/WSL2-Linux-Kernel/releases/tag/linux-msft-wsl-5.15.137.3)以降)より loadable modules に正式対応。/lib/modules 以下が overlayfs で管理されているので、追加するモジュール用にもう一段 overlayfs を重ねる。
```shell:shell
$ sudo mkdir -p /usr/lib/modules_overlay/work/5.15.146.1-microsoft-standard-WSL2
$ sudo mkdir -p /usr/lib/modules_overlay/upper/5.15.146.1-microsoft-standard-WSL2
$ sudo mount -t overlay overlay -o \
lowerdir=/usr/lib/modules/5.15.146.1-microsoft-standard-WSL2,\
upperdir=/usr/lib/modules_overlay/upper/5.15.146.1-microsoft-standard-WSL2,\
workdir=/usr/lib/modules_overlay/work/5.15.146.1-microsoft-standard-WSL2 \
/usr/lib/modules/5.15.146.1-microsoft-standard-WSL2
```

wsl.conf で overlayfs マウントするように指定し、WSL を再起動 (`wsl --shutdown`) する。
```conf:/etc/wsl.conf
[boot]
systemd=true
command=mount -t overlay overlay -o \
lowerdir=/usr/lib/modules/5.15.146.1-microsoft-standard-WSL2,\
upperdir=/usr/lib/modules_overlay/upper/5.15.146.1-microsoft-standard-WSL2,\
workdir=/usr/lib/modules_overlay/work/5.15.146.1-microsoft-standard-WSL2 \
/usr/lib/modules/5.15.146.1-microsoft-standard-WSL2;\
 modprobe zfs; modprobe scsi_transport_iscsi; modprobe usb-storage;\
 modprobe kheaders; modprobe act_gact; modprobe act_police; modprobe sch_sfq

[interop]
enabled=true
appendWindowsPath=true
```

# BTF エラーの問題
5.15.57.1-microsoft-standard-WSL2 の頃からUbuntu等のtoolchainでカーネルビルドすると modprobe にてBPFのエラーが発生してモジュールを読み込めなくなった。
## 詳細
CONFIG_DEBUG_INFO_BTF_MODULES=y で [bpf: Load and verify kernel module BTFs](https://github.com/microsoft/WSL2-Linux-Kernel/commit/36e68442d1afd4f720704ee1ea8486331507e834) が有効になったのが原因。
CONFIG_DEBUG_INFO_BTF_MODULES は CONFIG_DEBUG_INFO_BTF に依存して有効化されるパラメータで、[5.10.74.3](https://github.com/microsoft/WSL2-Linux-Kernel/releases/tag/linux-msft-wsl-5.10.74.3) のタイミングで[導入された](https://github.com/microsoft/WSL/issues/7437#issuecomment-965505745)。
Microsoftに対しては [Feature request: Support for loadable kernel modules](https://github.com/microsoft/WSL/issues/10450)という issue がすでに送られていて、[.wslconfigでカーネルを入れ替えること](https://github.com/microsoft/WSL/issues/10450#issuecomment-1710801702)がコメントされている([ビルドスクリプトを添付](https://github.com/microsoft/WSL/issues/10450#issuecomment-1866306744))。

```shell:shell
$ sudo modprobe usb-storage
modprobe: ERROR: could not insert 'usb_storage': Invalid argument
$ sudo dmesg
...
[49140.621143] BPF:     Invalid name_offset:2392682
[49140.621828] failed to validate module [usb_storage] BTF: -22
```

補足: [WSL2でカーネルモジュールを作る#追伸](https://qiita.com/mangos_/items/20a700fe6f494cc0fdba#%E8%BF%BD%E4%BC%B8)とはエラーメッセージが違うが失敗する。("Invalid module format"のエラーは[vermagicの不一致](https://enakai00.hatenablog.com/entry/20110509/1304910773)が原因)
```shell:shell
$ sudo insmod hello.ko
insmod: ERROR: could not insert module hello.ko: Invalid parameters
$ sudo dmesg
...
[ 7579.781091] BPF:[133978] Invalid name_offset:2392682
[ 7579.781906] failed to validate module [hello] BTF: -22
```

<details><summary>補足: この問題の原因と調査のメモ</summary><div>

.config で CONFIG_DEBUG_INFO_BTF_MODULES=y の設定をするとこの問題が起きる。

以下、調査方法のメモ。
モジュールビルド中、"BTF [M]" のメッセージが表示される。どのファイルで出力しているかを探す。
```shell:shell
make: Entering directory '/usr/src/WSL2-Linux-Kernel-linux-msft-wsl-5.15.133.1'
  CC [M]  /tmp/hello_module/hello.o
  MODPOST /tmp/hello_module/Module.symvers
  CC [M]  /tmp/hello_module/hello.mod.o
  LD [M]  /tmp/hello_module/hello.ko
  BTF [M] /tmp/hello_module/hello.ko
make: Leaving directory '/usr/src/WSL2-Linux-Kernel-linux-msft-wsl-5.15.133.1'
```

ソースコードのどの部分で表示しているか探すと、./scripts/Makefile.modfinal で表示していた。
```shell:shell
$ find WSL2-Linux-Kernel-linux-msft-wsl-5.15.133.1/ -type f | xargs grep 'BTF \[M\]'
WSL2-Linux-Kernel-linux-msft-wsl-5.15.133.1/scripts/Makefile.modfinal:quiet_cmd_btf_ko = BTF [M] $@
```

以下の部分、$(PAHOLE)で DWARF の情報を BTFに変換。
```Makefile:linux/scripts/Makefile.modfinal
quiet_cmd_btf_ko = BTF [M] $@
      cmd_btf_ko =                                                      \
        if [ -f vmlinux ]; then                                         \
                LLVM_OBJCOPY="$(OBJCOPY)" $(PAHOLE) -J $(PAHOLE_FLAGS) --btf_base vmlinux $@; \
        else                                                            \
                printf "Skipping BTF generation for %s due to unavailability of vmlinux\n" $@ 1>&2; \
        fi;

```

WSL の カーネルソースを git clone して、./scripts/Makefile.modfinal の履歴を調査。
```:shell
$ git log --oneline --graph ./scripts/Makefile.modfinal
* 5c883c42bd78 kbuild: Disable GCOV for *.mod.o
* 0baced0e0938 kbuild: Unify options for BTF generation for vmlinux and modules
* 850ded46c642 kbuild: Fix TRIM_UNUSED_KSYMS with LTO_CLANG
*   81361b837a34 Merge tag 'kbuild-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild
|\
| * 0d989ac2c90b kbuild: remove libelf checks from top Makefile
* | ff2e6efda0d5 kbuild: Quote OBJCOPY var to avoid a pahole call break the build
|/
* cf68fffb66d6 add support for Clang CFI
* b1a1a1a09b46 kbuild: lto: postpone objtool
* dc5723b02e52 kbuild: add support for Clang LTO
* e732b538f455 kbuild: Skip module BTF generation for out-of-tree external modules
* 5f9ae91f7c0d kbuild: Build kernel module BTFs if BTF is enabled and pahole supports it
* 596b0474d3d9 kbuild: preprocess module linker script
* eb27ea5ce7f3 kbuild: move modkern_{c,a}flags to Makefile.lib from Makefile.build
* 9b9a3f20cbe0 kbuild: split final module linking out into Makefile.modfinal
```

[5f9ae91f7c0d](https://github.com/microsoft/WSL2-Linux-Kernel/commit/5f9ae91f7c0dbbc4195e2a6c8eedcaeb5b9e4cbb) にて追加された変更と確認。

dmesg に残るメッセージをどこで出力しているかを確認。
./kernel/bpf/btf.c で出力していた。
```shell:shell
$ find ./ -type f -print | xargs grep -e 'failed to validate module \[.*\] BTF'
grep: ./vmlinux: binary file matches
grep: ./.tmp_vmlinux.btf: binary file matches
grep: ./vmlinux.o: binary file matches
grep: ./.tmp_vmlinux.kallsyms2: binary file matches
grep: ./.tmp_vmlinux.kallsyms1: binary file matches
./kernel/bpf/btf.c:                     pr_warn("failed to validate module [%s] BTF: %ld\n",
grep: ./kernel/bpf/btf.o: binary file matches
```

ソースコードでも CONFIG_DEBUG_INFO_BTF_MODULES でコードが有効化されていた。
```c:./kernel/bpf/btf.c
#ifdef CONFIG_DEBUG_INFO_BTF_MODULES
...
static int btf_module_notify(struct notifier_block *nb, unsigned long op,
                             void *module)
{
...
                if (IS_ERR(btf)) {
                        pr_warn("failed to validate module [%s] BTF: %ld\n",
                                mod->name, PTR_ERR(btf));
...
#endif /* CONFIG_DEBUG_INFO_BTF_MODULES */
```

./kernel/bpf/btf.c の履歴を調査。
```:shell
$ git log --oneline --graph ./kernel/bpf/btf.c
* b7db41a86541 bpf/btf: Accept function names that contain dots
* 18ab31b8cd37 btf: fix resolving BTF_KIND_VAR after ARRAY, STRUCT, UNION, PTR
* 95ab0725c521 bpf: Fix global subprog context argument resolution logic
* b327c68ace71 bpf: Prevent decl_tag from being referenced in func_proto arg
* 5d9222c68022 bpf: btf: fix truncated last_member_type_id in btf_struct_resolve
* 5c0ab17c5360 bpf: Fix calling global functions from BPF_PROG_TYPE_EXT programs
* 8c39925e98d4 bpf: Fix crash due to out of bounds access into reg2btf_ids.
* 2a77c58726ab bpf: Add MEM_RDONLY for helper args that are pointers to rdonly mem.
* b710f73704d6 bpf: Convert PTR_TO_MEM_OR_NULL to composable types.
* b453361384c2 bpf: Introduce MEM_RDONLY flag
* 8d38cde47a7e bpf: Replace PTR_TO_XXX_OR_NULL with PTR_TO_XXX | PTR_MAYBE_NULL
* 51b82141fffa bpf: Fix UAF due to race between btf_try_get_module and load_module
* 832d478ccd06 bpf: Disallow BPF_LOG_KERNEL log level for bpf(BPF_BTF_LOAD)
* 2571173d3e11 bpf: Adjust BTF log size limit.
* eb529c5b10b9 bpf: Fix bpf-next builds without CONFIG_BPF_EVENTS
* d36216429ff3 bpf: Emit better log message if bpf_iter ctx arg btf_id == 0
* 68134668c17f bpf: Add map side support for bpf timers.
*   a52171ae7b80 Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
|\
| * 8fb33b605530 bpf: Fix spelling mistakes
* |   5ada57a9a6b0 Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
|\ \
| |/
|/|
| * 31379397dcc3 bpf: Forbid trampoline attach for functions with variable arguments
* | 3d78417b60fb bpf: Add bpf_btf_find_by_name_kind() helper.
* | c571bd752e91 bpf: Make btf_load command to be bpfptr_t compatible.
|/
* 235fc0e36d35 bpf: Remove redundant assignment of variable id
* e6ac2450d6de bpf: Support bpf program calling kernel function
* 34747c412041 bpf: Refactor btf_check_func_arg_match
*   c1acda9807e2 Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
|\
| * b1828f0b0482 bpf: Add BTF_KIND_FLOAT support
| * 523a4cf491b3 bpf: Use MAX_BPF_FUNC_REG_ARGS macro
* | f4eda8b6e4a5 bpf: Drop imprecise log message
|/
* e5069b9c23b3 bpf: Support pointers in global func args
* feb4adfad575 bpf: Rename bpf_reg_state variables
* 13ca51d5eb35 bpf: Permit size-0 datasec
*   0fe2f273ab89 Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
|\
| * bcc5e6162d66 bpf: Allow empty module BTFs
* | 541c3bad8dc5 bpf: Support BPF ksym variables in kernel modules
|/
* 290248a5b7d8 bpf: Allow to specify kernel module BTFs when attaching BPF programs
* 22dc4a0f5ed1 bpf: Remove hard-coded btf_vmlinux assumption from BPF verifier
* 7112d127984b bpf: Compile out btf_parse_module() if module BTF is not enabled
* 36e68442d1af bpf: Load and verify kernel module BTFs
* 5329722057d4 bpf: Assign ID to vmlinux BTF and return extra info for BTF in GET_OBJ_INFO
* 951bb64621b8 bpf: Add in-kernel split BTF support
* 666475ccbf1d bpf, btf: Remove the duplicate btf_ids.h include
* eaa6bcb71ef6 bpf: Introduce bpf_per_cpu_ptr()
```

./kernel/bpf/btf.c の CONFIG_DEBUG_INFO_BTF_MODULES は [36e68442d1af](https://github.com/microsoft/WSL2-Linux-Kernel/commit/36e68442d1afd4f720704ee1ea8486331507e834) で追加された。

WSL カーネルのタグを調査。5.15.x 以降から有効化していることを確認。
```shell:shell
$ git show linux-msft-wsl-5.10.102.1:Microsoft/config-wsl|grep CONFIG_DEBUG_INFO_BTF_MODULES
$ git show linux-msft-wsl-5.15.57.1:Microsoft/config-wsl|grep CONFIG_DEBUG_INFO_BTF_MODULES
CONFIG_DEBUG_INFO_BTF_MODULES=y
```

CONFIG_DEBUG_INFO_BTF_MODULES は CONFIG_DEBUG_INFO_BTF に依存して有効化される。
これは 5.10.74.3 から有効になっていることを確認。
```shell:shell
$ git show linux-msft-wsl-5.10.60.1:Microsoft/config-wsl|grep CONFIG_DEBUG_INFO_BTF
$ git show linux-msft-wsl-5.10.74.3:Microsoft/config-wsl|grep CONFIG_DEBUG_INFO_BTF
CONFIG_DEBUG_INFO_BTF=y
```
[5.10.74.3のリリースノート](https://github.com/microsoft/WSL2-Linux-Kernel/releases/tag/linux-msft-wsl-5.10.74.3) を見ると、[Enable kernel headers for eBPF tools. #7437](https://github.com/microsoft/WSL/issues/7437)の提案を取り入れたものと確認ができた。
</div></details>

## CBL-Mariner2.0
[カーネルとモジュールが別のビルド](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1003210#36)だとこの問題が起きる。
WSL2 のシステム本体が CBL-Mariner2.0 なのでカーネルも同じ環境でビルドしているのではないかと推測し、試してみた。

```powershell:powershell
PS C:\> wsl --system cat /etc/os-release
NAME="Common Base Linux Mariner"
VERSION="2.0.20230630"
ID=mariner
VERSION_ID="2.0"
PRETTY_NAME="CBL-Mariner/Linux"
ANSI_COLOR="1;34"
HOME_URL="https://aka.ms/cbl-mariner"
BUG_REPORT_URL="https://aka.ms/cbl-mariner"
SUPPORT_URL="https://aka.ms/cbl-mariner"
```
# USBマスストレージモジュール
USBマスストレージモジュールを例として説明。

## CBL-Mariner2.0でカーネルビルド
docker-desktopのインストール方法・設定方法は割愛。

```Dockerfile:Dockerfile
FROM mcr.microsoft.com/cbl-mariner/base/core:2.0

RUN tdnf install -y --releasever=2.0 shadow-utils \
  && useradd -U builder --shell /bin/sh --home-dir /home/builder --create-home \
  && tdnf install -y --releasever=2.0 \
    make \
    gcc \
    glibc-devel \
    ncurses-devel \
    binutils \
    kernel-headers \
    flex \
    bison \
    openssl-devel \
    diffutils \
    python3 \
    bc \
    gawk \
    perl \
    dwarves \
    cpio \
    tar \
    xz \
  && tdnf clean all

USER builder
```

dockerイメージファイル作成。wslソースコードを[入手](https://github.com/microsoft/WSL2-Linux-Kernel)して展開。
```shell:shell
$ docker build -t wslkernelbuilder:2.0 .
$ tar xvfz WSL2-Linux-Kernel-linux-msft-wsl-5.15.146.1.tar.gz
$ ln -s WSL2-Linux-Kernel-linux-msft-wsl-5.15.146.1 linux
```

下記ビルドスクリプトを用意。
```shell:build_wsl_modules.sh
#!/bin/sh
set -xe

build_modules(){
        docker run -u $(id -u $(whoami)):$(id -g $(whoami)) \
                -ti --rm --volume=$(pwd):/usr/src \
                -w /usr/src/linux wslkernelbuilder:2.0 \
                sh -c 'make mrproper \
                && cp Microsoft/config-wsl .config \
                && cat ../add_module_config >> .config \
                && make oldconfig \
                && make LOCALVERSION= modules -j8 \
                && cd tools/bpf/bpftool \
                && make \
                && cd ../../.. \
                && ./tools/bpf/bpftool/bpftool btf dump file vmlinux format c > vmlinux.h \
                && ./tools/bpf/bpftool/bpftool btf dump file /sys/kernel/btf/vmlinux format c > sys_vmlinux.h \
                && diff vmlinux.h sys_vmlinux.h > /dev/null \
                && echo btf check ok || (echo build fail; false)'
}

install_modules(){
        docker run -u $(id -u $(whoami)):$(id -g $(whoami)) \
                -ti --rm --volume=$(pwd):/usr/src \
                -w /usr/src/linux wslkernelbuilder:2.0 \
                make INSTALL_MOD_PATH=/usr/src/out LOCALVERSION= modules_install
}

build_deb(){
        KERNELVER=$(awk '/UTS_RELEASE/{gsub(/"/,"");print $3}' ./linux/include/generated/utsrelease.h)
        LINUX_VERSION=$(echo ${KERNELVER}|awk -F'[-]' '{print $1}')
        LINUX_RELEASE="1"
        mkdir -p out/DEBIAN

        # remove duplicate starndard modules
        rm -f out/lib/modules/${KERNELVER}/kernel/drivers/block/nbd.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/drivers/net/bonding/bonding.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/drivers/net/dummy.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/drivers/net/vrf.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/drivers/usb/serial/ch341.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/drivers/usb/serial/cp210x.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/drivers/usb/serial/ftdi_sio.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/drivers/usb/serial/usbserial.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/net/ipv4/ipip.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/net/ipv4/tunnel4.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/net/ipv6/sit.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/net/netfilter/xt_bpf.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/net/netfilter/xt_CT.ko
        rm -f out/lib/modules/${KERNELVER}/kernel/net/netfilter/xt_u32.ko
        find out/lib/modules/${KERNELVER} -type d -empty -delete

        INSTALLED_SIZE=$(du -ks out|awk '{print $1}')
        cat > out/DEBIAN/control << EOF
Package: linux-module-${KERNELVER}
Priority: extra
Section: kernel
Installed-Size: ${INSTALLED_SIZE}
Maintainer: $(whoami)@$(hostname)
Architecture: amd64
Version: ${LINUX_VERSION}-${LINUX_RELEASE}
Provides: linux-module
Description: module files for WSL linux kernel
 Enable modules:
 $(test -f ./add_module_config &&
sed 's/^/ /' ./add_module_config)
EOF

        cat > out/DEBIAN/postinst << EOF
#!/bin/sh
depmod ${KERNELVER}
EOF
        chmod 755 out/DEBIAN/postinst

        fakeroot dpkg-deb --build out .
}

if type "$1" | grep -e 'is a.* function' > /dev/null;then
        "$1"
else
        build_modules \
        && install_modules \
        && build_deb
fi

```
```shell:build_usb-storage.sh
#!/bin/sh
set -xe

cat > add_module_config << EOF
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_REALTEK=m
CONFIG_USB_STORAGE_DATAFAB=m
CONFIG_USB_STORAGE_FREECOM=m
CONFIG_USB_STORAGE_ISD200=m
CONFIG_USB_STORAGE_USBAT=m
CONFIG_USB_STORAGE_SDDR09=m
CONFIG_USB_STORAGE_SDDR55=m
CONFIG_USB_STORAGE_JUMPSHOT=m
CONFIG_USB_STORAGE_ALAUDA=m
CONFIG_USB_STORAGE_ONETOUCH=m
CONFIG_USB_STORAGE_KARMA=m
CONFIG_USB_STORAGE_CYPRESS_ATACB=m
CONFIG_USB_STORAGE_ENE_UB6250=m
CONFIG_USB_UAS=m
EOF

sh build_wsl_modules.sh
```

dockerを使いモジュールをビルド、dpkgでモジュールをインストール。
```shell:shell
$ sh build_usb-storage.sh
$ sudo dpkg -i linux-module-5.15.146.1-microsoft-standard-wsl2_5.15.146.1-1_amd64.deb
```

lsmodで結果が返ってくる。dmesgでも問題なし。
```shell:shell
$ sudo modprobe usb-storage
$ sudo lsmod
Module                  Size  Used by
usb_storage            69632  0
$ sudo dmesg
...
[49236.916526] usbcore: registered new interface driver usb-storage
```
## ビルドに失敗する場合
スクリプトを実行して "build fail" で止まる場合は標準カーネルでモジュールを使うのはあきらめて [.wslconfig にカスタムカーネルを追加](https://github.com/microsoft/WSL/issues/10450#issuecomment-1710801702)しましょう。
<details><summary>build failになる例: usbmonモジュールを作ろうとした時のログ</summary><div>

```shell:shell
$ cat >> add_module_config << EOF
> CONFIG_USB_MON=m
EOF
$ sh build_wsl_modules.sh
...
build fail
```
BTFの変化点:
```diff:shell
$ diff -u linux/vmlinux.h linux/sys_vmlinux.h
--- linux/vmlinux.h     2023-12-18 20:31:57.644548235 +0900
+++ linux/sys_vmlinux.h 2023-12-18 20:31:57.914548594 +0900
@@ -112626,8 +112626,6 @@
        long unsigned int devicemap[2];
 };

-struct mon_bus;
-
 struct usb_device;

 struct usb_bus {
@@ -112651,8 +112649,6 @@
        int bandwidth_int_reqs;
        int bandwidth_isoc_reqs;
        unsigned int resuming_ports;
-       struct mon_bus *mon_bus;
-       int monitored;
 };

 struct wusb_dev;
@@ -115435,12 +115431,6 @@
        USB_LED_EVENT_GADGET = 1,
 };

-struct usb_mon_operations {
-       void (*urb_submit)(struct usb_bus *, struct urb *);
-       void (*urb_submit_error)(struct usb_bus *, struct urb *, int);
-       void (*urb_complete)(struct usb_bus *, struct urb *, int);
-};
-
 struct usb_sg_request {
        int status;
        size_t bytes;

```
</div></details>

# ユーザ作成のモジュール
CBL-Mariner2.0でモジュールをビルドすることにより、[カーネルの入れ替え](https://qiita.com/mangos_/items/20a700fe6f494cc0fdba#5-wsl2%E3%81%AE%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E8%A8%AD%E5%AE%9A%E3%82%92update)を行わなくても問題なし。
<details><summary>参考:確認用スクリプト</summary><div>

```shell:hello_module.sh
#!/bin/sh
set -xe

mkdir -p /tmp/hello_module

cat > /tmp/hello_module/Makefile << EOF
obj-m := hello.o

all:
$(echo \\t)make -C $(pwd)/linux M=/tmp/hello_module modules
clean:
$(echo \\t)make -C $(pwd)/linux M=/tmp/hello_module clean
EOF

cat > /tmp/hello_module/hello.c << EOF
#include <linux/module.h>

static int hello_init(void)
{
    printk("hello world.\n");
    return 0;
}

static void hello_exit(void)
{
    printk("Goodbye, cruel world.\n");
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("");
EOF

docker run -u $(id -u $(whoami)):$(id -g $(whoami)) \
    -ti --rm --volume=$(pwd):/usr/src \
	--volume=/tmp/hello_module:/tmp/hello_module \
	-w /usr/src wslkernelbuilder:2.0 \
	make -C /usr/src/linux M=/tmp/hello_module modules

cd /tmp/hello_module
ls
modinfo hello.ko
sudo insmod hello.ko
sudo rmmod hello.ko
sudo dmesg | tail -2
```
</div></details>

```shell:shell
$ sudo insmod hello.ko
$ sudo rmmod hello.ko
$ sudo dmesg
...
[ 7607.899848] hello world.
[ 7630.322974] Goodbye, cruel world.
```
# ZFS モジュール
[この記事](https://qiita.com/qawsed477/items/0c9217803e8f70ee1f48)を書いた時はCBL-Mariner2.0 を使ったビルドを思いつかず、/sys/kernel/btf/vmlinux を無理やりコピーしていた。

zfs のソースコードを展開して準備。
```shell:shell
$ tar xvfz zfs-2.2.2.tar.gz
$ ln -s zfs-2.2.2 zfs
```
下記スクリプトでパッケージを作成可能。
```shell:build_zfs.sh
#!/bin/sh
set -xe

cat > add_module_config << EOF
# ZFS support
EOF

sh build_wsl_modules.sh build_modules

sh -c 'cd zfs \
	&& ./configure \
	--prefix=/usr \
	--sysconfdir=/etc \
	--libdir=/lib \
	--includedir=/usr/include \
	--datarootdir=/usr/share \
	--enable-linux-builtin=no \
	--with-linux=$(pwd)/../linux \
	--with-linux-obj=$(pwd)/../linux'

docker run -u $(id -u $(whoami)):$(id -g $(whoami)) -ti --rm --volume=$(pwd):$(pwd) \
	-w $(pwd)/zfs/module wslkernelbuilder:2.0 \
	make

sh build_wsl_modules.sh install_modules

docker run -u $(id -u $(whoami)):$(id -g $(whoami)) -ti --rm --volume=$(pwd):$(pwd) \
	-w $(pwd)/zfs/module wslkernelbuilder:2.0 \
	make DESTDIR=$(pwd)/out install

sh build_wsl_modules.sh build_deb

```

dockerを使いモジュールをビルド、dpkgでモジュールをインストール。
```shell:shell
$ sh build_zfs.sh
$ sudo dpkg -i linux-module-5.15.146.1-microsoft-standard-wsl2_5.15.146.1-1_amd64.deb
```

`zfs --version`で結果が返ってくる。dmesgでも問題なし。
```shell:shell
$ sudo modprobe zfs
$ sudo zfs --version
zfs-2.2.2-1
zfs-kmod-2.2.2-1
$ sudo dmesg
...
[    1.294668] spl: loading out-of-tree module taints kernel.
[    1.367794] zfs: module license 'CDDL' taints kernel.
[    1.368395] Disabling lock debugging due to kernel taint
...
[    2.229800] ZFS: Loaded module v2.2.2-1, ZFS pool version 5000, ZFS filesystem version 5
```