1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/* 2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright (C) 2008 The Android Open Source Project 3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License. 6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at 7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software 11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and 14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License. 15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */ 16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdio.h> 18f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdlib.h> 19f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <errno.h> 20f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <string.h> 213578c41ef138cb3edf38bb488cb9864921f55c79San Mehat#include <sys/stat.h> 223578c41ef138cb3edf38bb488cb9864921f55c79San Mehat#include <sys/types.h> 233578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 243578c41ef138cb3edf38bb488cb9864921f55c79San Mehat#include <fcntl.h> 253578c41ef138cb3edf38bb488cb9864921f55c79San Mehat#include <dirent.h> 2656ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall#include <fs_mgr.h> 27f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#define LOG_TAG "Vold" 29f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 30b9738ea9692f887cf2e2fef132519f4e71cc2905Ken Sumrall#include "cutils/klog.h" 31f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "cutils/log.h" 3256ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall#include "cutils/properties.h" 33f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 34f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "VolumeManager.h" 35f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "CommandListener.h" 36f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "NetlinkManager.h" 37ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat#include "DirectVolume.h" 3829d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall#include "cryptfs.h" 39f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatstatic int process_config(VolumeManager *vm); 413578c41ef138cb3edf38bb488cb9864921f55c79San Mehatstatic void coldboot(const char *path); 42f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 4356ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall#define FSTAB_PREFIX "/fstab." 4456ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrallstruct fstab *fstab; 4556ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall 46f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatint main() { 47f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 48f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat VolumeManager *vm; 49f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat CommandListener *cl; 50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat NetlinkManager *nm; 51f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 5297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGI("Vold 2.1 (the revenge) firing up"); 53a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 54a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mkdir("/dev/block/vold", 0755); 55f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 56b9738ea9692f887cf2e2fef132519f4e71cc2905Ken Sumrall /* For when cryptfs checks and mounts an encrypted filesystem */ 57b9738ea9692f887cf2e2fef132519f4e71cc2905Ken Sumrall klog_set_level(6); 58b9738ea9692f887cf2e2fef132519f4e71cc2905Ken Sumrall 59f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat /* Create our singleton managers */ 60f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (!(vm = VolumeManager::Instance())) { 6197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to create VolumeManager"); 62f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat exit(1); 63f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat }; 64f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 65f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (!(nm = NetlinkManager::Instance())) { 6697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to create NetlinkManager"); 67f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat exit(1); 68f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat }; 69f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 70a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 71f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat cl = new CommandListener(); 72f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat vm->setBroadcaster((SocketListener *) cl); 73f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat nm->setBroadcaster((SocketListener *) cl); 74f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 75f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (vm->start()) { 7697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to start VolumeManager (%s)", strerror(errno)); 77f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat exit(1); 78f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 79f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 80f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (process_config(vm)) { 8197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error reading configuration (%s)... continuing anyways", strerror(errno)); 82f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 83f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 84f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (nm->start()) { 8597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to start NetlinkManager (%s)", strerror(errno)); 86f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat exit(1); 87f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 88f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 893578c41ef138cb3edf38bb488cb9864921f55c79San Mehat coldboot("/sys/block"); 900cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat// coldboot("/sys/class/switch"); 913578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 92f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat /* 93f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Now that we're up, we can respond to commands 94f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */ 95f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (cl->startListener()) { 9697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to start CommandListener (%s)", strerror(errno)); 97f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat exit(1); 98f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 99f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 100f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat // Eventually we'll become the monitoring thread 101f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat while(1) { 102f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat sleep(1000); 103f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 104f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 10597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGI("Vold exiting"); 106f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat exit(0); 107f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 108f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 1093578c41ef138cb3edf38bb488cb9864921f55c79San Mehatstatic void do_coldboot(DIR *d, int lvl) 1103578c41ef138cb3edf38bb488cb9864921f55c79San Mehat{ 1113578c41ef138cb3edf38bb488cb9864921f55c79San Mehat struct dirent *de; 1123578c41ef138cb3edf38bb488cb9864921f55c79San Mehat int dfd, fd; 1133578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 1143578c41ef138cb3edf38bb488cb9864921f55c79San Mehat dfd = dirfd(d); 1153578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 1163578c41ef138cb3edf38bb488cb9864921f55c79San Mehat fd = openat(dfd, "uevent", O_WRONLY); 1173578c41ef138cb3edf38bb488cb9864921f55c79San Mehat if(fd >= 0) { 1183578c41ef138cb3edf38bb488cb9864921f55c79San Mehat write(fd, "add\n", 4); 1193578c41ef138cb3edf38bb488cb9864921f55c79San Mehat close(fd); 1203578c41ef138cb3edf38bb488cb9864921f55c79San Mehat } 1213578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 1223578c41ef138cb3edf38bb488cb9864921f55c79San Mehat while((de = readdir(d))) { 1233578c41ef138cb3edf38bb488cb9864921f55c79San Mehat DIR *d2; 1243578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 1253578c41ef138cb3edf38bb488cb9864921f55c79San Mehat if (de->d_name[0] == '.') 1263578c41ef138cb3edf38bb488cb9864921f55c79San Mehat continue; 1273578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 1283578c41ef138cb3edf38bb488cb9864921f55c79San Mehat if (de->d_type != DT_DIR && lvl > 0) 1293578c41ef138cb3edf38bb488cb9864921f55c79San Mehat continue; 1303578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 1313578c41ef138cb3edf38bb488cb9864921f55c79San Mehat fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); 1323578c41ef138cb3edf38bb488cb9864921f55c79San Mehat if(fd < 0) 1333578c41ef138cb3edf38bb488cb9864921f55c79San Mehat continue; 1343578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 1353578c41ef138cb3edf38bb488cb9864921f55c79San Mehat d2 = fdopendir(fd); 1363578c41ef138cb3edf38bb488cb9864921f55c79San Mehat if(d2 == 0) 1373578c41ef138cb3edf38bb488cb9864921f55c79San Mehat close(fd); 1383578c41ef138cb3edf38bb488cb9864921f55c79San Mehat else { 1393578c41ef138cb3edf38bb488cb9864921f55c79San Mehat do_coldboot(d2, lvl + 1); 1403578c41ef138cb3edf38bb488cb9864921f55c79San Mehat closedir(d2); 1413578c41ef138cb3edf38bb488cb9864921f55c79San Mehat } 1423578c41ef138cb3edf38bb488cb9864921f55c79San Mehat } 1433578c41ef138cb3edf38bb488cb9864921f55c79San Mehat} 1443578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 1453578c41ef138cb3edf38bb488cb9864921f55c79San Mehatstatic void coldboot(const char *path) 1463578c41ef138cb3edf38bb488cb9864921f55c79San Mehat{ 1473578c41ef138cb3edf38bb488cb9864921f55c79San Mehat DIR *d = opendir(path); 1483578c41ef138cb3edf38bb488cb9864921f55c79San Mehat if(d) { 1493578c41ef138cb3edf38bb488cb9864921f55c79San Mehat do_coldboot(d, 0); 1503578c41ef138cb3edf38bb488cb9864921f55c79San Mehat closedir(d); 1513578c41ef138cb3edf38bb488cb9864921f55c79San Mehat } 1523578c41ef138cb3edf38bb488cb9864921f55c79San Mehat} 1533578c41ef138cb3edf38bb488cb9864921f55c79San Mehat 15456ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrallstatic int process_config(VolumeManager *vm) 15529d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall{ 15656ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; 15756ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall char propbuf[PROPERTY_VALUE_MAX]; 15856ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall int i; 15956ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall int ret = -1; 16056ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall int flags; 16156ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall 16256ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall property_get("ro.hardware", propbuf, ""); 16356ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf); 16456ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall 16556ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall fstab = fs_mgr_read_fstab(fstab_filename); 16656ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall if (!fstab) { 16756ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall SLOGE("failed to open %s\n", fstab_filename); 168f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return -1; 169f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 170f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 17156ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall /* Loop through entries looking for ones that vold manages */ 17256ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall for (i = 0; i < fstab->num_entries; i++) { 17356ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall if (fs_mgr_is_voldmanaged(&fstab->recs[i])) { 174ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat DirectVolume *dv = NULL; 17556ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall flags = 0; 176f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 17756ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall /* Set any flags that might be set for this volume */ 17856ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall if (fs_mgr_is_nonremovable(&fstab->recs[i])) { 17956ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall flags |= VOL_NONREMOVABLE; 18056ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall } 18156ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall if (fs_mgr_is_encryptable(&fstab->recs[i])) { 18256ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall flags |= VOL_ENCRYPTABLE; 183f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 184ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey /* Only set this flag if there is not an emulated sd card */ 185ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey if (fs_mgr_is_noemulatedsd(&fstab->recs[i]) && 186ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey !strcmp(fstab->recs[i].fs_type, "vfat")) { 187ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey flags |= VOL_PROVIDES_ASEC; 188ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey } 189ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey dv = new DirectVolume(vm, &(fstab->recs[i]), flags); 190ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey 191ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey if (dv->addPath(fstab->recs[i].blk_device)) { 192ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey SLOGE("Failed to add devpath %s to volume %s", 193ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey fstab->recs[i].blk_device, fstab->recs[i].label); 194ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey goto out_fail; 195ba6ae8db137d012c9b8e11f9f8321c7771698e92Jeff Sharkey } 19629d8da8cefa99e436c13295d4c9bad060ca18a6dKen Sumrall 197f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat vm->addVolume(dv); 198f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 199f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 200f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 20156ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall ret = 0; 202f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 203f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatout_fail: 20456ad03cae13524b32898dc4ccf01040ced5a53b4Ken Sumrall return ret; 205f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 206