1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER 18 19#include "model/Disk.h" 20#include "VolumeManager.h" 21#include "NetlinkManager.h" 22#include "VoldNativeService.h" 23#include "VoldUtil.h" 24#include "cryptfs.h" 25#include "sehandle.h" 26 27#include <android-base/logging.h> 28#include <android-base/properties.h> 29#include <android-base/stringprintf.h> 30#include <cutils/klog.h> 31#include <utils/Trace.h> 32 33#include <stdio.h> 34#include <stdlib.h> 35#include <errno.h> 36#include <string.h> 37#include <sys/stat.h> 38#include <sys/types.h> 39#include <getopt.h> 40#include <fcntl.h> 41#include <dirent.h> 42#include <fs_mgr.h> 43 44static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quota, 45 bool* has_reserved); 46static void coldboot(const char *path); 47static void parse_args(int argc, char** argv); 48 49struct selabel_handle *sehandle; 50 51using android::base::StringPrintf; 52 53int main(int argc, char** argv) { 54 atrace_set_tracing_enabled(false); 55 setenv("ANDROID_LOG_TAGS", "*:v", 1); 56 android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM)); 57 58 LOG(INFO) << "Vold 3.0 (the awakening) firing up"; 59 60 ATRACE_BEGIN("main"); 61 62 63 LOG(VERBOSE) << "Detected support for:" 64 << (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "") 65 << (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "") 66 << (android::vold::IsFilesystemSupported("vfat") ? " vfat" : ""); 67 68 VolumeManager *vm; 69 NetlinkManager *nm; 70 71 parse_args(argc, argv); 72 73 sehandle = selinux_android_file_context_handle(); 74 if (sehandle) { 75 selinux_android_set_sehandle(sehandle); 76 } 77 78 mkdir("/dev/block/vold", 0755); 79 80 /* For when cryptfs checks and mounts an encrypted filesystem */ 81 klog_set_level(6); 82 83 /* Create our singleton managers */ 84 if (!(vm = VolumeManager::Instance())) { 85 LOG(ERROR) << "Unable to create VolumeManager"; 86 exit(1); 87 } 88 89 if (!(nm = NetlinkManager::Instance())) { 90 LOG(ERROR) << "Unable to create NetlinkManager"; 91 exit(1); 92 } 93 94 if (android::base::GetBoolProperty("vold.debug", false)) { 95 vm->setDebug(true); 96 } 97 98 if (vm->start()) { 99 PLOG(ERROR) << "Unable to start VolumeManager"; 100 exit(1); 101 } 102 103 bool has_adoptable; 104 bool has_quota; 105 bool has_reserved; 106 107 if (process_config(vm, &has_adoptable, &has_quota, &has_reserved)) { 108 PLOG(ERROR) << "Error reading configuration... continuing anyways"; 109 } 110 111 ATRACE_BEGIN("VoldNativeService::start"); 112 if (android::vold::VoldNativeService::start() != android::OK) { 113 LOG(ERROR) << "Unable to start VoldNativeService"; 114 exit(1); 115 } 116 ATRACE_END(); 117 118 LOG(DEBUG) << "VoldNativeService::start() completed OK"; 119 120 ATRACE_BEGIN("NetlinkManager::start"); 121 if (nm->start()) { 122 PLOG(ERROR) << "Unable to start NetlinkManager"; 123 exit(1); 124 } 125 ATRACE_END(); 126 127 // This call should go after listeners are started to avoid 128 // a deadlock between vold and init (see b/34278978 for details) 129 android::base::SetProperty("vold.has_adoptable", has_adoptable ? "1" : "0"); 130 android::base::SetProperty("vold.has_quota", has_quota ? "1" : "0"); 131 android::base::SetProperty("vold.has_reserved", has_reserved ? "1" : "0"); 132 133 // Do coldboot here so it won't block booting, 134 // also the cold boot is needed in case we have flash drive 135 // connected before Vold launched 136 coldboot("/sys/block"); 137 138 ATRACE_END(); 139 140 android::IPCThreadState::self()->joinThreadPool(); 141 LOG(INFO) << "vold shutting down"; 142 143 exit(0); 144} 145 146static void parse_args(int argc, char** argv) { 147 static struct option opts[] = { 148 {"blkid_context", required_argument, 0, 'b' }, 149 {"blkid_untrusted_context", required_argument, 0, 'B' }, 150 {"fsck_context", required_argument, 0, 'f' }, 151 {"fsck_untrusted_context", required_argument, 0, 'F' }, 152 }; 153 154 int c; 155 while ((c = getopt_long(argc, argv, "", opts, nullptr)) != -1) { 156 switch (c) { 157 case 'b': android::vold::sBlkidContext = optarg; break; 158 case 'B': android::vold::sBlkidUntrustedContext = optarg; break; 159 case 'f': android::vold::sFsckContext = optarg; break; 160 case 'F': android::vold::sFsckUntrustedContext = optarg; break; 161 } 162 } 163 164 CHECK(android::vold::sBlkidContext != nullptr); 165 CHECK(android::vold::sBlkidUntrustedContext != nullptr); 166 CHECK(android::vold::sFsckContext != nullptr); 167 CHECK(android::vold::sFsckUntrustedContext != nullptr); 168} 169 170static void do_coldboot(DIR *d, int lvl) { 171 struct dirent *de; 172 int dfd, fd; 173 174 dfd = dirfd(d); 175 176 fd = openat(dfd, "uevent", O_WRONLY | O_CLOEXEC); 177 if(fd >= 0) { 178 write(fd, "add\n", 4); 179 close(fd); 180 } 181 182 while((de = readdir(d))) { 183 DIR *d2; 184 185 if (de->d_name[0] == '.') 186 continue; 187 188 if (de->d_type != DT_DIR && lvl > 0) 189 continue; 190 191 fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC); 192 if(fd < 0) 193 continue; 194 195 d2 = fdopendir(fd); 196 if(d2 == 0) 197 close(fd); 198 else { 199 do_coldboot(d2, lvl + 1); 200 closedir(d2); 201 } 202 } 203} 204 205static void coldboot(const char *path) { 206 ATRACE_NAME("coldboot"); 207 DIR *d = opendir(path); 208 if(d) { 209 do_coldboot(d, 0); 210 closedir(d); 211 } 212} 213 214static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quota, 215 bool* has_reserved) { 216 ATRACE_NAME("process_config"); 217 218 fstab_default = fs_mgr_read_fstab_default(); 219 if (!fstab_default) { 220 PLOG(ERROR) << "Failed to open default fstab"; 221 return -1; 222 } 223 224 /* Loop through entries looking for ones that vold manages */ 225 *has_adoptable = false; 226 *has_quota = false; 227 *has_reserved = false; 228 for (int i = 0; i < fstab_default->num_entries; i++) { 229 auto rec = &fstab_default->recs[i]; 230 if (fs_mgr_is_quota(rec)) { 231 *has_quota = true; 232 } 233 if (rec->reserved_size > 0) { 234 *has_reserved = true; 235 } 236 237 if (fs_mgr_is_voldmanaged(rec)) { 238 if (fs_mgr_is_nonremovable(rec)) { 239 LOG(WARNING) << "nonremovable no longer supported; ignoring volume"; 240 continue; 241 } 242 243 std::string sysPattern(rec->blk_device); 244 std::string nickname(rec->label); 245 int flags = 0; 246 247 if (fs_mgr_is_encryptable(rec)) { 248 flags |= android::vold::Disk::Flags::kAdoptable; 249 *has_adoptable = true; 250 } 251 if (fs_mgr_is_noemulatedsd(rec) 252 || android::base::GetBoolProperty("vold.debug.default_primary", false)) { 253 flags |= android::vold::Disk::Flags::kDefaultPrimary; 254 } 255 256 vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>( 257 new VolumeManager::DiskSource(sysPattern, nickname, flags))); 258 } 259 } 260 return 0; 261} 262