aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Zongker <dougz@google.com>2014-07-10 07:31:46 -0700
committerDoug Zongker <dougz@google.com>2014-07-10 10:55:07 -0700
commit18a78e0a162c35756628610307f41179816d3333 (patch)
tree0fc0d66dacdb35be53da27a80e77865f68dc8325
parent93950229cf9a991589f6bb071a966b00349d18d6 (diff)
downloadbootable_recovery-18a78e0a162c35756628610307f41179816d3333.zip
bootable_recovery-18a78e0a162c35756628610307f41179816d3333.tar.gz
bootable_recovery-18a78e0a162c35756628610307f41179816d3333.tar.bz2
refactor fuse sideloading code
Split the adb-specific portions (fetching a block from the adb host and closing the connections) out from the rest of the FUSE filesystem code, so that we can reuse the fuse stuff for installing off sdcards as well. Change-Id: I0ba385fd35999c5f5cad27842bc82024a264dd14
-rw-r--r--Android.mk13
-rw-r--r--adb_install.cpp11
-rw-r--r--fuse_sideload.c (renamed from minadbd/fuse_sideload.c)43
-rw-r--r--fuse_sideload.h38
-rw-r--r--minadbd/Android.mk6
-rw-r--r--minadbd/adb.h7
-rw-r--r--minadbd/fuse_adb_provider.c67
-rw-r--r--minadbd/fuse_adb_provider.h (renamed from minadbd/fuse_sideload.h)6
-rw-r--r--minadbd/services.c4
9 files changed, 152 insertions, 43 deletions
diff --git a/Android.mk b/Android.mk
index 1165acb..f469182 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,6 +17,18 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_SRC_FILES := fuse_sideload.c
+
+LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
+LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
+
+LOCAL_MODULE := libfusesideload
+
+LOCAL_STATIC_LIBRARIES := libcutils libc libmincrypt
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
LOCAL_SRC_FILES := \
recovery.cpp \
bootloader.cpp \
@@ -49,6 +61,7 @@ LOCAL_STATIC_LIBRARIES := \
libmtdutils \
libmincrypt \
libminadbd \
+ libfusesideload \
libminui \
libpng \
libfs_mgr \
diff --git a/adb_install.cpp b/adb_install.cpp
index fb7860c..be3b9a0 100644
--- a/adb_install.cpp
+++ b/adb_install.cpp
@@ -31,7 +31,8 @@
#include "common.h"
#include "adb_install.h"
extern "C" {
-#include "minadbd/adb.h"
+#include "minadbd/fuse_adb_provider.h"
+#include "fuse_sideload.h"
}
static RecoveryUI* ui = NULL;
@@ -89,7 +90,7 @@ apply_from_adb(RecoveryUI* ui_, int* wipe_cache, const char* install_file) {
_exit(-1);
}
- // ADB_SIDELOAD_HOST_PATHNAME will start to exist once the host
+ // FUSE_SIDELOAD_HOST_PATHNAME will start to exist once the host
// connects and starts serving a package. Poll for its
// appearance. (Note that inotify doesn't work with FUSE.)
int result;
@@ -103,7 +104,7 @@ apply_from_adb(RecoveryUI* ui_, int* wipe_cache, const char* install_file) {
break;
}
- if (stat(ADB_SIDELOAD_HOST_PATHNAME, &st) != 0) {
+ if (stat(FUSE_SIDELOAD_HOST_PATHNAME, &st) != 0) {
if (errno == ENOENT && i < ADB_INSTALL_TIMEOUT-1) {
sleep(1);
continue;
@@ -114,14 +115,14 @@ apply_from_adb(RecoveryUI* ui_, int* wipe_cache, const char* install_file) {
break;
}
}
- result = install_package(ADB_SIDELOAD_HOST_PATHNAME, wipe_cache, install_file, false);
+ result = install_package(FUSE_SIDELOAD_HOST_PATHNAME, wipe_cache, install_file, false);
break;
}
if (!waited) {
// Calling stat() on this magic filename signals the minadbd
// subprocess to shut down.
- stat(ADB_SIDELOAD_HOST_EXIT_PATHNAME, &st);
+ stat(FUSE_SIDELOAD_HOST_EXIT_PATHNAME, &st);
// TODO(dougz): there should be a way to cancel waiting for a
// package (by pushing some button combo on the device). For now
diff --git a/minadbd/fuse_sideload.c b/fuse_sideload.c
index def068e..ab91def 100644
--- a/minadbd/fuse_sideload.c
+++ b/fuse_sideload.c
@@ -60,9 +60,8 @@
#include <sys/uio.h>
#include <unistd.h>
-#include "transport.h"
-#include "adb.h"
#include "mincrypt/sha256.h"
+#include "fuse_sideload.h"
#define PACKAGE_FILE_ID (FUSE_ROOT_ID+1)
#define EXIT_FLAG_ID (FUSE_ROOT_ID+2)
@@ -72,7 +71,9 @@
struct fuse_data {
int ffd; // file descriptor for the fuse socket
- int sfd; // file descriptor for the adb channel
+
+ struct provider_vtab* vtab;
+ void* cookie;
uint64_t file_size; // bytes
@@ -170,13 +171,13 @@ static int handle_lookup(void* data, struct fuse_data* fd,
out.entry_valid = 10;
out.attr_valid = 10;
- if (strncmp(ADB_SIDELOAD_HOST_FILENAME, data,
- sizeof(ADB_SIDELOAD_HOST_FILENAME)) == 0) {
+ if (strncmp(FUSE_SIDELOAD_HOST_FILENAME, data,
+ sizeof(FUSE_SIDELOAD_HOST_FILENAME)) == 0) {
out.nodeid = PACKAGE_FILE_ID;
out.generation = PACKAGE_FILE_ID;
fill_attr(&(out.attr), fd, PACKAGE_FILE_ID, fd->file_size, S_IFREG | 0444);
- } else if (strncmp(ADB_SIDELOAD_HOST_EXIT_FLAG, data,
- sizeof(ADB_SIDELOAD_HOST_EXIT_FLAG)) == 0) {
+ } else if (strncmp(FUSE_SIDELOAD_HOST_EXIT_FLAG, data,
+ sizeof(FUSE_SIDELOAD_HOST_EXIT_FLAG)) == 0) {
out.nodeid = EXIT_FLAG_ID;
out.generation = EXIT_FLAG_ID;
fill_attr(&(out.attr), fd, EXIT_FLAG_ID, 0, S_IFREG | 0);
@@ -231,17 +232,8 @@ static int fetch_block(struct fuse_data* fd, uint32_t block) {
memset(fd->block_data + fetch_size, 0, fd->block_size - fetch_size);
}
- char buf[10];
- snprintf(buf, sizeof(buf), "%08u", block);
- if (writex(fd->sfd, buf, 8) < 0) {
- fprintf(stderr, "failed to write to adb host: %s\n", strerror(errno));
- return -EIO;
- }
-
- if (readx(fd->sfd, fd->block_data, fetch_size) < 0) {
- fprintf(stderr, "failed to read from adb host: %s\n", strerror(errno));
- return -EIO;
- }
+ int result = fd->vtab->read_block(fd->cookie, block, fd->block_data, fetch_size);
+ if (result < 0) return result;
fd->curr_block = block;
@@ -346,13 +338,14 @@ static int handle_read(void* data, struct fuse_data* fd, const struct fuse_in_he
return NO_STATUS;
}
-int run_fuse(int sfd, uint64_t file_size, uint32_t block_size)
+int run_fuse_sideload(struct provider_vtab* vtab, void* cookie,
+ uint64_t file_size, uint32_t block_size)
{
int result;
// If something's already mounted on our mountpoint, try to remove
// it. (Mostly in case of a previous abnormal exit.)
- umount2(ADB_SIDELOAD_HOST_MOUNTPOINT, MNT_FORCE);
+ umount2(FUSE_SIDELOAD_HOST_MOUNTPOINT, MNT_FORCE);
if (block_size < 1024) {
fprintf(stderr, "block size (%u) is too small\n", block_size);
@@ -365,7 +358,8 @@ int run_fuse(int sfd, uint64_t file_size, uint32_t block_size)
struct fuse_data fd;
memset(&fd, 0, sizeof(fd));
- fd.sfd = sfd;
+ fd.vtab = vtab;
+ fd.cookie = cookie;
fd.file_size = file_size;
fd.block_size = block_size;
fd.file_blocks = (file_size == 0) ? 0 : (((file_size-1) / block_size) + 1);
@@ -414,7 +408,7 @@ int run_fuse(int sfd, uint64_t file_size, uint32_t block_size)
"allow_other,rootmode=040000"),
fd.ffd, fd.uid, fd.gid, block_size);
- result = mount("/dev/fuse", ADB_SIDELOAD_HOST_MOUNTPOINT,
+ result = mount("/dev/fuse", FUSE_SIDELOAD_HOST_MOUNTPOINT,
"fuse", MS_NOSUID | MS_NODEV | MS_RDONLY | MS_NOEXEC, opts);
if (result < 0) {
perror("mount");
@@ -493,8 +487,9 @@ int run_fuse(int sfd, uint64_t file_size, uint32_t block_size)
}
done:
- writex(sfd, "DONEDONE", 8);
- result = umount2(ADB_SIDELOAD_HOST_MOUNTPOINT, MNT_DETACH);
+ fd.vtab->close(fd.cookie);
+
+ result = umount2(FUSE_SIDELOAD_HOST_MOUNTPOINT, MNT_DETACH);
if (result < 0) {
printf("fuse_sideload umount failed: %s\n", strerror(errno));
}
diff --git a/fuse_sideload.h b/fuse_sideload.h
new file mode 100644
index 0000000..c0b16ef
--- /dev/null
+++ b/fuse_sideload.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __FUSE_SIDELOAD_H
+#define __FUSE_SIDELOAD_H
+
+// define the filenames created by the sideload FUSE filesystem
+#define FUSE_SIDELOAD_HOST_MOUNTPOINT "/sideload"
+#define FUSE_SIDELOAD_HOST_FILENAME "package.zip"
+#define FUSE_SIDELOAD_HOST_PATHNAME (FUSE_SIDELOAD_HOST_MOUNTPOINT "/" FUSE_SIDELOAD_HOST_FILENAME)
+#define FUSE_SIDELOAD_HOST_EXIT_FLAG "exit"
+#define FUSE_SIDELOAD_HOST_EXIT_PATHNAME (FUSE_SIDELOAD_HOST_MOUNTPOINT "/" FUSE_SIDELOAD_HOST_EXIT_FLAG)
+
+struct provider_vtab {
+ // read a block
+ int (*read_block)(void* cookie, uint32_t block, uint8_t* buffer, uint32_t fetch_size);
+
+ // close down
+ void (*close)(void* cookie);
+};
+
+int run_fuse_sideload(struct provider_vtab* vtab, void* cookie,
+ uint64_t file_size, uint32_t block_size);
+
+#endif
diff --git a/minadbd/Android.mk b/minadbd/Android.mk
index b5fb844..04956d8 100644
--- a/minadbd/Android.mk
+++ b/minadbd/Android.mk
@@ -13,7 +13,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
adb.c \
fdevent.c \
- fuse_sideload.c \
+ fuse_adb_provider.c \
transport.c \
transport_usb.c \
sockets.c \
@@ -23,8 +23,10 @@ LOCAL_SRC_FILES := \
LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE
+LOCAL_C_INCLUDES += bootable/recovery
LOCAL_MODULE := libminadbd
-LOCAL_STATIC_LIBRARIES := libcutils libc libmincrypt
+LOCAL_STATIC_LIBRARIES := libfusesideload libcutils libc
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/minadbd/adb.h b/minadbd/adb.h
index 770f34d..714868f 100644
--- a/minadbd/adb.h
+++ b/minadbd/adb.h
@@ -421,11 +421,4 @@ extern int SHELL_EXIT_NOTIFY_FD;
int sendfailmsg(int fd, const char *reason);
int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s);
-// define the filenames created by the sideload-host FUSE filesystem
-#define ADB_SIDELOAD_HOST_MOUNTPOINT "/sideload"
-#define ADB_SIDELOAD_HOST_FILENAME "package.zip"
-#define ADB_SIDELOAD_HOST_PATHNAME (ADB_SIDELOAD_HOST_MOUNTPOINT "/" ADB_SIDELOAD_HOST_FILENAME)
-#define ADB_SIDELOAD_HOST_EXIT_FLAG "exit"
-#define ADB_SIDELOAD_HOST_EXIT_PATHNAME (ADB_SIDELOAD_HOST_MOUNTPOINT "/" ADB_SIDELOAD_HOST_EXIT_FLAG)
-
#endif
diff --git a/minadbd/fuse_adb_provider.c b/minadbd/fuse_adb_provider.c
new file mode 100644
index 0000000..f80533a
--- /dev/null
+++ b/minadbd/fuse_adb_provider.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "adb.h"
+#include "fuse_sideload.h"
+
+struct adb_data {
+ int sfd; // file descriptor for the adb channel
+
+ uint64_t file_size;
+ uint32_t block_size;
+};
+
+static int read_block_adb(void* cookie, uint32_t block, uint8_t* buffer, uint32_t fetch_size) {
+ struct adb_data* ad = (struct adb_data*)cookie;
+
+ char buf[10];
+ snprintf(buf, sizeof(buf), "%08u", block);
+ if (writex(ad->sfd, buf, 8) < 0) {
+ fprintf(stderr, "failed to write to adb host: %s\n", strerror(errno));
+ return -EIO;
+ }
+
+ if (readx(ad->sfd, buffer, fetch_size) < 0) {
+ fprintf(stderr, "failed to read from adb host: %s\n", strerror(errno));
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void close_adb(void* cookie) {
+ struct adb_data* ad = (struct adb_data*)cookie;
+
+ writex(ad->sfd, "DONEDONE", 8);
+}
+
+int run_adb_fuse(int sfd, uint64_t file_size, uint32_t block_size) {
+ struct adb_data ad;
+ struct provider_vtab vtab;
+
+ ad.sfd = sfd;
+ ad.file_size = file_size;
+ ad.block_size = block_size;
+
+ vtab.read_block = read_block_adb;
+ vtab.close = close_adb;
+
+ return run_fuse_sideload(&vtab, &ad, file_size, block_size);
+}
diff --git a/minadbd/fuse_sideload.h b/minadbd/fuse_adb_provider.h
index caeeec7..0eb1f79 100644
--- a/minadbd/fuse_sideload.h
+++ b/minadbd/fuse_adb_provider.h
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#ifndef __FUSE_SIDELOAD_H
-#define __FUSE_SIDELOAD_H
+#ifndef __FUSE_ADB_PROVIDER_H
+#define __FUSE_ADB_PROVIDER_H
-int run_fuse(int sfd, uint64_t file_size, uint32_t block_size);
+int run_adb_fuse(int sfd, uint64_t file_size, uint32_t block_size);
#endif
diff --git a/minadbd/services.c b/minadbd/services.c
index bf57dc3..218b84a 100644
--- a/minadbd/services.c
+++ b/minadbd/services.c
@@ -22,7 +22,7 @@
#include "sysdeps.h"
#include "fdevent.h"
-#include "fuse_sideload.h"
+#include "fuse_adb_provider.h"
#define TRACE_TAG TRACE_SERVICES
#include "adb.h"
@@ -54,7 +54,7 @@ static void sideload_host_service(int sfd, void* cookie)
printf("sideload-host file size %llu block size %lu\n", file_size, block_size);
- int result = run_fuse(sfd, file_size, block_size);
+ int result = run_adb_fuse(sfd, file_size, block_size);
printf("sideload_host finished\n");
sleep(1);