• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright (C) 2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <fcntl.h>
24 #include <pthread.h>
25 
26 #include <sys/socket.h>
27 #include <sys/select.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <sys/un.h>
31 
32 #include <cutils/config_utils.h>
33 #include <cutils/cpu_info.h>
34 #include <cutils/properties.h>
35 #include <cutils/sockets.h>
36 
37 #include <linux/netlink.h>
38 
39 #include <private/android_filesystem_config.h>
40 
41 #include "vold.h"
42 #include "volmgr.h"
43 
44 
45 #define VOLD_SOCKET "vold"
46 
47 /*
48  * Globals
49  */
50 
51 static int ver_major = 2;
52 static int ver_minor = 0;
53 static pthread_mutex_t write_mutex = PTHREAD_MUTEX_INITIALIZER;
54 static int fw_sock = -1;
55 
56 int bootstrap = 0;
57 
main(int argc,char ** argv)58 int main(int argc, char **argv)
59 {
60     int door_sock = -1;
61     int uevent_sock = -1;
62     struct sockaddr_nl nladdr;
63     int uevent_sz = 64 * 1024;
64 
65     LOGI("Android Volume Daemon version %d.%d", ver_major, ver_minor);
66 
67     /*
68      * Create all the various sockets we'll need
69      */
70 
71     // Socket to listen on for incomming framework connections
72     if ((door_sock = android_get_control_socket(VOLD_SOCKET)) < 0) {
73         LOGE("Obtaining file descriptor socket '%s' failed: %s",
74              VOLD_SOCKET, strerror(errno));
75         exit(1);
76     }
77 
78     if (listen(door_sock, 4) < 0) {
79         LOGE("Unable to listen on fd '%d' for socket '%s': %s",
80              door_sock, VOLD_SOCKET, strerror(errno));
81         exit(1);
82     }
83 
84     mkdir("/dev/block/vold", 0755);
85 
86     // Socket to listen on for uevent changes
87     memset(&nladdr, 0, sizeof(nladdr));
88     nladdr.nl_family = AF_NETLINK;
89     nladdr.nl_pid = getpid();
90     nladdr.nl_groups = 0xffffffff;
91 
92     if ((uevent_sock = socket(PF_NETLINK,
93                              SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {
94         LOGE("Unable to create uevent socket: %s", strerror(errno));
95         exit(1);
96     }
97 
98     if (setsockopt(uevent_sock, SOL_SOCKET, SO_RCVBUFFORCE, &uevent_sz,
99                    sizeof(uevent_sz)) < 0) {
100         LOGE("Unable to set uevent socket options: %s", strerror(errno));
101         exit(1);
102     }
103 
104     if (bind(uevent_sock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
105         LOGE("Unable to bind uevent socket: %s", strerror(errno));
106         exit(1);
107     }
108 
109     /*
110      * Bootstrap
111      */
112 
113     bootstrap = 1;
114     // Volume Manager
115     volmgr_bootstrap();
116 
117     // SD Card system
118     mmc_bootstrap();
119 
120     // USB Mass Storage
121     ums_bootstrap();
122 
123     // Switch
124     switch_bootstrap();
125 
126     bootstrap = 0;
127     /*
128      * Main loop
129      */
130     LOG_VOL("Bootstrapping complete");
131     while(1) {
132         fd_set read_fds;
133         struct timeval to;
134         int max = 0;
135         int rc = 0;
136 
137         to.tv_sec = (60 * 60);
138         to.tv_usec = 0;
139 
140         FD_ZERO(&read_fds);
141         FD_SET(door_sock, &read_fds);
142         if (door_sock > max)
143             max = door_sock;
144         FD_SET(uevent_sock, &read_fds);
145         if (uevent_sock > max)
146             max = uevent_sock;
147 
148         if (fw_sock != -1) {
149             FD_SET(fw_sock, &read_fds);
150             if (fw_sock > max)
151                 max = fw_sock;
152         }
153 
154         if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) {
155             LOGE("select() failed (%s)", strerror(errno));
156             sleep(1);
157             continue;
158         }
159 
160         if (!rc) {
161             continue;
162         }
163 
164         if (FD_ISSET(door_sock, &read_fds)) {
165             struct sockaddr addr;
166             socklen_t alen;
167 
168             alen = sizeof(addr);
169 
170             if (fw_sock != -1) {
171                 LOGE("Dropping duplicate framework connection");
172                 int tmp = accept(door_sock, &addr, &alen);
173                 close(tmp);
174                 continue;
175             }
176 
177             if ((fw_sock = accept(door_sock, &addr, &alen)) < 0) {
178                 LOGE("Unable to accept framework connection (%s)",
179                      strerror(errno));
180             }
181             LOG_VOL("Accepted connection from framework");
182             if ((rc = volmgr_send_states()) < 0) {
183                 LOGE("Unable to send volmgr status to framework (%d)", rc);
184             }
185         }
186 
187         if (FD_ISSET(fw_sock, &read_fds)) {
188             if ((rc = process_framework_command(fw_sock)) < 0) {
189                 if (rc == -ECONNRESET) {
190                     LOGE("Framework disconnected");
191                     close(fw_sock);
192                     fw_sock = -1;
193                 } else {
194                     LOGE("Error processing framework command (%s)",
195                          strerror(errno));
196                 }
197             }
198         }
199 
200         if (FD_ISSET(uevent_sock, &read_fds)) {
201             if ((rc = process_uevent_message(uevent_sock)) < 0) {
202                 LOGE("Error processing uevent msg (%s)", strerror(errno));
203             }
204         }
205     } // while
206 
207 }
208 
send_msg(char * message)209 int send_msg(char* message)
210 {
211     int result = -1;
212 
213     pthread_mutex_lock(&write_mutex);
214 
215 //    LOG_VOL("send_msg(%s):", message);
216 
217     if (fw_sock >= 0)
218         result = write(fw_sock, message, strlen(message) + 1);
219 
220     pthread_mutex_unlock(&write_mutex);
221 
222     return result;
223 }
224 
send_msg_with_data(char * message,char * data)225 int send_msg_with_data(char *message, char *data)
226 {
227     int result = -1;
228 
229     char* buffer = (char *)alloca(strlen(message) + strlen(data) + 1);
230     if (!buffer) {
231         LOGE("alloca failed in send_msg_with_data");
232         return -1;
233     }
234 
235     strcpy(buffer, message);
236     strcat(buffer, data);
237     return send_msg(buffer);
238 }
239