1b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat/* 2b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * Copyright (C) 2008 The Android Open Source Project 3b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * 4b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * you may not use this file except in compliance with the License. 6b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * You may obtain a copy of the License at 7b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * 8b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * 10b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * Unless required by applicable law or agreed to in writing, software 11b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * See the License for the specific language governing permissions and 14b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat * limitations under the License. 15b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat */ 16b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 17b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <stdio.h> 1837dcda68d334f70e1f7f69a9817def65fe3ee717Olivier Bailly#include <stdlib.h> 19b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <fcntl.h> 20b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <unistd.h> 21b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <errno.h> 22b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <string.h> 23092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm#include <stdlib.h> 24b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 25b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <sys/types.h> 26b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <sys/ioctl.h> 27b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <sys/stat.h> 28b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 29d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#include <linux/kdev_t.h> 30d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 31b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#define LOG_TAG "Vold" 32b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 33b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include <cutils/log.h> 34b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 35d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat#include <sysutils/SocketClient.h> 36d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 37b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include "Devmapper.h" 38b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 39092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm#define DEVMAPPER_BUFFER_SIZE 4096 40092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm 41d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehatint Devmapper::dumpState(SocketClient *c) { 42d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 43d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat char *buffer = (char *) malloc(1024 * 64); 44d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!buffer) { 4597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error allocating memory (%s)", strerror(errno)); 46d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 47d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 48d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat memset(buffer, 0, (1024 * 64)); 49d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 50092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm char *buffer2 = (char *) malloc(DEVMAPPER_BUFFER_SIZE); 51d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!buffer2) { 5297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error allocating memory (%s)", strerror(errno)); 53d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer); 54d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 55d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 56d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 57d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat int fd; 58d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { 5997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error opening devmapper (%s)", strerror(errno)); 60d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer); 61d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer2); 62d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 63d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 64d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 65d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat struct dm_ioctl *io = (struct dm_ioctl *) buffer; 66d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat ioctlInit(io, (1024 * 64), NULL, 0); 67d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 68d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (ioctl(fd, DM_LIST_DEVICES, io)) { 6997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("DM_LIST_DEVICES ioctl failed (%s)", strerror(errno)); 70d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer); 71d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer2); 72d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat close(fd); 73d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 74d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 75d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 76d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat struct dm_name_list *n = (struct dm_name_list *) (((char *) buffer) + io->data_start); 77d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!n->dev) { 78d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer); 79d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer2); 80d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat close(fd); 81d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return 0; 82d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 83d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 84d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat unsigned nxt = 0; 85d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat do { 86d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat n = (struct dm_name_list *) (((char *) n) + nxt); 87d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 88092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm memset(buffer2, 0, DEVMAPPER_BUFFER_SIZE); 89d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat struct dm_ioctl *io2 = (struct dm_ioctl *) buffer2; 90092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ioctlInit(io2, DEVMAPPER_BUFFER_SIZE, n->name, 0); 91d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (ioctl(fd, DM_DEV_STATUS, io2)) { 92d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (errno != ENXIO) { 9397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("DM_DEV_STATUS ioctl failed (%s)", strerror(errno)); 94d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 95d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat io2 = NULL; 96d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 97d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 98d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat char *tmp; 99d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!io2) { 100d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat asprintf(&tmp, "%s %llu:%llu (no status available)", n->name, MAJOR(n->dev), MINOR(n->dev)); 101d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } else { 102d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat asprintf(&tmp, "%s %llu:%llu %d %d 0x%.8x %llu:%llu", n->name, MAJOR(n->dev), 103d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat MINOR(n->dev), io2->target_count, io2->open_count, io2->flags, MAJOR(io2->dev), 104d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat MINOR(io2->dev)); 105d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 106d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat c->sendMsg(0, tmp, false); 107d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(tmp); 108d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat nxt = n->next; 109d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } while (nxt); 110d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 111d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer); 112d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat free(buffer2); 113d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat close(fd); 114d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return 0; 115d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat} 116d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 117b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatvoid Devmapper::ioctlInit(struct dm_ioctl *io, size_t dataSize, 118b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat const char *name, unsigned flags) { 119b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat memset(io, 0, dataSize); 120b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat io->data_size = dataSize; 121b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat io->data_start = sizeof(struct dm_ioctl); 122b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat io->version[0] = 4; 123b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat io->version[1] = 0; 124b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat io->version[2] = 0; 125b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat io->flags = flags; 126d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (name) { 127092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm int ret = strlcpy(io->name, name, sizeof(io->name)); 128092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm if (ret >= sizeof(io->name)) 129092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm abort(); 130d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 131b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 132b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 133b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatint Devmapper::lookupActive(const char *name, char *ubuffer, size_t len) { 134092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE); 135b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (!buffer) { 13697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error allocating memory (%s)", strerror(errno)); 137b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 138b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 139b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 140b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat int fd; 141b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { 14297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error opening devmapper (%s)", strerror(errno)); 143b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 144b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 145b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 146b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 147b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat struct dm_ioctl *io = (struct dm_ioctl *) buffer; 148b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 149092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); 150b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (ioctl(fd, DM_DEV_STATUS, io)) { 1518b8f71b1d760411279f3b07a5c97709f052c689eSan Mehat if (errno != ENXIO) { 15297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("DM_DEV_STATUS ioctl failed for lookup (%s)", strerror(errno)); 153b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 154b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 155b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 156b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 157b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 158b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 159b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 160b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat unsigned minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); 161b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 162b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat snprintf(ubuffer, len, "/dev/block/dm-%u", minor); 163b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return 0; 164b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 165b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 1668b8f71b1d760411279f3b07a5c97709f052c689eSan Mehatint Devmapper::create(const char *name, const char *loopFile, const char *key, 1678b8f71b1d760411279f3b07a5c97709f052c689eSan Mehat unsigned int numSectors, char *ubuffer, size_t len) { 168092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE); 169b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (!buffer) { 17097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error allocating memory (%s)", strerror(errno)); 171b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 172b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 173b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 174b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat int fd; 175b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { 17697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error opening devmapper (%s)", strerror(errno)); 177b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 178b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 179b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 180b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 181b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat struct dm_ioctl *io = (struct dm_ioctl *) buffer; 182b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 183b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat // Create the DM device 184092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); 185b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 186b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (ioctl(fd, DM_DEV_CREATE, io)) { 18797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error creating device mapping (%s)", strerror(errno)); 188b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 189b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 190b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 191b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 192b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 193b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat // Set the legacy geometry 194092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); 195b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 196b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat char *geoParams = buffer + sizeof(struct dm_ioctl); 197b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat // 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 198b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat strcpy(geoParams, "0 64 63 0"); 199b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat geoParams += strlen(geoParams) + 1; 200b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat geoParams = (char *) _align(geoParams, 8); 201b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (ioctl(fd, DM_DEV_SET_GEOMETRY, io)) { 20297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error setting device geometry (%s)", strerror(errno)); 203b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 204b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 205b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 206b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 207b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 208b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat // Retrieve the device number we were allocated 209092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); 210b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (ioctl(fd, DM_DEV_STATUS, io)) { 21197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error retrieving devmapper status (%s)", strerror(errno)); 212b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 213b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 214b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 215b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 216b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 217b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat unsigned minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); 218b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat snprintf(ubuffer, len, "/dev/block/dm-%u", minor); 219b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 220b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat // Load the table 221b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat struct dm_target_spec *tgt; 222b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; 223b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 224092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, DM_STATUS_TABLE_FLAG); 225b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat io->target_count = 1; 226b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat tgt->status = 0; 227fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 228b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat tgt->sector_start = 0; 2298b8f71b1d760411279f3b07a5c97709f052c689eSan Mehat tgt->length = numSectors; 230fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 231092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm strlcpy(tgt->target_type, "crypt", sizeof(tgt->target_type)); 232b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 233b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat char *cryptParams = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); 234092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm snprintf(cryptParams, 235092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm DEVMAPPER_BUFFER_SIZE - (sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec)), 236092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm "twofish %s 0 %s 0", key, loopFile); 237b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat cryptParams += strlen(cryptParams) + 1; 238b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat cryptParams = (char *) _align(cryptParams, 8); 239b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat tgt->next = cryptParams - buffer; 240b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 241b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (ioctl(fd, DM_TABLE_LOAD, io)) { 24297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error loading mapping table (%s)", strerror(errno)); 243b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 244b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 245b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 246b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 247b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 248b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat // Resume the new table 249092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); 250b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 251b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (ioctl(fd, DM_DEV_SUSPEND, io)) { 25297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error Resuming (%s)", strerror(errno)); 253b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 254b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 255b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 256b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 257b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 258b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 259b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 2608c940ef7dbd423cadc92982b44a65ed1014389e2San Mehat close(fd); 261b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return 0; 262b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 263b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 264b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatint Devmapper::destroy(const char *name) { 265092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE); 266b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (!buffer) { 26797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error allocating memory (%s)", strerror(errno)); 268b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 269b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 270b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 271b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat int fd; 272b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { 27397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error opening devmapper (%s)", strerror(errno)); 274b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 275b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 276b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 277b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 278b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat struct dm_ioctl *io = (struct dm_ioctl *) buffer; 279b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 280b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat // Create the DM device 281092aa1c585fedd9e169eece41b8a471f1739908aPeter Bohm ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0); 282b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 283b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (ioctl(fd, DM_DEV_REMOVE, io)) { 2840586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat if (errno != ENXIO) { 28597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error destroying device mapping (%s)", strerror(errno)); 2860586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat } 287b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 288b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 289b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 290b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 291b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 292b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat free(buffer); 293b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat close(fd); 294b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return 0; 295b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 296b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 297b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehatvoid *Devmapper::_align(void *ptr, unsigned int a) 298b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat{ 299b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat register unsigned long agn = --a; 300b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 301b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return (void *) (((unsigned long) ptr + agn) & ~agn); 302b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 303