blob: b42467c049d335723d63111ca186fe6c932ed9b4 [file] [log] [blame]
San Mehatb78a32c2010-01-10 13:02:12 -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
Jeff Sharkey67b8c492017-09-21 17:08:43 -060017#define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
18
Paul Crowley14c8c072018-09-18 13:30:21 -070019#include <errno.h>
20#include <fcntl.h>
San Mehatb78a32c2010-01-10 13:02:12 -080021#include <stdio.h>
Olivier Bailly37dcda62010-11-16 10:41:53 -080022#include <stdlib.h>
San Mehatb78a32c2010-01-10 13:02:12 -080023#include <string.h>
Paul Crowley14c8c072018-09-18 13:30:21 -070024#include <unistd.h>
San Mehatb78a32c2010-01-10 13:02:12 -080025
San Mehatb78a32c2010-01-10 13:02:12 -080026#include <sys/ioctl.h>
27#include <sys/stat.h>
Paul Crowley14c8c072018-09-18 13:30:21 -070028#include <sys/types.h>
San Mehatb78a32c2010-01-10 13:02:12 -080029
San Mehatd9a4e352010-03-12 13:32:47 -080030#include <linux/kdev_t.h>
31
Jeff Sharkey11c2d382017-09-11 10:32:01 -060032#include <android-base/logging.h>
33#include <android-base/stringprintf.h>
Paul Crowley14c8c072018-09-18 13:30:21 -070034#include <android-base/strings.h>
Jeff Sharkey67b8c492017-09-21 17:08:43 -060035#include <utils/Trace.h>
San Mehatd9a4e352010-03-12 13:32:47 -080036
San Mehatb78a32c2010-01-10 13:02:12 -080037#include "Devmapper.h"
38
Peter Bohm092aa1c2011-04-01 12:35:25 +020039#define DEVMAPPER_BUFFER_SIZE 4096
40
Jeff Sharkey11c2d382017-09-11 10:32:01 -060041using android::base::StringPrintf;
42
43static const char* kVoldPrefix = "vold:";
44
Paul Crowley14c8c072018-09-18 13:30:21 -070045void Devmapper::ioctlInit(struct dm_ioctl* io, size_t dataSize, const char* name, unsigned flags) {
San Mehatb78a32c2010-01-10 13:02:12 -080046 memset(io, 0, dataSize);
47 io->data_size = dataSize;
48 io->data_start = sizeof(struct dm_ioctl);
49 io->version[0] = 4;
50 io->version[1] = 0;
51 io->version[2] = 0;
52 io->flags = flags;
San Mehatd9a4e352010-03-12 13:32:47 -080053 if (name) {
Chih-Wei Huang7929deb2013-02-10 22:57:14 +080054 size_t ret = strlcpy(io->name, name, sizeof(io->name));
Paul Crowley14c8c072018-09-18 13:30:21 -070055 if (ret >= sizeof(io->name)) abort();
San Mehatd9a4e352010-03-12 13:32:47 -080056 }
San Mehatb78a32c2010-01-10 13:02:12 -080057}
58
Paul Crowley14c8c072018-09-18 13:30:21 -070059int Devmapper::create(const char* name_raw, const char* loopFile, const char* key,
60 unsigned long numSectors, char* ubuffer, size_t len) {
Jeff Sharkey11c2d382017-09-11 10:32:01 -060061 auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
62 const char* name = name_string.c_str();
63
Paul Crowley14c8c072018-09-18 13:30:21 -070064 char* buffer = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
San Mehatb78a32c2010-01-10 13:02:12 -080065 if (!buffer) {
Jeff Sharkey3472e522017-10-06 18:02:53 -060066 PLOG(ERROR) << "Failed malloc";
San Mehatb78a32c2010-01-10 13:02:12 -080067 return -1;
68 }
69
70 int fd;
Jeff Sharkeyce6a9132015-04-08 21:07:21 -070071 if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
Jeff Sharkey3472e522017-10-06 18:02:53 -060072 PLOG(ERROR) << "Failed open";
San Mehatb78a32c2010-01-10 13:02:12 -080073 free(buffer);
74 return -1;
75 }
76
Paul Crowley14c8c072018-09-18 13:30:21 -070077 struct dm_ioctl* io = (struct dm_ioctl*)buffer;
78
San Mehatb78a32c2010-01-10 13:02:12 -080079 // Create the DM device
Peter Bohm092aa1c2011-04-01 12:35:25 +020080 ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
San Mehatb78a32c2010-01-10 13:02:12 -080081
82 if (ioctl(fd, DM_DEV_CREATE, io)) {
Jeff Sharkey3472e522017-10-06 18:02:53 -060083 PLOG(ERROR) << "Failed DM_DEV_CREATE";
San Mehatb78a32c2010-01-10 13:02:12 -080084 free(buffer);
85 close(fd);
86 return -1;
87 }
88
89 // Set the legacy geometry
Peter Bohm092aa1c2011-04-01 12:35:25 +020090 ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
San Mehatb78a32c2010-01-10 13:02:12 -080091
Paul Crowley14c8c072018-09-18 13:30:21 -070092 char* geoParams = buffer + sizeof(struct dm_ioctl);
San Mehatb78a32c2010-01-10 13:02:12 -080093 // bps=512 spc=8 res=32 nft=2 sec=8190 mid=0xf0 spt=63 hds=64 hid=0 bspf=8 rdcl=2 infs=1 bkbs=2
Jeff Sharkey32ebb732017-03-27 16:18:50 -060094 strlcpy(geoParams, "0 64 63 0", DEVMAPPER_BUFFER_SIZE - sizeof(struct dm_ioctl));
San Mehatb78a32c2010-01-10 13:02:12 -080095 geoParams += strlen(geoParams) + 1;
Paul Crowley14c8c072018-09-18 13:30:21 -070096 geoParams = (char*)_align(geoParams, 8);
San Mehatb78a32c2010-01-10 13:02:12 -080097 if (ioctl(fd, DM_DEV_SET_GEOMETRY, io)) {
Jeff Sharkey3472e522017-10-06 18:02:53 -060098 PLOG(ERROR) << "Failed DM_DEV_SET_GEOMETRY";
San Mehatb78a32c2010-01-10 13:02:12 -080099 free(buffer);
100 close(fd);
101 return -1;
102 }
103
104 // Retrieve the device number we were allocated
Peter Bohm092aa1c2011-04-01 12:35:25 +0200105 ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
San Mehatb78a32c2010-01-10 13:02:12 -0800106 if (ioctl(fd, DM_DEV_STATUS, io)) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600107 PLOG(ERROR) << "Failed DM_DEV_STATUS";
San Mehatb78a32c2010-01-10 13:02:12 -0800108 free(buffer);
109 close(fd);
110 return -1;
111 }
112
113 unsigned minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
San Mehatb78a32c2010-01-10 13:02:12 -0800114 snprintf(ubuffer, len, "/dev/block/dm-%u", minor);
115
116 // Load the table
Paul Crowley14c8c072018-09-18 13:30:21 -0700117 struct dm_target_spec* tgt;
118 tgt = (struct dm_target_spec*)&buffer[sizeof(struct dm_ioctl)];
San Mehatb78a32c2010-01-10 13:02:12 -0800119
Peter Bohm092aa1c2011-04-01 12:35:25 +0200120 ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, DM_STATUS_TABLE_FLAG);
San Mehatb78a32c2010-01-10 13:02:12 -0800121 io->target_count = 1;
122 tgt->status = 0;
San Mehatfcf24fe2010-03-03 12:37:32 -0800123
San Mehatb78a32c2010-01-10 13:02:12 -0800124 tgt->sector_start = 0;
San Mehat8b8f71b2010-01-11 09:17:25 -0800125 tgt->length = numSectors;
San Mehatfcf24fe2010-03-03 12:37:32 -0800126
Peter Bohm092aa1c2011-04-01 12:35:25 +0200127 strlcpy(tgt->target_type, "crypt", sizeof(tgt->target_type));
San Mehatb78a32c2010-01-10 13:02:12 -0800128
Paul Crowley14c8c072018-09-18 13:30:21 -0700129 char* cryptParams = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
Peter Bohm092aa1c2011-04-01 12:35:25 +0200130 snprintf(cryptParams,
Paul Crowley14c8c072018-09-18 13:30:21 -0700131 DEVMAPPER_BUFFER_SIZE - (sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec)),
132 "twofish %s 0 %s 0", key, loopFile);
San Mehatb78a32c2010-01-10 13:02:12 -0800133 cryptParams += strlen(cryptParams) + 1;
Paul Crowley14c8c072018-09-18 13:30:21 -0700134 cryptParams = (char*)_align(cryptParams, 8);
San Mehatb78a32c2010-01-10 13:02:12 -0800135 tgt->next = cryptParams - buffer;
136
137 if (ioctl(fd, DM_TABLE_LOAD, io)) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600138 PLOG(ERROR) << "Failed DM_TABLE_LOAD";
San Mehatb78a32c2010-01-10 13:02:12 -0800139 free(buffer);
140 close(fd);
141 return -1;
142 }
143
144 // Resume the new table
Peter Bohm092aa1c2011-04-01 12:35:25 +0200145 ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
San Mehatb78a32c2010-01-10 13:02:12 -0800146
147 if (ioctl(fd, DM_DEV_SUSPEND, io)) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600148 PLOG(ERROR) << "Failed DM_DEV_SUSPEND";
San Mehatb78a32c2010-01-10 13:02:12 -0800149 free(buffer);
150 close(fd);
151 return -1;
152 }
153
154 free(buffer);
155
San Mehat8c940ef2010-02-13 14:19:53 -0800156 close(fd);
San Mehatb78a32c2010-01-10 13:02:12 -0800157 return 0;
158}
159
Paul Crowley14c8c072018-09-18 13:30:21 -0700160int Devmapper::destroy(const char* name_raw) {
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600161 auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
162 const char* name = name_string.c_str();
163
Paul Crowley14c8c072018-09-18 13:30:21 -0700164 char* buffer = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
San Mehatb78a32c2010-01-10 13:02:12 -0800165 if (!buffer) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600166 PLOG(ERROR) << "Failed malloc";
San Mehatb78a32c2010-01-10 13:02:12 -0800167 return -1;
168 }
169
170 int fd;
Jeff Sharkeyce6a9132015-04-08 21:07:21 -0700171 if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600172 PLOG(ERROR) << "Failed open";
San Mehatb78a32c2010-01-10 13:02:12 -0800173 free(buffer);
174 return -1;
175 }
176
Paul Crowley14c8c072018-09-18 13:30:21 -0700177 struct dm_ioctl* io = (struct dm_ioctl*)buffer;
178
San Mehatb78a32c2010-01-10 13:02:12 -0800179 // Create the DM device
Peter Bohm092aa1c2011-04-01 12:35:25 +0200180 ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
San Mehatb78a32c2010-01-10 13:02:12 -0800181
182 if (ioctl(fd, DM_DEV_REMOVE, io)) {
San Mehat0586d542010-01-12 15:38:59 -0800183 if (errno != ENXIO) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600184 PLOG(ERROR) << "Failed DM_DEV_REMOVE";
San Mehat0586d542010-01-12 15:38:59 -0800185 }
San Mehatb78a32c2010-01-10 13:02:12 -0800186 free(buffer);
187 close(fd);
188 return -1;
189 }
190
191 free(buffer);
192 close(fd);
193 return 0;
194}
195
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600196int Devmapper::destroyAll() {
Jeff Sharkey67b8c492017-09-21 17:08:43 -0600197 ATRACE_NAME("Devmapper::destroyAll");
Paul Crowley14c8c072018-09-18 13:30:21 -0700198 char* buffer = (char*)malloc(1024 * 64);
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600199 if (!buffer) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600200 PLOG(ERROR) << "Failed malloc";
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600201 return -1;
202 }
203 memset(buffer, 0, (1024 * 64));
204
Paul Crowley14c8c072018-09-18 13:30:21 -0700205 char* buffer2 = (char*)malloc(DEVMAPPER_BUFFER_SIZE);
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600206 if (!buffer2) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600207 PLOG(ERROR) << "Failed malloc";
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600208 free(buffer);
209 return -1;
210 }
211
212 int fd;
213 if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600214 PLOG(ERROR) << "Failed open";
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600215 free(buffer);
216 free(buffer2);
217 return -1;
218 }
219
Paul Crowley14c8c072018-09-18 13:30:21 -0700220 struct dm_ioctl* io = (struct dm_ioctl*)buffer;
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600221 ioctlInit(io, (1024 * 64), NULL, 0);
222
223 if (ioctl(fd, DM_LIST_DEVICES, io)) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600224 PLOG(ERROR) << "Failed DM_LIST_DEVICES";
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600225 free(buffer);
226 free(buffer2);
227 close(fd);
228 return -1;
229 }
230
Paul Crowley14c8c072018-09-18 13:30:21 -0700231 struct dm_name_list* n = (struct dm_name_list*)(((char*)buffer) + io->data_start);
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600232 if (!n->dev) {
233 free(buffer);
234 free(buffer2);
235 close(fd);
236 return 0;
237 }
238
239 unsigned nxt = 0;
240 do {
Paul Crowley14c8c072018-09-18 13:30:21 -0700241 n = (struct dm_name_list*)(((char*)n) + nxt);
Jeff Sharkey3472e522017-10-06 18:02:53 -0600242 auto name = std::string(n->name);
243 if (android::base::StartsWith(name, kVoldPrefix)) {
244 LOG(DEBUG) << "Tearing down stale dm device named " << name;
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600245
246 memset(buffer2, 0, DEVMAPPER_BUFFER_SIZE);
Paul Crowley14c8c072018-09-18 13:30:21 -0700247 struct dm_ioctl* io2 = (struct dm_ioctl*)buffer2;
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600248 ioctlInit(io2, DEVMAPPER_BUFFER_SIZE, n->name, 0);
249 if (ioctl(fd, DM_DEV_REMOVE, io2)) {
250 if (errno != ENXIO) {
Jeff Sharkey3472e522017-10-06 18:02:53 -0600251 PLOG(WARNING) << "Failed to destroy dm device named " << name;
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600252 }
253 }
254 } else {
Sudheer Shanka4b6ca4e2018-09-21 10:54:54 -0700255 LOG(DEBUG) << "Found unmanaged dm device named " << name;
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600256 }
257 nxt = n->next;
258 } while (nxt);
259
260 free(buffer);
261 free(buffer2);
262 close(fd);
263 return 0;
264}
265
Paul Crowley14c8c072018-09-18 13:30:21 -0700266void* Devmapper::_align(void* ptr, unsigned int a) {
267 unsigned long agn = --a;
San Mehatb78a32c2010-01-10 13:02:12 -0800268
Paul Crowley14c8c072018-09-18 13:30:21 -0700269 return (void*)(((unsigned long)ptr + agn) & ~agn);
San Mehatb78a32c2010-01-10 13:02:12 -0800270}