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> 22a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <stdio.h> 23a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <stdlib.h> 24a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <string.h> 25a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <unistd.h> 26a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <sys/stat.h> 27a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 28a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <cutils/log.h> 29a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 30a6391f1006b961ca89d1c79a826375380684a4deSan Mehat#include <diskconfig/diskconfig.h> 31a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 32a6391f1006b961ca89d1c79a826375380684a4deSan Mehatint 33a6391f1006b961ca89d1c79a826375380684a4deSan Mehatwrite_raw_image(const char *dst, const char *src, loff_t offset, int test) 34a6391f1006b961ca89d1c79a826375380684a4deSan Mehat{ 35a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int dst_fd = -1; 36a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int src_fd = -1; 37a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint8_t buffer[2048]; 38a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int nr_bytes; 39a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int tmp; 40a6391f1006b961ca89d1c79a826375380684a4deSan Mehat int done = 0; 41a6391f1006b961ca89d1c79a826375380684a4deSan Mehat uint64_t total = 0; 42a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 43fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block ALOGI("Writing RAW image '%s' to '%s' (offset=%llu)", src, dst, offset); 44a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((src_fd = open(src, O_RDONLY)) < 0) { 4501dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not open %s for reading (errno=%d).", src, errno); 46a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 47a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 48a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 49a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!test) { 50a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((dst_fd = open(dst, O_RDWR)) < 0) { 5101dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not open '%s' for read/write (errno=%d).", dst, errno); 52a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 53a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 54a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 55a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (lseek64(dst_fd, offset, SEEK_SET) != offset) { 5601dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Could not seek to offset %lld in %s.", offset, dst); 57a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 58a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 59a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 60a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 61a6391f1006b961ca89d1c79a826375380684a4deSan Mehat while (!done) { 62a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((nr_bytes = read(src_fd, buffer, sizeof(buffer))) < 0) { 63a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* XXX: Should we not even bother with EINTR? */ 64a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (errno == EINTR) 65a6391f1006b961ca89d1c79a826375380684a4deSan Mehat continue; 6601dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Error (%d) while reading from '%s'", errno, src); 67a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 68a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 69a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 70a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!nr_bytes) { 71a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* we're done. */ 72a6391f1006b961ca89d1c79a826375380684a4deSan Mehat done = 1; 73a6391f1006b961ca89d1c79a826375380684a4deSan Mehat break; 74a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 75a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 76a6391f1006b961ca89d1c79a826375380684a4deSan Mehat total += nr_bytes; 77a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 78a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* skip the write loop if we're testing */ 79a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (test) 80a6391f1006b961ca89d1c79a826375380684a4deSan Mehat nr_bytes = 0; 81a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 82a6391f1006b961ca89d1c79a826375380684a4deSan Mehat while (nr_bytes > 0) { 83a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if ((tmp = write(dst_fd, buffer, nr_bytes)) < 0) { 84a6391f1006b961ca89d1c79a826375380684a4deSan Mehat /* XXX: Should we not even bother with EINTR? */ 85a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (errno == EINTR) 86a6391f1006b961ca89d1c79a826375380684a4deSan Mehat continue; 8701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Error (%d) while writing to '%s'", errno, dst); 88a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 89a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 90a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!tmp) 91a6391f1006b961ca89d1c79a826375380684a4deSan Mehat continue; 92a6391f1006b961ca89d1c79a826375380684a4deSan Mehat nr_bytes -= tmp; 93a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 94a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 95a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 96a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (!done) { 9701dda204cd28fe181691b4a44a51be7e5666d0c8Steve Block ALOGE("Exited read/write loop without setting flag! WTF?!"); 98a6391f1006b961ca89d1c79a826375380684a4deSan Mehat goto fail; 99a6391f1006b961ca89d1c79a826375380684a4deSan Mehat } 100a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 101a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dst_fd >= 0) 102a6391f1006b961ca89d1c79a826375380684a4deSan Mehat fsync(dst_fd); 103a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 104fe71a61e5b0cb666675900d206251a7c18ed944bSteve Block ALOGI("Wrote %llu bytes to %s @ %lld", total, dst, offset); 105a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 106a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(src_fd); 107a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dst_fd >= 0) 108a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(dst_fd); 109a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 0; 110a6391f1006b961ca89d1c79a826375380684a4deSan Mehat 111a6391f1006b961ca89d1c79a826375380684a4deSan Mehatfail: 112a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (dst_fd >= 0) 113a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(dst_fd); 114a6391f1006b961ca89d1c79a826375380684a4deSan Mehat if (src_fd >= 0) 115a6391f1006b961ca89d1c79a826375380684a4deSan Mehat close(src_fd); 116a6391f1006b961ca89d1c79a826375380684a4deSan Mehat return 1; 117a6391f1006b961ca89d1c79a826375380684a4deSan Mehat} 118