Browse Source

Revert "recovery: Fork a process for fuse when sideloading from SD card."

This reverts commit cdcf28f54f.

Change-Id: Ib62aa4a8439a1fab7db681730bf75ff35e41106a
Tom Marshall 4 years ago
parent
commit
45cb2a2820
3 changed files with 69 additions and 69 deletions
  1. 63
    11
      fuse_sdcard_provider.cpp
  2. 2
    1
      fuse_sdcard_provider.h
  3. 4
    57
      recovery.cpp

+ 63
- 11
fuse_sdcard_provider.cpp View File

@@ -21,6 +21,7 @@
21 21
 #include <stdio.h>
22 22
 #include <stdlib.h>
23 23
 #include <string.h>
24
+#include <pthread.h>
24 25
 #include <sys/mount.h>
25 26
 #include <sys/stat.h>
26 27
 #include <unistd.h>
@@ -54,30 +55,81 @@ static int read_block_file(const file_data& fd, uint32_t block, uint8_t* buffer,
54 55
   return 0;
55 56
 }
56 57
 
57
-bool start_sdcard_fuse(const char* path) {
58
+struct token {
59
+    pthread_t th;
60
+    const char* path;
61
+    int result;
62
+};
63
+
64
+static void* run_sdcard_fuse(void* cookie) {
65
+  token* t = reinterpret_cast<token*>(cookie);
66
+
58 67
   struct stat sb;
59
-  if (stat(path, &sb) == -1) {
60
-    fprintf(stderr, "failed to stat %s: %s\n", path, strerror(errno));
61
-    return false;
68
+  if (stat(t->path, &sb) < 0) {
69
+    fprintf(stderr, "failed to stat %s: %s\n", t->path, strerror(errno));
70
+    t->result = -1;
71
+    return nullptr;
62 72
   }
63 73
 
64
-  file_data fd;
65
-  fd.fd = open(path, O_RDONLY);
66
-  if (fd.fd == -1) {
67
-    fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno));
68
-    return false;
74
+  struct file_data fd;
75
+  struct provider_vtab vtab;
76
+
77
+  fd.fd = open(t->path, O_RDONLY);
78
+  if (fd.fd < 0) {
79
+    fprintf(stderr, "failed to open %s: %s\n", t->path, strerror(errno));
80
+    t->result = -1;
81
+    return nullptr;
69 82
   }
70 83
   fd.file_size = sb.st_size;
71 84
   fd.block_size = 65536;
72 85
 
73
-  provider_vtab vtab;
74 86
   vtab.read_block = std::bind(&read_block_file, fd, std::placeholders::_1, std::placeholders::_2,
75 87
                               std::placeholders::_3);
76 88
   vtab.close = [&fd]() { close(fd.fd); };
77 89
 
90
+  t->result = run_fuse_sideload(vtab, fd.file_size, fd.block_size);
91
+  return nullptr;
92
+}
93
+
94
+// How long (in seconds) we wait for the fuse-provided package file to
95
+// appear, before timing out.
96
+#define SDCARD_INSTALL_TIMEOUT 10
97
+
98
+void* start_sdcard_fuse(const char* path) {
99
+  token* t = new token;
100
+
101
+  t->path = path;
102
+  pthread_create(&(t->th), NULL, run_sdcard_fuse, t);
103
+
104
+  struct stat st;
105
+  int i;
106
+  for (i = 0; i < SDCARD_INSTALL_TIMEOUT; ++i) {
107
+    if (stat(FUSE_SIDELOAD_HOST_PATHNAME, &st) != 0) {
108
+      if (errno == ENOENT && i < SDCARD_INSTALL_TIMEOUT-1) {
109
+        sleep(1);
110
+        continue;
111
+      } else {
112
+        return nullptr;
113
+      }
114
+    }
115
+  }
116
+
78 117
   // The installation process expects to find the sdcard unmounted. Unmount it with MNT_DETACH so
79 118
   // that our open file continues to work but new references see it as unmounted.
80 119
   umount2("/sdcard", MNT_DETACH);
81 120
 
82
-  return run_fuse_sideload(vtab, fd.file_size, fd.block_size) == 0;
121
+  return t;
122
+}
123
+
124
+void finish_sdcard_fuse(void* cookie) {
125
+  if (cookie == NULL) return;
126
+  token* t = reinterpret_cast<token*>(cookie);
127
+
128
+  // Calling stat() on this magic filename signals the fuse
129
+  // filesystem to shut down.
130
+  struct stat st;
131
+  stat(FUSE_SIDELOAD_HOST_EXIT_PATHNAME, &st);
132
+
133
+  pthread_join(t->th, nullptr);
134
+  delete t;
83 135
 }

+ 2
- 1
fuse_sdcard_provider.h View File

@@ -17,6 +17,7 @@
17 17
 #ifndef __FUSE_SDCARD_PROVIDER_H
18 18
 #define __FUSE_SDCARD_PROVIDER_H
19 19
 
20
-bool start_sdcard_fuse(const char* path);
20
+void* start_sdcard_fuse(const char* path);
21
+void finish_sdcard_fuse(void* token);
21 22
 
22 23
 #endif

+ 4
- 57
recovery.cpp View File

@@ -30,7 +30,6 @@
30 30
 #include <sys/klog.h>
31 31
 #include <sys/stat.h>
32 32
 #include <sys/types.h>
33
-#include <sys/wait.h>
34 33
 #include <time.h>
35 34
 #include <unistd.h>
36 35
 
@@ -1034,10 +1033,6 @@ static void run_graphics_test() {
1034 1033
   ui->ShowText(true);
1035 1034
 }
1036 1035
 
1037
-// How long (in seconds) we wait for the fuse-provided package file to
1038
-// appear, before timing out.
1039
-#define SDCARD_INSTALL_TIMEOUT 10
1040
-
1041 1036
 static int apply_from_sdcard(Device* device, bool* wipe_cache) {
1042 1037
     modified_flash = true;
1043 1038
 
@@ -1055,62 +1050,14 @@ static int apply_from_sdcard(Device* device, bool* wipe_cache) {
1055 1050
 
1056 1051
     ui->Print("\n-- Install %s ...\n", path.c_str());
1057 1052
     set_sdcard_update_bootloader_message();
1053
+    void* token = start_sdcard_fuse(path.c_str());
1058 1054
 
1059
-    // We used to use fuse in a thread as opposed to a process. Since accessing
1060
-    // through fuse involves going from kernel to userspace to kernel, it leads
1061
-    // to deadlock when a page fault occurs. (Bug: 26313124)
1062
-    pid_t child;
1063
-    if ((child = fork()) == 0) {
1064
-        bool status = start_sdcard_fuse(path.c_str());
1065
-
1066
-        _exit(status ? EXIT_SUCCESS : EXIT_FAILURE);
1067
-    }
1068
-
1069
-    // FUSE_SIDELOAD_HOST_PATHNAME will start to exist once the fuse in child
1070
-    // process is ready.
1071
-    int result = INSTALL_ERROR;
1072
-    int status;
1073
-    bool waited = false;
1074
-    for (int i = 0; i < SDCARD_INSTALL_TIMEOUT; ++i) {
1075
-        if (waitpid(child, &status, WNOHANG) == -1) {
1076
-            result = INSTALL_ERROR;
1077
-            waited = true;
1078
-            break;
1079
-        }
1080
-
1081
-        struct stat sb;
1082
-        if (stat(FUSE_SIDELOAD_HOST_PATHNAME, &sb) == -1) {
1083
-            if (errno == ENOENT && i < SDCARD_INSTALL_TIMEOUT-1) {
1084
-                sleep(1);
1085
-                continue;
1086
-            } else {
1087
-                LOG(ERROR) << "Timed out waiting for the fuse-provided package.";
1088
-                result = INSTALL_ERROR;
1089
-                kill(child, SIGKILL);
1090
-                break;
1091
-            }
1092
-        }
1093
-
1094
-        result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache,
1055
+    int status = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache,
1095 1056
                                  TEMPORARY_INSTALL_FILE, false, 0/*retry_count*/);
1096
-        break;
1097
-    }
1098
-
1099
-    if (!waited) {
1100
-        // Calling stat() on this magic filename signals the fuse
1101
-        // filesystem to shut down.
1102
-        struct stat sb;
1103
-        stat(FUSE_SIDELOAD_HOST_EXIT_PATHNAME, &sb);
1104
-
1105
-        waitpid(child, &status, 0);
1106
-    }
1107
-
1108
-    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
1109
-        LOG(ERROR) << "Error exit from the fuse process: " << WEXITSTATUS(status);
1110
-    }
1111 1057
 
1058
+    finish_sdcard_fuse(token);
1112 1059
     ensure_path_unmounted(SDCARD_ROOT);
1113
-    return result;
1060
+    return status;
1114 1061
 }
1115 1062
 
1116 1063
 // Returns REBOOT, SHUTDOWN, or REBOOT_BOOTLOADER. Returning NO_ACTION means to take the default,