1a6391f1006b961ca89d1c79a826375380684a4deSan Mehat/* libs/diskconfig/diskutils.c 2a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 3a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * Copyright 2008, The Android Open Source Project 4a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 5a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 6a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * you may not use this file except in compliance with the License. 7a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * You may obtain a copy of the License at 8a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 9a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * http://www.apache.org/licenses/LICENSE-2.0 10a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * 11a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * Unless required by applicable law or agreed to in writing, software 12a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * distributed under the License is distributed on an "AS IS" BASIS, 13a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * See the License for the specific language governing permissions and 15a6391f1006b961ca89d1c79a826375380684a4deSan Mehat * limitations under the License. 16a6391f1006b961ca89d1c79a826375380684a4deSan Mehat */ 17a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 18a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#define LOG_TAG "diskutils" 19a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 20a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <errno.h> 21a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <fcntl.h> 221874e6557cbaf36e6893e502d4cdd7c645444b8fMark Salyzyn#include <inttypes.h> 23a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <stdio.h> 24a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <stdlib.h> 25a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <string.h> 26a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <sys/stat.h> 27ff2dcd9af994a23ed483939a416b48bdc10eefd5Mark Salyzyn#include <unistd.h> 28a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 2930f991f251940be3ed11566fb71139852286f68aMark Salyzyn#include <log/log.h> 30a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 31a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <diskconfig/diskconfig.h> 32a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 33a6391f1006b961ca89d1c79a826375380684a4deSan Mehatint 34a6391f1006b961ca89d1c79a826375380684a4deSan Mehatwrite_raw_image(const char *dst, const char *src, loff_t offset, int test) 35a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 36a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int dst_fd = -1; 37a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int src_fd = -1; 38a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint8_t buffer[2048]; 391874e6557cbaf36e6893e502d4cdd7c645444b8fMark Salyzyn ssize_t nr_bytes; 401874e6557cbaf36e6893e502d4cdd7c645444b8fMark Salyzyn ssize_t tmp; 41a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int done = 0; 42a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint64_t total = 0; 43a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 449d4c76f15249432c7bfdef1dca29597bcd90ac97Ying Wang ALOGI("Writing RAW image '%s' to '%s' (offset=%llu)", src, dst, (unsigned long long)offset); 45a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((src_fd = open(src, O_RDONLY)) < 0) { 4601dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not open %s for reading (errno=%d).", src, errno); 47a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 48a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 49a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 50a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!test) { 51a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((dst_fd = open(dst, O_RDWR)) < 0) { 5201dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not open '%s' for read/write (errno=%d).", dst, errno); 53a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 54a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 55a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 56a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (lseek64(dst_fd, offset, SEEK_SET) != offset) { 579d4c76f15249432c7bfdef1dca29597bcd90ac97Ying Wang ALOGE("Could not seek to offset %lld in %s.", (long long)offset, dst); 58a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 59a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 60a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 61a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 62a6391f1006b961ca89d1c79a826375380684a4deSan Mehat while (!done) { 63a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((nr_bytes = read(src_fd, buffer, sizeof(buffer))) < 0) { 64a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* XXX: Should we not even bother with EINTR? */ 65a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (errno == EINTR) 66a6391f1006b961ca89d1c79a826375380684a4deSan Mehat continue; 6701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Error (%d) while reading from '%s'", errno, src); 68a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 69a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 70a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 71a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!nr_bytes) { 72a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* we're done. */ 73a6391f1006b961ca89d1c79a826375380684a4deSan Mehat done = 1; 74a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 75a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 76a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 77a6391f1006b961ca89d1c79a826375380684a4deSan Mehat total += nr_bytes; 78a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 79a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* skip the write loop if we're testing */ 80a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (test) 81a6391f1006b961ca89d1c79a826375380684a4deSan Mehat nr_bytes = 0; 82a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 83a6391f1006b961ca89d1c79a826375380684a4deSan Mehat while (nr_bytes > 0) { 84a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((tmp = write(dst_fd, buffer, nr_bytes)) < 0) { 85a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* XXX: Should we not even bother with EINTR? */ 86a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (errno == EINTR) 87a6391f1006b961ca89d1c79a826375380684a4deSan Mehat continue; 8801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Error (%d) while writing to '%s'", errno, dst); 89a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 90a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 91a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!tmp) 92a6391f1006b961ca89d1c79a826375380684a4deSan Mehat continue; 93a6391f1006b961ca89d1c79a826375380684a4deSan Mehat nr_bytes -= tmp; 94a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 95a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 96a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 97a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!done) { 9801dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Exited read/write loop without setting flag! WTF?!"); 99a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 100a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 101a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 102a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dst_fd >= 0) 103a6391f1006b961ca89d1c79a826375380684a4deSan Mehat fsync(dst_fd); 104a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 1059d4c76f15249432c7bfdef1dca29597bcd90ac97Ying Wang ALOGI("Wrote %" PRIu64 " bytes to %s @ %lld", total, dst, (long long)offset); 106a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 107a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(src_fd); 108a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dst_fd >= 0) 109a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(dst_fd); 110a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 111a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 112a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfail: 113a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dst_fd >= 0) 114a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(dst_fd); 115a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (src_fd >= 0) 116a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(src_fd); 117a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 118a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 119