2 * Copyright (C) 2008 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <sys/types.h>
27 #define LOG_TAG "Vold"
29 #include "cutils/log.h"
31 #include "VolumeManager.h"
32 #include "CommandListener.h"
33 #include "NetlinkManager.h"
34 #include "AutoVolume.h"
36 static int process_config(VolumeManager *vm);
37 static void coldboot(const char *path);
45 SLOGI("Vold 2.1 (the revenge) firing up");
47 mkdir("/dev/block/vold", 0755);
49 /* Create our singleton managers */
50 if (!(vm = VolumeManager::Instance())) {
51 SLOGE("Unable to create VolumeManager");
55 if (!(nm = NetlinkManager::Instance())) {
56 SLOGE("Unable to create NetlinkManager");
61 cl = new CommandListener();
62 vm->setBroadcaster((SocketListener *) cl);
63 nm->setBroadcaster((SocketListener *) cl);
66 SLOGE("Unable to start VolumeManager (%s)", strerror(errno));
70 if (process_config(vm)) {
71 SLOGE("Error reading configuration (%s)... continuing anyways", strerror(errno));
75 SLOGE("Unable to start NetlinkManager (%s)", strerror(errno));
79 coldboot("/sys/block");
81 * Switch uevents are broken.
82 * For now we manually bootstrap
89 if ((fp = fopen("/sys/devices/virtual/switch/usb_mass_storage/state",
91 if (fgets(state, sizeof(state), fp)) {
92 if (!strncmp(state, "online", 6)) {
93 vm->notifyUmsConnected(true);
95 vm->notifyUmsConnected(false);
98 SLOGE("Failed to read switch state (%s)", strerror(errno));
103 SLOGW("No UMS switch available");
106 // coldboot("/sys/class/switch");
109 * Now that we're up, we can respond to commands
111 if (cl->startListener()) {
112 SLOGE("Unable to start CommandListener (%s)", strerror(errno));
116 // Eventually we'll become the monitoring thread
121 SLOGI("Vold exiting");
125 static void do_coldboot(DIR *d, int lvl)
132 fd = openat(dfd, "uevent", O_WRONLY);
134 write(fd, "add\n", 4);
138 while((de = readdir(d))) {
141 if (de->d_name[0] == '.')
144 if (de->d_type != DT_DIR && lvl > 0)
147 fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);
155 do_coldboot(d2, lvl + 1);
161 static void coldboot(const char *path)
163 DIR *d = opendir(path);
170 static int process_config(VolumeManager *vm) {
175 if (!(fp = fopen("/etc/vold.fstab", "r"))) {
176 const char *sdcard = 0;
177 if ((fp = fopen("/proc/cmdline", "r"))) {
178 while (fscanf(fp, "%s", line) > 0) {
179 if (!strncmp(line, "SDCARD=", 7)) {
186 // FIXME: should not hardcode the label and mount_point
187 AutoVolume *dv = new AutoVolume(vm, "sdcard", "/mnt/sdcard", sdcard);
192 while(fgets(line, sizeof(line), fp)) {
193 const char *delim = " \t";
195 char *type, *label, *mount_point;
198 line[strlen(line)-1] = '\0';
200 if (line[0] == '#' || line[0] == '\0')
203 if (!(type = strtok_r(line, delim, &save_ptr))) {
204 SLOGE("Error parsing type");
207 if (!(label = strtok_r(NULL, delim, &save_ptr))) {
208 SLOGE("Error parsing label");
211 if (!(mount_point = strtok_r(NULL, delim, &save_ptr))) {
212 SLOGE("Error parsing mount point");
216 if (!strcmp(type, "dev_mount")) {
217 DirectVolume *dv = NULL;
220 if (!(part = strtok_r(NULL, delim, &save_ptr))) {
221 SLOGE("Error parsing partition");
224 if (int idx = (strcmp(part, "auto") ? atoi(part) : -1)) {
225 dv = new DirectVolume(vm, label, mount_point, idx);
227 SLOGE("Partition must either be 'auto' or 1 based index instead of '%s'", part);
231 while (char *sysfs_path = strtok_r(NULL, delim, &save_ptr)) {
232 if (dv->addPath(sysfs_path)) {
233 SLOGE("Failed to add devpath %s to volume %s", sysfs_path,
239 } else if (!strcmp(type, "map_mount")) {
241 SLOGE("Unknown type '%s'", type);
250 SLOGE("Syntax error on config line %d", n);