VolumeManager.cpp revision fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77
1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/* 2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright (C) 2008 The Android Open Source Project 3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License. 6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at 7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software 11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and 14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License. 15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */ 16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdio.h> 18fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <stdlib.h> 19fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <string.h> 20f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <errno.h> 21a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <fcntl.h> 22a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <sys/stat.h> 23a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <sys/types.h> 24a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include <sys/mount.h> 25a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 26a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <linux/kdev_t.h> 27f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#define LOG_TAG "Vold" 29f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 307b18a7b36f61574c0f0bdde0a7409dc36676fa12Kenny Root#include <openssl/md5.h> 317b18a7b36f61574c0f0bdde0a7409dc36676fa12Kenny Root 32f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <cutils/log.h> 33f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 34fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <sysutils/NetlinkEvent.h> 35fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 36f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include "VolumeManager.h" 37ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat#include "DirectVolume.h" 38a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "ResponseCode.h" 39a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include "Loop.h" 40a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat#include "Fat.h" 41b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat#include "Devmapper.h" 42586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat#include "Process.h" 43fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat#include "Asec.h" 4423969931fad6e993832208f099f6eea0f6f76eb5San Mehat 45f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatVolumeManager *VolumeManager::sInstance = NULL; 46f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 47f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatVolumeManager *VolumeManager::Instance() { 48f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (!sInstance) 49f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat sInstance = new VolumeManager(); 50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return sInstance; 51f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 52f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 53f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatVolumeManager::VolumeManager() { 54d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat mDebug = false; 55f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mVolumes = new VolumeCollection(); 5688705166ab82057090a070c6d4200c3d9db76f11San Mehat mActiveContainers = new AsecIdCollection(); 57f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mBroadcaster = NULL; 5899635f6c289fe2528c226403ea215c917ce86037Mike Lockwood mUsbMassStorageEnabled = false; 5999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood mUsbConnected = false; 6099635f6c289fe2528c226403ea215c917ce86037Mike Lockwood 6199635f6c289fe2528c226403ea215c917ce86037Mike Lockwood readInitialState(); 6299635f6c289fe2528c226403ea215c917ce86037Mike Lockwood} 6399635f6c289fe2528c226403ea215c917ce86037Mike Lockwood 6499635f6c289fe2528c226403ea215c917ce86037Mike Lockwoodvoid VolumeManager::readInitialState() { 6599635f6c289fe2528c226403ea215c917ce86037Mike Lockwood FILE *fp; 6699635f6c289fe2528c226403ea215c917ce86037Mike Lockwood char state[255]; 6799635f6c289fe2528c226403ea215c917ce86037Mike Lockwood 6899635f6c289fe2528c226403ea215c917ce86037Mike Lockwood /* 6999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood * Read the initial mass storage enabled state 7099635f6c289fe2528c226403ea215c917ce86037Mike Lockwood */ 7199635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if ((fp = fopen("/sys/devices/virtual/usb_composite/usb_mass_storage/enable", "r"))) { 7299635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if (fgets(state, sizeof(state), fp)) { 7399635f6c289fe2528c226403ea215c917ce86037Mike Lockwood mUsbMassStorageEnabled = !strncmp(state, "1", 1); 7499635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } else { 7599635f6c289fe2528c226403ea215c917ce86037Mike Lockwood SLOGE("Failed to read usb_mass_storage enabled state (%s)", strerror(errno)); 7699635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } 7799635f6c289fe2528c226403ea215c917ce86037Mike Lockwood fclose(fp); 7899635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } else { 7999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood SLOGD("USB mass storage support is not enabled in the kernel"); 8099635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } 8199635f6c289fe2528c226403ea215c917ce86037Mike Lockwood 8299635f6c289fe2528c226403ea215c917ce86037Mike Lockwood /* 8399635f6c289fe2528c226403ea215c917ce86037Mike Lockwood * Read the initial USB connected state 8499635f6c289fe2528c226403ea215c917ce86037Mike Lockwood */ 8599635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if ((fp = fopen("/sys/devices/virtual/switch/usb_configuration/state", "r"))) { 8699635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if (fgets(state, sizeof(state), fp)) { 8799635f6c289fe2528c226403ea215c917ce86037Mike Lockwood mUsbConnected = !strncmp(state, "1", 1); 8899635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } else { 8999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood SLOGE("Failed to read usb_configuration switch (%s)", strerror(errno)); 9099635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } 9199635f6c289fe2528c226403ea215c917ce86037Mike Lockwood fclose(fp); 9299635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } else { 9399635f6c289fe2528c226403ea215c917ce86037Mike Lockwood SLOGD("usb_configuration switch is not enabled in the kernel"); 9499635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } 95f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 96f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 97f1b736bc5605e92e917ab27f5abf3ba839be2270San MehatVolumeManager::~VolumeManager() { 9888705166ab82057090a070c6d4200c3d9db76f11San Mehat delete mVolumes; 9988705166ab82057090a070c6d4200c3d9db76f11San Mehat delete mActiveContainers; 100f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 101f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 102d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehatchar *VolumeManager::asecHash(const char *id, char *buffer, size_t len) { 103acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root static const char* digits = "0123456789abcdef"; 104acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root 1057b18a7b36f61574c0f0bdde0a7409dc36676fa12Kenny Root unsigned char sig[MD5_DIGEST_LENGTH]; 106d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 107acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root if (buffer == NULL) { 108acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root SLOGE("Destination buffer is NULL"); 109acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root errno = ESPIPE; 110acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root return NULL; 111acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root } else if (id == NULL) { 112acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root SLOGE("Source buffer is NULL"); 113acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root errno = ESPIPE; 114acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root return NULL; 115acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root } else if (len < MD5_ASCII_LENGTH_PLUS_NULL) { 116acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root SLOGE("Target hash buffer size < %d bytes (%d)", 117acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root MD5_ASCII_LENGTH_PLUS_NULL, len); 118d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat errno = ESPIPE; 119d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return NULL; 120d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 1217b18a7b36f61574c0f0bdde0a7409dc36676fa12Kenny Root 1227b18a7b36f61574c0f0bdde0a7409dc36676fa12Kenny Root MD5(reinterpret_cast<const unsigned char*>(id), strlen(id), sig); 123d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 124acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root char *p = buffer; 1257b18a7b36f61574c0f0bdde0a7409dc36676fa12Kenny Root for (int i = 0; i < MD5_DIGEST_LENGTH; i++) { 126acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root *p++ = digits[sig[i] >> 4]; 127acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root *p++ = digits[sig[i] & 0x0F]; 128d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 129acc9e7dcca8978fc809fa5b4d9b819c515a980ffKenny Root *p = '\0'; 130d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 131d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return buffer; 132d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat} 133d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 134d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehatvoid VolumeManager::setDebug(bool enable) { 135d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat mDebug = enable; 136d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat VolumeCollection::iterator it; 137d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat for (it = mVolumes->begin(); it != mVolumes->end(); ++it) { 138d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat (*it)->setDebug(enable); 139d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 140d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat} 141d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 142f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatint VolumeManager::start() { 143f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 144f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 145f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 146f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatint VolumeManager::stop() { 147f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 148f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 149f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 150f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatint VolumeManager::addVolume(Volume *v) { 151f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mVolumes->push_back(v); 152f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 153f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 154f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 15599635f6c289fe2528c226403ea215c917ce86037Mike Lockwoodvoid VolumeManager::notifyUmsAvailable(bool available) { 156a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char msg[255]; 157a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 158a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat snprintf(msg, sizeof(msg), "Share method ums now %s", 15999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood (available ? "available" : "unavailable")); 16099635f6c289fe2528c226403ea215c917ce86037Mike Lockwood SLOGD(msg); 161a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat getBroadcaster()->sendBroadcast(ResponseCode::ShareAvailabilityChange, 162a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg, false); 163a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 164a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 165a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatvoid VolumeManager::handleSwitchEvent(NetlinkEvent *evt) { 1660cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat const char *devpath = evt->findParam("DEVPATH"); 167a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat const char *name = evt->findParam("SWITCH_NAME"); 168a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat const char *state = evt->findParam("SWITCH_STATE"); 169a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1700cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat if (!name || !state) { 17197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Switch %s event missing name/state info", devpath); 1720cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat return; 1730cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat } 1740cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat 17599635f6c289fe2528c226403ea215c917ce86037Mike Lockwood bool oldAvailable = massStorageAvailable(); 17699635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if (!strcmp(name, "usb_configuration")) { 17799635f6c289fe2528c226403ea215c917ce86037Mike Lockwood mUsbConnected = !strcmp(state, "1"); 17899635f6c289fe2528c226403ea215c917ce86037Mike Lockwood SLOGD("USB %s", mUsbConnected ? "connected" : "disconnected"); 17999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood bool newAvailable = massStorageAvailable(); 18099635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if (newAvailable != oldAvailable) { 18199635f6c289fe2528c226403ea215c917ce86037Mike Lockwood notifyUmsAvailable(newAvailable); 182a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 183a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 18497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Ignoring unknown switch '%s'", name); 185a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 186a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 18799635f6c289fe2528c226403ea215c917ce86037Mike Lockwoodvoid VolumeManager::handleUsbCompositeEvent(NetlinkEvent *evt) { 18899635f6c289fe2528c226403ea215c917ce86037Mike Lockwood const char *function = evt->findParam("FUNCTION"); 18999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood const char *enabled = evt->findParam("ENABLED"); 19099635f6c289fe2528c226403ea215c917ce86037Mike Lockwood 19199635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if (!function || !enabled) { 19299635f6c289fe2528c226403ea215c917ce86037Mike Lockwood SLOGW("usb_composite event missing function/enabled info"); 19399635f6c289fe2528c226403ea215c917ce86037Mike Lockwood return; 19499635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } 19599635f6c289fe2528c226403ea215c917ce86037Mike Lockwood 19699635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if (!strcmp(function, "usb_mass_storage")) { 19799635f6c289fe2528c226403ea215c917ce86037Mike Lockwood bool oldAvailable = massStorageAvailable(); 19899635f6c289fe2528c226403ea215c917ce86037Mike Lockwood mUsbMassStorageEnabled = !strcmp(enabled, "1"); 19999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood SLOGD("usb_mass_storage function %s", mUsbMassStorageEnabled ? "enabled" : "disabled"); 20099635f6c289fe2528c226403ea215c917ce86037Mike Lockwood bool newAvailable = massStorageAvailable(); 20199635f6c289fe2528c226403ea215c917ce86037Mike Lockwood if (newAvailable != oldAvailable) { 20299635f6c289fe2528c226403ea215c917ce86037Mike Lockwood notifyUmsAvailable(newAvailable); 20399635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } 20499635f6c289fe2528c226403ea215c917ce86037Mike Lockwood } 20599635f6c289fe2528c226403ea215c917ce86037Mike Lockwood} 206a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 207fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehatvoid VolumeManager::handleBlockEvent(NetlinkEvent *evt) { 208fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat const char *devpath = evt->findParam("DEVPATH"); 209f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 210fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat /* Lookup a volume to handle this device */ 211f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat VolumeCollection::iterator it; 212f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat bool hit = false; 213f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat for (it = mVolumes->begin(); it != mVolumes->end(); ++it) { 214fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat if (!(*it)->handleBlockEvent(evt)) { 215a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifdef NETLINK_DEBUG 21697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Device '%s' event handled by volume %s\n", devpath, (*it)->getLabel()); 217a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif 218f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat hit = true; 219f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat break; 220f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 221f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 222f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 223f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (!hit) { 224a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifdef NETLINK_DEBUG 22597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("No volumes handled block event for '%s'", devpath); 226a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif 227f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 228f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 229f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 230f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehatint VolumeManager::listVolumes(SocketClient *cli) { 231f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat VolumeCollection::iterator i; 232f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 233f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat for (i = mVolumes->begin(); i != mVolumes->end(); ++i) { 234f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat char *buffer; 235f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat asprintf(&buffer, "%s %s %d", 236f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat (*i)->getLabel(), (*i)->getMountpoint(), 237f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat (*i)->getState()); 238a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat cli->sendMsg(ResponseCode::VolumeListResult, buffer, false); 239f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat free(buffer); 240f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 241a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat cli->sendMsg(ResponseCode::CommandOkay, "Volumes listed.", false); 242f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 243f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 24449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 245a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatint VolumeManager::formatVolume(const char *label) { 246a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat Volume *v = lookupVolume(label); 247a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 248a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!v) { 249a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = ENOENT; 250a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 251a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 252a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 253a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return v->formatVol(); 254a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 255a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 256a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatint VolumeManager::getAsecMountPath(const char *id, char *buffer, int maxlen) { 25788ac2c06539485942bf414efda2d39647fa1a415San Mehat char asecFileName[255]; 25888ac2c06539485942bf414efda2d39647fa1a415San Mehat snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id); 25988ac2c06539485942bf414efda2d39647fa1a415San Mehat 26088ac2c06539485942bf414efda2d39647fa1a415San Mehat memset(buffer, 0, maxlen); 26188ac2c06539485942bf414efda2d39647fa1a415San Mehat if (access(asecFileName, F_OK)) { 26288ac2c06539485942bf414efda2d39647fa1a415San Mehat errno = ENOENT; 26388ac2c06539485942bf414efda2d39647fa1a415San Mehat return -1; 26488ac2c06539485942bf414efda2d39647fa1a415San Mehat } 265a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 2663bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(buffer, maxlen, "%s/%s", Volume::ASECDIR, id); 267a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return 0; 268a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 269a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 2708b8f71b1d760411279f3b07a5c97709f052c689eSan Mehatint VolumeManager::createAsec(const char *id, unsigned int numSectors, 271a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat const char *fstype, const char *key, int ownerUid) { 272fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat struct asec_superblock sb; 273fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat memset(&sb, 0, sizeof(sb)); 274fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 275fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat sb.magic = ASEC_SB_MAGIC; 276fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat sb.ver = ASEC_SB_VER; 277a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 278d31e380bd9689dd9629b510ffe324707e261b439San Mehat if (numSectors < ((1024*1024)/512)) { 27997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Invalid container size specified (%d sectors)", numSectors); 280d31e380bd9689dd9629b510ffe324707e261b439San Mehat errno = EINVAL; 281d31e380bd9689dd9629b510ffe324707e261b439San Mehat return -1; 282d31e380bd9689dd9629b510ffe324707e261b439San Mehat } 283d31e380bd9689dd9629b510ffe324707e261b439San Mehat 284a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (lookupVolume(id)) { 28597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC id '%s' currently exists", id); 286a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat errno = EADDRINUSE; 287a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 288a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 289a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 290a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char asecFileName[255]; 2913bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id); 292a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 293a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (!access(asecFileName, F_OK)) { 29497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC file '%s' currently exists - destroy it first! (%s)", 295a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat asecFileName, strerror(errno)); 296a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat errno = EADDRINUSE; 297a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 298a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 299a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 300fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat /* 301fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat * Add some headroom 302fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat */ 303fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat unsigned fatSize = (((numSectors * 4) / 512) + 1) * 2; 304fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat unsigned numImgSectors = numSectors + fatSize + 2; 305fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 306fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (numImgSectors % 63) { 307fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat numImgSectors += (63 - (numImgSectors % 63)); 308fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 309fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 310fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat // Add +1 for our superblock which is at the end 311fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (Loop::createImageFile(asecFileName, numImgSectors + 1)) { 31297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC image file creation failed (%s)", strerror(errno)); 313a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 314a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 315a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 316d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat char idHash[33]; 317d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!asecHash(id, idHash, sizeof(idHash))) { 31897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Hash of '%s' failed (%s)", id, strerror(errno)); 319d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat unlink(asecFileName); 320d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 321d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 322d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 323a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char loopDevice[255]; 324d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (Loop::create(idHash, asecFileName, loopDevice, sizeof(loopDevice))) { 32597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC loop device creation failed (%s)", strerror(errno)); 326a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat unlink(asecFileName); 327a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 328a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 329a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 330b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat char dmDevice[255]; 331b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat bool cleanupDm = false; 332a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 333b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (strcmp(key, "none")) { 334fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat // XXX: This is all we support for now 335fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat sb.c_cipher = ASEC_SB_C_CIPHER_TWOFISH; 336d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (Devmapper::create(idHash, loopDevice, key, numImgSectors, dmDevice, 337b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat sizeof(dmDevice))) { 33897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC device mapping failed (%s)", strerror(errno)); 339b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat Loop::destroyByDevice(loopDevice); 340b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat unlink(asecFileName); 341b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 342b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 343b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat cleanupDm = true; 344b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } else { 345fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat sb.c_cipher = ASEC_SB_C_CIPHER_NONE; 346b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat strcpy(dmDevice, loopDevice); 347b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 348b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 349fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat /* 350fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat * Drop down the superblock at the end of the file 351fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat */ 352fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 353fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat int sbfd = open(loopDevice, O_RDWR); 354fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (sbfd < 0) { 35597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to open new DM device for superblock write (%s)", strerror(errno)); 356fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (cleanupDm) { 357d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat Devmapper::destroy(idHash); 358fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 359fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat Loop::destroyByDevice(loopDevice); 360fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat unlink(asecFileName); 361fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat return -1; 362fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 363fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 364fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (lseek(sbfd, (numImgSectors * 512), SEEK_SET) < 0) { 365fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat close(sbfd); 36697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to lseek for superblock (%s)", strerror(errno)); 367fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (cleanupDm) { 368d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat Devmapper::destroy(idHash); 369fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 370fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat Loop::destroyByDevice(loopDevice); 371fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat unlink(asecFileName); 372fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat return -1; 373fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 374fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 375fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (write(sbfd, &sb, sizeof(sb)) != sizeof(sb)) { 376fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat close(sbfd); 37797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to write superblock (%s)", strerror(errno)); 378fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (cleanupDm) { 379d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat Devmapper::destroy(idHash); 380fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 381fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat Loop::destroyByDevice(loopDevice); 382fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat unlink(asecFileName); 383fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat return -1; 384fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 385fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat close(sbfd); 386fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 387a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat if (strcmp(fstype, "none")) { 388a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat if (strcmp(fstype, "fat")) { 38997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Unknown fstype '%s' specified for container", fstype); 390b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 391a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 392fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (Fat::format(dmDevice, numImgSectors)) { 39397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC FAT format failed (%s)", strerror(errno)); 394b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (cleanupDm) { 395d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat Devmapper::destroy(idHash); 396b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 397eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat Loop::destroyByDevice(loopDevice); 398eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat unlink(asecFileName); 399eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat return -1; 400eb13a90bb96b329d8e24a6c3d4720ae88451d301San Mehat } 401a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat char mountPoint[255]; 402a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat 403a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); 404a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat if (mkdir(mountPoint, 0777)) { 405a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat if (errno != EEXIST) { 40697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Mountpoint creation failed (%s)", strerror(errno)); 407a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat if (cleanupDm) { 408d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat Devmapper::destroy(idHash); 409a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat } 410a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat Loop::destroyByDevice(loopDevice); 411a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat unlink(asecFileName); 412a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat return -1; 413a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat } 414a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat } 415a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 416a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat if (Fat::doMount(dmDevice, mountPoint, false, false, ownerUid, 417a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat 0, 0000, false)) { 41897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC FAT mount failed (%s)", strerror(errno)); 419a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat if (cleanupDm) { 420d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat Devmapper::destroy(idHash); 421a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat } 422a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat Loop::destroyByDevice(loopDevice); 423a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat unlink(asecFileName); 424a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat return -1; 425b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 426a1091cb0c448a933068f9120fe6946c09812bfb6San Mehat } else { 42797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGI("Created raw secure container %s (no filesystem)", id); 428a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 42988705166ab82057090a070c6d4200c3d9db76f11San Mehat 43088705166ab82057090a070c6d4200c3d9db76f11San Mehat mActiveContainers->push_back(strdup(id)); 431a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return 0; 432a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 433a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 434a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatint VolumeManager::finalizeAsec(const char *id) { 435a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char asecFileName[255]; 436a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char loopDevice[255]; 437a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char mountPoint[255]; 438a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 4393bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id); 440a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 441d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat char idHash[33]; 442d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!asecHash(id, idHash, sizeof(idHash))) { 44397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Hash of '%s' failed (%s)", id, strerror(errno)); 444d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 445d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 446d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 447d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) { 44897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to finalize %s (%s)", id, strerror(errno)); 449a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 450a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 451a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 4523bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); 453fff0b47998a722d57eea6a07350bbd7a6032b3ccSan Mehat // XXX: 454fff0b47998a722d57eea6a07350bbd7a6032b3ccSan Mehat if (Fat::doMount(loopDevice, mountPoint, true, true, 0, 0, 0227, false)) { 45597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC finalize mount failed (%s)", strerror(errno)); 456a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 457a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 458a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 459d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 46097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("ASEC %s finalized", id); 461d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 462a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return 0; 463a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 464a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 465048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehatint VolumeManager::renameAsec(const char *id1, const char *id2) { 466048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat char *asecFilename1; 467048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat char *asecFilename2; 468048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat char mountPoint[255]; 469048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat 4703bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat asprintf(&asecFilename1, "%s/%s.asec", Volume::SEC_ASECDIR, id1); 4713bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat asprintf(&asecFilename2, "%s/%s.asec", Volume::SEC_ASECDIR, id2); 472048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat 4733bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id1); 474048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat if (isMountpointMounted(mountPoint)) { 47597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Rename attempt when src mounted"); 476048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat errno = EBUSY; 477048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat goto out_err; 478048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat } 479048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat 48096956ed0e220cb62a4a96136976ded0d8c2d9075San Mehat snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id2); 48196956ed0e220cb62a4a96136976ded0d8c2d9075San Mehat if (isMountpointMounted(mountPoint)) { 48297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Rename attempt when dst mounted"); 48396956ed0e220cb62a4a96136976ded0d8c2d9075San Mehat errno = EBUSY; 48496956ed0e220cb62a4a96136976ded0d8c2d9075San Mehat goto out_err; 48596956ed0e220cb62a4a96136976ded0d8c2d9075San Mehat } 48696956ed0e220cb62a4a96136976ded0d8c2d9075San Mehat 487048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat if (!access(asecFilename2, F_OK)) { 48897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Rename attempt when dst exists"); 489048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat errno = EADDRINUSE; 490048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat goto out_err; 491048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat } 492048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat 493048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat if (rename(asecFilename1, asecFilename2)) { 49497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Rename of '%s' to '%s' failed (%s)", asecFilename1, asecFilename2, strerror(errno)); 495048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat goto out_err; 496048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat } 497048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat 498048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat free(asecFilename1); 499048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat free(asecFilename2); 500048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat return 0; 501048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat 502048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehatout_err: 503048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat free(asecFilename1); 504048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat free(asecFilename2); 505048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat return -1; 506048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat} 507048b0801fcd6fcfbb8fa812284c751181e4821b8San Mehat 508fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root#define UNMOUNT_RETRIES 5 509fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root#define UNMOUNT_SLEEP_BETWEEN_RETRY_MS (1000 * 1000) 5104ba8948dc16463053e21cda5744f519a555080d0San Mehatint VolumeManager::unmountAsec(const char *id, bool force) { 511a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char asecFileName[255]; 512a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char mountPoint[255]; 513a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 5143bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id); 5153bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); 516a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 517d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat char idHash[33]; 518d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!asecHash(id, idHash, sizeof(idHash))) { 51997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Hash of '%s' failed (%s)", id, strerror(errno)); 520d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 521d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 522d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat 523fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return unmountLoopImage(id, idHash, asecFileName, mountPoint, force); 524fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root} 525fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 526fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Rootint VolumeManager::unmountImage(const char *fileName, bool force) { 527fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root char mountPoint[255]; 528fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 529fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root char idHash[33]; 530fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (!asecHash(fileName, idHash, sizeof(idHash))) { 531fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Hash of '%s' failed (%s)", fileName, strerror(errno)); 532fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 533fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 534fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 535fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::LOOPDIR, idHash); 536fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 537fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return unmountLoopImage(fileName, idHash, fileName, mountPoint, force); 538fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root} 539fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 540fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Rootint VolumeManager::unmountLoopImage(const char *id, const char *idHash, 541fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root const char *fileName, const char *mountPoint, bool force) { 5420586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat if (!isMountpointMounted(mountPoint)) { 543fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Unmount request for %s when not mounted", id); 544b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat errno = EINVAL; 545b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 546b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 54723969931fad6e993832208f099f6eea0f6f76eb5San Mehat 548b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat int i, rc; 549fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root for (i = 1; i <= UNMOUNT_RETRIES; i++) { 550b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat rc = umount(mountPoint); 551b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (!rc) { 552b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat break; 553a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 554b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (rc && (errno == EINVAL || errno == ENOENT)) { 555fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGI("Container %s unmounted OK", id); 556b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat rc = 0; 557b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat break; 558a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 559fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGW("%s unmount attempt %d failed (%s)", 5608c940ef7dbd423cadc92982b44a65ed1014389e2San Mehat id, i, strerror(errno)); 5618c940ef7dbd423cadc92982b44a65ed1014389e2San Mehat 5624ba8948dc16463053e21cda5744f519a555080d0San Mehat int action = 0; // default is to just complain 5634ba8948dc16463053e21cda5744f519a555080d0San Mehat 5644ba8948dc16463053e21cda5744f519a555080d0San Mehat if (force) { 565fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (i > (UNMOUNT_RETRIES - 2)) 5664ba8948dc16463053e21cda5744f519a555080d0San Mehat action = 2; // SIGKILL 567fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root else if (i > (UNMOUNT_RETRIES - 3)) 5684ba8948dc16463053e21cda5744f519a555080d0San Mehat action = 1; // SIGHUP 5694ba8948dc16463053e21cda5744f519a555080d0San Mehat } 5708c940ef7dbd423cadc92982b44a65ed1014389e2San Mehat 571586536c60b773e3517531ad8a6cb0de6722c67fcSan Mehat Process::killProcessesWithOpenFiles(mountPoint, action); 572fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS); 573b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 574b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 575b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (rc) { 5764ba8948dc16463053e21cda5744f519a555080d0San Mehat errno = EBUSY; 57797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to unmount container %s (%s)", id, strerror(errno)); 578b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 579b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 580b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 58112f4b89046b54de1bdc188b7057ba77d7566e573San Mehat int retries = 10; 58212f4b89046b54de1bdc188b7057ba77d7566e573San Mehat 58312f4b89046b54de1bdc188b7057ba77d7566e573San Mehat while(retries--) { 58412f4b89046b54de1bdc188b7057ba77d7566e573San Mehat if (!rmdir(mountPoint)) { 58512f4b89046b54de1bdc188b7057ba77d7566e573San Mehat break; 58612f4b89046b54de1bdc188b7057ba77d7566e573San Mehat } 58712f4b89046b54de1bdc188b7057ba77d7566e573San Mehat 58897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Failed to rmdir %s (%s)", mountPoint, strerror(errno)); 589fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root usleep(UNMOUNT_SLEEP_BETWEEN_RETRY_MS); 59012f4b89046b54de1bdc188b7057ba77d7566e573San Mehat } 59112f4b89046b54de1bdc188b7057ba77d7566e573San Mehat 59212f4b89046b54de1bdc188b7057ba77d7566e573San Mehat if (!retries) { 59397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Timed out trying to rmdir %s (%s)", mountPoint, strerror(errno)); 594f5c61980969a0b49bda37b5dc94ffe675ebd5a5aSan Mehat } 59588705166ab82057090a070c6d4200c3d9db76f11San Mehat 596d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (Devmapper::destroy(idHash) && errno != ENXIO) { 59797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to destroy devmapper instance (%s)", strerror(errno)); 598a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 599a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 600a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char loopDevice[255]; 601d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) { 602a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat Loop::destroyByDevice(loopDevice); 603d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } else { 604fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGW("Failed to find loop device for {%s} (%s)", fileName, strerror(errno)); 605a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 60688705166ab82057090a070c6d4200c3d9db76f11San Mehat 60788705166ab82057090a070c6d4200c3d9db76f11San Mehat AsecIdCollection::iterator it; 60888705166ab82057090a070c6d4200c3d9db76f11San Mehat for (it = mActiveContainers->begin(); it != mActiveContainers->end(); ++it) { 60988705166ab82057090a070c6d4200c3d9db76f11San Mehat if (!strcmp(*it, id)) { 61088705166ab82057090a070c6d4200c3d9db76f11San Mehat free(*it); 61188705166ab82057090a070c6d4200c3d9db76f11San Mehat mActiveContainers->erase(it); 61288705166ab82057090a070c6d4200c3d9db76f11San Mehat break; 61388705166ab82057090a070c6d4200c3d9db76f11San Mehat } 61488705166ab82057090a070c6d4200c3d9db76f11San Mehat } 61588705166ab82057090a070c6d4200c3d9db76f11San Mehat if (it == mActiveContainers->end()) { 61697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("mActiveContainers is inconsistent!"); 61788705166ab82057090a070c6d4200c3d9db76f11San Mehat } 618b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return 0; 619b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat} 620b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 6214ba8948dc16463053e21cda5744f519a555080d0San Mehatint VolumeManager::destroyAsec(const char *id, bool force) { 622b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat char asecFileName[255]; 623b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat char mountPoint[255]; 624b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 6253bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id); 62655013f7131ffe094e1c7d929cfc32b3b25096a9bSan Mehat snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); 627b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 6280586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat if (isMountpointMounted(mountPoint)) { 629d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 63097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Unmounting container before destroy"); 631d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 6324ba8948dc16463053e21cda5744f519a555080d0San Mehat if (unmountAsec(id, force)) { 63397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to unmount asec %s for destroy (%s)", id, strerror(errno)); 6340586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat return -1; 6350586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat } 6360586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat } 637a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 6380586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat if (unlink(asecFileName)) { 63997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to unlink asec '%s' (%s)", asecFileName, strerror(errno)); 6400586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat return -1; 6410586d54053ee00e6d6523d4f125282ccb9a24aabSan Mehat } 642a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 643d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 64497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("ASEC %s destroyed", id); 645d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 646a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return 0; 647a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 648a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 649a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatint VolumeManager::mountAsec(const char *id, const char *key, int ownerUid) { 650a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char asecFileName[255]; 651a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char mountPoint[255]; 652a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 6533bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id); 6543bb6020e461e8872e8df0775cba6eb32e06b93ecSan Mehat snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); 655a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 656a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (isMountpointMounted(mountPoint)) { 65797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC %s already mounted", id); 658a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat errno = EBUSY; 659a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 660a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 661a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 662d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat char idHash[33]; 663d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (!asecHash(id, idHash, sizeof(idHash))) { 66497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Hash of '%s' failed (%s)", id, strerror(errno)); 665d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat return -1; 666d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 6677b18a7b36f61574c0f0bdde0a7409dc36676fa12Kenny Root 668a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char loopDevice[255]; 669d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) { 670d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (Loop::create(idHash, asecFileName, loopDevice, sizeof(loopDevice))) { 67197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC loop device creation failed (%s)", strerror(errno)); 672a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 673a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 674d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 67597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("New loop device created at %s", loopDevice); 676d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 677b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } else { 678d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 67997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Found active loopback for %s at %s", asecFileName, loopDevice); 680d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 681b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 682b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 683b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat char dmDevice[255]; 684b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat bool cleanupDm = false; 685fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat int fd; 686fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat unsigned int nr_sec = 0; 687b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 688fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if ((fd = open(loopDevice, O_RDWR)) < 0) { 68997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to open loopdevice (%s)", strerror(errno)); 690fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat Loop::destroyByDevice(loopDevice); 691fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat return -1; 692fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 693b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat 694fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (ioctl(fd, BLKGETSIZE, &nr_sec)) { 69597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to get loop size (%s)", strerror(errno)); 696fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat Loop::destroyByDevice(loopDevice); 697fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat close(fd); 698fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat return -1; 699fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 700fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 701fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat /* 702fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat * Validate superblock 703fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat */ 704fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat struct asec_superblock sb; 705fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat memset(&sb, 0, sizeof(sb)); 706fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (lseek(fd, ((nr_sec-1) * 512), SEEK_SET) < 0) { 70797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("lseek failed (%s)", strerror(errno)); 708fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat close(fd); 709fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat Loop::destroyByDevice(loopDevice); 710fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat return -1; 711fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 712fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { 71397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("superblock read failed (%s)", strerror(errno)); 714fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat close(fd); 715fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat Loop::destroyByDevice(loopDevice); 716fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat return -1; 717fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 718fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 719fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat close(fd); 720fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 721d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 72297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Container sb magic/ver (%.8x/%.2x)", sb.magic, sb.ver); 723d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 724fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (sb.magic != ASEC_SB_MAGIC || sb.ver != ASEC_SB_VER) { 72597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Bad container magic/version (%.8x/%.2x)", sb.magic, sb.ver); 726fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat Loop::destroyByDevice(loopDevice); 727fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat errno = EMEDIUMTYPE; 728fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat return -1; 729fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat } 730fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat nr_sec--; // We don't want the devmapping to extend onto our superblock 731fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat 732fcf24fe62f98c5d44431aa575555569c2c7a29b0San Mehat if (strcmp(key, "none")) { 733d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (Devmapper::lookupActive(idHash, dmDevice, sizeof(dmDevice))) { 734d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (Devmapper::create(idHash, loopDevice, key, nr_sec, 735b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat dmDevice, sizeof(dmDevice))) { 73697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC device mapping failed (%s)", strerror(errno)); 737b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat Loop::destroyByDevice(loopDevice); 738b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 739b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 740d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 74197ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("New devmapper instance created at %s", dmDevice); 742d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 743b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } else { 744d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 74597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Found active devmapper for %s at %s", asecFileName, dmDevice); 746d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 747b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 748b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat cleanupDm = true; 749b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } else { 750b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat strcpy(dmDevice, loopDevice); 751a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 752a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 753a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (mkdir(mountPoint, 0777)) { 754b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (errno != EEXIST) { 75597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Mountpoint creation failed (%s)", strerror(errno)); 756b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (cleanupDm) { 757d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat Devmapper::destroy(idHash); 758b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 759b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat Loop::destroyByDevice(loopDevice); 760b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat return -1; 761b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 762a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 763a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 764b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (Fat::doMount(dmDevice, mountPoint, true, false, ownerUid, 0, 765cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat 0222, false)) { 766cff5ec3d360b699ad13df05670efe0d0a7386fbeSan Mehat// 0227, false)) { 76797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("ASEC mount failed (%s)", strerror(errno)); 768b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat if (cleanupDm) { 769d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat Devmapper::destroy(idHash); 770b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat } 771b78a32c1d5eeb243bdac0eaf18effb1897f1ee67San Mehat Loop::destroyByDevice(loopDevice); 772a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return -1; 773a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 774a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 77588705166ab82057090a070c6d4200c3d9db76f11San Mehat mActiveContainers->push_back(strdup(id)); 776d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat if (mDebug) { 77797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("ASEC %s mounted", id); 778d9a4e358614a0c5f60cc76c0636ee4bb02004a32San Mehat } 779a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return 0; 780a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 781a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 782fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root/** 783fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root * Mounts an image file <code>img</code>. 784fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root */ 785fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Rootint VolumeManager::mountImage(const char *img, const char *key, int ownerUid) { 786fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root char mountPoint[255]; 787fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 788fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root#if 0 789fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root struct stat imgStat; 790fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (stat(img, &imgStat) != 0) { 791fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Could not stat '%s': %s", img, strerror(errno)); 792fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 793fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 794fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 795fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (imgStat.st_uid != ownerUid) { 796fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGW("Image UID does not match requestor UID (%d != %d)", 797fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root imgStat.st_uid, ownerUid); 798fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 799fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 800fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root#endif 801fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 802fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root char idHash[33]; 803fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (!asecHash(img, idHash, sizeof(idHash))) { 804fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Hash of '%s' failed (%s)", img, strerror(errno)); 805fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 806fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 807fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 808fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::LOOPDIR, idHash); 809fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 810fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (isMountpointMounted(mountPoint)) { 811fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Image %s already mounted", img); 812fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root errno = EBUSY; 813fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 814fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 815fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 816fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root char loopDevice[255]; 817fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) { 818fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (Loop::create(idHash, img, loopDevice, sizeof(loopDevice))) { 819fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Image loop device creation failed (%s)", strerror(errno)); 820fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 821fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 822fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (mDebug) { 823fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGD("New loop device created at %s", loopDevice); 824fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 825fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } else { 826fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (mDebug) { 827fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGD("Found active loopback for %s at %s", img, loopDevice); 828fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 829fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 830fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 831fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root char dmDevice[255]; 832fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root bool cleanupDm = false; 833fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root int fd; 834fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root unsigned int nr_sec = 0; 835fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 836fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if ((fd = open(loopDevice, O_RDWR)) < 0) { 837fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Failed to open loopdevice (%s)", strerror(errno)); 838fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root Loop::destroyByDevice(loopDevice); 839fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 840fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 841fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 842fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (ioctl(fd, BLKGETSIZE, &nr_sec)) { 843fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Failed to get loop size (%s)", strerror(errno)); 844fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root Loop::destroyByDevice(loopDevice); 845fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root close(fd); 846fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 847fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 848fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 849fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root close(fd); 850fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 851fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (strcmp(key, "none")) { 852fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (Devmapper::lookupActive(idHash, dmDevice, sizeof(dmDevice))) { 853fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (Devmapper::create(idHash, loopDevice, key, nr_sec, 854fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root dmDevice, sizeof(dmDevice))) { 855fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("ASEC device mapping failed (%s)", strerror(errno)); 856fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root Loop::destroyByDevice(loopDevice); 857fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 858fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 859fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (mDebug) { 860fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGD("New devmapper instance created at %s", dmDevice); 861fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 862fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } else { 863fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (mDebug) { 864fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGD("Found active devmapper for %s at %s", img, dmDevice); 865fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 866fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 867fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root cleanupDm = true; 868fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } else { 869fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root strcpy(dmDevice, loopDevice); 870fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 871fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 872fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (mkdir(mountPoint, 0755)) { 873fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (errno != EEXIST) { 874fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Mountpoint creation failed (%s)", strerror(errno)); 875fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (cleanupDm) { 876fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root Devmapper::destroy(idHash); 877fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 878fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root Loop::destroyByDevice(loopDevice); 879fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 880fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 881fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 882fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 883fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (Fat::doMount(dmDevice, mountPoint, true, false, ownerUid, 0, 884fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 0227, false)) { 885fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGE("Image mount failed (%s)", strerror(errno)); 886fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (cleanupDm) { 887fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root Devmapper::destroy(idHash); 888fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 889fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root Loop::destroyByDevice(loopDevice); 890fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return -1; 891fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 892fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 893fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root mActiveContainers->push_back(strdup(img)); 894fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root if (mDebug) { 895fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root SLOGD("Image %s mounted", img); 896fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root } 897fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root return 0; 898fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root} 899fb7c4d5a8a1031cf0e493ff182dcf458e5fe8c77Kenny Root 90049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehatint VolumeManager::mountVolume(const char *label) { 90149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat Volume *v = lookupVolume(label); 90249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 90349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if (!v) { 90449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat errno = ENOENT; 90549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat return -1; 90649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 90749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 908a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return v->mountVol(); 909a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 910a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 911a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatint VolumeManager::shareAvailable(const char *method, bool *avail) { 912a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 913a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (strcmp(method, "ums")) { 914a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = ENOSYS; 915a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 916a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 917a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 91899635f6c289fe2528c226403ea215c917ce86037Mike Lockwood *avail = massStorageAvailable(); 919a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 920a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 921a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 922eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehatint VolumeManager::shareEnabled(const char *label, const char *method, bool *enabled) { 923eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat Volume *v = lookupVolume(label); 924eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat 925eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat if (!v) { 926eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat errno = ENOENT; 927eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat return -1; 928eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat } 929eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat 930eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat if (strcmp(method, "ums")) { 931eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat errno = ENOSYS; 932eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat return -1; 933eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat } 934eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat 935eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat if (v->getState() != Volume::State_Shared) { 936eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat *enabled = false; 937b9aed74b146beb7499ebc5775e8ae179d16900efSan Mehat } else { 938b9aed74b146beb7499ebc5775e8ae179d16900efSan Mehat *enabled = true; 939eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat } 940eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat return 0; 941eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat} 942eba65e9d438a05f1c5dfd0f8d31bc463a5d08eeeSan Mehat 943a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatint VolumeManager::simulate(const char *cmd, const char *arg) { 944a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 945a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!strcmp(cmd, "ums")) { 946a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!strcmp(arg, "connect")) { 94799635f6c289fe2528c226403ea215c917ce86037Mike Lockwood notifyUmsAvailable(true); 948a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else if (!strcmp(arg, "disconnect")) { 94999635f6c289fe2528c226403ea215c917ce86037Mike Lockwood notifyUmsAvailable(false); 950a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 951a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = EINVAL; 952a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 953a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 954a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 955a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = EINVAL; 956a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 957a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 958a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 959a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 960a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 961a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatint VolumeManager::shareVolume(const char *label, const char *method) { 962a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat Volume *v = lookupVolume(label); 963a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 964a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!v) { 965a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = ENOENT; 966a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 967a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 968a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 969a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat /* 970a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * Eventually, we'll want to support additional share back-ends, 971a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * some of which may work while the media is mounted. For now, 972a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * we just support UMS 973a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat */ 974a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (strcmp(method, "ums")) { 975a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = ENOSYS; 976a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 977a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 978a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 979a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (v->getState() == Volume::State_NoMedia) { 980a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = ENODEV; 981a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 982a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 983a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 98449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if (v->getState() != Volume::State_Idle) { 985a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat // You need to unmount manually befoe sharing 98649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat errno = EBUSY; 98749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat return -1; 98849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 98949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 990a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat dev_t d = v->getDiskDevice(); 991a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if ((MAJOR(d) == 0) && (MINOR(d) == 0)) { 992a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat // This volume does not support raw disk access 993a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = EINVAL; 994a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 995a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 996a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 997a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int fd; 998a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char nodepath[255]; 999a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat snprintf(nodepath, 1000a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sizeof(nodepath), "/dev/block/vold/%d:%d", 1001a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat MAJOR(d), MINOR(d)); 1002a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 10030cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat if ((fd = open("/sys/devices/platform/usb_mass_storage/lun0/file", 10040cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat O_WRONLY)) < 0) { 100597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to open ums lunfile (%s)", strerror(errno)); 1006a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 1007a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 1008a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1009a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (write(fd, nodepath, strlen(nodepath)) < 0) { 101097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to write to ums lunfile (%s)", strerror(errno)); 1011a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat close(fd); 1012a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 1013a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 1014a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1015a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat close(fd); 1016a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat v->handleVolumeShared(); 1017a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 1018a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 1019a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1020a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatint VolumeManager::unshareVolume(const char *label, const char *method) { 1021a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat Volume *v = lookupVolume(label); 1022a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1023a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!v) { 1024a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = ENOENT; 1025a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 1026a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 1027a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1028a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (strcmp(method, "ums")) { 1029a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = ENOSYS; 1030a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 1031a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 1032a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1033a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (v->getState() != Volume::State_Shared) { 1034a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = EINVAL; 1035a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 1036a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 1037a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1038a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat dev_t d = v->getDiskDevice(); 1039a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1040a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int fd; 1041a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char nodepath[255]; 1042a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat snprintf(nodepath, 1043a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sizeof(nodepath), "/dev/block/vold/%d:%d", 1044a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat MAJOR(d), MINOR(d)); 1045a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 10460cde53ce7b44ce189d0bc6fa81c0036e096deb51San Mehat if ((fd = open("/sys/devices/platform/usb_mass_storage/lun0/file", O_WRONLY)) < 0) { 104797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to open ums lunfile (%s)", strerror(errno)); 1048a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 1049a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 1050a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1051a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char ch = 0; 1052a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (write(fd, &ch, 1) < 0) { 105397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Unable to write to ums lunfile (%s)", strerror(errno)); 1054a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat close(fd); 1055a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 1056a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 1057a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 1058a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat close(fd); 1059a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat v->handleVolumeUnshared(); 1060a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 0; 106149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat} 106249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 10634ba8948dc16463053e21cda5744f519a555080d0San Mehatint VolumeManager::unmountVolume(const char *label, bool force) { 106449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat Volume *v = lookupVolume(label); 106549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 106649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if (!v) { 106749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat errno = ENOENT; 106849e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat return -1; 106949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 107049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 1071a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (v->getState() == Volume::State_NoMedia) { 1072a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat errno = ENODEV; 1073a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return -1; 1074a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 1075a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 107649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat if (v->getState() != Volume::State_Mounted) { 107797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Attempt to unmount volume which isn't mounted (%d)\n", 1078a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat v->getState()); 107949e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat errno = EBUSY; 108049e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat return -1; 108149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 108249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 10831a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat cleanupAsec(v, force); 108488705166ab82057090a070c6d4200c3d9db76f11San Mehat 10854ba8948dc16463053e21cda5744f519a555080d0San Mehat return v->unmountVol(force); 108649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat} 108749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 1088a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat/* 1089a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * Looks up a volume by it's label or mount-point 1090a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat */ 109149e2bce5b74129c26a35e25d4693cbfe98c4688eSan MehatVolume *VolumeManager::lookupVolume(const char *label) { 109249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat VolumeCollection::iterator i; 109349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 109449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat for (i = mVolumes->begin(); i != mVolumes->end(); ++i) { 1095a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (label[0] == '/') { 1096a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!strcmp(label, (*i)->getMountpoint())) 1097a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return (*i); 1098a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 1099a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!strcmp(label, (*i)->getLabel())) 1100a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return (*i); 1101a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 110249e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat } 110349e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat return NULL; 110449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat} 1105a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 1106a19b250bd273455933ca3502cf2c2e0a803aff77San Mehatbool VolumeManager::isMountpointMounted(const char *mp) 1107a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat{ 1108a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char device[256]; 1109a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char mount_path[256]; 1110a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char rest[256]; 1111a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat FILE *fp; 1112a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat char line[1024]; 1113a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 1114a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (!(fp = fopen("/proc/mounts", "r"))) { 111597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error opening /proc/mounts (%s)", strerror(errno)); 1116a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return false; 1117a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 1118a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 1119a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat while(fgets(line, sizeof(line), fp)) { 1120a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat line[strlen(line)-1] = '\0'; 1121a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat sscanf(line, "%255s %255s %255s\n", device, mount_path, rest); 1122a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat if (!strcmp(mount_path, mp)) { 1123a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat fclose(fp); 1124a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return true; 1125a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 1126a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat } 1127a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 1128a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat fclose(fp); 1129a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat return false; 1130a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat} 1131a19b250bd273455933ca3502cf2c2e0a803aff77San Mehat 11321a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehatint VolumeManager::cleanupAsec(Volume *v, bool force) { 11331a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat while(mActiveContainers->size()) { 11341a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat AsecIdCollection::iterator it = mActiveContainers->begin(); 11351a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat SLOGI("Unmounting ASEC %s (dependant on %s)", *it, v->getMountpoint()); 11361a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat if (unmountAsec(*it, force)) { 11371a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat SLOGE("Failed to unmount ASEC %s (%s)", *it, strerror(errno)); 11381a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat return -1; 11391a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat } 11401a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat } 11411a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat return 0; 11421a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat} 11431a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat 1144