Skip to content

Commit c9553b0

Browse files
authored
Build patched libfuse3 to find more fusermount binaries (#11)
1 parent d40bf27 commit c9553b0

File tree

3 files changed

+146
-2
lines changed

3 files changed

+146
-2
lines changed

build.sh

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,26 @@ if ! command -v apk; then
88
fi
99

1010
apk update
11-
apk add alpine-sdk util-linux strace file autoconf automake libtool
11+
apk add alpine-sdk util-linux strace file autoconf automake libtool xz
12+
13+
# Build static libfuse3 with patch for https://github.com/AppImage/type2-runtime/issues/10
14+
apk add eudev-dev gettext-dev linux-headers meson # From https://git.alpinelinux.org/aports/tree/main/fuse3/APKBUILD
15+
wget -c -q "https://github.com/libfuse/libfuse/releases/download/fuse-3.15.0/fuse-3.15.0.tar.xz"
16+
tar xf fuse-3.*.tar.xz
17+
cd fuse-3.*/
18+
patch -p1 < ../patches/libfuse/mount.c.diff
19+
mkdir build
20+
cd build
21+
meson setup --prefix=/usr ..
22+
meson configure --default-library static
23+
ninja install
24+
cd ../../
1225

1326
# Minimize binary size
1427
export CFLAGS="-ffunction-sections -fdata-sections -Os"
1528

1629
# Build static squashfuse
17-
apk add fuse3-dev fuse3-static zstd-dev zlib-dev zlib-static # fuse-static fuse-dev
30+
apk add zstd-dev zlib-dev zlib-static # fuse3-dev fuse3-static fuse-static fuse-dev
1831
find / -name "libzstd.*" 2>/dev/null || true
1932
wget -c -q "https://github.com/vasi/squashfuse/archive/e51978c.tar.gz"
2033
tar xf e51978c.tar.gz

chroot_build.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ cd -
1818
#############################################
1919

2020
sudo cp -r ./src miniroot/src
21+
sudo cp -r ./patches miniroot/patches
2122

2223
sudo mount -o bind /dev miniroot/dev
2324
sudo mount -t proc none miniroot/proc

patches/libfuse/mount.c.diff

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
diff --git a/lib/mount.c b/lib/mount.c
2+
index d71e6fc55..acc1711ff 100644
3+
--- a/lib/mount.c
4+
+++ b/lib/mount.c
5+
@@ -41,7 +41,6 @@
6+
#define umount2(mnt, flags) unmount(mnt, (flags == 2) ? MNT_FORCE : 0)
7+
#endif
8+
9+
-#define FUSERMOUNT_PROG "fusermount3"
10+
#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
11+
12+
#ifndef HAVE_FORK
13+
@@ -117,17 +116,79 @@ static const struct fuse_opt fuse_mount_opts[] = {
14+
FUSE_OPT_END
15+
};
16+
17+
+int fileExists(const char* path);
18+
+char* findBinaryInFusermountDir(const char* binaryName);
19+
+
20+
+int fileExists(const char* path) {
21+
+ FILE* file = fopen(path, "r");
22+
+ if (file) {
23+
+ fclose(file);
24+
+ return 1;
25+
+ }
26+
+ return 0;
27+
+}
28+
+
29+
+char* findBinaryInFusermountDir(const char* binaryName) {
30+
+ // For security reasons, we do not search the binary on the $PATH;
31+
+ // instead, we check if the binary exists in FUSERMOUNT_DIR
32+
+ // as defined in meson.build
33+
+ char* binaryPath = malloc(strlen(FUSERMOUNT_DIR) + strlen(binaryName) + 2);
34+
+ strcpy(binaryPath, FUSERMOUNT_DIR);
35+
+ strcat(binaryPath, "/");
36+
+ strcat(binaryPath, binaryName);
37+
+ if (fileExists(binaryPath)) {
38+
+ return binaryPath;
39+
+ }
40+
+
41+
+ // If the binary does not exist in FUSERMOUNT_DIR, return NULL
42+
+ return NULL;
43+
+}
44+
+
45+
+static const char *fuse_mount_prog(void)
46+
+{
47+
+ // Check if the FUSERMOUNT_PROG environment variable is set and if so, use it
48+
+ const char *prog = getenv("FUSERMOUNT_PROG");
49+
+ if (prog) {
50+
+ if (access(prog, X_OK) == 0)
51+
+ return prog;
52+
+ }
53+
+
54+
+ // Check if there is a binary "fusermount3"
55+
+ prog = findBinaryInFusermountDir("fusermount3");
56+
+ if (access(prog, X_OK) == 0)
57+
+ return prog;
58+
+
59+
+ // Check if there is a binary called "fusermount"
60+
+ // This is known to work for our purposes
61+
+ prog = findBinaryInFusermountDir("fusermount");
62+
+ if (access(prog, X_OK) == 0)
63+
+ return prog;
64+
+
65+
+ // For i = 4...99, check if there is a binary called "fusermount" + i
66+
+ // It is not yet known whether this will work for our purposes, but it is better than not even attempting
67+
+ for (int i = 4; i < 100; i++) {
68+
+ prog = findBinaryInFusermountDir("fusermount" + i);
69+
+ if (access(prog, X_OK) == 0)
70+
+ return prog;
71+
+ }
72+
+
73+
+ // If all else fails, return NULL
74+
+ return NULL;
75+
+}
76+
+
77+
static void exec_fusermount(const char *argv[])
78+
{
79+
- execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
80+
- execvp(FUSERMOUNT_PROG, (char **) argv);
81+
+ const char *fusermount_prog = fuse_mount_prog();
82+
+ if (fusermount_prog) {
83+
+ execv(fusermount_prog, (char **) argv);
84+
+ }
85+
}
86+
87+
void fuse_mount_version(void)
88+
{
89+
int pid = fork();
90+
if (!pid) {
91+
- const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
92+
+ const char *argv[] = { fuse_mount_prog(), "--version", NULL };
93+
exec_fusermount(argv);
94+
_exit(1);
95+
} else if (pid != -1)
96+
@@ -300,7 +361,7 @@ void fuse_kern_unmount(const char *mountpoint, int fd)
97+
return;
98+
99+
if(pid == 0) {
100+
- const char *argv[] = { FUSERMOUNT_PROG, "-u", "-q", "-z",
101+
+ const char *argv[] = { fuse_mount_prog(), "-u", "-q", "-z",
102+
"--", mountpoint, NULL };
103+
104+
exec_fusermount(argv);
105+
@@ -346,7 +407,7 @@ static int setup_auto_unmount(const char *mountpoint, int quiet)
106+
}
107+
}
108+
109+
- argv[a++] = FUSERMOUNT_PROG;
110+
+ argv[a++] = fuse_mount_prog();
111+
argv[a++] = "--auto-unmount";
112+
argv[a++] = "--";
113+
argv[a++] = mountpoint;
114+
@@ -407,7 +468,7 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
115+
}
116+
}
117+
118+
- argv[a++] = FUSERMOUNT_PROG;
119+
+ argv[a++] = fuse_mount_prog();
120+
if (opts) {
121+
argv[a++] = "-o";
122+
argv[a++] = opts;
123+
@@ -421,7 +482,7 @@ static int fuse_mount_fusermount(const char *mountpoint, struct mount_opts *mo,
124+
snprintf(env, sizeof(env), "%i", fds[0]);
125+
setenv(FUSE_COMMFD_ENV, env, 1);
126+
exec_fusermount(argv);
127+
- perror("fuse: failed to exec fusermount3");
128+
+ perror("fuse: failed to exec fusermount");
129+
_exit(1);
130+
}

0 commit comments

Comments
 (0)