diff options
-rw-r--r-- | Android.mk | 1 | ||||
-rw-r--r-- | applypatch/Android.mk | 6 | ||||
-rw-r--r-- | applypatch/applypatch.cpp | 49 | ||||
-rw-r--r-- | minui/graphics_fbdev.cpp | 12 | ||||
-rw-r--r-- | otafault/Android.mk | 58 | ||||
-rw-r--r-- | otafault/ota_io.cpp | 160 | ||||
-rw-r--r-- | otafault/ota_io.h | 49 | ||||
-rw-r--r-- | otafault/test.cpp | 32 | ||||
-rw-r--r-- | recovery.cpp | 24 | ||||
-rw-r--r-- | roots.cpp | 8 | ||||
-rw-r--r-- | roots.h | 6 | ||||
-rw-r--r-- | updater/Android.mk | 2 | ||||
-rw-r--r-- | updater/blockimg.cpp | 13 | ||||
-rw-r--r-- | updater/install.cpp | 25 |
14 files changed, 385 insertions, 60 deletions
diff --git a/Android.mk b/Android.mk index a48980fe8..4da34eef5 100644 --- a/Android.mk +++ b/Android.mk @@ -117,6 +117,7 @@ include $(LOCAL_PATH)/minui/Android.mk \ $(LOCAL_PATH)/tools/Android.mk \ $(LOCAL_PATH)/edify/Android.mk \ $(LOCAL_PATH)/uncrypt/Android.mk \ + $(LOCAL_PATH)/otafault/Android.mk \ $(LOCAL_PATH)/updater/Android.mk \ $(LOCAL_PATH)/update_verifier/Android.mk \ $(LOCAL_PATH)/applypatch/Android.mk diff --git a/applypatch/Android.mk b/applypatch/Android.mk index 23d0f7bb1..887a570db 100644 --- a/applypatch/Android.mk +++ b/applypatch/Android.mk @@ -21,7 +21,7 @@ LOCAL_SRC_FILES := applypatch.cpp bspatch.cpp freecache.cpp imgpatch.cpp utils.c LOCAL_MODULE := libapplypatch LOCAL_MODULE_TAGS := eng LOCAL_C_INCLUDES += bootable/recovery -LOCAL_STATIC_LIBRARIES += libbase libmtdutils libcrypto_static libbz libz +LOCAL_STATIC_LIBRARIES += libbase libotafault libmtdutils libcrypto_static libbz libz include $(BUILD_STATIC_LIBRARY) @@ -55,7 +55,9 @@ LOCAL_CLANG := true LOCAL_SRC_FILES := main.cpp LOCAL_MODULE := applypatch LOCAL_C_INCLUDES += bootable/recovery -LOCAL_STATIC_LIBRARIES += libapplypatch libbase libmtdutils libcrypto_static libbz libedify +LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libmtdutils libcrypto_static libbz \ + libedify \ + LOCAL_SHARED_LIBRARIES += libz libcutils libc include $(BUILD_EXECUTABLE) diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp index 75d77372e..9f5e2f200 100644 --- a/applypatch/applypatch.cpp +++ b/applypatch/applypatch.cpp @@ -35,6 +35,7 @@ #include "mtdutils/mtdutils.h" #include "edify/expr.h" #include "print_sha1.h" +#include "otafault/ota_io.h" static int LoadPartitionContents(const char* filename, FileContents* file); static ssize_t FileSink(const unsigned char* data, ssize_t len, void* token); @@ -79,19 +80,19 @@ int LoadFileContents(const char* filename, FileContents* file) { return -1; } - FILE* f = fopen(filename, "rb"); + FILE* f = ota_fopen(filename, "rb"); if (f == NULL) { printf("failed to open \"%s\": %s\n", filename, strerror(errno)); return -1; } - size_t bytes_read = fread(data.get(), 1, file->size, f); + size_t bytes_read = ota_fread(data.get(), 1, file->size, f); if (bytes_read != static_cast<size_t>(file->size)) { printf("short read of \"%s\" (%zu bytes of %zd)\n", filename, bytes_read, file->size); fclose(f); return -1; } - fclose(f); + ota_fclose(f); file->data = data.release(); SHA1(file->data, file->size, file->sha1); return 0; @@ -180,7 +181,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) { } case EMMC: - dev = fopen(partition, "rb"); + dev = ota_fopen(partition, "rb"); if (dev == NULL) { printf("failed to open emmc partition \"%s\": %s\n", partition, strerror(errno)); return -1; @@ -209,7 +210,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) { break; case EMMC: - read = fread(p, 1, next, dev); + read = ota_fread(p, 1, next, dev); break; } if (next != read) { @@ -255,7 +256,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) { break; case EMMC: - fclose(dev); + ota_fclose(dev); break; } @@ -282,7 +283,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) { // Save the contents of the given FileContents object under the given // filename. Return 0 on success. int SaveFileContents(const char* filename, const FileContents* file) { - int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR); + int fd = ota_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR); if (fd < 0) { printf("failed to open \"%s\" for write: %s\n", filename, strerror(errno)); return -1; @@ -292,14 +293,14 @@ int SaveFileContents(const char* filename, const FileContents* file) { if (bytes_written != file->size) { printf("short write of \"%s\" (%zd bytes of %zd) (%s)\n", filename, bytes_written, file->size, strerror(errno)); - close(fd); + ota_close(fd); return -1; } - if (fsync(fd) != 0) { + if (ota_fsync(fd) != 0) { printf("fsync of \"%s\" failed: %s\n", filename, strerror(errno)); return -1; } - if (close(fd) != 0) { + if (ota_close(fd) != 0) { printf("close of \"%s\" failed: %s\n", filename, strerror(errno)); return -1; } @@ -382,7 +383,7 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target) case EMMC: { size_t start = 0; bool success = false; - int fd = open(partition, O_RDWR | O_SYNC); + int fd = ota_open(partition, O_RDWR | O_SYNC); if (fd < 0) { printf("failed to open %s: %s\n", partition, strerror(errno)); return -1; @@ -397,22 +398,22 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target) size_t to_write = len - start; if (to_write > 1<<20) to_write = 1<<20; - ssize_t written = TEMP_FAILURE_RETRY(write(fd, data+start, to_write)); + ssize_t written = TEMP_FAILURE_RETRY(ota_write(fd, data+start, to_write)); if (written == -1) { printf("failed write writing to %s: %s\n", partition, strerror(errno)); return -1; } start += written; } - if (fsync(fd) != 0) { + if (ota_fsync(fd) != 0) { printf("failed to sync to %s (%s)\n", partition, strerror(errno)); return -1; } - if (close(fd) != 0) { + if (ota_close(fd) != 0) { printf("failed to close %s (%s)\n", partition, strerror(errno)); return -1; } - fd = open(partition, O_RDONLY); + fd = ota_open(partition, O_RDONLY); if (fd < 0) { printf("failed to reopen %s for verify (%s)\n", partition, strerror(errno)); return -1; @@ -421,13 +422,13 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target) // Drop caches so our subsequent verification read // won't just be reading the cache. sync(); - int dc = open("/proc/sys/vm/drop_caches", O_WRONLY); - if (TEMP_FAILURE_RETRY(write(dc, "3\n", 2)) == -1) { + int dc = ota_open("/proc/sys/vm/drop_caches", O_WRONLY); + if (TEMP_FAILURE_RETRY(ota_write(dc, "3\n", 2)) == -1) { printf("write to /proc/sys/vm/drop_caches failed: %s\n", strerror(errno)); } else { printf(" caches dropped\n"); } - close(dc); + ota_close(dc); sleep(1); // verify @@ -447,7 +448,7 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target) size_t so_far = 0; while (so_far < to_read) { ssize_t read_count = - TEMP_FAILURE_RETRY(read(fd, buffer+so_far, to_read-so_far)); + TEMP_FAILURE_RETRY(ota_read(fd, buffer+so_far, to_read-so_far)); if (read_count == -1) { printf("verify read error %s at %zu: %s\n", partition, p, strerror(errno)); @@ -479,7 +480,7 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target) return -1; } - if (close(fd) != 0) { + if (ota_close(fd) != 0) { printf("error closing %s (%s)\n", partition, strerror(errno)); return -1; } @@ -589,7 +590,7 @@ ssize_t FileSink(const unsigned char* data, ssize_t len, void* token) { ssize_t done = 0; ssize_t wrote; while (done < len) { - wrote = TEMP_FAILURE_RETRY(write(fd, data+done, len-done)); + wrote = TEMP_FAILURE_RETRY(ota_write(fd, data+done, len-done)); if (wrote == -1) { printf("error writing %zd bytes: %s\n", (len-done), strerror(errno)); return done; @@ -934,7 +935,7 @@ static int GenerateTarget(FileContents* source_file, token = &memory_sink_str; } else { // We write the decoded output to "<tgt-file>.patch". - output_fd = open(tmp_target_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, + output_fd = ota_open(tmp_target_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR); if (output_fd < 0) { printf("failed to open output file %s: %s\n", tmp_target_filename.c_str(), @@ -958,12 +959,12 @@ static int GenerateTarget(FileContents* source_file, } if (!target_is_partition) { - if (fsync(output_fd) != 0) { + if (ota_fsync(output_fd) != 0) { printf("failed to fsync file \"%s\" (%s)\n", tmp_target_filename.c_str(), strerror(errno)); result = 1; } - if (close(output_fd) != 0) { + if (ota_close(output_fd) != 0) { printf("failed to close file \"%s\" (%s)\n", tmp_target_filename.c_str(), strerror(errno)); result = 1; diff --git a/minui/graphics_fbdev.cpp b/minui/graphics_fbdev.cpp index 997e9cac2..0788f7552 100644 --- a/minui/graphics_fbdev.cpp +++ b/minui/graphics_fbdev.cpp @@ -176,18 +176,6 @@ static GRSurface* fbdev_init(minui_backend* backend) { static GRSurface* fbdev_flip(minui_backend* backend __unused) { if (double_buffered) { -#if defined(RECOVERY_BGRA) - // In case of BGRA, do some byte swapping - unsigned int idx; - unsigned char tmp; - unsigned char* ucfb_vaddr = (unsigned char*)gr_draw->data; - for (idx = 0 ; idx < (gr_draw->height * gr_draw->row_bytes); - idx += 4) { - tmp = ucfb_vaddr[idx]; - ucfb_vaddr[idx ] = ucfb_vaddr[idx + 2]; - ucfb_vaddr[idx + 2] = tmp; - } -#endif // Change gr_draw to point to the buffer currently displayed, // then flip the driver so we're displaying the other buffer // instead. diff --git a/otafault/Android.mk b/otafault/Android.mk new file mode 100644 index 000000000..75617a146 --- /dev/null +++ b/otafault/Android.mk @@ -0,0 +1,58 @@ +# Copyright 2015 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 languae governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +empty := +space := $(empty) $(empty) +comma := , + +ifneq ($(TARGET_INJECT_FAULTS),) +TARGET_INJECT_FAULTS := $(subst $(comma),$(space),$(strip $(TARGET_INJECT_FAULTS))) +endif + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := ota_io.cpp +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE := libotafault +LOCAL_CLANG := true + +ifneq ($(TARGET_INJECT_FAULTS),) +$(foreach ft,$(TARGET_INJECT_FAULTS),\ + $(eval LOCAL_CFLAGS += -DTARGET_$(ft)_FAULT=$(TARGET_$(ft)_FAULT_FILE))) +LOCAL_CFLAGS += -Wno-unused-parameter +LOCAL_CFLAGS += -DTARGET_INJECT_FAULTS +endif + +LOCAL_STATIC_LIBRARIES := libc + +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := ota_io.cpp test.cpp +LOCAL_MODULE_TAGS := tests +LOCAL_MODULE := otafault_test +LOCAL_STATIC_LIBRARIES := libc +LOCAL_FORCE_STATIC_EXECUTABLE := true +LOCAL_CFLAGS += -Wno-unused-parameter -Wno-writable-strings + +ifneq ($(TARGET_INJECT_FAULTS),) +$(foreach ft,$(TARGET_INJECT_FAULTS),\ + $(eval LOCAL_CFLAGS += -DTARGET_$(ft)_FAULT=$(TARGET_$(ft)_FAULT_FILE))) +LOCAL_CFLAGS += -DTARGET_INJECT_FAULTS +endif + +include $(BUILD_EXECUTABLE) diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp new file mode 100644 index 000000000..02e80f9bf --- /dev/null +++ b/otafault/ota_io.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2015 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. + */ + +#if defined (TARGET_INJECT_FAULTS) +#include <map> +#endif + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "ota_io.h" + +#if defined (TARGET_INJECT_FAULTS) +static std::map<int, const char*> FilenameCache; +static std::string FaultFileName = +#if defined (TARGET_READ_FAULT) + TARGET_READ_FAULT; +#elif defined (TARGET_WRITE_FAULT) + TARGET_WRITE_FAULT; +#elif defined (TARGET_FSYNC_FAULT) + TARGET_FSYNC_FAULT; +#endif // defined (TARGET_READ_FAULT) +#endif // defined (TARGET_INJECT_FAULTS) + +int ota_open(const char* path, int oflags) { +#if defined (TARGET_INJECT_FAULTS) + // Let the caller handle errors; we do not care if open succeeds or fails + int fd = open(path, oflags); + FilenameCache[fd] = path; + return fd; +#else + return open(path, oflags); +#endif +} + +int ota_open(const char* path, int oflags, mode_t mode) { +#if defined (TARGET_INJECT_FAULTS) + int fd = open(path, oflags, mode); + FilenameCache[fd] = path; + return fd; +#else + return open(path, oflags, mode); +#endif +} + +FILE* ota_fopen(const char* path, const char* mode) { +#if defined (TARGET_INJECT_FAULTS) + FILE* fh = fopen(path, mode); + FilenameCache[(intptr_t)fh] = path; + return fh; +#else + return fopen(path, mode); +#endif +} + +int ota_close(int fd) { +#if defined (TARGET_INJECT_FAULTS) + // descriptors can be reused, so make sure not to leave them in the cahce + FilenameCache.erase(fd); +#endif + return close(fd); +} + +int ota_fclose(FILE* fh) { +#if defined (TARGET_INJECT_FAULTS) + FilenameCache.erase((intptr_t)fh); +#endif + return fclose(fh); +} + +size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) { +#if defined (TARGET_READ_FAULT) + if (FilenameCache.find((intptr_t)stream) != FilenameCache.end() + && FilenameCache[(intptr_t)stream] == FaultFileName) { + FaultFileName = ""; + errno = EIO; + return 0; + } else { + return fread(ptr, size, nitems, stream); + } +#else + return fread(ptr, size, nitems, stream); +#endif +} + +ssize_t ota_read(int fd, void* buf, size_t nbyte) { +#if defined (TARGET_READ_FAULT) + if (FilenameCache.find(fd) != FilenameCache.end() + && FilenameCache[fd] == FaultFileName) { + FaultFileName = ""; + errno = EIO; + return -1; + } else { + return read(fd, buf, nbyte); + } +#else + return read(fd, buf, nbyte); +#endif +} + +size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { +#if defined (TARGET_WRITE_FAULT) + if (FilenameCache.find((intptr_t)stream) != FilenameCache.end() + && FilenameCache[(intptr_t)stream] == FaultFileName) { + FaultFileName = ""; + errno = EIO; + return 0; + } else { + return fwrite(ptr, size, count, stream); + } +#else + return fwrite(ptr, size, count, stream); +#endif +} + +ssize_t ota_write(int fd, const void* buf, size_t nbyte) { +#if defined (TARGET_WRITE_FAULT) + if (FilenameCache.find(fd) != FilenameCache.end() + && FilenameCache[fd] == FaultFileName) { + FaultFileName = ""; + errno = EIO; + return -1; + } else { + return write(fd, buf, nbyte); + } +#else + return write(fd, buf, nbyte); +#endif +} + +int ota_fsync(int fd) { +#if defined (TARGET_FSYNC_FAULT) + if (FilenameCache.find(fd) != FilenameCache.end() + && FilenameCache[fd] == FaultFileName) { + FaultFileName = ""; + errno = EIO; + return -1; + } else { + return fsync(fd); + } +#else + return fsync(fd); +#endif +} diff --git a/otafault/ota_io.h b/otafault/ota_io.h new file mode 100644 index 000000000..641a5ae0a --- /dev/null +++ b/otafault/ota_io.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 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. + */ + +/* + * Provide a series of proxy functions for basic file accessors. + * The behavior of these functions can be changed to return different + * errors under a variety of conditions. + */ + +#ifndef _UPDATER_OTA_IO_H_ +#define _UPDATER_OTA_IO_H_ + +#include <stdio.h> +#include <sys/stat.h> + +int ota_open(const char* path, int oflags); + +int ota_open(const char* path, int oflags, mode_t mode); + +FILE* ota_fopen(const char* filename, const char* mode); + +int ota_close(int fd); + +int ota_fclose(FILE* fh); + +size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream); + +ssize_t ota_read(int fd, void* buf, size_t nbyte); + +size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream); + +ssize_t ota_write(int fd, const void* buf, size_t nbyte); + +int ota_fsync(int fd); + +#endif diff --git a/otafault/test.cpp b/otafault/test.cpp new file mode 100644 index 000000000..a0f731517 --- /dev/null +++ b/otafault/test.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015 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 <errno.h> +#include <fcntl.h> +#include <stdio.h> + +#include "ota_io.h" + +int main(int argc, char **argv) { + int fd = open("testdata/test.file", O_RDWR); + char buf[8]; + char *out = "321"; + int readv = ota_read(fd, buf, 4); + printf("Read returned %d\n", readv); + int writev = ota_write(fd, out, 4); + printf("Write returned %d\n", writev); + return 0; +} diff --git a/recovery.cpp b/recovery.cpp index 17e9eb66f..ee2fb43fc 100644 --- a/recovery.cpp +++ b/recovery.cpp @@ -77,7 +77,10 @@ static const char *INTENT_FILE = "/cache/recovery/intent"; static const char *LOG_FILE = "/cache/recovery/log"; static const char *LAST_INSTALL_FILE = "/cache/recovery/last_install"; static const char *LOCALE_FILE = "/cache/recovery/last_locale"; +static const char *CONVERT_FBE_DIR = "/cache/recovery/convert_fbe"; +static const char *CONVERT_FBE_FILE = "/cache/recovery/convert_fbe/convert_fbe"; static const char *CACHE_ROOT = "/cache"; +static const char *DATA_ROOT = "/data"; static const char *SDCARD_ROOT = "/sdcard"; static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log"; static const char *TEMPORARY_INSTALL_FILE = "/tmp/last_install"; @@ -504,6 +507,7 @@ typedef struct _saved_log_file { static bool erase_volume(const char* volume) { bool is_cache = (strcmp(volume, CACHE_ROOT) == 0); + bool is_data = (strcmp(volume, DATA_ROOT) == 0); ui->SetBackground(RecoveryUI::ERASING); ui->SetProgressType(RecoveryUI::INDETERMINATE); @@ -558,7 +562,25 @@ static bool erase_volume(const char* volume) { ui->Print("Formatting %s...\n", volume); ensure_path_unmounted(volume); - int result = format_volume(volume); + + int result; + + if (is_data && reason && strcmp(reason, "convert_fbe") == 0) { + // Create convert_fbe breadcrumb file to signal to init + // to convert to file based encryption, not full disk encryption + mkdir(CONVERT_FBE_DIR, 0700); + FILE* f = fopen(CONVERT_FBE_FILE, "wb"); + if (!f) { + ui->Print("Failed to convert to file encryption\n"); + return true; + } + fclose(f); + result = format_volume(volume, CONVERT_FBE_DIR); + remove(CONVERT_FBE_FILE); + rmdir(CONVERT_FBE_DIR); + } else { + result = format_volume(volume); + } if (is_cache) { while (head) { @@ -175,7 +175,7 @@ static int exec_cmd(const char* path, char* const argv[]) { return WEXITSTATUS(status); } -int format_volume(const char* volume) { +int format_volume(const char* volume, const char* directory) { Volume* v = volume_for_path(volume); if (v == NULL) { LOGE("unknown volume \"%s\"\n", volume); @@ -241,7 +241,7 @@ int format_volume(const char* volume) { } int result; if (strcmp(v->fs_type, "ext4") == 0) { - result = make_ext4fs(v->blk_device, length, volume, sehandle); + result = make_ext4fs_directory(v->blk_device, length, volume, sehandle, directory); } else { /* Has to be f2fs because we checked earlier. */ if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) { LOGE("format_volume: crypt footer + negative length (%zd) not supported on %s\n", length, v->fs_type); @@ -273,6 +273,10 @@ int format_volume(const char* volume) { return -1; } +int format_volume(const char* volume) { + return format_volume(volume, NULL); +} + int setup_install_mounts() { if (fstab == NULL) { LOGE("can't set up install mounts: no fstab loaded\n"); @@ -41,6 +41,12 @@ int ensure_path_unmounted(const char* path); // it is mounted. int format_volume(const char* volume); +// Reformat the given volume (must be the mount point only, eg +// "/cache"), no paths permitted. Attempts to unmount the volume if +// it is mounted. +// Copies 'directory' to root of the newly formatted volume +int format_volume(const char* volume, const char* directory); + // Ensure that all and only the volumes that packages expect to find // mounted (/tmp and /cache) are mounted. Returns 0 on success. int setup_install_mounts(); diff --git a/updater/Android.mk b/updater/Android.mk index 6fdd30895..d7aa613e9 100644 --- a/updater/Android.mk +++ b/updater/Android.mk @@ -45,7 +45,7 @@ LOCAL_STATIC_LIBRARIES += \ endif LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS) -LOCAL_STATIC_LIBRARIES += libapplypatch libbase libedify libmtdutils libminzip libz +LOCAL_STATIC_LIBRARIES += libapplypatch libbase libotafault libedify libmtdutils libminzip libz LOCAL_STATIC_LIBRARIES += libbz LOCAL_STATIC_LIBRARIES += libcutils liblog libc LOCAL_STATIC_LIBRARIES += libselinux diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp index 6e056006c..e9c8ddbc0 100644 --- a/updater/blockimg.cpp +++ b/updater/blockimg.cpp @@ -45,6 +45,7 @@ #include "install.h" #include "openssl/sha.h" #include "minzip/Hash.h" +#include "otafault/ota_io.h" #include "print_sha1.h" #include "unique_fd.h" #include "updater.h" @@ -139,7 +140,7 @@ static bool range_overlaps(const RangeSet& r1, const RangeSet& r2) { static int read_all(int fd, uint8_t* data, size_t size) { size_t so_far = 0; while (so_far < size) { - ssize_t r = TEMP_FAILURE_RETRY(read(fd, data+so_far, size-so_far)); + ssize_t r = TEMP_FAILURE_RETRY(ota_read(fd, data+so_far, size-so_far)); if (r == -1) { fprintf(stderr, "read failed: %s\n", strerror(errno)); return -1; @@ -156,7 +157,7 @@ static int read_all(int fd, std::vector<uint8_t>& buffer, size_t size) { static int write_all(int fd, const uint8_t* data, size_t size) { size_t written = 0; while (written < size) { - ssize_t w = TEMP_FAILURE_RETRY(write(fd, data+written, size-written)); + ssize_t w = TEMP_FAILURE_RETRY(ota_write(fd, data+written, size-written)); if (w == -1) { fprintf(stderr, "write failed: %s\n", strerror(errno)); return -1; @@ -622,7 +623,7 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks return -1; } - if (fsync(fd) == -1) { + if (ota_fsync(fd) == -1) { fprintf(stderr, "fsync \"%s\" failed: %s\n", fn.c_str(), strerror(errno)); return -1; } @@ -642,7 +643,7 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks return -1; } - if (fsync(dfd) == -1) { + if (ota_fsync(dfd) == -1) { fprintf(stderr, "fsync \"%s\" failed: %s\n", dname.c_str(), strerror(errno)); return -1; } @@ -1465,7 +1466,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg } if (params.canwrite) { - if (fsync(params.fd) == -1) { + if (ota_fsync(params.fd) == -1) { fprintf(stderr, "fsync failed: %s\n", strerror(errno)); goto pbiudone; } @@ -1490,7 +1491,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg rc = 0; pbiudone: - if (fsync(params.fd) == -1) { + if (ota_fsync(params.fd) == -1) { fprintf(stderr, "fsync failed: %s\n", strerror(errno)); } // params.fd will be automatically closed because of the fd_holder above. diff --git a/updater/install.cpp b/updater/install.cpp index 45bbf2bc1..a2efc0b97 100644 --- a/updater/install.cpp +++ b/updater/install.cpp @@ -51,6 +51,7 @@ #include "minzip/DirUtil.h" #include "mtdutils/mounts.h" #include "mtdutils/mtdutils.h" +#include "otafault/ota_io.h" #include "updater.h" #include "install.h" #include "tune2fs.h" @@ -557,18 +558,18 @@ Value* PackageExtractFileFn(const char* name, State* state, } { - int fd = TEMP_FAILURE_RETRY(open(dest_path, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, + int fd = TEMP_FAILURE_RETRY(ota_open(dest_path, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRUSR | S_IWUSR)); if (fd == -1) { printf("%s: can't open %s for write: %s\n", name, dest_path, strerror(errno)); goto done2; } success = mzExtractZipEntryToFile(za, entry, fd); - if (fsync(fd) == -1) { + if (ota_fsync(fd) == -1) { printf("fsync of \"%s\" failed: %s\n", dest_path, strerror(errno)); success = false; } - if (close(fd) == -1) { + if (ota_close(fd) == -1) { printf("close of \"%s\" failed: %s\n", dest_path, strerror(errno)); success = false; } @@ -1001,7 +1002,7 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) { goto done; } - if (fread(buffer, 1, st.st_size, f) != static_cast<size_t>(st.st_size)) { + if (ota_fread(buffer, 1, st.st_size, f) != static_cast<size_t>(st.st_size)) { ErrorAbort(state, "%s: failed to read %lld bytes from %s", name, (long long)st.st_size+1, filename); fclose(f); @@ -1104,7 +1105,7 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { if (contents->type == VAL_STRING) { // we're given a filename as the contents char* filename = contents->data; - FILE* f = fopen(filename, "rb"); + FILE* f = ota_fopen(filename, "rb"); if (f == NULL) { printf("%s: can't open %s: %s\n", name, filename, strerror(errno)); result = strdup(""); @@ -1114,12 +1115,12 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { success = true; char* buffer = reinterpret_cast<char*>(malloc(BUFSIZ)); int read; - while (success && (read = fread(buffer, 1, BUFSIZ, f)) > 0) { + while (success && (read = ota_fread(buffer, 1, BUFSIZ, f)) > 0) { int wrote = mtd_write_data(ctx, buffer, read); success = success && (wrote == read); } free(buffer); - fclose(f); + ota_fclose(f); } else { // we're given a blob as the contents ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size); @@ -1440,7 +1441,7 @@ Value* RebootNowFn(const char* name, State* state, int argc, Expr* argv[]) { memset(buffer, 0, sizeof(((struct bootloader_message*)0)->command)); FILE* f = fopen(filename, "r+b"); fseek(f, offsetof(struct bootloader_message, command), SEEK_SET); - fwrite(buffer, sizeof(((struct bootloader_message*)0)->command), 1, f); + ota_fwrite(buffer, sizeof(((struct bootloader_message*)0)->command), 1, f); fclose(f); free(filename); @@ -1488,7 +1489,7 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) { to_write = max_size; stagestr[max_size-1] = 0; } - fwrite(stagestr, to_write, 1, f); + ota_fwrite(stagestr, to_write, 1, f); fclose(f); free(stagestr); @@ -1508,7 +1509,7 @@ Value* GetStageFn(const char* name, State* state, int argc, Expr* argv[]) { char buffer[sizeof(((struct bootloader_message*)0)->stage)]; FILE* f = fopen(filename, "rb"); fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); - fread(buffer, sizeof(buffer), 1, f); + ota_fread(buffer, sizeof(buffer), 1, f); fclose(f); buffer[sizeof(buffer)-1] = '\0'; @@ -1526,13 +1527,13 @@ Value* WipeBlockDeviceFn(const char* name, State* state, int argc, Expr* argv[]) size_t len; android::base::ParseUint(len_str, &len); - int fd = open(filename, O_WRONLY, 0644); + int fd = ota_open(filename, O_WRONLY, 0644); int success = wipe_block_device(fd, len); free(filename); free(len_str); - close(fd); + ota_close(fd); return StringValue(strdup(success ? "t" : "")); } |