diff options
-rw-r--r-- | Android.mk | 13 | ||||
-rw-r--r-- | adb_install.cpp | 11 | ||||
-rw-r--r-- | fuse_sideload.c (renamed from minadbd/fuse_sideload.c) | 43 | ||||
-rw-r--r-- | fuse_sideload.h | 38 | ||||
-rw-r--r-- | minadbd/Android.mk | 6 | ||||
-rw-r--r-- | minadbd/adb.h | 7 | ||||
-rw-r--r-- | minadbd/fuse_adb_provider.c | 67 | ||||
-rw-r--r-- | minadbd/fuse_adb_provider.h (renamed from minadbd/fuse_sideload.h) | 6 | ||||
-rw-r--r-- | minadbd/services.c | 4 |
9 files changed, 152 insertions, 43 deletions
diff --git a/Android.mk b/Android.mk index 1165acba4..f469182ef 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 fb7860c9b..be3b9a063 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 def068e55..ab91defbf 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 000000000..c0b16efbe --- /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 b5fb8448a..04956d870 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 770f34d19..714868f5c 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 000000000..f80533a8c --- /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 caeeec757..0eb1f79d1 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 bf57dc372..218b84a38 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); |