remount_service.c revision c880ee0265a4057fd5086f4b9e8e5fae6e053087
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/mount.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define TRACE_TAG TRACE_ADB 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int system_ro = 1; 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross/* Returns the device used to mount a directory in /proc/mounts */ 34c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Crossstatic char *find_mount(const char *dir) 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int res; 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int size; 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *token = NULL; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char delims[] = "\n"; 41c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross char buf[4096]; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 43c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross fd = unix_open("/proc/mounts", O_RDONLY); 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd < 0) 45c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross return NULL; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf[sizeof(buf) - 1] = '\0'; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size = adb_read(fd, buf, sizeof(buf) - 1); 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project token = strtok(buf, delims); 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while (token) { 54c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross char mount_dev[256]; 55c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross char mount_dir[256]; 56c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross int mount_freq; 57c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross int mount_passno; 58c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross 59c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross res = sscanf(token, "%255s %255s %*s %*s %d %d\n", 60c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross mount_dev, mount_dir, &mount_freq, &mount_passno); 61c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross mount_dev[255] = 0; 62c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross mount_dir[255] = 0; 63c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross if (res == 4 && (strcmp(dir, mount_dir) == 0)) 64c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross return strdup(mount_dev); 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project token = strtok(NULL, delims); 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 68c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross return NULL; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Init mounts /system as read only, remount to enable writes. */ 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int remount_system() 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 74c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross char *dev; 75c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (system_ro == 0) { 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 79c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross 80c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross dev = find_mount("/system"); 81c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross 82c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross if (!dev) 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross system_ro = mount(dev, "/system", "none", MS_REMOUNT, NULL); 86c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross 87c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross free(dev); 88c880ee0265a4057fd5086f4b9e8e5fae6e053087Colin Cross 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return system_ro; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void write_string(int fd, const char* str) 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(fd, str, strlen(str)); 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid remount_service(int fd, void *cookie) 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret = remount_system(); 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!ret) 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project write_string(fd, "remount succeeded\n"); 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else { 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buffer[200]; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project snprintf(buffer, sizeof(buffer), "remount failed: %s\n", strerror(errno)); 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project write_string(fd, buffer); 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 112