Merge "IO fault injection for OTA packages"
This commit is contained in:
@@ -117,6 +117,7 @@ include $(LOCAL_PATH)/minui/Android.mk \
|
|||||||
$(LOCAL_PATH)/tools/Android.mk \
|
$(LOCAL_PATH)/tools/Android.mk \
|
||||||
$(LOCAL_PATH)/edify/Android.mk \
|
$(LOCAL_PATH)/edify/Android.mk \
|
||||||
$(LOCAL_PATH)/uncrypt/Android.mk \
|
$(LOCAL_PATH)/uncrypt/Android.mk \
|
||||||
|
$(LOCAL_PATH)/otafault/Android.mk \
|
||||||
$(LOCAL_PATH)/updater/Android.mk \
|
$(LOCAL_PATH)/updater/Android.mk \
|
||||||
$(LOCAL_PATH)/update_verifier/Android.mk \
|
$(LOCAL_PATH)/update_verifier/Android.mk \
|
||||||
$(LOCAL_PATH)/applypatch/Android.mk
|
$(LOCAL_PATH)/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 := libapplypatch
|
||||||
LOCAL_MODULE_TAGS := eng
|
LOCAL_MODULE_TAGS := eng
|
||||||
LOCAL_C_INCLUDES += bootable/recovery
|
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)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ LOCAL_CLANG := true
|
|||||||
LOCAL_SRC_FILES := main.cpp
|
LOCAL_SRC_FILES := main.cpp
|
||||||
LOCAL_MODULE := applypatch
|
LOCAL_MODULE := applypatch
|
||||||
LOCAL_C_INCLUDES += bootable/recovery
|
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
|
LOCAL_SHARED_LIBRARIES += libz libcutils libc
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|||||||
+27
-26
@@ -35,6 +35,7 @@
|
|||||||
#include "mtdutils/mtdutils.h"
|
#include "mtdutils/mtdutils.h"
|
||||||
#include "edify/expr.h"
|
#include "edify/expr.h"
|
||||||
#include "print_sha1.h"
|
#include "print_sha1.h"
|
||||||
|
#include "otafault/ota_io.h"
|
||||||
|
|
||||||
static int LoadPartitionContents(const char* filename, FileContents* file);
|
static int LoadPartitionContents(const char* filename, FileContents* file);
|
||||||
static ssize_t FileSink(const unsigned char* data, ssize_t len, void* token);
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* f = fopen(filename, "rb");
|
FILE* f = ota_fopen(filename, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
printf("failed to open \"%s\": %s\n", filename, strerror(errno));
|
printf("failed to open \"%s\": %s\n", filename, strerror(errno));
|
||||||
return -1;
|
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)) {
|
if (bytes_read != static_cast<size_t>(file->size)) {
|
||||||
printf("short read of \"%s\" (%zu bytes of %zd)\n", filename, bytes_read, file->size);
|
printf("short read of \"%s\" (%zu bytes of %zd)\n", filename, bytes_read, file->size);
|
||||||
fclose(f);
|
ota_fclose(f);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fclose(f);
|
ota_fclose(f);
|
||||||
file->data = data.release();
|
file->data = data.release();
|
||||||
SHA1(file->data, file->size, file->sha1);
|
SHA1(file->data, file->size, file->sha1);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -180,7 +181,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case EMMC:
|
case EMMC:
|
||||||
dev = fopen(partition, "rb");
|
dev = ota_fopen(partition, "rb");
|
||||||
if (dev == NULL) {
|
if (dev == NULL) {
|
||||||
printf("failed to open emmc partition \"%s\": %s\n", partition, strerror(errno));
|
printf("failed to open emmc partition \"%s\": %s\n", partition, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@@ -209,7 +210,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EMMC:
|
case EMMC:
|
||||||
read = fread(p, 1, next, dev);
|
read = ota_fread(p, 1, next, dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (next != read) {
|
if (next != read) {
|
||||||
@@ -255,7 +256,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EMMC:
|
case EMMC:
|
||||||
fclose(dev);
|
ota_fclose(dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +283,7 @@ static int LoadPartitionContents(const char* filename, FileContents* file) {
|
|||||||
// Save the contents of the given FileContents object under the given
|
// Save the contents of the given FileContents object under the given
|
||||||
// filename. Return 0 on success.
|
// filename. Return 0 on success.
|
||||||
int SaveFileContents(const char* filename, const FileContents* file) {
|
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) {
|
if (fd < 0) {
|
||||||
printf("failed to open \"%s\" for write: %s\n", filename, strerror(errno));
|
printf("failed to open \"%s\" for write: %s\n", filename, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@@ -292,14 +293,14 @@ int SaveFileContents(const char* filename, const FileContents* file) {
|
|||||||
if (bytes_written != file->size) {
|
if (bytes_written != file->size) {
|
||||||
printf("short write of \"%s\" (%zd bytes of %zd) (%s)\n",
|
printf("short write of \"%s\" (%zd bytes of %zd) (%s)\n",
|
||||||
filename, bytes_written, file->size, strerror(errno));
|
filename, bytes_written, file->size, strerror(errno));
|
||||||
close(fd);
|
ota_close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (fsync(fd) != 0) {
|
if (ota_fsync(fd) != 0) {
|
||||||
printf("fsync of \"%s\" failed: %s\n", filename, strerror(errno));
|
printf("fsync of \"%s\" failed: %s\n", filename, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (close(fd) != 0) {
|
if (ota_close(fd) != 0) {
|
||||||
printf("close of \"%s\" failed: %s\n", filename, strerror(errno));
|
printf("close of \"%s\" failed: %s\n", filename, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -382,7 +383,7 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target)
|
|||||||
case EMMC: {
|
case EMMC: {
|
||||||
size_t start = 0;
|
size_t start = 0;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
int fd = open(partition, O_RDWR | O_SYNC);
|
int fd = ota_open(partition, O_RDWR | O_SYNC);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
printf("failed to open %s: %s\n", partition, strerror(errno));
|
printf("failed to open %s: %s\n", partition, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@@ -397,22 +398,22 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target)
|
|||||||
size_t to_write = len - start;
|
size_t to_write = len - start;
|
||||||
if (to_write > 1<<20) to_write = 1<<20;
|
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) {
|
if (written == -1) {
|
||||||
printf("failed write writing to %s: %s\n", partition, strerror(errno));
|
printf("failed write writing to %s: %s\n", partition, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
start += written;
|
start += written;
|
||||||
}
|
}
|
||||||
if (fsync(fd) != 0) {
|
if (ota_fsync(fd) != 0) {
|
||||||
printf("failed to sync to %s (%s)\n", partition, strerror(errno));
|
printf("failed to sync to %s (%s)\n", partition, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (close(fd) != 0) {
|
if (ota_close(fd) != 0) {
|
||||||
printf("failed to close %s (%s)\n", partition, strerror(errno));
|
printf("failed to close %s (%s)\n", partition, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fd = open(partition, O_RDONLY);
|
fd = ota_open(partition, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
printf("failed to reopen %s for verify (%s)\n", partition, strerror(errno));
|
printf("failed to reopen %s for verify (%s)\n", partition, strerror(errno));
|
||||||
return -1;
|
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
|
// Drop caches so our subsequent verification read
|
||||||
// won't just be reading the cache.
|
// won't just be reading the cache.
|
||||||
sync();
|
sync();
|
||||||
int dc = open("/proc/sys/vm/drop_caches", O_WRONLY);
|
int dc = ota_open("/proc/sys/vm/drop_caches", O_WRONLY);
|
||||||
if (TEMP_FAILURE_RETRY(write(dc, "3\n", 2)) == -1) {
|
if (TEMP_FAILURE_RETRY(ota_write(dc, "3\n", 2)) == -1) {
|
||||||
printf("write to /proc/sys/vm/drop_caches failed: %s\n", strerror(errno));
|
printf("write to /proc/sys/vm/drop_caches failed: %s\n", strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
printf(" caches dropped\n");
|
printf(" caches dropped\n");
|
||||||
}
|
}
|
||||||
close(dc);
|
ota_close(dc);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
@@ -447,7 +448,7 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target)
|
|||||||
size_t so_far = 0;
|
size_t so_far = 0;
|
||||||
while (so_far < to_read) {
|
while (so_far < to_read) {
|
||||||
ssize_t read_count =
|
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) {
|
if (read_count == -1) {
|
||||||
printf("verify read error %s at %zu: %s\n",
|
printf("verify read error %s at %zu: %s\n",
|
||||||
partition, p, strerror(errno));
|
partition, p, strerror(errno));
|
||||||
@@ -479,7 +480,7 @@ int WriteToPartition(const unsigned char* data, size_t len, const char* target)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close(fd) != 0) {
|
if (ota_close(fd) != 0) {
|
||||||
printf("error closing %s (%s)\n", partition, strerror(errno));
|
printf("error closing %s (%s)\n", partition, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -589,7 +590,7 @@ ssize_t FileSink(const unsigned char* data, ssize_t len, void* token) {
|
|||||||
ssize_t done = 0;
|
ssize_t done = 0;
|
||||||
ssize_t wrote;
|
ssize_t wrote;
|
||||||
while (done < len) {
|
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) {
|
if (wrote == -1) {
|
||||||
printf("error writing %zd bytes: %s\n", (len-done), strerror(errno));
|
printf("error writing %zd bytes: %s\n", (len-done), strerror(errno));
|
||||||
return done;
|
return done;
|
||||||
@@ -934,8 +935,8 @@ static int GenerateTarget(FileContents* source_file,
|
|||||||
token = &memory_sink_str;
|
token = &memory_sink_str;
|
||||||
} else {
|
} else {
|
||||||
// We write the decoded output to "<tgt-file>.patch".
|
// 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);
|
S_IRUSR | S_IWUSR);
|
||||||
if (output_fd < 0) {
|
if (output_fd < 0) {
|
||||||
printf("failed to open output file %s: %s\n", tmp_target_filename.c_str(),
|
printf("failed to open output file %s: %s\n", tmp_target_filename.c_str(),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
@@ -958,12 +959,12 @@ static int GenerateTarget(FileContents* source_file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!target_is_partition) {
|
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(),
|
printf("failed to fsync file \"%s\" (%s)\n", tmp_target_filename.c_str(),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
result = 1;
|
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(),
|
printf("failed to close file \"%s\" (%s)\n", tmp_target_filename.c_str(),
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
result = 1;
|
result = 1;
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
+1
-1
@@ -45,7 +45,7 @@ LOCAL_STATIC_LIBRARIES += \
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
|
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 += libbz
|
||||||
LOCAL_STATIC_LIBRARIES += libcutils liblog libc
|
LOCAL_STATIC_LIBRARIES += libcutils liblog libc
|
||||||
LOCAL_STATIC_LIBRARIES += libselinux
|
LOCAL_STATIC_LIBRARIES += libselinux
|
||||||
|
|||||||
+13
-12
@@ -45,6 +45,7 @@
|
|||||||
#include "install.h"
|
#include "install.h"
|
||||||
#include "openssl/sha.h"
|
#include "openssl/sha.h"
|
||||||
#include "minzip/Hash.h"
|
#include "minzip/Hash.h"
|
||||||
|
#include "otafault/ota_io.h"
|
||||||
#include "print_sha1.h"
|
#include "print_sha1.h"
|
||||||
#include "unique_fd.h"
|
#include "unique_fd.h"
|
||||||
#include "updater.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) {
|
static int read_all(int fd, uint8_t* data, size_t size) {
|
||||||
size_t so_far = 0;
|
size_t so_far = 0;
|
||||||
while (so_far < size) {
|
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) {
|
if (r == -1) {
|
||||||
fprintf(stderr, "read failed: %s\n", strerror(errno));
|
fprintf(stderr, "read failed: %s\n", strerror(errno));
|
||||||
return -1;
|
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) {
|
static int write_all(int fd, const uint8_t* data, size_t size) {
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
while (written < size) {
|
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) {
|
if (w == -1) {
|
||||||
fprintf(stderr, "write failed: %s\n", strerror(errno));
|
fprintf(stderr, "write failed: %s\n", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@@ -553,7 +554,7 @@ static int LoadStash(const std::string& base, const std::string& id, bool verify
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), O_RDONLY));
|
int fd = TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_RDONLY));
|
||||||
unique_fd fd_holder(fd);
|
unique_fd fd_holder(fd);
|
||||||
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
@@ -610,7 +611,7 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks
|
|||||||
|
|
||||||
fprintf(stderr, " writing %d blocks to %s\n", blocks, cn.c_str());
|
fprintf(stderr, " writing %d blocks to %s\n", blocks, cn.c_str());
|
||||||
|
|
||||||
int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE));
|
int fd = TEMP_FAILURE_RETRY(ota_open(fn.c_str(), O_WRONLY | O_CREAT | O_TRUNC, STASH_FILE_MODE));
|
||||||
unique_fd fd_holder(fd);
|
unique_fd fd_holder(fd);
|
||||||
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
@@ -622,7 +623,7 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsync(fd) == -1) {
|
if (ota_fsync(fd) == -1) {
|
||||||
fprintf(stderr, "fsync \"%s\" failed: %s\n", fn.c_str(), strerror(errno));
|
fprintf(stderr, "fsync \"%s\" failed: %s\n", fn.c_str(), strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -634,7 +635,7 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string dname = GetStashFileName(base, "", "");
|
std::string dname = GetStashFileName(base, "", "");
|
||||||
int dfd = TEMP_FAILURE_RETRY(open(dname.c_str(), O_RDONLY | O_DIRECTORY));
|
int dfd = TEMP_FAILURE_RETRY(ota_open(dname.c_str(), O_RDONLY | O_DIRECTORY));
|
||||||
unique_fd dfd_holder(dfd);
|
unique_fd dfd_holder(dfd);
|
||||||
|
|
||||||
if (dfd == -1) {
|
if (dfd == -1) {
|
||||||
@@ -642,7 +643,7 @@ static int WriteStash(const std::string& base, const std::string& id, int blocks
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsync(dfd) == -1) {
|
if (ota_fsync(dfd) == -1) {
|
||||||
fprintf(stderr, "fsync \"%s\" failed: %s\n", dname.c_str(), strerror(errno));
|
fprintf(stderr, "fsync \"%s\" failed: %s\n", dname.c_str(), strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -1346,7 +1347,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
|
|||||||
return StringValue(strdup(""));
|
return StringValue(strdup(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
params.fd = TEMP_FAILURE_RETRY(open(blockdev_filename->data, O_RDWR));
|
params.fd = TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR));
|
||||||
unique_fd fd_holder(params.fd);
|
unique_fd fd_holder(params.fd);
|
||||||
|
|
||||||
if (params.fd == -1) {
|
if (params.fd == -1) {
|
||||||
@@ -1465,7 +1466,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params.canwrite) {
|
if (params.canwrite) {
|
||||||
if (fsync(params.fd) == -1) {
|
if (ota_fsync(params.fd) == -1) {
|
||||||
fprintf(stderr, "fsync failed: %s\n", strerror(errno));
|
fprintf(stderr, "fsync failed: %s\n", strerror(errno));
|
||||||
goto pbiudone;
|
goto pbiudone;
|
||||||
}
|
}
|
||||||
@@ -1490,7 +1491,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
pbiudone:
|
pbiudone:
|
||||||
if (fsync(params.fd) == -1) {
|
if (ota_fsync(params.fd) == -1) {
|
||||||
fprintf(stderr, "fsync failed: %s\n", strerror(errno));
|
fprintf(stderr, "fsync failed: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
// params.fd will be automatically closed because of the fd_holder above.
|
// params.fd will be automatically closed because of the fd_holder above.
|
||||||
@@ -1614,7 +1615,7 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[])
|
|||||||
return StringValue(strdup(""));
|
return StringValue(strdup(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = open(blockdev_filename->data, O_RDWR);
|
int fd = ota_open(blockdev_filename->data, O_RDWR);
|
||||||
unique_fd fd_holder(fd);
|
unique_fd fd_holder(fd);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ErrorAbort(state, "open \"%s\" failed: %s", blockdev_filename->data, strerror(errno));
|
ErrorAbort(state, "open \"%s\" failed: %s", blockdev_filename->data, strerror(errno));
|
||||||
@@ -1668,7 +1669,7 @@ Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[])
|
|||||||
return StringValue(strdup(""));
|
return StringValue(strdup(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = open(arg_filename->data, O_RDONLY);
|
int fd = ota_open(arg_filename->data, O_RDONLY);
|
||||||
unique_fd fd_holder(fd);
|
unique_fd fd_holder(fd);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
ErrorAbort(state, "open \"%s\" failed: %s", arg_filename->data, strerror(errno));
|
ErrorAbort(state, "open \"%s\" failed: %s", arg_filename->data, strerror(errno));
|
||||||
|
|||||||
+22
-21
@@ -51,6 +51,7 @@
|
|||||||
#include "minzip/DirUtil.h"
|
#include "minzip/DirUtil.h"
|
||||||
#include "mtdutils/mounts.h"
|
#include "mtdutils/mounts.h"
|
||||||
#include "mtdutils/mtdutils.h"
|
#include "mtdutils/mtdutils.h"
|
||||||
|
#include "otafault/ota_io.h"
|
||||||
#include "updater.h"
|
#include "updater.h"
|
||||||
#include "install.h"
|
#include "install.h"
|
||||||
#include "tune2fs.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));
|
S_IRUSR | S_IWUSR));
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
printf("%s: can't open %s for write: %s\n", name, dest_path, strerror(errno));
|
printf("%s: can't open %s for write: %s\n", name, dest_path, strerror(errno));
|
||||||
goto done2;
|
goto done2;
|
||||||
}
|
}
|
||||||
success = mzExtractZipEntryToFile(za, entry, fd);
|
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));
|
printf("fsync of \"%s\" failed: %s\n", dest_path, strerror(errno));
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
if (close(fd) == -1) {
|
if (ota_close(fd) == -1) {
|
||||||
printf("close of \"%s\" failed: %s\n", dest_path, strerror(errno));
|
printf("close of \"%s\" failed: %s\n", dest_path, strerror(errno));
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
@@ -995,21 +996,21 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FILE* f;
|
FILE* f;
|
||||||
f = fopen(filename, "rb");
|
f = ota_fopen(filename, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
ErrorAbort(state, "%s: failed to open %s: %s", name, filename, strerror(errno));
|
ErrorAbort(state, "%s: failed to open %s: %s", name, filename, strerror(errno));
|
||||||
goto done;
|
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",
|
ErrorAbort(state, "%s: failed to read %lld bytes from %s",
|
||||||
name, (long long)st.st_size+1, filename);
|
name, (long long)st.st_size+1, filename);
|
||||||
fclose(f);
|
ota_fclose(f);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
buffer[st.st_size] = '\0';
|
buffer[st.st_size] = '\0';
|
||||||
|
|
||||||
fclose(f);
|
ota_fclose(f);
|
||||||
|
|
||||||
char* line;
|
char* line;
|
||||||
line = strtok(buffer, "\n");
|
line = strtok(buffer, "\n");
|
||||||
@@ -1104,7 +1105,7 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) {
|
|||||||
if (contents->type == VAL_STRING) {
|
if (contents->type == VAL_STRING) {
|
||||||
// we're given a filename as the contents
|
// we're given a filename as the contents
|
||||||
char* filename = contents->data;
|
char* filename = contents->data;
|
||||||
FILE* f = fopen(filename, "rb");
|
FILE* f = ota_fopen(filename, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
printf("%s: can't open %s: %s\n", name, filename, strerror(errno));
|
printf("%s: can't open %s: %s\n", name, filename, strerror(errno));
|
||||||
result = strdup("");
|
result = strdup("");
|
||||||
@@ -1114,12 +1115,12 @@ Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) {
|
|||||||
success = true;
|
success = true;
|
||||||
char* buffer = reinterpret_cast<char*>(malloc(BUFSIZ));
|
char* buffer = reinterpret_cast<char*>(malloc(BUFSIZ));
|
||||||
int read;
|
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);
|
int wrote = mtd_write_data(ctx, buffer, read);
|
||||||
success = success && (wrote == read);
|
success = success && (wrote == read);
|
||||||
}
|
}
|
||||||
free(buffer);
|
free(buffer);
|
||||||
fclose(f);
|
ota_fclose(f);
|
||||||
} else {
|
} else {
|
||||||
// we're given a blob as the contents
|
// we're given a blob as the contents
|
||||||
ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size);
|
ssize_t wrote = mtd_write_data(ctx, contents->data, contents->size);
|
||||||
@@ -1438,10 +1439,10 @@ Value* RebootNowFn(const char* name, State* state, int argc, Expr* argv[]) {
|
|||||||
|
|
||||||
// zero out the 'command' field of the bootloader message.
|
// zero out the 'command' field of the bootloader message.
|
||||||
memset(buffer, 0, sizeof(((struct bootloader_message*)0)->command));
|
memset(buffer, 0, sizeof(((struct bootloader_message*)0)->command));
|
||||||
FILE* f = fopen(filename, "r+b");
|
FILE* f = ota_fopen(filename, "r+b");
|
||||||
fseek(f, offsetof(struct bootloader_message, command), SEEK_SET);
|
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);
|
ota_fclose(f);
|
||||||
free(filename);
|
free(filename);
|
||||||
|
|
||||||
strcpy(buffer, "reboot,");
|
strcpy(buffer, "reboot,");
|
||||||
@@ -1480,7 +1481,7 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) {
|
|||||||
// bootloader message that the main recovery uses to save its
|
// bootloader message that the main recovery uses to save its
|
||||||
// arguments in case of the device restarting midway through
|
// arguments in case of the device restarting midway through
|
||||||
// package installation.
|
// package installation.
|
||||||
FILE* f = fopen(filename, "r+b");
|
FILE* f = ota_fopen(filename, "r+b");
|
||||||
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
|
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
|
||||||
int to_write = strlen(stagestr)+1;
|
int to_write = strlen(stagestr)+1;
|
||||||
int max_size = sizeof(((struct bootloader_message*)0)->stage);
|
int max_size = sizeof(((struct bootloader_message*)0)->stage);
|
||||||
@@ -1488,8 +1489,8 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) {
|
|||||||
to_write = max_size;
|
to_write = max_size;
|
||||||
stagestr[max_size-1] = 0;
|
stagestr[max_size-1] = 0;
|
||||||
}
|
}
|
||||||
fwrite(stagestr, to_write, 1, f);
|
ota_fwrite(stagestr, to_write, 1, f);
|
||||||
fclose(f);
|
ota_fclose(f);
|
||||||
|
|
||||||
free(stagestr);
|
free(stagestr);
|
||||||
return StringValue(filename);
|
return StringValue(filename);
|
||||||
@@ -1506,10 +1507,10 @@ Value* GetStageFn(const char* name, State* state, int argc, Expr* argv[]) {
|
|||||||
if (ReadArgs(state, argv, 1, &filename) < 0) return NULL;
|
if (ReadArgs(state, argv, 1, &filename) < 0) return NULL;
|
||||||
|
|
||||||
char buffer[sizeof(((struct bootloader_message*)0)->stage)];
|
char buffer[sizeof(((struct bootloader_message*)0)->stage)];
|
||||||
FILE* f = fopen(filename, "rb");
|
FILE* f = ota_fopen(filename, "rb");
|
||||||
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
|
fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET);
|
||||||
fread(buffer, sizeof(buffer), 1, f);
|
ota_fread(buffer, sizeof(buffer), 1, f);
|
||||||
fclose(f);
|
ota_fclose(f);
|
||||||
buffer[sizeof(buffer)-1] = '\0';
|
buffer[sizeof(buffer)-1] = '\0';
|
||||||
|
|
||||||
return StringValue(strdup(buffer));
|
return StringValue(strdup(buffer));
|
||||||
@@ -1526,13 +1527,13 @@ Value* WipeBlockDeviceFn(const char* name, State* state, int argc, Expr* argv[])
|
|||||||
|
|
||||||
size_t len;
|
size_t len;
|
||||||
android::base::ParseUint(len_str, &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);
|
int success = wipe_block_device(fd, len);
|
||||||
|
|
||||||
free(filename);
|
free(filename);
|
||||||
free(len_str);
|
free(len_str);
|
||||||
|
|
||||||
close(fd);
|
ota_close(fd);
|
||||||
|
|
||||||
return StringValue(strdup(success ? "t" : ""));
|
return StringValue(strdup(success ? "t" : ""));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user