1/* 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> 18#include <stdlib.h> 19#include <fcntl.h> 20#include <unistd.h> 21#include <errno.h> 22#include <string.h> 23 24#include <sys/mount.h> 25#include <sys/types.h> 26#include <sys/stat.h> 27#include <sys/ioctl.h> 28 29#include <linux/kdev_t.h> 30 31#define LOG_TAG "Vold" 32 33#include <cutils/log.h> 34 35#include <sysutils/SocketClient.h> 36#include "Loop.h" 37#include "Asec.h" 38#include "VoldUtil.h" 39#include "sehandle.h" 40 41int Loop::dumpState(SocketClient *c) { 42 int i; 43 int fd; 44 char filename[256]; 45 46 for (i = 0; i < LOOP_MAX; i++) { 47 struct loop_info64 li; 48 int rc; 49 50 sprintf(filename, "/dev/block/loop%d", i); 51 52 if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) { 53 if (errno != ENOENT) { 54 SLOGE("Unable to open %s (%s)", filename, strerror(errno)); 55 } else { 56 continue; 57 } 58 return -1; 59 } 60 61 rc = ioctl(fd, LOOP_GET_STATUS64, &li); 62 close(fd); 63 if (rc < 0 && errno == ENXIO) { 64 continue; 65 } 66 67 if (rc < 0) { 68 SLOGE("Unable to get loop status for %s (%s)", filename, 69 strerror(errno)); 70 return -1; 71 } 72 char *tmp = NULL; 73 asprintf(&tmp, "%s %d %lld:%lld %llu %lld:%lld %lld 0x%x {%s} {%s}", filename, li.lo_number, 74 MAJOR(li.lo_device), MINOR(li.lo_device), li.lo_inode, MAJOR(li.lo_rdevice), 75 MINOR(li.lo_rdevice), li.lo_offset, li.lo_flags, li.lo_crypt_name, 76 li.lo_file_name); 77 c->sendMsg(0, tmp, false); 78 free(tmp); 79 } 80 return 0; 81} 82 83int Loop::lookupActive(const char *id, char *buffer, size_t len) { 84 int i; 85 int fd; 86 char filename[256]; 87 88 memset(buffer, 0, len); 89 90 for (i = 0; i < LOOP_MAX; i++) { 91 struct loop_info64 li; 92 int rc; 93 94 sprintf(filename, "/dev/block/loop%d", i); 95 96 if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) { 97 if (errno != ENOENT) { 98 SLOGE("Unable to open %s (%s)", filename, strerror(errno)); 99 } else { 100 continue; 101 } 102 return -1; 103 } 104 105 rc = ioctl(fd, LOOP_GET_STATUS64, &li); 106 if (rc < 0 && errno == ENXIO) { 107 close(fd); 108 continue; 109 } 110 close(fd); 111 112 if (rc < 0) { 113 SLOGE("Unable to get loop status for %s (%s)", filename, 114 strerror(errno)); 115 return -1; 116 } 117 if (!strncmp((const char*) li.lo_crypt_name, id, LO_NAME_SIZE)) { 118 break; 119 } 120 } 121 122 if (i == LOOP_MAX) { 123 errno = ENOENT; 124 return -1; 125 } 126 strlcpy(buffer, filename, len); 127 return 0; 128} 129 130int Loop::create(const char *id, const char *loopFile, char *loopDeviceBuffer, size_t len) { 131 int i; 132 int fd; 133 char filename[256]; 134 135 for (i = 0; i < LOOP_MAX; i++) { 136 struct loop_info64 li; 137 int rc; 138 char *secontext = NULL; 139 140 sprintf(filename, "/dev/block/loop%d", i); 141 142 /* 143 * The kernel starts us off with 8 loop nodes, but more 144 * are created on-demand if needed. 145 */ 146 mode_t mode = 0660 | S_IFBLK; 147 unsigned int dev = (0xff & i) | ((i << 12) & 0xfff00000) | (7 << 8); 148 149 if (sehandle) { 150 rc = selabel_lookup(sehandle, &secontext, filename, S_IFBLK); 151 if (rc == 0) 152 setfscreatecon(secontext); 153 } 154 155 if (mknod(filename, mode, dev) < 0) { 156 if (errno != EEXIST) { 157 int sverrno = errno; 158 SLOGE("Error creating loop device node (%s)", strerror(errno)); 159 if (secontext) { 160 freecon(secontext); 161 setfscreatecon(NULL); 162 } 163 errno = sverrno; 164 return -1; 165 } 166 } 167 if (secontext) { 168 freecon(secontext); 169 setfscreatecon(NULL); 170 } 171 172 if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) { 173 SLOGE("Unable to open %s (%s)", filename, strerror(errno)); 174 return -1; 175 } 176 177 rc = ioctl(fd, LOOP_GET_STATUS64, &li); 178 if (rc < 0 && errno == ENXIO) 179 break; 180 181 close(fd); 182 183 if (rc < 0) { 184 SLOGE("Unable to get loop status for %s (%s)", filename, 185 strerror(errno)); 186 return -1; 187 } 188 } 189 190 if (i == LOOP_MAX) { 191 SLOGE("Exhausted all loop devices"); 192 errno = ENOSPC; 193 return -1; 194 } 195 196 strlcpy(loopDeviceBuffer, filename, len); 197 198 int file_fd; 199 200 if ((file_fd = open(loopFile, O_RDWR | O_CLOEXEC)) < 0) { 201 SLOGE("Unable to open %s (%s)", loopFile, strerror(errno)); 202 close(fd); 203 return -1; 204 } 205 206 if (ioctl(fd, LOOP_SET_FD, file_fd) < 0) { 207 SLOGE("Error setting up loopback interface (%s)", strerror(errno)); 208 close(file_fd); 209 close(fd); 210 return -1; 211 } 212 213 struct loop_info64 li; 214 215 memset(&li, 0, sizeof(li)); 216 strlcpy((char*) li.lo_crypt_name, id, LO_NAME_SIZE); 217 strlcpy((char*) li.lo_file_name, loopFile, LO_NAME_SIZE); 218 219 if (ioctl(fd, LOOP_SET_STATUS64, &li) < 0) { 220 SLOGE("Error setting loopback status (%s)", strerror(errno)); 221 close(file_fd); 222 close(fd); 223 return -1; 224 } 225 226 close(fd); 227 close(file_fd); 228 229 return 0; 230} 231 232int Loop::destroyByDevice(const char *loopDevice) { 233 int device_fd; 234 235 device_fd = open(loopDevice, O_RDONLY | O_CLOEXEC); 236 if (device_fd < 0) { 237 SLOGE("Failed to open loop (%d)", errno); 238 return -1; 239 } 240 241 if (ioctl(device_fd, LOOP_CLR_FD, 0) < 0) { 242 SLOGE("Failed to destroy loop (%d)", errno); 243 close(device_fd); 244 return -1; 245 } 246 247 close(device_fd); 248 return 0; 249} 250 251int Loop::destroyByFile(const char * /*loopFile*/) { 252 errno = ENOSYS; 253 return -1; 254} 255 256int Loop::createImageFile(const char *file, unsigned long numSectors) { 257 int fd; 258 259 if ((fd = creat(file, 0600)) < 0) { 260 SLOGE("Error creating imagefile (%s)", strerror(errno)); 261 return -1; 262 } 263 264 if (ftruncate(fd, numSectors * 512) < 0) { 265 SLOGE("Error truncating imagefile (%s)", strerror(errno)); 266 close(fd); 267 return -1; 268 } 269 close(fd); 270 return 0; 271} 272 273int Loop::resizeImageFile(const char *file, unsigned long numSectors) { 274 int fd; 275 276 if ((fd = open(file, O_RDWR | O_CLOEXEC)) < 0) { 277 SLOGE("Error opening imagefile (%s)", strerror(errno)); 278 return -1; 279 } 280 281 SLOGD("Attempting to increase size of %s to %lu sectors.", file, numSectors); 282 283 if (fallocate(fd, 0, 0, numSectors * 512)) { 284 if (errno == ENOSYS || errno == ENOTSUP) { 285 SLOGW("fallocate not found. Falling back to ftruncate."); 286 if (ftruncate(fd, numSectors * 512) < 0) { 287 SLOGE("Error truncating imagefile (%s)", strerror(errno)); 288 close(fd); 289 return -1; 290 } 291 } else { 292 SLOGE("Error allocating space (%s)", strerror(errno)); 293 close(fd); 294 return -1; 295 } 296 } 297 close(fd); 298 return 0; 299} 300 301int Loop::lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigned long *nr_sec) { 302 int fd; 303 struct asec_superblock buffer; 304 305 if ((fd = open(loopDevice, O_RDONLY | O_CLOEXEC)) < 0) { 306 SLOGE("Failed to open loopdevice (%s)", strerror(errno)); 307 destroyByDevice(loopDevice); 308 return -1; 309 } 310 311 get_blkdev_size(fd, nr_sec); 312 if (*nr_sec == 0) { 313 SLOGE("Failed to get loop size (%s)", strerror(errno)); 314 destroyByDevice(loopDevice); 315 close(fd); 316 return -1; 317 } 318 319 /* 320 * Try to read superblock. 321 */ 322 memset(&buffer, 0, sizeof(struct asec_superblock)); 323 if (lseek(fd, ((*nr_sec - 1) * 512), SEEK_SET) < 0) { 324 SLOGE("lseek failed (%s)", strerror(errno)); 325 close(fd); 326 destroyByDevice(loopDevice); 327 return -1; 328 } 329 if (read(fd, &buffer, sizeof(struct asec_superblock)) != sizeof(struct asec_superblock)) { 330 SLOGE("superblock read failed (%s)", strerror(errno)); 331 close(fd); 332 destroyByDevice(loopDevice); 333 return -1; 334 } 335 close(fd); 336 337 /* 338 * Superblock successfully read. Copy to caller's struct. 339 */ 340 memcpy(sb, &buffer, sizeof(struct asec_superblock)); 341 return 0; 342} 343