am f4a8c0b9: am 10939ac7: Merge "Extract UUID and label from inserted volumes." into klp-dev

* commit 'f4a8c0b9f646cd9fa51fe3746bc8a00bb987124b':
  Extract UUID and label from inserted volumes.
This commit is contained in:
Jeff Sharkey 2013-10-17 18:59:02 -07:00 committed by Android Git Automerger
commit 0368cd4355
4 changed files with 118 additions and 25 deletions

View file

@ -22,10 +22,13 @@ common_c_includes := \
$(KERNEL_HEADERS) \
system/extras/ext4_utils \
external/openssl/include \
external/stlport/stlport \
bionic \
external/scrypt/lib/crypto
common_shared_libraries := \
libsysutils \
libstlport \
libcutils \
liblog \
libdiskconfig \

View file

@ -56,6 +56,8 @@ public:
static const int VolumeMountFailedBlank = 610;
static const int VolumeMountFailedDamaged = 611;
static const int VolumeMountFailedNoMedia = 612;
static const int VolumeUuidChange = 613;
static const int VolumeUserLabelChange = 614;
static const int ShareAvailabilityChange = 620;

View file

@ -40,6 +40,8 @@
#include <cutils/fs.h>
#include <cutils/log.h>
#include <string>
#include "Volume.h"
#include "VolumeManager.h"
#include "ResponseCode.h"
@ -80,6 +82,8 @@ const char *Volume::ASECDIR = "/mnt/asec";
*/
const char *Volume::LOOPDIR = "/mnt/obb";
const char *Volume::BLKID_PATH = "/system/bin/blkid";
static const char *stateToStr(int state) {
if (state == Volume::State_Init)
return "Initializing";
@ -109,6 +113,8 @@ Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) {
mVm = vm;
mDebug = false;
mLabel = strdup(rec->label);
mUuid = NULL;
mUserLabel = NULL;
mState = Volume::State_Init;
mFlags = flags;
mCurrentlyMountedKdev = -1;
@ -118,25 +124,8 @@ Volume::Volume(VolumeManager *vm, const fstab_rec* rec, int flags) {
Volume::~Volume() {
free(mLabel);
}
void Volume::protectFromAutorunStupidity() {
char filename[255];
snprintf(filename, sizeof(filename), "%s/autorun.inf", getMountpoint());
if (!access(filename, F_OK)) {
SLOGW("Volume contains an autorun.inf! - removing");
/*
* Ensure the filename is all lower-case so
* the process killer can find the inode.
* Probably being paranoid here but meh.
*/
rename(filename, filename);
Process::killProcessesWithOpenFiles(filename, 2);
if (unlink(filename)) {
SLOGE("Failed to remove %s (%s)", filename, strerror(errno));
}
}
free(mUuid);
free(mUserLabel);
}
void Volume::setDebug(bool enable) {
@ -162,6 +151,46 @@ int Volume::handleBlockEvent(NetlinkEvent *evt) {
return -1;
}
void Volume::setUuid(const char* uuid) {
char msg[256];
if (mUuid) {
free(mUuid);
}
if (uuid) {
mUuid = strdup(uuid);
snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(),
getFuseMountpoint(), mUuid);
} else {
mUuid = NULL;
snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint());
}
mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUuidChange, msg,
false);
}
void Volume::setUserLabel(const char* userLabel) {
char msg[256];
if (mUserLabel) {
free(mUserLabel);
}
if (userLabel) {
mUserLabel = strdup(userLabel);
snprintf(msg, sizeof(msg), "%s %s \"%s\"", getLabel(),
getFuseMountpoint(), mUserLabel);
} else {
mUserLabel = NULL;
snprintf(msg, sizeof(msg), "%s %s", getLabel(), getFuseMountpoint());
}
mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeUserLabelChange,
msg, false);
}
void Volume::setState(int state) {
char msg[255];
int oldState = mState;
@ -274,7 +303,6 @@ bool Volume::isMountpointMounted(const char *path) {
fclose(fp);
return true;
}
}
fclose(fp);
@ -413,7 +441,7 @@ int Volume::mountVol() {
continue;
}
protectFromAutorunStupidity();
extractMetadata(devicePath);
if (providesAsec && mountAsecExternal() != 0) {
SLOGE("Failed to mount secure area (%s)", strerror(errno));
@ -550,6 +578,8 @@ int Volume::unmountVol(bool force, bool revert) {
SLOGI("Encrypted volume %s reverted successfully", getMountpoint());
}
setUuid(NULL);
setUserLabel(NULL);
setState(Volume::State_Idle);
mCurrentlyMountedKdev = -1;
return 0;
@ -608,3 +638,55 @@ int Volume::initializeMbr(const char *deviceNode) {
return rc;
}
/*
* Use blkid to extract UUID and label from device, since it handles many
* obscure edge cases around partition types and formats. Always broadcasts
* updated metadata values.
*/
int Volume::extractMetadata(const char* devicePath) {
int res = 0;
std::string cmd;
cmd = BLKID_PATH;
cmd += " -c /dev/null ";
cmd += devicePath;
FILE* fp = popen(cmd.c_str(), "r");
if (!fp) {
ALOGE("Failed to run %s: %s", cmd.c_str(), strerror(errno));
res = -1;
goto done;
}
char line[1024];
char value[128];
if (fgets(line, sizeof(line), fp) != NULL) {
ALOGD("blkid reported: %s", line);
char* start = strstr(line, "UUID=") + 5;
if (sscanf(start, "\"%127[^\"]\"", value) == 1) {
setUuid(value);
} else {
setUuid(NULL);
}
start = strstr(line, "LABEL=") + 6;
if (sscanf(start, "\"%127[^\"]\"", value) == 1) {
setUserLabel(value);
} else {
setUserLabel(NULL);
}
} else {
res = -1;
}
pclose(fp);
done:
if (res == -1) {
setUuid(NULL);
setUserLabel(NULL);
}
return res;
}

View file

@ -45,11 +45,13 @@ public:
static const char *SEC_ASECDIR_EXT;
static const char *SEC_ASECDIR_INT;
static const char *ASECDIR;
static const char *LOOPDIR;
static const char *BLKID_PATH;
protected:
char *mLabel;
char* mLabel;
char* mUuid;
char* mUserLabel;
VolumeManager *mVm;
bool mDebug;
int mPartIdx;
@ -69,7 +71,9 @@ public:
int unmountVol(bool force, bool revert);
int formatVol(bool wipe);
const char *getLabel() { return mLabel; }
const char* getLabel() { return mLabel; }
const char* getUuid() { return mUuid; }
const char* getUserLabel() { return mUserLabel; }
int getState() { return mState; }
int getFlags() { return mFlags; };
@ -87,6 +91,8 @@ public:
virtual int getVolInfo(struct volume_info *v) = 0;
protected:
void setUuid(const char* uuid);
void setUserLabel(const char* userLabel);
void setState(int state);
virtual int getDeviceNodes(dev_t *devs, int max) = 0;
@ -101,7 +107,7 @@ private:
bool isMountpointMounted(const char *path);
int mountAsecExternal();
int doUnmount(const char *path, bool force);
void protectFromAutorunStupidity();
int extractMetadata(const char* devicePath);
};
typedef android::List<Volume *> VolumeCollection;