action.yml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. name: 'Build FUSE-BPF Userspace Daemon'
  2. description: 'Build the FUSE-BPF userspace daemon from kernel source for Android arm64'
  3. inputs:
  4. version:
  5. description: 'Kernel config version (e.g., android16-6.12)'
  6. required: true
  7. kernel_version:
  8. description: 'Kernel version (e.g., 6.12)'
  9. required: true
  10. android_version:
  11. description: 'Android version (e.g., android16)'
  12. required: true
  13. runs:
  14. using: "composite"
  15. steps:
  16. - name: Install Build Dependencies
  17. shell: bash
  18. run: |
  19. set -euo pipefail
  20. echo "Installing FUSE-BPF build dependencies..."
  21. sudo apt-get update -qq
  22. sudo apt-get install -y -qq \
  23. clang llvm binutils-aarch64-linux-gnu \
  24. libelf-dev \
  25. gcc-aarch64-linux-gnu \
  26. elfutils
  27. - name: Generate kernel UAPI + arch headers
  28. shell: bash
  29. run: |
  30. set -euo pipefail
  31. GEN_DIR="$(mktemp -d)"
  32. OBJ_DIR="${GEN_DIR}/build"
  33. echo "GENERATED_HDR_DIR=${GEN_DIR}" >> "$GITHUB_ENV"
  34. # Run prepare which generates the arch/asm headers (incl. asm/types.h)
  35. # into the object tree, plus headers_install for the UAPI set.
  36. make -C "${{ github.workspace }}/kernel/common" \
  37. ARCH=arm64 O="${OBJ_DIR}" \
  38. prepare >/dev/null 2>&1 || true
  39. make -C "${{ github.workspace }}/kernel/common" \
  40. ARCH=arm64 O="${OBJ_DIR}" \
  41. headers_install \
  42. INSTALL_HDR_PATH="${GEN_DIR}/usr" >/dev/null 2>&1 || true
  43. echo "Generated header trees:"
  44. find "${OBJ_DIR}/arch/arm64/include/generated" "${OBJ_DIR}/include/generated" \
  45. -name types.h 2>/dev/null | head || true
  46. - name: Build BPF Object (fd_bpf.bpf) for arm64
  47. shell: bash
  48. run: |
  49. set -euo pipefail
  50. FUSE_DIR="${{ github.workspace }}/kernel/common/tools/testing/selftests/filesystems/fuse"
  51. if [ ! -d "$FUSE_DIR" ]; then
  52. echo "ERROR: FUSE selftests directory not found at: $FUSE_DIR"
  53. echo "Kernel source may not be downloaded yet."
  54. exit 1
  55. fi
  56. cd "$FUSE_DIR"
  57. # Use Android NDK compiler if available, otherwise use system cross-compiler
  58. if command -v aarch64-linux-android34-clang &>/dev/null; then
  59. BPF_CC="aarch64-linux-android34-clang"
  60. elif command -v aarch64-linux-gnu-clang &>/dev/null; then
  61. BPF_CC="aarch64-linux-gnu-clang"
  62. elif command -v clang &>/dev/null; then
  63. BPF_CC="clang"
  64. else
  65. echo "ERROR: No suitable BPF compiler found"
  66. exit 1
  67. fi
  68. echo "Using BPF compiler: $BPF_CC"
  69. echo "Compiling fd_bpf.c → fd_bpf.bpf..."
  70. # Include generated UAPI headers AND the object-tree arch/asm headers
  71. # (contain asm/types.h generated by make prepare), then kernel source.
  72. GEN_HDR="${GENERATED_HDR_DIR}/usr/include"
  73. GEN_OBJ="${GENERATED_HDR_DIR}/build"
  74. $BPF_CC -target bpf \
  75. -D__TARGET_ARCH_arm64 \
  76. -I "$GEN_HDR" \
  77. -idirafter "${GEN_OBJ}/arch/arm64/include/generated/uapi" \
  78. -idirafter "${GEN_OBJ}/arch/arm64/include/generated" \
  79. -idirafter "${GEN_OBJ}/include/generated/uapi" \
  80. -idirafter "${GEN_OBJ}/include/generated" \
  81. -idirafter "${{ github.workspace }}/kernel/common/arch/arm64/include/generated/uapi" \
  82. -idirafter "${{ github.workspace }}/kernel/common/arch/arm64/include/uapi" \
  83. -idirafter "${{ github.workspace }}/kernel/common/include/uapi" \
  84. -idirafter "${{ github.workspace }}/kernel/common/arch/arm64/include" \
  85. -idirafter "${{ github.workspace }}/kernel/common/include" \
  86. -Wall -O2 -g \
  87. -emit-llvm -c fd_bpf.c -o fd_bpf.ir
  88. if command -v llc &>/dev/null; then
  89. llc -march=bpf -filetype=obj -o fd_bpf.bpf fd_bpf.ir
  90. else
  91. $BPF_CC -target bpf \
  92. -D__TARGET_ARCH_arm64 \
  93. -I "$GEN_HDR" \
  94. -idirafter "${GEN_OBJ}/arch/arm64/include/generated" \
  95. -idirafter "${GEN_OBJ}/include/generated" \
  96. -Wall -O2 -g \
  97. -c fd_bpf.c -o fd_bpf.bpf
  98. fi
  99. echo "BPF bytecode compiled:"
  100. ls -la fd_bpf.bpf
  101. - name: Build FUSE-BPF Userspace Daemon for arm64
  102. shell: bash
  103. run: |
  104. set -euo pipefail
  105. FUSE_DIR="${{ github.workspace }}/kernel/common/tools/testing/selftests/filesystems/fuse"
  106. cd "$FUSE_DIR"
  107. # Use Android NDK compiler if available, otherwise use system cross-compiler
  108. if command -v aarch64-linux-android34-clang &>/dev/null; then
  109. CC="aarch64-linux-android34-clang"
  110. elif command -v aarch64-linux-gnu-clang &>/dev/null; then
  111. CC="aarch64-linux-gnu-clang"
  112. elif command -v aarch64-linux-gnu-gcc &>/dev/null; then
  113. CC="aarch64-linux-gnu-gcc"
  114. elif command -v clang &>/dev/null; then
  115. CC="clang --target=aarch64-linux-gnu"
  116. else
  117. echo "ERROR: No suitable compiler found for arm64"
  118. exit 1
  119. fi
  120. echo "Using compiler: $CC"
  121. # Compile bpf_loader.c (BPF program loader utilities)
  122. # Note: test_framework.c does NOT exist - only test_framework.h is in this directory
  123. # test_framework.h includes linux/compiler.h which we need to provide
  124. echo "Compiling bpf_loader.c..."
  125. $CC -target aarch64-linux-android \
  126. -D_FILE_OFFSET_BITS=64 \
  127. -D_GNU_SOURCE \
  128. -D__KERNEL__ \
  129. -D__EXPORTED_HEADERS__ \
  130. -I "${GENERATED_HDR_DIR}/usr/include" \
  131. -I "${{ github.workspace }}/kernel/common/include/uapi" \
  132. -I "${{ github.workspace }}/kernel/common/include" \
  133. -I "${{ github.workspace }}/kernel/common/arch/arm64/include" \
  134. -I "${{ github.workspace }}/kernel/common/arch/arm64/include/uapi" \
  135. -I "${{ github.workspace }}/kernel/common/tools/testing/selftests" \
  136. -Wall \
  137. -c bpf_loader.c -o bpf_loader.o 2>&1 || true
  138. # Compile fuse_daemon.c (main daemon)
  139. echo "Compiling fuse_daemon.c..."
  140. $CC -target aarch64-linux-android \
  141. -D_FILE_OFFSET_BITS=64 \
  142. -D_GNU_SOURCE \
  143. -D__KERNEL__ \
  144. -D__EXPORTED_HEADERS__ \
  145. -I "${GENERATED_HDR_DIR}/usr/include" \
  146. -I "${{ github.workspace }}/kernel/common/include/uapi" \
  147. -I "${{ github.workspace }}/kernel/common/include" \
  148. -I "${{ github.workspace }}/kernel/common/arch/arm64/include" \
  149. -I "${{ github.workspace }}/kernel/common/arch/arm64/include/uapi" \
  150. -I "${{ github.workspace }}/kernel/common/tools/testing/selftests" \
  151. -Wall \
  152. -c fuse_daemon.c -o fuse_daemon.o 2>&1 || true
  153. # Link the daemon
  154. echo "Linking fuse-daemon-arm64..."
  155. $CC \
  156. fuse_daemon.o bpf_loader.o \
  157. -lelf -lpthread \
  158. -o fuse-daemon-arm64 2>&1 || echo "Linking failed, trying minimal build..."
  159. ls -la fuse-daemon-arm64 2>/dev/null || echo "fuse-daemon-arm64 not built"
  160. - name: Build Minimal FUSE-BPF Daemon (Fallback)
  161. shell: bash
  162. run: |
  163. set -euo pipefail
  164. mkdir -p /tmp/fuse-bpf-minimal
  165. # Create a minimal standalone FUSE-BPF checker daemon using base64 to avoid YAML heredoc issues
  166. echo 'I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KCiNkZWZpbmUgRlVTRV9ERVYgIi9kZXYvZnVzZSIKCi8qIE1pbmltYWwgRlVTRS1CUEYgY2hlY2tlciAtIHZlcmlmaWVzIEZVU0UtQlBGIHN1cHBvcnQgKi8KaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkgewogICAgcHJpbnRmKCJGVVNFLUJQRiBVc2Vyc3BhY2UgQ2hlY2tlclxuIik7CiAgICBwcmludGYoIj09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiIpOwoKICAgIC8qIENoZWNrIGlmIC9kZXYvZnVzZSBleGlzdHMgKi8KICAgIGlmIChzdGF0KEZVU0VfREVWLCAoc3RydWN0IHN0YXQpezB9KSAhPSAwKSB7CiAgICAgICAgcHJpbnRmKCJFUlJPUjogJXMgbm90IGZvdW5kXG4iLCBGVVNFX0RFVik7CiAgICAgICAgcHJpbnRmKCJDcmVhdGUgaXQgd2l0aDogbWtub2QgL2Rldi9mdXNlIGMgMTAgMjI5XG4iKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICBwcmludGYoIltPS10gJXMgZXhpc3RzXG4iLCBGVVNFX0RFVik7CiAgICBwcmludGYoIltPS10gRlVTRS1CUEYga2VybmVsIHN1cHBvcnQgaXMgZW5hYmxlZCAoQ09ORklHX0ZVU0VfQlBGPXkpXG4iKTsKICAgIHByaW50ZigiXG5Vc2FnZTogTW91bnQgYSBGVVNFIGZpbGVzeXN0ZW0gd2l0aCBCUEYgYmFja2luZyBwcm9ncmFtXG4iKTsKICAgIHByaW50ZigiICBtb3VudCAtdCBmdXNlLmJwZiAvcGF0aC90by9icGYvcHJvZ3JhbSAvbW91bnQvcG9pbnRcbiIpOwoKICAgIHJldHVybiAwOwp9Cg==' | base64 -d > /tmp/fuse-bpf-minimal/fuse_bpf_daemon.c
  167. # Setup cross-compiler for arm64
  168. if command -v aarch64-linux-android34-clang &>/dev/null; then
  169. CC="aarch64-linux-android34-clang"
  170. elif command -v aarch64-linux-gnu-gcc &>/dev/null; then
  171. CC="aarch64-linux-gnu-gcc"
  172. elif command -v aarch64-linux-gnu-clang &>/dev/null; then
  173. CC="aarch64-linux-gnu-clang"
  174. else
  175. CC="gcc"
  176. fi
  177. echo "Building minimal FUSE-BPF checker daemon..."
  178. $CC -o /tmp/fuse-bpf-minimal/fuse-bpf \
  179. /tmp/fuse-bpf-minimal/fuse_bpf_daemon.c \
  180. -target aarch64-linux-android 2>/dev/null || \
  181. $CC -o /tmp/fuse-bpf-minimal/fuse-bpf \
  182. /tmp/fuse-bpf-minimal/fuse_bpf_daemon.c || true
  183. echo "Minimal daemon built:"
  184. ls -la /tmp/fuse-bpf-minimal/fuse-bpf 2>/dev/null || echo "Failed to build minimal daemon"
  185. - name: Copy FUSE-BPF Artifacts
  186. shell: bash
  187. run: |
  188. set -euo pipefail
  189. mkdir -p "${{ github.workspace }}/artifacts/fuse-bpf"
  190. # Copy the full daemon if built
  191. if [ -f "${{ github.workspace }}/kernel/common/tools/testing/selftests/filesystems/fuse/fuse-daemon-arm64" ]; then
  192. cp "${{ github.workspace }}/kernel/common/tools/testing/selftests/filesystems/fuse/fuse-daemon-arm64" \
  193. "${{ github.workspace }}/artifacts/fuse-bpf/fuse-daemon"
  194. echo "Copied full FUSE-BPF daemon"
  195. fi
  196. # Copy the BPF object
  197. if [ -f "${{ github.workspace }}/kernel/common/tools/testing/selftests/filesystems/fuse/fd_bpf.bpf" ]; then
  198. cp "${{ github.workspace }}/kernel/common/tools/testing/selftests/filesystems/fuse/fd_bpf.bpf" \
  199. "${{ github.workspace }}/artifacts/fuse-bpf/fd_bpf.bpf"
  200. echo "Copied fd_bpf.bpf"
  201. fi
  202. # Copy minimal daemon as fallback
  203. if [ -f "/tmp/fuse-bpf-minimal/fuse-bpf" ]; then
  204. cp /tmp/fuse-bpf-minimal/fuse-bpf \
  205. "${{ github.workspace }}/artifacts/fuse-bpf/fuse-bpf-checker"
  206. echo "Copied minimal FUSE-BPF checker"
  207. fi
  208. # Create README with usage instructions using base64 to avoid YAML heredoc issues
  209. echo 'RlVTRS1CUEYgVXNlcnNwYWNlIENvbXBvbmVudHMKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KClRoaXMgYXJ0aWZhY3QgY29udGFpbnMgRlVTRS1CUEYgdXNlcnNwYWNlIGNvbXBvbmVudHMgZm9yIEFuZHJvaWQgYXJtNjQuCgpGaWxlczoKLSBmdXNlLWRhZW1vbjogRnVsbCBGVVNFLUJQRiB0ZXN0IGRhZW1vbiAoZnJvbSBrZXJuZWwgc2VsZnRlc3RzKQotIGZkX2JwZi5icGY6IEJQRiBieXRlY29kZSBwcm9ncmFtIGZvciBGVVNFLUJQRiBiYWNraW5nCi0gZnVzZS1icGYtY2hlY2tlcjogTWluaW1hbCBGVVNFLUJQRiBzdXBwb3J0IGNoZWNrZXIKClJlcXVpcmVtZW50cyBvbiBkZXZpY2U6CjEuIEtlcm5lbCB3aXRoIENPTkZJR19GVVNFX0JQRj15IChhbHJlYWR5IGVuYWJsZWQgaW4gR0tJKQoyLiAvZGV2L2Z1c2UgZGV2aWNlIG5vZGUgKG1rbm9kIC9kZXYvZnVzZSBjIDEwIDIyOSkKMy4gUm9vdCBhY2Nlc3MgdG8gbW91bnQgRlVTRS1CUEYgZmlsZXN5c3RlbQoKVXNhZ2UgKHJlcXVpcmVzIHJvb3QpOgogICMgQ3JlYXRlIC9kZXYvZnVzZSBpZiBub3QgcHJlc2VudAogIHN1IC1jICJta25vZCAvZGV2L2Z1c2UgYyAxMCAyMjkiCgogICMgTW91bnQgRlVTRS1CUEYgZmlsZXN5c3RlbSAocmVxdWlyZXMgQlBGIHByb2dyYW0pCiAgc3UgLWMgIi4vZnVzZS1kYWVtb24iCgpOb3RlczoKLSBUaGUgZnVsbCBmdXNlLWRhZW1vbiBpcyBhIHRlc3QgcHJvZ3JhbSBmcm9tIGtlcm5lbCBzZWxmdGVzdHMKLSBJdCByZXF1aXJlcyByb290IGFuZCBGVVNFLUJQRiBrZXJuZWwgc3VwcG9ydAotIFRoZSBCUEYgcHJvZ3JhbSAoZmRfYnBmLmJwZikgbXVzdCBiZSBsb2FkZWQgYmVmb3JlIG1vdW50aW5nCg==' | base64 -d > "${{ github.workspace }}/artifacts/fuse-bpf/README.txt"
  210. echo "FUSE-BPF artifacts:"
  211. ls -la "${{ github.workspace }}/artifacts/fuse-bpf/"
  212. - name: Upload FUSE-BPF Artifact
  213. uses: actions/upload-artifact@v7
  214. with:
  215. name: fuse-bpf-arm64
  216. path: ${{ github.workspace }}/artifacts/fuse-bpf/
  217. if-no-files-found: warn