diff options
author | Pawit Pornkitprasan <p.pawit@gmail.com> | 2011-12-03 15:25:33 +0700 |
---|---|---|
committer | Ricardo Cerqueira <cyanogenmod@cerqueira.org> | 2012-07-10 20:10:35 +0100 |
commit | f2067eadd5bfd9fd13420151d83e324ca35f9878 (patch) | |
tree | afbb885946e7cf267567111d8c8fb5c10cc0cd4d | |
parent | 92ab32708cb5210319ba3e5f02bcd02bd2fbb2cf (diff) | |
download | system_vold-f2067eadd5bfd9fd13420151d83e324ca35f9878.zip system_vold-f2067eadd5bfd9fd13420151d83e324ca35f9878.tar.gz system_vold-f2067eadd5bfd9fd13420151d83e324ca35f9878.tar.bz2 |
Allow mounting of multiple volumes via mass storage (vold part)
commit 662006fe5419803938790a164cb1ba73b05e3f41
Author: Pawit Pornkitprasan <p.pawit@gmail.com>
Date: Sat Dec 3 13:31:46 2011 +0700
Extracted primary storage detection into isPrimaryStorage()
Change-Id: Ia76ace183869283e7e6563ea8d5eb919283ffe55
commit 0303f8b0722bfac3c1b0a522f42c921e3ed4666a
Author: Genokolar <genokolar@gmail.com>
Date: Sat Oct 1 21:34:00 2011 +0800
Add custom second lun number support
like u8800 have different second lun number
use TARGET_USE_CUSTOM_SECOND_LUN_NUM options to custom lun number
Change-Id: I36f8c92f1f8041efeaa0304795a11eb1cc49e5e1
(cherry picked from commit 24860389177df3aa839a8eb77d79608b15e0af8d)
commit 4b99cd585d12fa47b2f8d99cde430f37d2fe7293
Author: Alex Zepeda <alex@inferiorhumanorgans.com>
Date: Mon Jul 18 10:55:33 2011 -0700
Use a list of possible lun paths instead of a hardcoded one.
This will easily play nice with kernels that use gadget drivers and
function drivers (ex: tethering support doesn't require a new vold).
Change-Id: I71796114501cf2d64dea5fd077ac5baf54873af4
commit 1f822e51cde73bc0d8e1b575848614f696534a88
Author: mik_os <kiril.mik.os@gmail.com>
Date: Mon Feb 14 16:10:36 2011 +0200
Added ability to use custom lun path.
Change-Id: If39e445383c0ea0d64556df5708de80c06056174
(cherry picked from commit 5edf3ce983ddd3ffed01c398244493ab962e3304)
commit baa2d75929be1bebb1e04d93044d7718460d5b14
Author: Josh Stone <cuviper@gmail.com>
Date: Sat Jan 22 11:52:01 2011 -0800
vold: cleanupAsec should only do work for EXTERNAL_STORAGE
For devices like DINC which have both emmc and sdcard storage, only one
of these is used for ASEC mounts. When we're unmounting volumes, we
need to discriminate which is which before forcing ASEC closures.
Change-Id: I94efda36414bb0eb2c4c4e31891ce4f318582a8e
(cherry picked from commit 61272bf32aff5515aa6f48acb2e8ea7e95b47aa3)
commit 73aeea8a3c834d7d822edc088f19934843511779
Author: Tony Layher <layhertony@gmail.com>
Date: Sun Jan 2 19:17:39 2011 -0500
Fix build break on Vold, have to remove uneeded code
Change-Id: Ie594367d3675cf25cf4c86703aaa01055a9892a6
(cherry picked from commit f04648bda6bf58391f46fc8694718e5878e4abb9)
commit 332a373eaadb487f069fd86f0876abade84f7189
Author: Tony Layher <layhertony@gmail.com>
Date: Sun Jan 2 14:48:26 2011 -0500
Forward Port of vold changes for having 2 UMS devices and use only EXTERNAL_STORAGE for ASEC
Change-Id: Ia26b4251226103441afb2656ea411c68525974c9
Change-Id: I5695a0441a6672e9c1c2f2aef95c38f0b08a7145
-rw-r--r-- | Android.mk | 8 | ||||
-rw-r--r-- | Volume.cpp | 42 | ||||
-rw-r--r-- | Volume.h | 1 | ||||
-rw-r--r-- | VolumeManager.cpp | 63 | ||||
-rw-r--r-- | VolumeManager.h | 9 |
5 files changed, 98 insertions, 25 deletions
@@ -70,6 +70,14 @@ ifeq ($(BOARD_VOLD_EMMC_SHARES_DEV_MAJOR), true) LOCAL_CFLAGS += -DVOLD_EMMC_SHARES_DEV_MAJOR endif +ifneq ($(TARGET_USE_CUSTOM_LUN_FILE_PATH),) +LOCAL_CFLAGS += -DCUSTOM_LUN_FILE=\"$(TARGET_USE_CUSTOM_LUN_FILE_PATH)\" +endif + +ifneq ($(TARGET_USE_CUSTOM_SECOND_LUN_NUM),) +LOCAL_CFLAGS += -DCUSTOM_SECOND_LUN_NUM=$(TARGET_USE_CUSTOM_SECOND_LUN_NUM) +endif + LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) LOCAL_STATIC_LIBRARIES := libfs_mgr @@ -170,6 +170,11 @@ int Volume::handleBlockEvent(NetlinkEvent *evt) { return -1; } +bool Volume::isPrimaryStorage() { + const char* externalStorage = getenv("EXTERNAL_STORAGE") ? : "/mnt/sdcard"; + return !strcmp(getMountpoint(), externalStorage); +} + void Volume::setState(int state) { char msg[255]; int oldState = mState; @@ -302,8 +307,7 @@ int Volume::mountVol() { dev_t deviceNodes[4]; int n, i, rc = 0; char errmsg[255]; - const char* externalStorage = getenv("EXTERNAL_STORAGE"); - bool primaryStorage = externalStorage && !strcmp(getMountpoint(), externalStorage); + bool primaryStorage = isPrimaryStorage(); char decrypt_state[PROPERTY_VALUE_MAX]; char crypto_state[PROPERTY_VALUE_MAX]; char encrypt_progress[PROPERTY_VALUE_MAX]; @@ -602,6 +606,7 @@ int Volume::doUnmount(const char *path, bool force) { int Volume::unmountVol(bool force, bool revert) { int i, rc; + const char* externalStorage = getenv("EXTERNAL_STORAGE"); if (getState() != Volume::State_Mounted) { SLOGE("Volume %s unmount request when not mounted", getLabel()); @@ -624,24 +629,27 @@ int Volume::unmountVol(bool force, bool revert) { protectFromAutorunStupidity(); - /* - * Unmount the tmpfs which was obscuring the asec image directory - * from non root users - */ + /* Undo createBindMounts(), which is only called for primary storage */ + if (isPrimaryStorage()) { + /* + * Unmount the tmpfs which was obscuring the asec image directory + * from non root users + */ - if (doUnmount(Volume::SEC_STG_SECIMGDIR, force)) { - SLOGE("Failed to unmount tmpfs on %s (%s)", SEC_STG_SECIMGDIR, strerror(errno)); - goto fail_republish; - } + if (doUnmount(Volume::SEC_STG_SECIMGDIR, force)) { + SLOGE("Failed to unmount tmpfs on %s (%s)", SEC_STG_SECIMGDIR, strerror(errno)); + goto fail_republish; + } - /* - * Remove the bindmount we were using to keep a reference to - * the previously obscured directory. - */ + /* + * Remove the bindmount we were using to keep a reference to + * the previously obscured directory. + */ - if (doUnmount(Volume::SEC_ASECDIR_EXT, force)) { - SLOGE("Failed to remove bindmount on %s (%s)", SEC_ASECDIR_EXT, strerror(errno)); - goto fail_remount_tmpfs; + if (doUnmount(Volume::SEC_ASECDIR_EXT, force)) { + SLOGE("Failed to remove bindmount on %s (%s)", SEC_ASECDIR_EXT, strerror(errno)); + goto fail_remount_tmpfs; + } } /* @@ -72,6 +72,7 @@ public: const char *getLabel() { return mLabel; } const char *getMountpoint() { return mMountpoint; } int getState() { return mState; } + bool isPrimaryStorage(); virtual int handleBlockEvent(NetlinkEvent *evt); virtual dev_t getDiskDevice(); diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 4a71c05..32a4707 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -49,8 +49,6 @@ #include "Asec.h" #include "cryptfs.h" -#define MASS_STORAGE_FILE_PATH "/sys/class/android_usb/android0/f_mass_storage/lun/file" - VolumeManager *VolumeManager::sInstance = NULL; VolumeManager *VolumeManager::Instance() { @@ -1166,6 +1164,36 @@ int VolumeManager::shareEnabled(const char *label, const char *method, bool *ena return 0; } +static const char *LUN_FILES[] = { +#ifdef CUSTOM_LUN_FILE + CUSTOM_LUN_FILE, +#endif + /* Only andriod0 exists, but the %d in there is a hack to satisfy the + format string and also give a not found error when %d > 0 */ + "/sys/class/android_usb/android%d/f_mass_storage/lun/file", + NULL +}; + +int VolumeManager::openLun(int number) { + const char **iterator = LUN_FILES; + char qualified_lun[255]; + while (*iterator) { + bzero(qualified_lun, 255); + snprintf(qualified_lun, 254, *iterator, number); + int fd = open(qualified_lun, O_WRONLY); + if (fd >= 0) { + SLOGD("Opened lunfile %s", qualified_lun); + return fd; + } + SLOGE("Unable to open ums lunfile %s (%s)", qualified_lun, strerror(errno)); + iterator++; + } + + errno = EINVAL; + SLOGE("Unable to find ums lunfile for LUN %d", number); + return -1; +} + int VolumeManager::shareVolume(const char *label, const char *method) { Volume *v = lookupVolume(label); @@ -1190,7 +1218,7 @@ int VolumeManager::shareVolume(const char *label, const char *method) { } if (v->getState() != Volume::State_Idle) { - // You need to unmount manually befoe sharing + // You need to unmount manually before sharing errno = EBUSY; return -1; } @@ -1218,14 +1246,21 @@ int VolumeManager::shareVolume(const char *label, const char *method) { } #endif - int fd; + int fd, lun_number; char nodepath[255]; snprintf(nodepath, sizeof(nodepath), "/dev/block/vold/%d:%d", MAJOR(d), MINOR(d)); - if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) { - SLOGE("Unable to open ums lunfile (%s)", strerror(errno)); + // TODO: Currently only two mounts are supported, defaulting + // /mnt/sdcard to lun0 and anything else to lun1. Fix this. + if (v->isPrimaryStorage()) { + lun_number = 0; + } else { + lun_number = SECOND_LUN_NUM; + } + + if ((fd = openLun(lun_number)) < 0) { return -1; } @@ -1274,8 +1309,16 @@ int VolumeManager::unshareVolume(const char *label, const char *method) { } int fd; - if ((fd = open(MASS_STORAGE_FILE_PATH, O_WRONLY)) < 0) { - SLOGE("Unable to open ums lunfile (%s)", strerror(errno)); + int lun_number; + + // /mnt/sdcard to lun0 and anything else to lun1. Fix this. + if (v->isPrimaryStorage()) { + lun_number = 0; + } else { + lun_number = SECOND_LUN_NUM; + } + + if ((fd = openLun(lun_number)) < 0) { return -1; } @@ -1473,6 +1516,10 @@ bool VolumeManager::isMountpointMounted(const char *mp) } int VolumeManager::cleanupAsec(Volume *v, bool force) { + /* Only EXTERNAL_STORAGE needs ASEC cleanup. */ + if (!v->isPrimaryStorage()) + return 0; + while(mActiveContainers->size()) { AsecIdCollection::iterator it = mActiveContainers->begin(); ContainerData* cd = *it; diff --git a/VolumeManager.h b/VolumeManager.h index 4399b76..fdaff79 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -28,6 +28,10 @@ /* The length of an MD5 hash when encoded into ASCII hex characters */ #define MD5_ASCII_LENGTH_PLUS_NULL ((MD5_DIGEST_LENGTH*2)+1) +#ifndef CUSTOM_SECOND_LUN_NUM +#define CUSTOM_SECOND_LUN_NUM 1 +#endif + typedef enum { ASEC, OBB } container_type_t; class ContainerData { @@ -51,6 +55,10 @@ public: typedef android::List<ContainerData*> AsecIdCollection; class VolumeManager { + +public: + static const int SECOND_LUN_NUM = CUSTOM_SECOND_LUN_NUM; + private: static VolumeManager *sInstance; @@ -142,6 +150,7 @@ private: VolumeManager(); void readInitialState(); bool isMountpointMounted(const char *mp); + int openLun(int number); bool isAsecInDirectory(const char *dir, const char *asec) const; }; |