From 46c301c03e03ddae5df3b91b73e20d1d5f9999ae Mon Sep 17 00:00:00 2001 From: Octavian Purdila Date: Mon, 5 May 2014 15:13:12 +0300 Subject: [PATCH] vold: wildcard support for device path matching Switching the kernel to the new sysfs layout (unselecting CONFIG_SYSFS_DEPRECATED) complicates VolD block device recognition. The uevents are reporting full specific paths, such as: /devices/pci0000:0e/0000:0e:18.0/mmc_host/mmc0/mmc0:1234/block/mmcblk0 Because the full device path may contain variable IDs (in this MMC case "1234") using full path entries in fstab does not work. Android supports partial matches but only as a prefix at the beginning of the path. This patch adds support for matching shell wildcard patterns via fnmatch(). The prefix matching rule is preserved, but if it is detected a warning is issued. Change-Id: Ia0c5eddec06bd71bec6ce838be3b5345278e0bab Author: Octavian Purdila Signed-off-by: Radu Moisan Signed-off-by: Jim Bride Reviewed-by: Bergeron, Michael Tested-by: Uyyala, Sridhar Reviewed-by: Leung, Daniel Reviewed-by: Uyyala, Sridhar --- DirectVolume.cpp | 45 +++++++++++++++++++++++++++++++++++++++++---- DirectVolume.h | 14 +++++++++++++- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/DirectVolume.cpp b/DirectVolume.cpp index 67f89ea..9de7aea 100644 --- a/DirectVolume.cpp +++ b/DirectVolume.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -33,6 +34,42 @@ // #define PARTITION_DEBUG +PathInfo::PathInfo(const char *p) +{ + warned = false; + pattern = strdup(p); + + if (!strchr(pattern, '*')) { + patternType = prefix; + } else { + patternType = wildcard; + } +} + +PathInfo::~PathInfo() +{ + free(pattern); +} + +bool PathInfo::match(const char *path) +{ + switch (patternType) { + case prefix: + { + bool ret = (strncmp(path, pattern, strlen(pattern)) == 0); + if (!warned && ret && (strlen(pattern) != strlen(path))) { + SLOGW("Deprecated implied prefix pattern detected, please use '%s*' instead", pattern); + warned = true; + } + return ret; + } + case wildcard: + return fnmatch(pattern, path, 0) == 0; + } + SLOGE("Bad matching type"); + return false; +} + DirectVolume::DirectVolume(VolumeManager *vm, const fstab_rec* rec, int flags) : Volume(vm, rec, flags) { mPaths = new PathCollection(); @@ -62,12 +99,12 @@ DirectVolume::~DirectVolume() { PathCollection::iterator it; for (it = mPaths->begin(); it != mPaths->end(); ++it) - free(*it); + delete *it; delete mPaths; } int DirectVolume::addPath(const char *path) { - mPaths->push_back(strdup(path)); + mPaths->push_back(new PathInfo(path)); return 0; } @@ -96,7 +133,7 @@ int DirectVolume::handleBlockEvent(NetlinkEvent *evt) { PathCollection::iterator it; for (it = mPaths->begin(); it != mPaths->end(); ++it) { - if (!strncmp(dp, *it, strlen(*it))) { + if ((*it)->match(dp)) { /* We can handle this disk */ int action = evt->getAction(); const char *devtype = evt->findParam("DEVTYPE"); @@ -407,7 +444,7 @@ int DirectVolume::updateDeviceInfo(char *new_path, int new_major, int new_minor) } it = mPaths->begin(); - free(*it); /* Free the string storage */ + delete *it; /* Free the string storage */ mPaths->erase(it); /* Remove it from the list */ addPath(new_path); /* Put the new path on the list */ diff --git a/DirectVolume.h b/DirectVolume.h index beda7c3..b1388bb 100644 --- a/DirectVolume.h +++ b/DirectVolume.h @@ -21,7 +21,19 @@ #include "Volume.h" -typedef android::List PathCollection; +class PathInfo { +public: + PathInfo(const char *pattern); + ~PathInfo(); + bool match(const char *path); +private: + bool warned; + char *pattern; + enum PatternType { prefix, wildcard }; + PatternType patternType; +}; + +typedef android::List PathCollection; class DirectVolume : public Volume { public: -- 2.11.0