From a7b9a4660c18a88413280c84c03917ae953d62b0 Mon Sep 17 00:00:00 2001 From: Jed Estep Date: Tue, 15 Dec 2015 16:04:53 -0800 Subject: IO fault injection for OTA packages Bug: 25951086 Change-Id: I31c74c735eb7a975b7f41fe2b2eff042e5699c0c (cherry-picked from commit f1fc48c6e62cfee42d25ad12f443e22d50c15d0b) --- otafault/Android.mk | 58 +++++++++++++++++++ otafault/ota_io.cpp | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++ otafault/ota_io.h | 49 ++++++++++++++++ otafault/test.cpp | 32 +++++++++++ 4 files changed, 299 insertions(+) create mode 100644 otafault/Android.mk create mode 100644 otafault/ota_io.cpp create mode 100644 otafault/ota_io.h create mode 100644 otafault/test.cpp (limited to 'otafault') 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 +#endif + +#include +#include +#include +#include +#include + +#include "ota_io.h" + +#if defined (TARGET_INJECT_FAULTS) +static std::map 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 +#include + +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 +#include +#include + +#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; +} -- cgit v1.2.3 From 39c1b5e8722dbf0bbb3ee45e201373099f075345 Mon Sep 17 00:00:00 2001 From: Jed Estep Date: Tue, 15 Dec 2015 16:04:53 -0800 Subject: Control fault injection with config files instead of build flags Bug: 26570379 Change-Id: I76109d09276d6e3ed3a32b6fedafb2582f545c0c (cherry picked from commit d940887dde23597dc358b16d96ca48dd7480fee6) --- otafault/Android.mk | 43 +++++--------- otafault/config.cpp | 65 +++++++++++++++++++++ otafault/config.h | 74 ++++++++++++++++++++++++ otafault/ota_io.cpp | 163 ++++++++++++++++++++++++---------------------------- otafault/ota_io.h | 4 ++ otafault/test.cpp | 6 +- 6 files changed, 237 insertions(+), 118 deletions(-) create mode 100644 otafault/config.cpp create mode 100644 otafault/config.h (limited to 'otafault') diff --git a/otafault/Android.mk b/otafault/Android.mk index 75617a146..7468de6c4 100644 --- a/otafault/Android.mk +++ b/otafault/Android.mk @@ -1,10 +1,10 @@ -# Copyright 2015 The ANdroid Open Source Project +# 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 +# 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, @@ -14,45 +14,30 @@ 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 +otafault_static_libs := \ + libminzip \ + libz \ + libselinux \ + +LOCAL_SRC_FILES := config.cpp 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 +LOCAL_C_INCLUDES := bootable/recovery +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs) include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) -LOCAL_SRC_FILES := ota_io.cpp test.cpp +LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp LOCAL_MODULE_TAGS := tests LOCAL_MODULE := otafault_test -LOCAL_STATIC_LIBRARIES := libc +LOCAL_STATIC_LIBRARIES := $(otafault_static_libs) +LOCAL_C_INCLUDES := bootable/recovery 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/config.cpp b/otafault/config.cpp new file mode 100644 index 000000000..c87f9a631 --- /dev/null +++ b/otafault/config.cpp @@ -0,0 +1,65 @@ +/* + * 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 +#include + +#include +#include + +#include "minzip/Zip.h" +#include "config.h" +#include "ota_io.h" + +#define OTAIO_MAX_FNAME_SIZE 128 + +static ZipArchive* archive; +static std::map should_inject_cache; + +static const char* get_type_path(const char* io_type) { + char* path = (char*)calloc(strlen(io_type) + strlen(OTAIO_BASE_DIR) + 2, sizeof(char)); + sprintf(path, "%s/%s", OTAIO_BASE_DIR, io_type); + return path; +} + +void ota_io_init(ZipArchive* za) { + archive = za; + ota_set_fault_files(); +} + +bool should_fault_inject(const char* io_type) { + if (should_inject_cache.find(io_type) != should_inject_cache.end()) { + return should_inject_cache[io_type]; + } + const char* type_path = get_type_path(io_type); + const ZipEntry* entry = mzFindZipEntry(archive, type_path); + should_inject_cache[type_path] = entry != nullptr; + free((void*)type_path); + return entry != NULL; +} + +bool should_hit_cache() { + return should_fault_inject(OTAIO_CACHE); +} + +std::string fault_fname(const char* io_type) { + const char* type_path = get_type_path(io_type); + char* fname = (char*) calloc(OTAIO_MAX_FNAME_SIZE, sizeof(char)); + const ZipEntry* entry = mzFindZipEntry(archive, type_path); + mzReadZipEntry(archive, entry, fname, OTAIO_MAX_FNAME_SIZE); + free((void*)type_path); + return std::string(fname); +} diff --git a/otafault/config.h b/otafault/config.h new file mode 100644 index 000000000..4430be3fb --- /dev/null +++ b/otafault/config.h @@ -0,0 +1,74 @@ +/* + * 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. + */ + +/* + * Read configuration files in the OTA package to determine which files, if any, will trigger errors. + * + * OTA packages can be modified to trigger errors by adding a top-level + * directory called .libotafault, which may optionally contain up to three + * files called READ, WRITE, and FSYNC. Each one of these optional files + * contains the name of a single file on the device disk which will cause + * an IO error on the first call of the appropriate I/O action to that file. + * + * Example: + * ota.zip + * + * .libotafault + * WRITE + * + * If the contents of the file WRITE were /system/build.prop, the first write + * action to /system/build.prop would fail with EIO. Note that READ and + * FSYNC files are absent, so these actions will not cause an error. + */ + +#ifndef _UPDATER_OTA_IO_CFG_H_ +#define _UPDATER_OTA_IO_CFG_H_ + +#include + +#include + +#include "minzip/Zip.h" + +#define OTAIO_BASE_DIR ".libotafault" +#define OTAIO_READ "READ" +#define OTAIO_WRITE "WRITE" +#define OTAIO_FSYNC "FSYNC" +#define OTAIO_CACHE "CACHE" + +/* + * Initialize libotafault by providing a reference to the OTA package. + */ +void ota_io_init(ZipArchive* za); + +/* + * Return true if a config file is present for the given IO type. + */ +bool should_fault_inject(const char* io_type); + +/* + * Return true if an EIO should occur on the next hit to /cache/saved.file + * instead of the next hit to the specified file. + */ +bool should_hit_cache(); + +/* + * Return the name of the file that should cause an error for the + * given IO type. + */ +std::string fault_fname(const char* io_type); + +#endif diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index 02e80f9bf..2ce3dfcc2 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -14,9 +14,7 @@ * limitations under the License. */ -#if defined (TARGET_INJECT_FAULTS) #include -#endif #include #include @@ -24,137 +22,128 @@ #include #include +#include "config.h" #include "ota_io.h" -#if defined (TARGET_INJECT_FAULTS) -static std::map 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) +static std::map filename_cache; +static std::string read_fault_file_name = ""; +static std::string write_fault_file_name = ""; +static std::string fsync_fault_file_name = ""; + +static bool get_hit_file(const char* cached_path, std::string ffn) { + return should_hit_cache() + ? !strncmp(cached_path, OTAIO_CACHE_FNAME, strlen(cached_path)) + : !strncmp(cached_path, ffn.c_str(), strlen(cached_path)); +} + +void ota_set_fault_files() { + if (should_fault_inject(OTAIO_READ)) { + read_fault_file_name = fault_fname(OTAIO_READ); + } + if (should_fault_inject(OTAIO_WRITE)) { + write_fault_file_name = fault_fname(OTAIO_WRITE); + } + if (should_fault_inject(OTAIO_FSYNC)) { + fsync_fault_file_name = fault_fname(OTAIO_FSYNC); + } +} 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; + filename_cache[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 -} + filename_cache[fd] = path; + return fd; } FILE* ota_fopen(const char* path, const char* mode) { -#if defined (TARGET_INJECT_FAULTS) FILE* fh = fopen(path, mode); - FilenameCache[(intptr_t)fh] = path; + filename_cache[(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 + // descriptors can be reused, so make sure not to leave them in the cache + filename_cache.erase(fd); return close(fd); } int ota_fclose(FILE* fh) { -#if defined (TARGET_INJECT_FAULTS) - FilenameCache.erase((intptr_t)fh); -#endif + filename_cache.erase((intptr_t)fh); 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); + if (should_fault_inject(OTAIO_READ)) { + auto cached = filename_cache.find((intptr_t)stream); + const char* cached_path = cached->second; + if (cached != filename_cache.end() && + get_hit_file(cached_path, read_fault_file_name)) { + read_fault_file_name = ""; + errno = EIO; + return 0; + } } -#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); + if (should_fault_inject(OTAIO_READ)) { + auto cached = filename_cache.find(fd); + const char* cached_path = cached->second; + if (cached != filename_cache.end() + && get_hit_file(cached_path, read_fault_file_name)) { + read_fault_file_name = ""; + errno = EIO; + return -1; + } } -#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); + if (should_fault_inject(OTAIO_WRITE)) { + auto cached = filename_cache.find((intptr_t)stream); + const char* cached_path = cached->second; + if (cached != filename_cache.end() && + get_hit_file(cached_path, write_fault_file_name)) { + write_fault_file_name = ""; + errno = EIO; + return 0; + } } -#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); + if (should_fault_inject(OTAIO_WRITE)) { + auto cached = filename_cache.find(fd); + const char* cached_path = cached->second; + if (cached != filename_cache.end() && + get_hit_file(cached_path, write_fault_file_name)) { + write_fault_file_name = ""; + errno = EIO; + return -1; + } } -#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); + if (should_fault_inject(OTAIO_FSYNC)) { + auto cached = filename_cache.find(fd); + const char* cached_path = cached->second; + if (cached != filename_cache.end() && + get_hit_file(cached_path, fsync_fault_file_name)) { + fsync_fault_file_name = ""; + errno = EIO; + return -1; + } } -#else return fsync(fd); -#endif } + diff --git a/otafault/ota_io.h b/otafault/ota_io.h index 641a5ae0a..84187a76e 100644 --- a/otafault/ota_io.h +++ b/otafault/ota_io.h @@ -26,6 +26,10 @@ #include #include +#define OTAIO_CACHE_FNAME "/cache/saved.file" + +void ota_set_fault_files(); + int ota_open(const char* path, int oflags); int ota_open(const char* path, int oflags, mode_t mode); diff --git a/otafault/test.cpp b/otafault/test.cpp index a0f731517..6514782bf 100644 --- a/otafault/test.cpp +++ b/otafault/test.cpp @@ -17,16 +17,18 @@ #include #include #include +#include #include "ota_io.h" -int main(int argc, char **argv) { +int main(int /* argc */, char** /* argv */) { int fd = open("testdata/test.file", O_RDWR); char buf[8]; - char *out = "321"; + const 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); + close(fd); return 0; } -- cgit v1.2.3 From 3c62b67faf8a25f1dd1c44dc19759c3997fdfd36 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Fri, 5 Feb 2016 18:25:58 -0800 Subject: Reboot and retry on I/O errors When I/O error happens, reboot and retry installation two times before we abort this OTA update. Bug: 25633753 Change-Id: Iba6d4203a343a725aa625a41d237606980d62f69 --- otafault/ota_io.cpp | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'otafault') diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index 2ce3dfcc2..dd805e56e 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -29,6 +29,7 @@ static std::map filename_cache; static std::string read_fault_file_name = ""; static std::string write_fault_file_name = ""; static std::string fsync_fault_file_name = ""; +bool have_eio_error = false; static bool get_hit_file(const char* cached_path, std::string ffn) { return should_hit_cache() @@ -85,10 +86,16 @@ size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) { get_hit_file(cached_path, read_fault_file_name)) { read_fault_file_name = ""; errno = EIO; + have_eio_error = true; return 0; } } - return fread(ptr, size, nitems, stream); + size_t status = fread(ptr, size, nitems, stream); + // If I/O error occurs, set the retry-update flag. + if (status != nitems && errno == EIO) { + have_eio_error = true; + } + return status; } ssize_t ota_read(int fd, void* buf, size_t nbyte) { @@ -99,10 +106,15 @@ ssize_t ota_read(int fd, void* buf, size_t nbyte) { && get_hit_file(cached_path, read_fault_file_name)) { read_fault_file_name = ""; errno = EIO; + have_eio_error = true; return -1; } } - return read(fd, buf, nbyte); + ssize_t status = read(fd, buf, nbyte); + if (status == -1 && errno == EIO) { + have_eio_error = true; + } + return status; } size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { @@ -113,10 +125,15 @@ size_t ota_fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { get_hit_file(cached_path, write_fault_file_name)) { write_fault_file_name = ""; errno = EIO; + have_eio_error = true; return 0; } } - return fwrite(ptr, size, count, stream); + size_t status = fwrite(ptr, size, count, stream); + if (status != count && errno == EIO) { + have_eio_error = true; + } + return status; } ssize_t ota_write(int fd, const void* buf, size_t nbyte) { @@ -127,10 +144,15 @@ ssize_t ota_write(int fd, const void* buf, size_t nbyte) { get_hit_file(cached_path, write_fault_file_name)) { write_fault_file_name = ""; errno = EIO; + have_eio_error = true; return -1; } } - return write(fd, buf, nbyte); + ssize_t status = write(fd, buf, nbyte); + if (status == -1 && errno == EIO) { + have_eio_error = true; + } + return status; } int ota_fsync(int fd) { @@ -141,9 +163,14 @@ int ota_fsync(int fd) { get_hit_file(cached_path, fsync_fault_file_name)) { fsync_fault_file_name = ""; errno = EIO; + have_eio_error = true; return -1; } } - return fsync(fd); + int status = fsync(fd); + if (status == -1 && errno == EIO) { + have_eio_error = true; + } + return status; } -- cgit v1.2.3 From d80a99883d5ae2b117c54f076fe1df7eae86d2f8 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Thu, 3 Mar 2016 11:43:47 -0800 Subject: Fix the improper use of LOCAL_WHOLE_STATIC_LIBRARIES. If two libraries both use LOCAL_WHOLE_STATIC_LIBRARIES and include a same library, there would be linking errors when generating a shared library (or executable) that depends on the two libraries both. Also clean up Android.mk files. Remove the "LOCAL_MODULE_TAGS := eng" line for the updater module. The module will then default to "optional" which won't be built until needed. Change-Id: I3ec227109b8aa744b7568e7f82f575aae3fe0e6f --- otafault/Android.mk | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'otafault') diff --git a/otafault/Android.mk b/otafault/Android.mk index 7468de6c4..52d706722 100644 --- a/otafault/Android.mk +++ b/otafault/Android.mk @@ -14,29 +14,34 @@ LOCAL_PATH := $(call my-dir) +# otafault (static library) +# =============================== include $(CLEAR_VARS) otafault_static_libs := \ libminzip \ - libz \ libselinux \ + libz LOCAL_SRC_FILES := config.cpp ota_io.cpp -LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libotafault LOCAL_CLANG := true LOCAL_C_INCLUDES := bootable/recovery LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) -LOCAL_WHOLE_STATIC_LIBRARIES := $(otafault_static_libs) +LOCAL_STATIC_LIBRARIES := $(otafault_static_libs) include $(BUILD_STATIC_LIBRARY) +# otafault_test (static executable) +# =============================== include $(CLEAR_VARS) LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp LOCAL_MODULE_TAGS := tests LOCAL_MODULE := otafault_test -LOCAL_STATIC_LIBRARIES := $(otafault_static_libs) +LOCAL_STATIC_LIBRARIES := \ + libotafault \ + $(otafault_static_libs) LOCAL_C_INCLUDES := bootable/recovery LOCAL_FORCE_STATIC_EXECUTABLE := true -- cgit v1.2.3 From e326b224460cfe2e3f7e2c7c79778ef092f4f917 Mon Sep 17 00:00:00 2001 From: Jed Estep Date: Tue, 22 Mar 2016 15:25:27 -0700 Subject: Correct caching behavior for should_inject_cache Bug: 27800498 Change-Id: I5255283c1d04a385ed719c5bc2be461cae9f3648 (cherry picked from commit 88dd7796a1fd4c64d57afb20021bf66cb26fa886) --- otafault/Android.mk | 5 +++-- otafault/config.cpp | 36 ++++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 18 deletions(-) (limited to 'otafault') diff --git a/otafault/Android.mk b/otafault/Android.mk index 52d706722..50e385efb 100644 --- a/otafault/Android.mk +++ b/otafault/Android.mk @@ -19,9 +19,10 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) otafault_static_libs := \ + libbase \ libminzip \ - libselinux \ - libz + libz \ + libselinux LOCAL_SRC_FILES := config.cpp ota_io.cpp LOCAL_MODULE := libotafault diff --git a/otafault/config.cpp b/otafault/config.cpp index c87f9a631..b4567392d 100644 --- a/otafault/config.cpp +++ b/otafault/config.cpp @@ -20,6 +20,8 @@ #include #include +#include + #include "minzip/Zip.h" #include "config.h" #include "ota_io.h" @@ -27,12 +29,10 @@ #define OTAIO_MAX_FNAME_SIZE 128 static ZipArchive* archive; -static std::map should_inject_cache; +static std::map should_inject_cache; -static const char* get_type_path(const char* io_type) { - char* path = (char*)calloc(strlen(io_type) + strlen(OTAIO_BASE_DIR) + 2, sizeof(char)); - sprintf(path, "%s/%s", OTAIO_BASE_DIR, io_type); - return path; +static std::string get_type_path(const char* io_type) { + return android::base::StringPrintf("%s/%s", OTAIO_BASE_DIR, io_type); } void ota_io_init(ZipArchive* za) { @@ -41,13 +41,17 @@ void ota_io_init(ZipArchive* za) { } bool should_fault_inject(const char* io_type) { - if (should_inject_cache.find(io_type) != should_inject_cache.end()) { - return should_inject_cache[io_type]; + // archive will be NULL if we used an entry point other + // than updater/updater.cpp:main + if (archive == NULL) { + return false; + } + const std::string type_path = get_type_path(io_type); + if (should_inject_cache.find(type_path) != should_inject_cache.end()) { + return should_inject_cache[type_path]; } - const char* type_path = get_type_path(io_type); - const ZipEntry* entry = mzFindZipEntry(archive, type_path); + const ZipEntry* entry = mzFindZipEntry(archive, type_path.c_str()); should_inject_cache[type_path] = entry != nullptr; - free((void*)type_path); return entry != NULL; } @@ -56,10 +60,10 @@ bool should_hit_cache() { } std::string fault_fname(const char* io_type) { - const char* type_path = get_type_path(io_type); - char* fname = (char*) calloc(OTAIO_MAX_FNAME_SIZE, sizeof(char)); - const ZipEntry* entry = mzFindZipEntry(archive, type_path); - mzReadZipEntry(archive, entry, fname, OTAIO_MAX_FNAME_SIZE); - free((void*)type_path); - return std::string(fname); + std::string type_path = get_type_path(io_type); + std::string fname; + fname.resize(OTAIO_MAX_FNAME_SIZE); + const ZipEntry* entry = mzFindZipEntry(archive, type_path.c_str()); + mzReadZipEntry(archive, entry, &fname[0], OTAIO_MAX_FNAME_SIZE); + return fname; } -- cgit v1.2.3 From 23abfd37a55f281186f9275ad35b7182efd2e8b6 Mon Sep 17 00:00:00 2001 From: Chih-Hung Hsieh Date: Wed, 27 Jul 2016 10:19:47 -0700 Subject: Fix clang-tidy performance warnings. * Use const reference parameter type to avoid unnecessary copy. * Use more efficient overloaded string methods. Bug: 30407689 Bug: 30411878 Change-Id: Iefab05c077367f272abf545036b853e8a295c8cd Test: build with WITH_TIDY=1 --- otafault/ota_io.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'otafault') diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index dd805e56e..cb37d515a 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -31,7 +31,7 @@ static std::string write_fault_file_name = ""; static std::string fsync_fault_file_name = ""; bool have_eio_error = false; -static bool get_hit_file(const char* cached_path, std::string ffn) { +static bool get_hit_file(const char* cached_path, const std::string& ffn) { return should_hit_cache() ? !strncmp(cached_path, OTAIO_CACHE_FNAME, strlen(cached_path)) : !strncmp(cached_path, ffn.c_str(), strlen(cached_path)); -- cgit v1.2.3 From 7b0ad9c638176dc364dabb65b363536055a0ea9c Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Fri, 5 Aug 2016 18:00:04 -0700 Subject: Switch recovery to libbase logging Clean up the recovery image and switch to libbase logging. Bug: 28191554 Change-Id: Icd999c3cc832f0639f204b5c36cea8afe303ad35 Merged-In: Icd999c3cc832f0639f204b5c36cea8afe303ad35 --- otafault/Android.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'otafault') diff --git a/otafault/Android.mk b/otafault/Android.mk index d0b1174a4..47c04050b 100644 --- a/otafault/Android.mk +++ b/otafault/Android.mk @@ -17,10 +17,11 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) otafault_static_libs := \ - libbase \ libminzip \ libz \ - libselinux + libselinux \ + libbase \ + liblog LOCAL_SRC_FILES := config.cpp ota_io.cpp LOCAL_MODULE_TAGS := eng -- cgit v1.2.3 From 7aa88748f6ec4e53333d1a15747bc44826ccc410 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Wed, 28 Sep 2016 11:42:17 -0700 Subject: Turn on -Werror for recovery Also remove the 0xff comparison when validating the bootloader message fields. As the fields won't be erased to 0xff after we remove the MTD support. Bug: 28202046 Test: The recovery folder compiles for aosp_x86-eng Change-Id: Ibb30ea1b2b28676fb08c7e92a1e5f7b6ef3247ab --- otafault/Android.mk | 2 ++ 1 file changed, 2 insertions(+) (limited to 'otafault') diff --git a/otafault/Android.mk b/otafault/Android.mk index 47c04050b..82c267101 100644 --- a/otafault/Android.mk +++ b/otafault/Android.mk @@ -23,6 +23,7 @@ otafault_static_libs := \ libbase \ liblog +LOCAL_CFLAGS := -Werror LOCAL_SRC_FILES := config.cpp ota_io.cpp LOCAL_MODULE_TAGS := eng LOCAL_MODULE := libotafault @@ -41,6 +42,7 @@ LOCAL_SRC_FILES := config.cpp ota_io.cpp test.cpp LOCAL_MODULE_TAGS := tests LOCAL_MODULE := otafault_test LOCAL_STATIC_LIBRARIES := $(otafault_static_libs) +LOCAL_CFLAGS := -Werror LOCAL_C_INCLUDES := bootable/recovery LOCAL_FORCE_STATIC_EXECUTABLE := true -- cgit v1.2.3 From 8cf5c8f60f51049278b08ae4cbc31df397b651fd Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Thu, 8 Sep 2016 20:10:11 -0700 Subject: Replace minzip with libziparchive Clean up the duplicated codes that handle the zip files in bootable/recovery; and rename the library of the remaining utility functions to libotautil. Test: Update package installed successfully on angler. Bug: 19472796 Change-Id: Iea8962fcf3004473cb0322b6bb3a9ea3ca7f679e --- otafault/Android.mk | 2 +- otafault/config.cpp | 20 ++++++++++++-------- otafault/config.h | 4 ++-- 3 files changed, 15 insertions(+), 11 deletions(-) (limited to 'otafault') diff --git a/otafault/Android.mk b/otafault/Android.mk index 82c267101..71c2c62f6 100644 --- a/otafault/Android.mk +++ b/otafault/Android.mk @@ -17,7 +17,7 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) otafault_static_libs := \ - libminzip \ + libziparchive \ libz \ libselinux \ libbase \ diff --git a/otafault/config.cpp b/otafault/config.cpp index b4567392d..ee4ef8911 100644 --- a/otafault/config.cpp +++ b/otafault/config.cpp @@ -21,21 +21,21 @@ #include #include +#include -#include "minzip/Zip.h" #include "config.h" #include "ota_io.h" #define OTAIO_MAX_FNAME_SIZE 128 -static ZipArchive* archive; +static ZipArchiveHandle archive; static std::map should_inject_cache; static std::string get_type_path(const char* io_type) { return android::base::StringPrintf("%s/%s", OTAIO_BASE_DIR, io_type); } -void ota_io_init(ZipArchive* za) { +void ota_io_init(ZipArchiveHandle za) { archive = za; ota_set_fault_files(); } @@ -50,9 +50,11 @@ bool should_fault_inject(const char* io_type) { if (should_inject_cache.find(type_path) != should_inject_cache.end()) { return should_inject_cache[type_path]; } - const ZipEntry* entry = mzFindZipEntry(archive, type_path.c_str()); - should_inject_cache[type_path] = entry != nullptr; - return entry != NULL; + ZipString zip_type_path(type_path.c_str()); + ZipEntry entry; + int status = FindEntry(archive, zip_type_path, &entry); + should_inject_cache[type_path] = (status == 0); + return (status == 0); } bool should_hit_cache() { @@ -63,7 +65,9 @@ std::string fault_fname(const char* io_type) { std::string type_path = get_type_path(io_type); std::string fname; fname.resize(OTAIO_MAX_FNAME_SIZE); - const ZipEntry* entry = mzFindZipEntry(archive, type_path.c_str()); - mzReadZipEntry(archive, entry, &fname[0], OTAIO_MAX_FNAME_SIZE); + ZipString zip_type_path(type_path.c_str()); + ZipEntry entry; + int status = FindEntry(archive, zip_type_path, &entry); + ExtractToMemory(archive, &entry, reinterpret_cast(&fname[0]), OTAIO_MAX_FNAME_SIZE); return fname; } diff --git a/otafault/config.h b/otafault/config.h index 4430be3fb..c048617c2 100644 --- a/otafault/config.h +++ b/otafault/config.h @@ -41,7 +41,7 @@ #include -#include "minzip/Zip.h" +#include #define OTAIO_BASE_DIR ".libotafault" #define OTAIO_READ "READ" @@ -52,7 +52,7 @@ /* * Initialize libotafault by providing a reference to the OTA package. */ -void ota_io_init(ZipArchive* za); +void ota_io_init(ZipArchiveHandle zip); /* * Return true if a config file is present for the given IO type. -- cgit v1.2.3 From 6e02ea92ec8af1da74f55e616b7cda82740dccc0 Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Thu, 17 Nov 2016 11:24:07 -0800 Subject: applypatch: Use unique_fd to avoid leaking FDs. Add unique_fd that calls ota_close() instead of the default closer. Test: recovery_component_test passes. Test: Apply a package that calls apply_patch(). Change-Id: I0c19921731757934f76cf7d5215916673a8f2777 --- otafault/ota_io.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'otafault') diff --git a/otafault/ota_io.h b/otafault/ota_io.h index 84187a76e..e119eef08 100644 --- a/otafault/ota_io.h +++ b/otafault/ota_io.h @@ -26,6 +26,8 @@ #include #include +#include + #define OTAIO_CACHE_FNAME "/cache/saved.file" void ota_set_fault_files(); @@ -50,4 +52,12 @@ ssize_t ota_write(int fd, const void* buf, size_t nbyte); int ota_fsync(int fd); +struct OtaCloser { + static void Close(int fd) { + ota_close(fd); + } +}; + +using unique_fd = android::base::unique_fd_impl; + #endif -- cgit v1.2.3 From 3dc14cb429061e49ef76948cf55a0e3edf8b170a Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Tue, 22 Nov 2016 11:37:13 -0800 Subject: Add ota_close(unique_fd&) and ota_fclose(std::unique_ptr&). We were using the below sequence prior to the CL in [1]. unique_fd fd(ota_open(...)); ota_close(fd); fd.reset(ota_open(...)); fd.reset() may unintentionally close the newly opened FD if it has the same value as the early ota_open. The CL in [1] changed to "ota_close(fd.release())" to avoid the issue. This CL adds a new overloaded function ota_close(unique_fd&) to handle the release automatically. Similarly add ota_fclose(std::unique_ptr&). [1] commit 48cf770471ef53fbf0a1837196220862a0bdb18d. Bug: 33034669 Test: recovery_component_test passes. Change-Id: Ief91edc590e95a7426e33364b28754173efb1056 --- otafault/ota_io.cpp | 14 ++++++++++++-- otafault/ota_io.h | 6 ++++++ 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'otafault') diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index 2efd3004a..874cb1d5c 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include +#include "ota_io.h" #include #include @@ -22,8 +22,10 @@ #include #include +#include +#include + #include "config.h" -#include "ota_io.h" static std::map filename_cache; static std::string read_fault_file_name = ""; @@ -74,11 +76,19 @@ int ota_close(int fd) { return close(fd); } +int ota_close(unique_fd& fd) { + return ota_close(fd.release()); +} + int ota_fclose(FILE* fh) { filename_cache.erase((intptr_t)fh); return fclose(fh); } +int ota_fclose(std::unique_ptr& fh) { + return ota_fclose(fh.release()); +} + size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) { if (should_fault_inject(OTAIO_READ)) { auto cached = filename_cache.find((intptr_t)stream); diff --git a/otafault/ota_io.h b/otafault/ota_io.h index e119eef08..45d17b1bb 100644 --- a/otafault/ota_io.h +++ b/otafault/ota_io.h @@ -26,6 +26,8 @@ #include #include +#include + #include #define OTAIO_CACHE_FNAME "/cache/saved.file" @@ -60,4 +62,8 @@ struct OtaCloser { using unique_fd = android::base::unique_fd_impl; +int ota_close(unique_fd& fd); + +int ota_fclose(std::unique_ptr& fh); + #endif -- cgit v1.2.3 From 358c2ec1dca24d48a503b441d38545ace021ea8e Mon Sep 17 00:00:00 2001 From: Tao Bao Date: Mon, 28 Nov 2016 11:48:43 -0800 Subject: Remove ota_close(int) and ota_fclose(FILE*). We should always use unique_fd or unique_file to hold the FD or FILE* pointer when opening via ota_(f)open functions. This CL avoids accidentally closing raw FDs or FILE* pointers that are managed by unique_fd/unique_file. Test: recovery_component_test passes. Change-Id: If58eb8b5c5da507563f85efd5d56276472a1c957 --- otafault/ota_io.cpp | 20 ++++++++++++++------ otafault/ota_io.h | 16 ++++++++-------- 2 files changed, 22 insertions(+), 14 deletions(-) (limited to 'otafault') diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index 874cb1d5c..f5b01136f 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -70,23 +70,31 @@ FILE* ota_fopen(const char* path, const char* mode) { return fh; } -int ota_close(int fd) { +static int __ota_close(int fd) { // descriptors can be reused, so make sure not to leave them in the cache filename_cache.erase(fd); return close(fd); } +void OtaCloser::Close(int fd) { + __ota_close(fd); +} + int ota_close(unique_fd& fd) { - return ota_close(fd.release()); + return __ota_close(fd.release()); } -int ota_fclose(FILE* fh) { - filename_cache.erase((intptr_t)fh); +static int __ota_fclose(FILE* fh) { + filename_cache.erase(reinterpret_cast(fh)); return fclose(fh); } -int ota_fclose(std::unique_ptr& fh) { - return ota_fclose(fh.release()); +void OtaFcloser::operator()(FILE* f) { + __ota_fclose(f); +}; + +int ota_fclose(unique_file& fh) { + return __ota_fclose(fh.release()); } size_t ota_fread(void* ptr, size_t size, size_t nitems, FILE* stream) { diff --git a/otafault/ota_io.h b/otafault/ota_io.h index 45d17b1bb..395b4230e 100644 --- a/otafault/ota_io.h +++ b/otafault/ota_io.h @@ -40,10 +40,6 @@ 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); @@ -55,15 +51,19 @@ ssize_t ota_write(int fd, const void* buf, size_t nbyte); int ota_fsync(int fd); struct OtaCloser { - static void Close(int fd) { - ota_close(fd); - } + static void Close(int); }; using unique_fd = android::base::unique_fd_impl; int ota_close(unique_fd& fd); -int ota_fclose(std::unique_ptr& fh); +struct OtaFcloser { + void operator()(FILE*); +}; + +using unique_file = std::unique_ptr; + +int ota_fclose(unique_file& fh); #endif -- cgit v1.2.3 From 4728242070ce806828024f00ab3dac6ba48f3206 Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Mon, 9 Jan 2017 13:45:37 -0800 Subject: Do not inject I/O fault on a retry We could inject I/O faults during an OTA update for test purpose. But we should skip the injection if the update is an retry. Otherwise the update test will simply keeps failing. Bug: 34159970 Test: Apply the same package on angler and the update succeeds on the 2nd try. Change-Id: Id274e5475e3bc8d25d50a8cf61a77d2e32c569d6 --- otafault/config.cpp | 6 ++++-- otafault/config.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'otafault') diff --git a/otafault/config.cpp b/otafault/config.cpp index ee4ef8911..8590833ee 100644 --- a/otafault/config.cpp +++ b/otafault/config.cpp @@ -29,21 +29,23 @@ #define OTAIO_MAX_FNAME_SIZE 128 static ZipArchiveHandle archive; +static bool is_retry = false; static std::map should_inject_cache; static std::string get_type_path(const char* io_type) { return android::base::StringPrintf("%s/%s", OTAIO_BASE_DIR, io_type); } -void ota_io_init(ZipArchiveHandle za) { +void ota_io_init(ZipArchiveHandle za, bool retry) { archive = za; + is_retry = retry; ota_set_fault_files(); } bool should_fault_inject(const char* io_type) { // archive will be NULL if we used an entry point other // than updater/updater.cpp:main - if (archive == NULL) { + if (archive == nullptr || is_retry) { return false; } const std::string type_path = get_type_path(io_type); diff --git a/otafault/config.h b/otafault/config.h index c048617c2..4adbdd121 100644 --- a/otafault/config.h +++ b/otafault/config.h @@ -52,7 +52,7 @@ /* * Initialize libotafault by providing a reference to the OTA package. */ -void ota_io_init(ZipArchiveHandle zip); +void ota_io_init(ZipArchiveHandle zip, bool retry); /* * Return true if a config file is present for the given IO type. -- cgit v1.2.3 From b49767c0bacb714e14f988423e14832689c6faf2 Mon Sep 17 00:00:00 2001 From: Mikhail Lappo Date: Thu, 23 Mar 2017 21:44:26 +0100 Subject: Const modifiers This functions do not change class variables Would be good to mark them as const, so class variables are not changed by coincidence Change-Id: Iea34f6d26dbd1bde813035160e07ff2a681989e6 --- otafault/ota_io.cpp | 2 +- otafault/ota_io.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'otafault') diff --git a/otafault/ota_io.cpp b/otafault/ota_io.cpp index f5b01136f..3a89bb5dd 100644 --- a/otafault/ota_io.cpp +++ b/otafault/ota_io.cpp @@ -89,7 +89,7 @@ static int __ota_fclose(FILE* fh) { return fclose(fh); } -void OtaFcloser::operator()(FILE* f) { +void OtaFcloser::operator()(FILE* f) const { __ota_fclose(f); }; diff --git a/otafault/ota_io.h b/otafault/ota_io.h index 395b4230e..9428f1b1f 100644 --- a/otafault/ota_io.h +++ b/otafault/ota_io.h @@ -59,7 +59,7 @@ using unique_fd = android::base::unique_fd_impl; int ota_close(unique_fd& fd); struct OtaFcloser { - void operator()(FILE*); + void operator()(FILE*) const; }; using unique_file = std::unique_ptr; -- cgit v1.2.3