blob: 325b0d3fb7e38c611a5e20434a06d9305c23f6e7 [file] [log] [blame]
San Mehata19b2502010-01-06 10:33:53 -08001/*
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#include <stdio.h>
Olivier Bailly37dcda62010-11-16 10:41:53 -080018#include <stdlib.h>
San Mehata19b2502010-01-06 10:33:53 -080019#include <fcntl.h>
20#include <unistd.h>
21#include <errno.h>
22#include <string.h>
23
Kenny Root344ca102012-04-03 17:23:01 -070024#include <sys/mount.h>
San Mehat8da6bcb2010-01-09 12:24:05 -080025#include <sys/types.h>
26#include <sys/stat.h>
Olivier Bailly37dcda62010-11-16 10:41:53 -080027#include <sys/ioctl.h>
San Mehat8da6bcb2010-01-09 12:24:05 -080028
San Mehatd9a4e352010-03-12 13:32:47 -080029#include <linux/kdev_t.h>
30
San Mehata19b2502010-01-06 10:33:53 -080031#define LOG_TAG "Vold"
32
33#include <cutils/log.h>
34
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -060035#include <android-base/logging.h>
36#include <android-base/stringprintf.h>
37#include <android-base/unique_fd.h>
38
San Mehatd9a4e352010-03-12 13:32:47 -080039#include <sysutils/SocketClient.h>
San Mehata19b2502010-01-06 10:33:53 -080040#include "Loop.h"
Kenny Root344ca102012-04-03 17:23:01 -070041#include "Asec.h"
Hiroaki Miyazawa14eab552015-02-04 13:29:15 +090042#include "VoldUtil.h"
Stephen Smalley684e6622014-09-30 10:29:24 -040043#include "sehandle.h"
San Mehata19b2502010-01-06 10:33:53 -080044
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -060045using android::base::StringPrintf;
46using android::base::unique_fd;
47
Jeff Sharkey11c2d382017-09-11 10:32:01 -060048static const char* kVoldPrefix = "vold:";
49
San Mehatd9a4e352010-03-12 13:32:47 -080050int Loop::dumpState(SocketClient *c) {
51 int i;
52 int fd;
53 char filename[256];
54
55 for (i = 0; i < LOOP_MAX; i++) {
Kenny Root508c0e12010-07-12 09:59:49 -070056 struct loop_info64 li;
San Mehatd9a4e352010-03-12 13:32:47 -080057 int rc;
58
George Burgess IV605d7ae2016-02-29 13:39:17 -080059 snprintf(filename, sizeof(filename), "/dev/block/loop%d", i);
San Mehatd9a4e352010-03-12 13:32:47 -080060
Jeff Sharkeyce6a9132015-04-08 21:07:21 -070061 if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
San Mehatd9a4e352010-03-12 13:32:47 -080062 if (errno != ENOENT) {
San Mehat97ac40e2010-03-24 10:24:19 -070063 SLOGE("Unable to open %s (%s)", filename, strerror(errno));
San Mehatd9a4e352010-03-12 13:32:47 -080064 } else {
65 continue;
66 }
67 return -1;
68 }
69
Kenny Root508c0e12010-07-12 09:59:49 -070070 rc = ioctl(fd, LOOP_GET_STATUS64, &li);
San Mehatd9a4e352010-03-12 13:32:47 -080071 close(fd);
72 if (rc < 0 && errno == ENXIO) {
73 continue;
74 }
75
76 if (rc < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -070077 SLOGE("Unable to get loop status for %s (%s)", filename,
San Mehatd9a4e352010-03-12 13:32:47 -080078 strerror(errno));
79 return -1;
80 }
81 char *tmp = NULL;
Kenny Root508c0e12010-07-12 09:59:49 -070082 asprintf(&tmp, "%s %d %lld:%lld %llu %lld:%lld %lld 0x%x {%s} {%s}", filename, li.lo_number,
San Mehatd9a4e352010-03-12 13:32:47 -080083 MAJOR(li.lo_device), MINOR(li.lo_device), li.lo_inode, MAJOR(li.lo_rdevice),
Kenny Root508c0e12010-07-12 09:59:49 -070084 MINOR(li.lo_rdevice), li.lo_offset, li.lo_flags, li.lo_crypt_name,
85 li.lo_file_name);
San Mehatd9a4e352010-03-12 13:32:47 -080086 c->sendMsg(0, tmp, false);
87 free(tmp);
88 }
89 return 0;
90}
91
Jeff Sharkey11c2d382017-09-11 10:32:01 -060092int Loop::lookupActive(const char *id_raw, char *buffer, size_t len) {
93 auto id_string = StringPrintf("%s%s", kVoldPrefix, id_raw);
94 const char* id = id_string.c_str();
95
San Mehata19b2502010-01-06 10:33:53 -080096 int i;
97 int fd;
98 char filename[256];
99
100 memset(buffer, 0, len);
101
102 for (i = 0; i < LOOP_MAX; i++) {
Kenny Root508c0e12010-07-12 09:59:49 -0700103 struct loop_info64 li;
San Mehata19b2502010-01-06 10:33:53 -0800104 int rc;
105
George Burgess IV605d7ae2016-02-29 13:39:17 -0800106 snprintf(filename, sizeof(filename), "/dev/block/loop%d", i);
San Mehata19b2502010-01-06 10:33:53 -0800107
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700108 if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
San Mehatb78a32c2010-01-10 13:02:12 -0800109 if (errno != ENOENT) {
San Mehat97ac40e2010-03-24 10:24:19 -0700110 SLOGE("Unable to open %s (%s)", filename, strerror(errno));
San Mehatd9a4e352010-03-12 13:32:47 -0800111 } else {
112 continue;
San Mehatb78a32c2010-01-10 13:02:12 -0800113 }
San Mehata19b2502010-01-06 10:33:53 -0800114 return -1;
115 }
116
Kenny Root508c0e12010-07-12 09:59:49 -0700117 rc = ioctl(fd, LOOP_GET_STATUS64, &li);
San Mehata19b2502010-01-06 10:33:53 -0800118 if (rc < 0 && errno == ENXIO) {
tao.peia1038a92015-08-17 20:18:49 +0800119 close(fd);
San Mehata19b2502010-01-06 10:33:53 -0800120 continue;
San Mehata19b2502010-01-06 10:33:53 -0800121 }
tao.peia1038a92015-08-17 20:18:49 +0800122 close(fd);
San Mehata19b2502010-01-06 10:33:53 -0800123
124 if (rc < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -0700125 SLOGE("Unable to get loop status for %s (%s)", filename,
San Mehata19b2502010-01-06 10:33:53 -0800126 strerror(errno));
127 return -1;
128 }
Kenny Root508c0e12010-07-12 09:59:49 -0700129 if (!strncmp((const char*) li.lo_crypt_name, id, LO_NAME_SIZE)) {
San Mehata19b2502010-01-06 10:33:53 -0800130 break;
131 }
132 }
133
134 if (i == LOOP_MAX) {
135 errno = ENOENT;
136 return -1;
137 }
Henrik Baard21522662015-02-06 09:24:14 +0100138 strlcpy(buffer, filename, len);
San Mehata19b2502010-01-06 10:33:53 -0800139 return 0;
140}
141
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600142int Loop::create(const char *id_raw, const char *loopFile, char *loopDeviceBuffer, size_t len) {
143 auto id_string = StringPrintf("%s%s", kVoldPrefix, id_raw);
144 const char* id = id_string.c_str();
145
San Mehata19b2502010-01-06 10:33:53 -0800146 int i;
147 int fd;
148 char filename[256];
149
San Mehata19b2502010-01-06 10:33:53 -0800150 for (i = 0; i < LOOP_MAX; i++) {
Kenny Root7c165022011-02-01 15:58:25 -0800151 struct loop_info64 li;
San Mehata19b2502010-01-06 10:33:53 -0800152 int rc;
Stephen Smalley684e6622014-09-30 10:29:24 -0400153 char *secontext = NULL;
San Mehata19b2502010-01-06 10:33:53 -0800154
George Burgess IV605d7ae2016-02-29 13:39:17 -0800155 snprintf(filename, sizeof(filename), "/dev/block/loop%d", i);
San Mehata19b2502010-01-06 10:33:53 -0800156
San Mehat8da6bcb2010-01-09 12:24:05 -0800157 /*
158 * The kernel starts us off with 8 loop nodes, but more
159 * are created on-demand if needed.
160 */
161 mode_t mode = 0660 | S_IFBLK;
San Mehatb78a32c2010-01-10 13:02:12 -0800162 unsigned int dev = (0xff & i) | ((i << 12) & 0xfff00000) | (7 << 8);
Stephen Smalley684e6622014-09-30 10:29:24 -0400163
164 if (sehandle) {
165 rc = selabel_lookup(sehandle, &secontext, filename, S_IFBLK);
166 if (rc == 0)
167 setfscreatecon(secontext);
168 }
169
San Mehat8da6bcb2010-01-09 12:24:05 -0800170 if (mknod(filename, mode, dev) < 0) {
171 if (errno != EEXIST) {
Stephen Smalley684e6622014-09-30 10:29:24 -0400172 int sverrno = errno;
San Mehat97ac40e2010-03-24 10:24:19 -0700173 SLOGE("Error creating loop device node (%s)", strerror(errno));
Stephen Smalley684e6622014-09-30 10:29:24 -0400174 if (secontext) {
175 freecon(secontext);
176 setfscreatecon(NULL);
177 }
178 errno = sverrno;
San Mehat8da6bcb2010-01-09 12:24:05 -0800179 return -1;
180 }
181 }
Stephen Smalley684e6622014-09-30 10:29:24 -0400182 if (secontext) {
183 freecon(secontext);
184 setfscreatecon(NULL);
185 }
San Mehat8da6bcb2010-01-09 12:24:05 -0800186
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700187 if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -0700188 SLOGE("Unable to open %s (%s)", filename, strerror(errno));
San Mehata19b2502010-01-06 10:33:53 -0800189 return -1;
190 }
191
Kenny Root7c165022011-02-01 15:58:25 -0800192 rc = ioctl(fd, LOOP_GET_STATUS64, &li);
San Mehata19b2502010-01-06 10:33:53 -0800193 if (rc < 0 && errno == ENXIO)
194 break;
195
San Mehat8da6bcb2010-01-09 12:24:05 -0800196 close(fd);
197
San Mehata19b2502010-01-06 10:33:53 -0800198 if (rc < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -0700199 SLOGE("Unable to get loop status for %s (%s)", filename,
San Mehata19b2502010-01-06 10:33:53 -0800200 strerror(errno));
201 return -1;
202 }
203 }
204
205 if (i == LOOP_MAX) {
San Mehat97ac40e2010-03-24 10:24:19 -0700206 SLOGE("Exhausted all loop devices");
San Mehata19b2502010-01-06 10:33:53 -0800207 errno = ENOSPC;
208 return -1;
209 }
San Mehata19b2502010-01-06 10:33:53 -0800210
Henrik Baard21522662015-02-06 09:24:14 +0100211 strlcpy(loopDeviceBuffer, filename, len);
San Mehat8da6bcb2010-01-09 12:24:05 -0800212
San Mehata19b2502010-01-06 10:33:53 -0800213 int file_fd;
214
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700215 if ((file_fd = open(loopFile, O_RDWR | O_CLOEXEC)) < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -0700216 SLOGE("Unable to open %s (%s)", loopFile, strerror(errno));
San Mehata19b2502010-01-06 10:33:53 -0800217 close(fd);
218 return -1;
219 }
220
221 if (ioctl(fd, LOOP_SET_FD, file_fd) < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -0700222 SLOGE("Error setting up loopback interface (%s)", strerror(errno));
San Mehata19b2502010-01-06 10:33:53 -0800223 close(file_fd);
224 close(fd);
225 return -1;
226 }
227
Kenny Root508c0e12010-07-12 09:59:49 -0700228 struct loop_info64 li;
San Mehata19b2502010-01-06 10:33:53 -0800229
230 memset(&li, 0, sizeof(li));
Peter Bohm092aa1c2011-04-01 12:35:25 +0200231 strlcpy((char*) li.lo_crypt_name, id, LO_NAME_SIZE);
232 strlcpy((char*) li.lo_file_name, loopFile, LO_NAME_SIZE);
San Mehata19b2502010-01-06 10:33:53 -0800233
Kenny Root508c0e12010-07-12 09:59:49 -0700234 if (ioctl(fd, LOOP_SET_STATUS64, &li) < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -0700235 SLOGE("Error setting loopback status (%s)", strerror(errno));
San Mehata19b2502010-01-06 10:33:53 -0800236 close(file_fd);
237 close(fd);
238 return -1;
239 }
240
241 close(fd);
242 close(file_fd);
243
244 return 0;
245}
246
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -0600247int Loop::create(const std::string& target, std::string& out_device) {
Jeff Sharkeyfd3dc3c2017-03-27 10:49:21 -0600248 unique_fd ctl_fd(open("/dev/loop-control", O_RDWR | O_CLOEXEC));
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -0600249 if (ctl_fd.get() == -1) {
250 PLOG(ERROR) << "Failed to open loop-control";
251 return -errno;
252 }
253
254 int num = ioctl(ctl_fd.get(), LOOP_CTL_GET_FREE);
255 if (num == -1) {
256 PLOG(ERROR) << "Failed LOOP_CTL_GET_FREE";
257 return -errno;
258 }
259
260 out_device = StringPrintf("/dev/block/loop%d", num);
261
Jeff Sharkeyfd3dc3c2017-03-27 10:49:21 -0600262 unique_fd target_fd(open(target.c_str(), O_RDWR | O_CLOEXEC));
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -0600263 if (target_fd.get() == -1) {
264 PLOG(ERROR) << "Failed to open " << target;
265 return -errno;
266 }
Jeff Sharkeyfd3dc3c2017-03-27 10:49:21 -0600267 unique_fd device_fd(open(out_device.c_str(), O_RDWR | O_CLOEXEC));
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -0600268 if (device_fd.get() == -1) {
269 PLOG(ERROR) << "Failed to open " << out_device;
270 return -errno;
271 }
272
273 if (ioctl(device_fd.get(), LOOP_SET_FD, target_fd.get()) == -1) {
274 PLOG(ERROR) << "Failed to LOOP_SET_FD";
275 return -errno;
276 }
277
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600278 struct loop_info64 li;
279 memset(&li, 0, sizeof(li));
280 strlcpy((char*) li.lo_crypt_name, kVoldPrefix, LO_NAME_SIZE);
281 if (ioctl(device_fd.get(), LOOP_SET_STATUS64, &li) == -1) {
282 PLOG(ERROR) << "Failed to LOOP_SET_STATUS64";
283 return -errno;
284 }
285
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -0600286 return 0;
287}
288
San Mehata19b2502010-01-06 10:33:53 -0800289int Loop::destroyByDevice(const char *loopDevice) {
290 int device_fd;
291
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700292 device_fd = open(loopDevice, O_RDONLY | O_CLOEXEC);
San Mehata19b2502010-01-06 10:33:53 -0800293 if (device_fd < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -0700294 SLOGE("Failed to open loop (%d)", errno);
San Mehata19b2502010-01-06 10:33:53 -0800295 return -1;
296 }
297
298 if (ioctl(device_fd, LOOP_CLR_FD, 0) < 0) {
San Mehat97ac40e2010-03-24 10:24:19 -0700299 SLOGE("Failed to destroy loop (%d)", errno);
San Mehata19b2502010-01-06 10:33:53 -0800300 close(device_fd);
301 return -1;
302 }
303
304 close(device_fd);
305 return 0;
306}
307
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600308int Loop::destroyAll() {
309 for (int i = 0; i < LOOP_MAX; i++) {
310 auto path = StringPrintf("/dev/block/loop%d", i);
311
312 unique_fd fd(open(path.c_str(), O_RDWR | O_CLOEXEC));
313 if (fd.get() == -1) {
314 if (errno != ENOENT) {
315 PLOG(WARNING) << "Failed to open " << path;
316 }
317 continue;
318 }
319
320 struct loop_info64 li;
321 if (ioctl(fd.get(), LOOP_GET_STATUS64, &li) < 0) {
322 PLOG(WARNING) << "Failed to LOOP_GET_STATUS64 " << path;
323 continue;
324 }
325
326 char* id = (char*) li.lo_crypt_name;
327 if (strncmp(id, kVoldPrefix, strlen(kVoldPrefix)) == 0) {
328 LOG(DEBUG) << "Tearing down stale loop device at " << path << " named " << id;
329
330 if (ioctl(fd.get(), LOOP_CLR_FD, 0) < 0) {
331 PLOG(WARNING) << "Failed to LOOP_CLR_FD " << path;
332 }
333 } else {
334 LOG(VERBOSE) << "Found unmanaged loop device at " << path << " named " << id;
335 }
336 }
337 return 0;
San Mehata19b2502010-01-06 10:33:53 -0800338}
339
Mateusz Nowaka4f48d02015-08-03 18:06:39 +0200340int Loop::createImageFile(const char *file, unsigned long numSectors) {
Jeff Sharkeyfd3dc3c2017-03-27 10:49:21 -0600341 unique_fd fd(open(file, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 0600));
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -0600342 if (fd.get() == -1) {
343 PLOG(ERROR) << "Failed to create image " << file;
Jeff Sharkeyfd3dc3c2017-03-27 10:49:21 -0600344 return -errno;
San Mehata19b2502010-01-06 10:33:53 -0800345 }
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -0600346 if (fallocate(fd.get(), 0, 0, numSectors * 512) == -1) {
347 PLOG(WARNING) << "Failed to fallocate; falling back to ftruncate";
348 if (ftruncate(fd, numSectors * 512) == -1) {
349 PLOG(ERROR) << "Failed to ftruncate";
Jeff Sharkeyfd3dc3c2017-03-27 10:49:21 -0600350 return -errno;
Jeff Sharkeyfa1c6772017-03-25 22:49:13 -0600351 }
352 }
Jeff Sharkeyfd3dc3c2017-03-27 10:49:21 -0600353 return 0;
San Mehata19b2502010-01-06 10:33:53 -0800354}
Kenny Root344ca102012-04-03 17:23:01 -0700355
Mateusz Nowaka4f48d02015-08-03 18:06:39 +0200356int Loop::resizeImageFile(const char *file, unsigned long numSectors) {
Daniel Rosenbergfcd34a02014-05-22 11:23:56 -0700357 int fd;
358
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700359 if ((fd = open(file, O_RDWR | O_CLOEXEC)) < 0) {
Daniel Rosenbergfcd34a02014-05-22 11:23:56 -0700360 SLOGE("Error opening imagefile (%s)", strerror(errno));
361 return -1;
362 }
363
Mateusz Nowaka4f48d02015-08-03 18:06:39 +0200364 SLOGD("Attempting to increase size of %s to %lu sectors.", file, numSectors);
Daniel Rosenbergfcd34a02014-05-22 11:23:56 -0700365
366 if (fallocate(fd, 0, 0, numSectors * 512)) {
Jeff Sharkey43ed1232014-08-22 12:29:05 -0700367 if (errno == ENOSYS || errno == ENOTSUP) {
Daniel Rosenbergfcd34a02014-05-22 11:23:56 -0700368 SLOGW("fallocate not found. Falling back to ftruncate.");
369 if (ftruncate(fd, numSectors * 512) < 0) {
370 SLOGE("Error truncating imagefile (%s)", strerror(errno));
371 close(fd);
372 return -1;
373 }
374 } else {
375 SLOGE("Error allocating space (%s)", strerror(errno));
376 close(fd);
377 return -1;
378 }
379 }
380 close(fd);
381 return 0;
382}
383
Hiroaki Miyazawa14eab552015-02-04 13:29:15 +0900384int Loop::lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigned long *nr_sec) {
Kenny Root344ca102012-04-03 17:23:01 -0700385 int fd;
386 struct asec_superblock buffer;
387
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700388 if ((fd = open(loopDevice, O_RDONLY | O_CLOEXEC)) < 0) {
Kenny Root344ca102012-04-03 17:23:01 -0700389 SLOGE("Failed to open loopdevice (%s)", strerror(errno));
390 destroyByDevice(loopDevice);
391 return -1;
392 }
393
Hiroaki Miyazawa14eab552015-02-04 13:29:15 +0900394 get_blkdev_size(fd, nr_sec);
395 if (*nr_sec == 0) {
Kenny Root344ca102012-04-03 17:23:01 -0700396 SLOGE("Failed to get loop size (%s)", strerror(errno));
397 destroyByDevice(loopDevice);
398 close(fd);
399 return -1;
400 }
401
402 /*
403 * Try to read superblock.
404 */
405 memset(&buffer, 0, sizeof(struct asec_superblock));
406 if (lseek(fd, ((*nr_sec - 1) * 512), SEEK_SET) < 0) {
407 SLOGE("lseek failed (%s)", strerror(errno));
408 close(fd);
409 destroyByDevice(loopDevice);
410 return -1;
411 }
412 if (read(fd, &buffer, sizeof(struct asec_superblock)) != sizeof(struct asec_superblock)) {
413 SLOGE("superblock read failed (%s)", strerror(errno));
414 close(fd);
415 destroyByDevice(loopDevice);
416 return -1;
417 }
418 close(fd);
419
420 /*
421 * Superblock successfully read. Copy to caller's struct.
422 */
423 memcpy(sb, &buffer, sizeof(struct asec_superblock));
424 return 0;
425}