Merge "Move to modern utility methods from android::base."
diff --git a/Devmapper.cpp b/Devmapper.cpp
index 2cbed86..2510771 100644
--- a/Devmapper.cpp
+++ b/Devmapper.cpp
@@ -30,11 +30,8 @@
#include <linux/kdev_t.h>
-#define LOG_TAG "Vold"
-
-#include <cutils/log.h>
-
#include <android-base/logging.h>
+#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <utils/Trace.h>
@@ -62,42 +59,6 @@
}
}
-int Devmapper::lookupActive(const char *name_raw, char *ubuffer, size_t len) {
- auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
- const char* name = name_string.c_str();
-
- char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
- if (!buffer) {
- SLOGE("Error allocating memory (%s)", strerror(errno));
- return -1;
- }
-
- int fd;
- if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Error opening devmapper (%s)", strerror(errno));
- free(buffer);
- return -1;
- }
-
- struct dm_ioctl *io = (struct dm_ioctl *) buffer;
-
- ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
- if (ioctl(fd, DM_DEV_STATUS, io)) {
- if (errno != ENXIO) {
- SLOGE("DM_DEV_STATUS ioctl failed for lookup (%s)", strerror(errno));
- }
- free(buffer);
- close(fd);
- return -1;
- }
- close(fd);
-
- unsigned minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
- free(buffer);
- snprintf(ubuffer, len, "/dev/block/dm-%u", minor);
- return 0;
-}
-
int Devmapper::create(const char *name_raw, const char *loopFile, const char *key,
unsigned long numSectors, char *ubuffer, size_t len) {
auto name_string = StringPrintf("%s%s", kVoldPrefix, name_raw);
@@ -105,13 +66,13 @@
char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
if (!buffer) {
- SLOGE("Error allocating memory (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed malloc";
return -1;
}
int fd;
if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Error opening devmapper (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed open";
free(buffer);
return -1;
}
@@ -122,7 +83,7 @@
ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
if (ioctl(fd, DM_DEV_CREATE, io)) {
- SLOGE("Error creating device mapping (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed DM_DEV_CREATE";
free(buffer);
close(fd);
return -1;
@@ -137,7 +98,7 @@
geoParams += strlen(geoParams) + 1;
geoParams = (char *) _align(geoParams, 8);
if (ioctl(fd, DM_DEV_SET_GEOMETRY, io)) {
- SLOGE("Error setting device geometry (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed DM_DEV_SET_GEOMETRY";
free(buffer);
close(fd);
return -1;
@@ -146,7 +107,7 @@
// Retrieve the device number we were allocated
ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
if (ioctl(fd, DM_DEV_STATUS, io)) {
- SLOGE("Error retrieving devmapper status (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed DM_DEV_STATUS";
free(buffer);
close(fd);
return -1;
@@ -177,7 +138,7 @@
tgt->next = cryptParams - buffer;
if (ioctl(fd, DM_TABLE_LOAD, io)) {
- SLOGE("Error loading mapping table (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed DM_TABLE_LOAD";
free(buffer);
close(fd);
return -1;
@@ -187,7 +148,7 @@
ioctlInit(io, DEVMAPPER_BUFFER_SIZE, name, 0);
if (ioctl(fd, DM_DEV_SUSPEND, io)) {
- SLOGE("Error Resuming (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed DM_DEV_SUSPEND";
free(buffer);
close(fd);
return -1;
@@ -205,13 +166,13 @@
char *buffer = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
if (!buffer) {
- SLOGE("Error allocating memory (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed malloc";
return -1;
}
int fd;
if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Error opening devmapper (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed open";
free(buffer);
return -1;
}
@@ -223,7 +184,7 @@
if (ioctl(fd, DM_DEV_REMOVE, io)) {
if (errno != ENXIO) {
- SLOGE("Error destroying device mapping (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed DM_DEV_REMOVE";
}
free(buffer);
close(fd);
@@ -239,21 +200,21 @@
ATRACE_NAME("Devmapper::destroyAll");
char *buffer = (char *) malloc(1024 * 64);
if (!buffer) {
- SLOGE("Error allocating memory (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed malloc";
return -1;
}
memset(buffer, 0, (1024 * 64));
char *buffer2 = (char *) malloc(DEVMAPPER_BUFFER_SIZE);
if (!buffer2) {
- SLOGE("Error allocating memory (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed malloc";
free(buffer);
return -1;
}
int fd;
if ((fd = open("/dev/device-mapper", O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Error opening devmapper (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed open";
free(buffer);
free(buffer2);
return -1;
@@ -263,7 +224,7 @@
ioctlInit(io, (1024 * 64), NULL, 0);
if (ioctl(fd, DM_LIST_DEVICES, io)) {
- SLOGE("DM_LIST_DEVICES ioctl failed (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed DM_LIST_DEVICES";
free(buffer);
free(buffer2);
close(fd);
@@ -281,19 +242,20 @@
unsigned nxt = 0;
do {
n = (struct dm_name_list *) (((char *) n) + nxt);
- if (strncmp(n->name, kVoldPrefix, strlen(kVoldPrefix)) == 0) {
- LOG(DEBUG) << "Tearing down stale dm device named " << n->name;
+ auto name = std::string(n->name);
+ if (android::base::StartsWith(name, kVoldPrefix)) {
+ LOG(DEBUG) << "Tearing down stale dm device named " << name;
memset(buffer2, 0, DEVMAPPER_BUFFER_SIZE);
struct dm_ioctl *io2 = (struct dm_ioctl *) buffer2;
ioctlInit(io2, DEVMAPPER_BUFFER_SIZE, n->name, 0);
if (ioctl(fd, DM_DEV_REMOVE, io2)) {
if (errno != ENXIO) {
- PLOG(WARNING) << "Failed to destroy dm device named " << n->name;
+ PLOG(WARNING) << "Failed to destroy dm device named " << name;
}
}
} else {
- LOG(VERBOSE) << "Found unmanaged dm device named " << n->name;
+ LOG(VERBOSE) << "Found unmanaged dm device named " << name;
}
nxt = n->next;
} while (nxt);
diff --git a/Devmapper.h b/Devmapper.h
index 086ad78..7bb9786 100644
--- a/Devmapper.h
+++ b/Devmapper.h
@@ -26,7 +26,6 @@
unsigned long numSectors, char *buffer, size_t len);
static int destroy(const char *name);
static int destroyAll();
- static int lookupActive(const char *name, char *buffer, size_t len);
private:
static void *_align(void *ptr, unsigned int a);
diff --git a/Loop.cpp b/Loop.cpp
index 1eb9865..3736d6a 100644
--- a/Loop.cpp
+++ b/Loop.cpp
@@ -31,11 +31,8 @@
#include <linux/kdev_t.h>
-#define LOG_TAG "Vold"
-
-#include <cutils/log.h>
-
#include <android-base/logging.h>
+#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <utils/Trace.h>
@@ -49,161 +46,6 @@
static const char* kVoldPrefix = "vold:";
-int Loop::lookupActive(const char *id_raw, char *buffer, size_t len) {
- auto id_string = StringPrintf("%s%s", kVoldPrefix, id_raw);
- const char* id = id_string.c_str();
-
- int i;
- int fd;
- char filename[256];
-
- memset(buffer, 0, len);
-
- for (i = 0; i < LOOP_MAX; i++) {
- struct loop_info64 li;
- int rc;
-
- snprintf(filename, sizeof(filename), "/dev/block/loop%d", i);
-
- if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
- if (errno != ENOENT) {
- SLOGE("Unable to open %s (%s)", filename, strerror(errno));
- } else {
- continue;
- }
- return -1;
- }
-
- rc = ioctl(fd, LOOP_GET_STATUS64, &li);
- if (rc < 0 && errno == ENXIO) {
- close(fd);
- continue;
- }
- close(fd);
-
- if (rc < 0) {
- SLOGE("Unable to get loop status for %s (%s)", filename,
- strerror(errno));
- return -1;
- }
- if (!strncmp((const char*) li.lo_crypt_name, id, LO_NAME_SIZE)) {
- break;
- }
- }
-
- if (i == LOOP_MAX) {
- errno = ENOENT;
- return -1;
- }
- strlcpy(buffer, filename, len);
- return 0;
-}
-
-int Loop::create(const char *id_raw, const char *loopFile, char *loopDeviceBuffer, size_t len) {
- auto id_string = StringPrintf("%s%s", kVoldPrefix, id_raw);
- const char* id = id_string.c_str();
-
- int i;
- int fd;
- char filename[256];
-
- for (i = 0; i < LOOP_MAX; i++) {
- struct loop_info64 li;
- int rc;
- char *secontext = NULL;
-
- snprintf(filename, sizeof(filename), "/dev/block/loop%d", i);
-
- /*
- * The kernel starts us off with 8 loop nodes, but more
- * are created on-demand if needed.
- */
- mode_t mode = 0660 | S_IFBLK;
- unsigned int dev = (0xff & i) | ((i << 12) & 0xfff00000) | (7 << 8);
-
- if (sehandle) {
- rc = selabel_lookup(sehandle, &secontext, filename, S_IFBLK);
- if (rc == 0)
- setfscreatecon(secontext);
- }
-
- if (mknod(filename, mode, dev) < 0) {
- if (errno != EEXIST) {
- int sverrno = errno;
- SLOGE("Error creating loop device node (%s)", strerror(errno));
- if (secontext) {
- freecon(secontext);
- setfscreatecon(NULL);
- }
- errno = sverrno;
- return -1;
- }
- }
- if (secontext) {
- freecon(secontext);
- setfscreatecon(NULL);
- }
-
- if ((fd = open(filename, O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Unable to open %s (%s)", filename, strerror(errno));
- return -1;
- }
-
- rc = ioctl(fd, LOOP_GET_STATUS64, &li);
- if (rc < 0 && errno == ENXIO)
- break;
-
- close(fd);
-
- if (rc < 0) {
- SLOGE("Unable to get loop status for %s (%s)", filename,
- strerror(errno));
- return -1;
- }
- }
-
- if (i == LOOP_MAX) {
- SLOGE("Exhausted all loop devices");
- errno = ENOSPC;
- return -1;
- }
-
- strlcpy(loopDeviceBuffer, filename, len);
-
- int file_fd;
-
- if ((file_fd = open(loopFile, O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Unable to open %s (%s)", loopFile, strerror(errno));
- close(fd);
- return -1;
- }
-
- if (ioctl(fd, LOOP_SET_FD, file_fd) < 0) {
- SLOGE("Error setting up loopback interface (%s)", strerror(errno));
- close(file_fd);
- close(fd);
- return -1;
- }
-
- struct loop_info64 li;
-
- memset(&li, 0, sizeof(li));
- strlcpy((char*) li.lo_crypt_name, id, LO_NAME_SIZE);
- strlcpy((char*) li.lo_file_name, loopFile, LO_NAME_SIZE);
-
- if (ioctl(fd, LOOP_SET_STATUS64, &li) < 0) {
- SLOGE("Error setting loopback status (%s)", strerror(errno));
- close(file_fd);
- close(fd);
- return -1;
- }
-
- close(fd);
- close(file_fd);
-
- return 0;
-}
-
int Loop::create(const std::string& target, std::string& out_device) {
unique_fd ctl_fd(open("/dev/loop-control", O_RDWR | O_CLOEXEC));
if (ctl_fd.get() == -1) {
@@ -251,12 +93,12 @@
device_fd = open(loopDevice, O_RDONLY | O_CLOEXEC);
if (device_fd < 0) {
- SLOGE("Failed to open loop (%d)", errno);
+ PLOG(ERROR) << "Failed to open " << loopDevice;
return -1;
}
if (ioctl(device_fd, LOOP_CLR_FD, 0) < 0) {
- SLOGE("Failed to destroy loop (%d)", errno);
+ PLOG(ERROR) << "Failed to destroy " << loopDevice;
close(device_fd);
return -1;
}
@@ -279,7 +121,8 @@
// Poke through all devices looking for loops
while ((de = readdir(dir))) {
- if (strncmp(de->d_name, "loop", 4) != 0) continue;
+ auto test = std::string(de->d_name);
+ if (!android::base::StartsWith(test, "loop")) continue;
auto path = root + de->d_name;
unique_fd fd(open(path.c_str(), O_RDWR | O_CLOEXEC));
@@ -296,8 +139,8 @@
continue;
}
- char* id = (char*) li.lo_crypt_name;
- if (strncmp(id, kVoldPrefix, strlen(kVoldPrefix)) == 0) {
+ auto id = std::string((char*) li.lo_crypt_name);
+ if (android::base::StartsWith(id, kVoldPrefix)) {
LOG(DEBUG) << "Tearing down stale loop device at " << path << " named " << id;
if (ioctl(fd.get(), LOOP_CLR_FD, 0) < 0) {
@@ -332,22 +175,22 @@
int fd;
if ((fd = open(file, O_RDWR | O_CLOEXEC)) < 0) {
- SLOGE("Error opening imagefile (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed to open " << file;
return -1;
}
- SLOGD("Attempting to increase size of %s to %lu sectors.", file, numSectors);
+ LOG(DEBUG) << "Attempting to increase " << file << " to " << numSectors;
if (fallocate(fd, 0, 0, numSectors * 512)) {
if (errno == ENOSYS || errno == ENOTSUP) {
- SLOGW("fallocate not found. Falling back to ftruncate.");
+ PLOG(WARNING) << "fallocate not found. Falling back to ftruncate.";
if (ftruncate(fd, numSectors * 512) < 0) {
- SLOGE("Error truncating imagefile (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed to ftruncate";
close(fd);
return -1;
}
} else {
- SLOGE("Error allocating space (%s)", strerror(errno));
+ PLOG(ERROR) << "Failed to fallocate";
close(fd);
return -1;
}
diff --git a/Loop.h b/Loop.h
index 654b8ad..130c5b6 100644
--- a/Loop.h
+++ b/Loop.h
@@ -25,8 +25,6 @@
public:
static const int LOOP_MAX = 4096;
public:
- static int lookupActive(const char *id, char *buffer, size_t len);
- static int create(const char *id, const char *loopFile, char *loopDeviceBuffer, size_t len);
static int create(const std::string& file, std::string& out_device);
static int destroyByDevice(const char *loopDevice);
static int destroyAll();
diff --git a/NetlinkHandler.cpp b/NetlinkHandler.cpp
index ecda2a0..92131e9 100644
--- a/NetlinkHandler.cpp
+++ b/NetlinkHandler.cpp
@@ -19,9 +19,7 @@
#include <errno.h>
#include <string.h>
-#define LOG_TAG "Vold"
-
-#include <cutils/log.h>
+#include <android-base/logging.h>
#include <sysutils/NetlinkEvent.h>
#include "NetlinkHandler.h"
@@ -47,11 +45,11 @@
const char *subsys = evt->getSubsystem();
if (!subsys) {
- SLOGW("No subsystem found in netlink event");
+ LOG(WARNING) << "No subsystem found in netlink event";
return;
}
- if (!strcmp(subsys, "block")) {
+ if (std::string(subsys) == "block") {
vm->handleBlockEvent(evt);
}
}
diff --git a/NetlinkManager.cpp b/NetlinkManager.cpp
index 90e3c6c..409cdc8 100644
--- a/NetlinkManager.cpp
+++ b/NetlinkManager.cpp
@@ -26,9 +26,7 @@
#include <linux/netlink.h>
-#define LOG_TAG "Vold"
-
-#include <cutils/log.h>
+#include <android-base/logging.h>
#include "NetlinkManager.h"
#include "NetlinkHandler.h"
@@ -60,7 +58,7 @@
if ((mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC,
NETLINK_KOBJECT_UEVENT)) < 0) {
- SLOGE("Unable to create uevent socket: %s", strerror(errno));
+ PLOG(ERROR) << "Unable to create uevent socket";
return -1;
}
@@ -69,23 +67,23 @@
// Try using SO_RCVBUF if that fails.
if ((setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) &&
(setsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)) < 0)) {
- SLOGE("Unable to set uevent socket SO_RCVBUF/SO_RCVBUFFORCE option: %s", strerror(errno));
+ PLOG(ERROR) << "Unable to set uevent socket SO_RCVBUF/SO_RCVBUFFORCE option";
goto out;
}
if (setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
- SLOGE("Unable to set uevent socket SO_PASSCRED option: %s", strerror(errno));
+ PLOG(ERROR) << "Unable to set uevent socket SO_PASSCRED option";
goto out;
}
if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
- SLOGE("Unable to bind uevent socket: %s", strerror(errno));
+ PLOG(ERROR) << "Unable to bind uevent socket";
goto out;
}
mHandler = new NetlinkHandler(mSock);
if (mHandler->start()) {
- SLOGE("Unable to start NetlinkHandler: %s", strerror(errno));
+ PLOG(ERROR) << "Unable to start NetlinkHandler";
goto out;
}
@@ -100,7 +98,7 @@
int status = 0;
if (mHandler->stop()) {
- SLOGE("Unable to stop NetlinkHandler: %s", strerror(errno));
+ PLOG(ERROR) << "Unable to stop NetlinkHandler";
status = -1;
}
delete mHandler;
diff --git a/Process.cpp b/Process.cpp
index 1c0f504..042ba2d 100644
--- a/Process.cpp
+++ b/Process.cpp
@@ -19,6 +19,7 @@
#include <errno.h>
#include <string.h>
#include <fcntl.h>
+#include <fts.h>
#include <dirent.h>
#include <ctype.h>
#include <pwd.h>
@@ -27,196 +28,98 @@
#include <sys/stat.h>
#include <signal.h>
-#define LOG_TAG "ProcessKiller"
+#include <fstream>
+#include <unordered_set>
#include <android-base/file.h>
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <android-base/logging.h>
-#include <cutils/log.h>
#include "Process.h"
-using android::base::ReadFileToString;
using android::base::StringPrintf;
-int Process::readSymLink(const char *path, char *link, size_t max) {
- struct stat s;
- int length;
+namespace android {
+namespace vold {
- if (lstat(path, &s) < 0)
- return 0;
- if ((s.st_mode & S_IFMT) != S_IFLNK)
- return 0;
-
- // we have a symlink
- length = readlink(path, link, max- 1);
- if (length <= 0)
- return 0;
- link[length] = 0;
- return 1;
-}
-
-int Process::pathMatchesMountPoint(const char* path, const char* mountPoint) {
- int length = strlen(mountPoint);
- if (length > 1 && strncmp(path, mountPoint, length) == 0) {
- // we need to do extra checking if mountPoint does not end in a '/'
- if (mountPoint[length - 1] == '/')
- return 1;
- // if mountPoint does not have a trailing slash, we need to make sure
- // there is one in the path to avoid partial matches.
- return (path[length] == 0 || path[length] == '/');
- }
-
- return 0;
-}
-
-void Process::getProcessName(int pid, std::string& out_name) {
- if (!ReadFileToString(StringPrintf("/proc/%d/cmdline", pid), &out_name)) {
- out_name = "???";
- }
-}
-
-int Process::checkFileDescriptorSymLinks(int pid, const char *mountPoint) {
- return checkFileDescriptorSymLinks(pid, mountPoint, NULL, 0);
-}
-
-int Process::checkFileDescriptorSymLinks(int pid, const char *mountPoint, char *openFilename, size_t max) {
-
-
- // compute path to process's directory of open files
- char path[PATH_MAX];
- snprintf(path, sizeof(path), "/proc/%d/fd", pid);
- DIR *dir = opendir(path);
- if (!dir)
- return 0;
-
- // remember length of the path
- int parent_length = strlen(path);
- // append a trailing '/'
- path[parent_length++] = '/';
-
- struct dirent* de;
- while ((de = readdir(dir))) {
- if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")
- || strlen(de->d_name) + parent_length + 1 >= PATH_MAX)
- continue;
-
- // append the file name, after truncating to parent directory
- path[parent_length] = 0;
- strlcat(path, de->d_name, PATH_MAX);
-
- char link[PATH_MAX];
-
- if (readSymLink(path, link, sizeof(link)) && pathMatchesMountPoint(link, mountPoint)) {
- if (openFilename) {
- memset(openFilename, 0, max);
- strlcpy(openFilename, link, max);
+static bool checkMaps(const std::string& path, const std::string& prefix) {
+ bool found = false;
+ std::ifstream infile(path);
+ std::string line;
+ while (std::getline(infile, line)) {
+ std::string::size_type pos = line.find('/');
+ if (pos != std::string::npos) {
+ line = line.substr(pos);
+ if (android::base::StartsWith(line, prefix.c_str())) {
+ LOG(WARNING) << "Found map " << path << " referencing " << line;
+ found = true;
}
- closedir(dir);
- return 1;
}
}
-
- closedir(dir);
- return 0;
+ return found;
}
-int Process::checkFileMaps(int pid, const char *mountPoint) {
- return checkFileMaps(pid, mountPoint, NULL, 0);
-}
-
-int Process::checkFileMaps(int pid, const char *mountPoint, char *openFilename, size_t max) {
- FILE *file;
- char buffer[PATH_MAX + 100];
-
- snprintf(buffer, sizeof(buffer), "/proc/%d/maps", pid);
- file = fopen(buffer, "re");
- if (!file)
- return 0;
-
- while (fgets(buffer, sizeof(buffer), file)) {
- // skip to the path
- const char* path = strchr(buffer, '/');
- if (path && pathMatchesMountPoint(path, mountPoint)) {
- if (openFilename) {
- memset(openFilename, 0, max);
- strlcpy(openFilename, path, max);
- }
- fclose(file);
- return 1;
+static bool checkSymlink(const std::string& path, const std::string& prefix) {
+ std::string res;
+ if (android::base::Readlink(path, &res)) {
+ if (android::base::StartsWith(res, prefix.c_str())) {
+ LOG(WARNING) << "Found symlink " << path << " referencing " << res;
+ return true;
}
}
-
- fclose(file);
- return 0;
+ return false;
}
-int Process::checkSymLink(int pid, const char *mountPoint, const char *name) {
- char path[PATH_MAX];
- char link[PATH_MAX];
+int KillProcessesWithOpenFiles(const std::string& prefix, int signal) {
+ std::unordered_set<pid_t> pids;
- snprintf(path, sizeof(path), "/proc/%d/%s", pid, name);
- if (readSymLink(path, link, sizeof(link)) && pathMatchesMountPoint(link, mountPoint))
- return 1;
- return 0;
-}
-
-int Process::getPid(const char *s) {
- int result = 0;
- while (*s) {
- if (!isdigit(*s)) return -1;
- result = 10 * result + (*s++ - '0');
- }
- return result;
-}
-
-extern "C" void vold_killProcessesWithOpenFiles(const char *path, int signal) {
- Process::killProcessesWithOpenFiles(path, signal);
-}
-
-/*
- * Hunt down processes that have files open at the given mount point.
- */
-int Process::killProcessesWithOpenFiles(const char *path, int signal) {
- int count = 0;
- DIR* dir;
- struct dirent* de;
-
- if (!(dir = opendir("/proc"))) {
- SLOGE("opendir failed (%s)", strerror(errno));
- return count;
+ auto proc_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/proc"), closedir);
+ if (!proc_d) {
+ PLOG(ERROR) << "Failed to open proc";
+ return -1;
}
- while ((de = readdir(dir))) {
- int pid = getPid(de->d_name);
- if (pid == -1)
- continue;
+ struct dirent* proc_de;
+ while ((proc_de = readdir(proc_d.get())) != nullptr) {
+ // We only care about valid PIDs
+ pid_t pid;
+ if (proc_de->d_type != DT_DIR) continue;
+ if (!android::base::ParseInt(proc_de->d_name, &pid)) continue;
- std::string name;
- getProcessName(pid, name);
+ // Look for references to prefix
+ bool found = false;
+ auto path = StringPrintf("/proc/%d", pid);
+ found |= checkMaps(path + "/maps", prefix);
+ found |= checkSymlink(path + "/cwd", prefix);
+ found |= checkSymlink(path + "/root", prefix);
+ found |= checkSymlink(path + "/exe", prefix);
- char openfile[PATH_MAX];
-
- if (checkFileDescriptorSymLinks(pid, path, openfile, sizeof(openfile))) {
- SLOGE("Process %s (%d) has open file %s", name.c_str(), pid, openfile);
- } else if (checkFileMaps(pid, path, openfile, sizeof(openfile))) {
- SLOGE("Process %s (%d) has open filemap for %s", name.c_str(), pid, openfile);
- } else if (checkSymLink(pid, path, "cwd")) {
- SLOGE("Process %s (%d) has cwd within %s", name.c_str(), pid, path);
- } else if (checkSymLink(pid, path, "root")) {
- SLOGE("Process %s (%d) has chroot within %s", name.c_str(), pid, path);
- } else if (checkSymLink(pid, path, "exe")) {
- SLOGE("Process %s (%d) has executable path within %s", name.c_str(), pid, path);
+ auto fd_path = path + "/fd";
+ auto fd_d = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(fd_path.c_str()), closedir);
+ if (!fd_d) {
+ PLOG(WARNING) << "Failed to open " << fd_path;
} else {
- continue;
+ struct dirent* fd_de;
+ while ((fd_de = readdir(fd_d.get())) != nullptr) {
+ if (fd_de->d_type != DT_LNK) continue;
+ found |= checkSymlink(fd_path + "/" + fd_de->d_name, prefix);
+ }
}
- if (signal != 0) {
- SLOGW("Sending %s to process %d", strsignal(signal), pid);
- kill(pid, signal);
- count++;
+ if (found) {
+ pids.insert(pid);
}
}
- closedir(dir);
- return count;
+ if (signal != 0) {
+ for (const auto& pid : pids) {
+ LOG(WARNING) << "Sending " << strsignal(signal) << " to " << pid;
+ kill(pid, signal);
+ }
+ }
+ return pids.size();
}
+
+} // namespace vold
+} // namespace android
diff --git a/Process.h b/Process.h
index 4ddbdb9..1406782 100644
--- a/Process.h
+++ b/Process.h
@@ -17,28 +17,12 @@
#ifndef _PROCESS_H
#define _PROCESS_H
-#ifdef __cplusplus
+namespace android {
+namespace vold {
-class Process {
-public:
- static int killProcessesWithOpenFiles(const char *path, int signal);
- static int getPid(const char *s);
- static int checkSymLink(int pid, const char *path, const char *name);
- static int checkFileMaps(int pid, const char *path);
- static int checkFileMaps(int pid, const char *path, char *openFilename, size_t max);
- static int checkFileDescriptorSymLinks(int pid, const char *mountPoint);
- static int checkFileDescriptorSymLinks(int pid, const char *mountPoint, char *openFilename, size_t max);
- static void getProcessName(int pid, std::string& out_name);
-private:
- static int readSymLink(const char *path, char *link, size_t max);
- static int pathMatchesMountPoint(const char *path, const char *mountPoint);
-};
+int KillProcessesWithOpenFiles(const std::string& path, int signal);
-extern "C" {
-#endif /* __cplusplus */
- void vold_killProcessesWithOpenFiles(const char *path, int signal);
-#ifdef __cplusplus
-}
-#endif
+} // namespace vold
+} // namespace android
#endif
diff --git a/TrimTask.cpp b/TrimTask.cpp
index fafb345..2718095 100644
--- a/TrimTask.cpp
+++ b/TrimTask.cpp
@@ -20,7 +20,6 @@
#include <android-base/stringprintf.h>
#include <android-base/logging.h>
-#include <cutils/properties.h>
#include <fs_mgr.h>
#include <private/android_filesystem_config.h>
#include <hardware_legacy/power.h>
@@ -67,9 +66,9 @@
struct fstab_rec *prev_rec = NULL;
for (int i = 0; i < fstab->num_entries; i++) {
+ auto fs_type = std::string(fstab->recs[i].fs_type);
/* Skip raw partitions */
- if (!strcmp(fstab->recs[i].fs_type, "emmc") ||
- !strcmp(fstab->recs[i].fs_type, "mtd")) {
+ if (fs_type == "emmc" || fs_type == "mtd") {
continue;
}
/* Skip read-only filesystems */
diff --git a/Utils.cpp b/Utils.cpp
index a9350e8..484de90 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -22,6 +22,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
+#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <cutils/fs.h>
#include <logwrap/logwrap.h>
@@ -129,19 +130,19 @@
// we start sending signals
if (!VolumeManager::shutting_down) sleep(5);
- Process::killProcessesWithOpenFiles(cpath, SIGINT);
+ KillProcessesWithOpenFiles(path, SIGINT);
if (!VolumeManager::shutting_down) sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
- Process::killProcessesWithOpenFiles(cpath, SIGTERM);
+ KillProcessesWithOpenFiles(path, SIGTERM);
if (!VolumeManager::shutting_down) sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
}
- Process::killProcessesWithOpenFiles(cpath, SIGKILL);
+ KillProcessesWithOpenFiles(path, SIGKILL);
if (!VolumeManager::shutting_down) sleep(5);
if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
return OK;
@@ -151,25 +152,24 @@
}
status_t KillProcessesUsingPath(const std::string& path) {
- const char* cpath = path.c_str();
- if (Process::killProcessesWithOpenFiles(cpath, SIGINT) == 0) {
+ if (KillProcessesWithOpenFiles(path, SIGINT) == 0) {
return OK;
}
if (!VolumeManager::shutting_down) sleep(5);
- if (Process::killProcessesWithOpenFiles(cpath, SIGTERM) == 0) {
+ if (KillProcessesWithOpenFiles(path, SIGTERM) == 0) {
return OK;
}
if (!VolumeManager::shutting_down) sleep(5);
- if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
+ if (KillProcessesWithOpenFiles(path, SIGKILL) == 0) {
return OK;
}
if (!VolumeManager::shutting_down) sleep(5);
// Send SIGKILL a second time to determine if we've
// actually killed everyone with open files
- if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) {
+ if (KillProcessesWithOpenFiles(path, SIGKILL) == 0) {
return OK;
}
PLOG(ERROR) << "Failed to kill processes using " << path;
@@ -184,11 +184,28 @@
return OK;
}
-static status_t readMetadata(const std::string& path, std::string& fsType,
- std::string& fsUuid, std::string& fsLabel, bool untrusted) {
- fsType.clear();
- fsUuid.clear();
- fsLabel.clear();
+bool FindValue(const std::string& raw, const std::string& key, std::string* value) {
+ auto qual = key + "=\"";
+ auto start = raw.find(qual);
+ if (start > 0 && raw[start - 1] != ' ') {
+ start = raw.find(qual, start + 1);
+ }
+
+ if (start == std::string::npos) return false;
+ start += qual.length();
+
+ auto end = raw.find("\"", start);
+ if (end == std::string::npos) return false;
+
+ *value = raw.substr(start, end - start);
+ return true;
+}
+
+static status_t readMetadata(const std::string& path, std::string* fsType,
+ std::string* fsUuid, std::string* fsLabel, bool untrusted) {
+ fsType->clear();
+ fsUuid->clear();
+ fsLabel->clear();
std::vector<std::string> cmd;
cmd.push_back(kBlkidPath);
@@ -209,36 +226,23 @@
return res;
}
- char value[128];
for (const auto& line : output) {
// Extract values from blkid output, if defined
- const char* cline = line.c_str();
- const char* start = strstr(cline, "TYPE=");
- if (start != nullptr && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) {
- fsType = value;
- }
-
- start = strstr(cline, "UUID=");
- if (start != nullptr && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) {
- fsUuid = value;
- }
-
- start = strstr(cline, "LABEL=");
- if (start != nullptr && sscanf(start + 6, "\"%127[^\"]\"", value) == 1) {
- fsLabel = value;
- }
+ FindValue(line, "TYPE", fsType);
+ FindValue(line, "UUID", fsUuid);
+ FindValue(line, "LABEL", fsLabel);
}
return OK;
}
-status_t ReadMetadata(const std::string& path, std::string& fsType,
- std::string& fsUuid, std::string& fsLabel) {
+status_t ReadMetadata(const std::string& path, std::string* fsType,
+ std::string* fsUuid, std::string* fsLabel) {
return readMetadata(path, fsType, fsUuid, fsLabel, false);
}
-status_t ReadMetadataUntrusted(const std::string& path, std::string& fsType,
- std::string& fsUuid, std::string& fsLabel) {
+status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType,
+ std::string* fsUuid, std::string* fsLabel) {
return readMetadata(path, fsType, fsUuid, fsLabel, true);
}
@@ -673,15 +677,27 @@
return OK;
}
-status_t SaneReadLinkAt(int dirfd, const char* path, char* buf, size_t bufsiz) {
- ssize_t len = readlinkat(dirfd, path, buf, bufsiz);
- if (len < 0) {
- return -1;
- } else if (len == (ssize_t) bufsiz) {
- return -1;
- } else {
- buf[len] = '\0';
- return 0;
+bool Readlinkat(int dirfd, const std::string& path, std::string* result) {
+ // Shamelessly borrowed from android::base::Readlink()
+ result->clear();
+
+ // Most Linux file systems (ext2 and ext4, say) limit symbolic links to
+ // 4095 bytes. Since we'll copy out into the string anyway, it doesn't
+ // waste memory to just start there. We add 1 so that we can recognize
+ // whether it actually fit (rather than being truncated to 4095).
+ std::vector<char> buf(4095 + 1);
+ while (true) {
+ ssize_t size = readlinkat(dirfd, path.c_str(), &buf[0], buf.size());
+ // Unrecoverable error?
+ if (size == -1)
+ return false;
+ // It fit! (If size == buf.size(), it may have been truncated.)
+ if (static_cast<size_t>(size) < buf.size()) {
+ result->assign(&buf[0], size);
+ return true;
+ }
+ // Double our buffer and try again.
+ buf.resize(buf.size() * 2);
}
}
diff --git a/Utils.h b/Utils.h
index 8d09ddf..9163006 100644
--- a/Utils.h
+++ b/Utils.h
@@ -53,13 +53,15 @@
/* Creates bind mount from source to target */
status_t BindMount(const std::string& source, const std::string& target);
+bool FindValue(const std::string& raw, const std::string& key, std::string* value);
+
/* Reads filesystem metadata from device at path */
-status_t ReadMetadata(const std::string& path, std::string& fsType,
- std::string& fsUuid, std::string& fsLabel);
+status_t ReadMetadata(const std::string& path, std::string* fsType,
+ std::string* fsUuid, std::string* fsLabel);
/* Reads filesystem metadata from untrusted device at path */
-status_t ReadMetadataUntrusted(const std::string& path, std::string& fsType,
- std::string& fsUuid, std::string& fsLabel);
+status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType,
+ std::string* fsUuid, std::string* fsLabel);
/* Returns either WEXITSTATUS() status, or a negative errno */
status_t ForkExecvp(const std::vector<std::string>& args);
@@ -112,7 +114,8 @@
status_t RestoreconRecursive(const std::string& path);
-status_t SaneReadLinkAt(int dirfd, const char* path, char* buf, size_t bufsiz);
+// TODO: promote to android::base
+bool Readlinkat(int dirfd, const std::string& path, std::string* result);
/* Checks if Android is running in QEMU */
bool IsRunningInEmulator();
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index a900ba1..c82eb92 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -37,10 +37,6 @@
#include <private/android_filesystem_config.h>
#include <utils/Trace.h>
-#ifndef LOG_TAG
-#define LOG_TAG "vold"
-#endif
-
using android::base::StringPrintf;
using std::endl;
@@ -423,7 +419,7 @@
CHECK_ARGUMENT_PATH(path);
ACQUIRE_LOCK;
- return translate(VolumeManager::Instance()->mkdirs(path.c_str()));
+ return translate(VolumeManager::Instance()->mkdirs(path));
}
binder::Status VoldNativeService::createObb(const std::string& sourcePath,
@@ -519,7 +515,7 @@
if (rc == 0) {
return 0;
} else if (tries == 0) {
- Process::killProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
+ KillProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
}
}
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index d441297..c1d51d9 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -19,7 +19,6 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#include <fts.h>
#include <mntent.h>
#include <stdio.h>
#include <stdlib.h>
@@ -34,14 +33,11 @@
#include <linux/kdev_t.h>
-#define LOG_TAG "Vold"
-
-#include <openssl/md5.h>
-
#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include <cutils/fs.h>
-#include <cutils/log.h>
#include <utils/Trace.h>
#include <selinux/android.h>
@@ -98,7 +94,7 @@
int VolumeManager::updateVirtualDisk() {
ATRACE_NAME("VolumeManager::updateVirtualDisk");
- if (property_get_bool(kPropVirtualDisk, false)) {
+ if (android::base::GetBoolProperty(kPropVirtualDisk, false)) {
if (access(kPathVirtualDisk, F_OK) != 0) {
Loop::createImageFile(kPathVirtualDisk, kSizeVirtualDisk / 512);
}
@@ -323,13 +319,12 @@
std::string target(StringPrintf("/mnt/user/%d/primary", userId));
if (TEMP_FAILURE_RETRY(unlink(target.c_str()))) {
if (errno != ENOENT) {
- SLOGW("Failed to unlink %s: %s", target.c_str(), strerror(errno));
+ PLOG(WARNING) << "Failed to unlink " << target;
}
}
LOG(DEBUG) << "Linking " << source << " to " << target;
if (TEMP_FAILURE_RETRY(symlink(source.c_str(), target.c_str()))) {
- SLOGW("Failed to link %s to %s: %s", source.c_str(), target.c_str(),
- strerror(errno));
+ PLOG(WARNING) << "Failed to link";
return -errno;
}
return 0;
@@ -372,12 +367,10 @@
return 0;
}
-static int unmount_tree(const char* path) {
- size_t path_len = strlen(path);
-
+static int unmount_tree(const std::string& prefix) {
FILE* fp = setmntent("/proc/mounts", "r");
if (fp == NULL) {
- ALOGE("Error opening /proc/mounts: %s", strerror(errno));
+ PLOG(ERROR) << "Failed to open /proc/mounts";
return -errno;
}
@@ -386,15 +379,16 @@
std::list<std::string> toUnmount;
mntent* mentry;
while ((mentry = getmntent(fp)) != NULL) {
- if (strncmp(mentry->mnt_dir, path, path_len) == 0) {
- toUnmount.push_front(std::string(mentry->mnt_dir));
+ auto test = std::string(mentry->mnt_dir) + "/";
+ if (android::base::StartsWith(test, prefix.c_str())) {
+ toUnmount.push_front(test);
}
}
endmntent(fp);
for (const auto& path : toUnmount) {
if (umount2(path.c_str(), MNT_DETACH)) {
- ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
+ PLOG(ERROR) << "Failed to unmount " << path;
}
}
return 0;
@@ -405,8 +399,8 @@
DIR* dir;
struct dirent* de;
- char rootName[PATH_MAX];
- char pidName[PATH_MAX];
+ std::string rootName;
+ std::string pidName;
int pidFd;
int nsFd;
struct stat sb;
@@ -418,8 +412,8 @@
}
// Figure out root namespace to compare against below
- if (android::vold::SaneReadLinkAt(dirfd(dir), "1/ns/mnt", rootName, PATH_MAX) == -1) {
- PLOG(ERROR) << "Failed to readlink";
+ if (!android::vold::Readlinkat(dirfd(dir), "1/ns/mnt", &rootName)) {
+ PLOG(ERROR) << "Failed to read root namespace";
closedir(dir);
return -1;
}
@@ -443,11 +437,11 @@
// Matches so far, but refuse to touch if in root namespace
LOG(DEBUG) << "Found matching PID " << de->d_name;
- if (android::vold::SaneReadLinkAt(pidFd, "ns/mnt", pidName, PATH_MAX) == -1) {
+ if (!android::vold::Readlinkat(pidFd, "ns/mnt", &pidName)) {
PLOG(WARNING) << "Failed to read namespace for " << de->d_name;
goto next;
}
- if (!strcmp(rootName, pidName)) {
+ if (rootName == pidName) {
LOG(WARNING) << "Skipping due to root namespace";
goto next;
}
@@ -465,7 +459,7 @@
_exit(1);
}
- unmount_tree("/storage");
+ unmount_tree("/storage/");
std::string storageSource;
if (mode == "default") {
@@ -568,7 +562,7 @@
// force unmount those just to be safe.
FILE* fp = setmntent("/proc/mounts", "r");
if (fp == NULL) {
- SLOGE("Error opening /proc/mounts: %s", strerror(errno));
+ PLOG(ERROR) << "Failed to open /proc/mounts";
return -errno;
}
@@ -577,9 +571,10 @@
std::list<std::string> toUnmount;
mntent* mentry;
while ((mentry = getmntent(fp)) != NULL) {
- if (strncmp(mentry->mnt_dir, "/mnt/", 5) == 0
- || strncmp(mentry->mnt_dir, "/storage/", 9) == 0) {
- toUnmount.push_front(std::string(mentry->mnt_dir));
+ auto test = std::string(mentry->mnt_dir);
+ if (android::base::StartsWith(test, "/mnt/")
+ || android::base::StartsWith(test, "/storage/")) {
+ toUnmount.push_front(test);
}
}
endmntent(fp);
@@ -597,13 +592,13 @@
return vm->unmountAll();
}
-int VolumeManager::mkdirs(const char* path) {
+int VolumeManager::mkdirs(const std::string& path) {
// Only offer to create directories for paths managed by vold
- if (strncmp(path, "/storage/", 9) == 0) {
+ if (android::base::StartsWith(path, "/storage/")) {
// fs_mkdirs() does symlink checking and relative path enforcement
- return fs_mkdirs(path, 0700);
+ return fs_mkdirs(path.c_str(), 0700);
} else {
- SLOGE("Failed to find mounted volume for %s", path);
+ LOG(ERROR) << "Failed to find mounted volume for " << path;
return -EINVAL;
}
}
@@ -694,21 +689,14 @@
// Matches so far, but refuse to touch if in root namespace
{
- char rootName[PATH_MAX];
- char pidName[PATH_MAX];
- const int root_result =
- android::vold::SaneReadLinkAt(dir.get(), "1/ns/mnt", rootName, PATH_MAX);
- const int pid_result =
- android::vold::SaneReadLinkAt(pid_fd.get(), "ns/mnt", pidName, PATH_MAX);
- if (root_result == -1) {
- LOG(ERROR) << "Failed to readlink for /proc/1/ns/mnt";
+ std::string rootName;
+ std::string pidName;
+ if (!android::vold::Readlinkat(dir.get(), "1/ns/mnt", &rootName)
+ || !android::vold::Readlinkat(pid_fd.get(), "ns/mnt", &pidName)) {
+ PLOG(ERROR) << "Failed to read namespaces";
return -EPERM;
}
- if (pid_result == -1) {
- LOG(ERROR) << "Failed to readlink for /proc/" << pid << "/ns/mnt";
- return -EPERM;
- }
- if (!strcmp(rootName, pidName)) {
+ if (rootName == pidName) {
LOG(ERROR) << "Don't mount appfuse in root namespace";
return -EPERM;
}
diff --git a/VolumeManager.h b/VolumeManager.h
index dcfbdad..4f62de9 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -123,7 +123,7 @@
* is treated as filename and ignored, unless the path ends with "/". Also
* ensures that path belongs to a volume managed by vold.
*/
- int mkdirs(const char* path);
+ int mkdirs(const std::string& path);
int createObb(const std::string& path, const std::string& key, int32_t ownerGid,
std::string* outVolId);
diff --git a/cryptfs.cpp b/cryptfs.cpp
index 08a3d16..ae9b0af 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -1277,10 +1277,10 @@
if (kill) {
if (i == (WAIT_UNMOUNT_COUNT - 3)) {
SLOGW("sending SIGHUP to processes with open files\n");
- vold_killProcessesWithOpenFiles(mountpoint, SIGTERM);
+ android::vold::KillProcessesWithOpenFiles(mountpoint, SIGTERM);
} else if (i == (WAIT_UNMOUNT_COUNT - 2)) {
SLOGW("sending SIGKILL to processes with open files\n");
- vold_killProcessesWithOpenFiles(mountpoint, SIGKILL);
+ android::vold::KillProcessesWithOpenFiles(mountpoint, SIGKILL);
}
}
@@ -1291,7 +1291,7 @@
SLOGD("unmounting %s succeeded\n", mountpoint);
rc = 0;
} else {
- vold_killProcessesWithOpenFiles(mountpoint, 0);
+ android::vold::KillProcessesWithOpenFiles(mountpoint, 0);
SLOGE("unmounting %s failed: %s\n", mountpoint, strerror(err));
rc = -1;
}
diff --git a/fs/Ext4.cpp b/fs/Ext4.cpp
index 1898155..89b8414 100644
--- a/fs/Ext4.cpp
+++ b/fs/Ext4.cpp
@@ -146,7 +146,7 @@
rc = mount(c_source, c_target, "ext4", flags, NULL);
if (rc && errno == EROFS) {
- SLOGE("%s appears to be a read only filesystem - retrying mount RO", c_source);
+ LOG(ERROR) << source << " appears to be a read only filesystem - retrying mount RO";
flags |= MS_RDONLY;
rc = mount(c_source, c_target, "ext4", flags, NULL);
}
diff --git a/fs/Vfat.cpp b/fs/Vfat.cpp
index dc1fe33..538178e 100644
--- a/fs/Vfat.cpp
+++ b/fs/Vfat.cpp
@@ -35,12 +35,8 @@
#include <linux/kdev_t.h>
-#define LOG_TAG "Vold"
-
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
#include <selinux/selinux.h>
#include <logwrap/logwrap.h>
@@ -65,11 +61,6 @@
}
status_t Check(const std::string& source) {
- if (access(kFsckPath, X_OK)) {
- SLOGW("Skipping fs checks\n");
- return 0;
- }
-
int pass = 1;
int rc = 0;
do {
@@ -83,38 +74,37 @@
rc = ForkExecvp(cmd, sFsckUntrustedContext);
if (rc < 0) {
- SLOGE("Filesystem check failed due to logwrap error");
+ LOG(ERROR) << "Filesystem check failed due to logwrap error";
errno = EIO;
return -1;
}
switch(rc) {
case 0:
- SLOGI("Filesystem check completed OK");
+ LOG(INFO) << "Filesystem check completed OK";
return 0;
case 2:
- SLOGE("Filesystem check failed (not a FAT filesystem)");
+ LOG(ERROR) << "Filesystem check failed (not a FAT filesystem)";
errno = ENODATA;
return -1;
case 4:
if (pass++ <= 3) {
- SLOGW("Filesystem modified - rechecking (pass %d)",
- pass);
+ LOG(WARNING) << "Filesystem modified - rechecking (pass " << pass << ")";
continue;
}
- SLOGE("Failing check after too many rechecks");
+ LOG(ERROR) << "Failing check after too many rechecks";
errno = EIO;
return -1;
case 8:
- SLOGE("Filesystem check failed (no filesystem)");
+ LOG(ERROR) << "Filesystem check failed (no filesystem)";
errno = ENODATA;
return -1;
default:
- SLOGE("Filesystem check failed (unknown exit code %d)", rc);
+ LOG(ERROR) << "Filesystem check failed (unknown exit code " << rc << ")";
errno = EIO;
return -1;
}
@@ -128,7 +118,6 @@
bool createLost) {
int rc;
unsigned long flags;
- char mountData[255];
const char* c_source = source.c_str();
const char* c_target = target.c_str();
@@ -139,31 +128,29 @@
flags |= (ro ? MS_RDONLY : 0);
flags |= (remount ? MS_REMOUNT : 0);
- snprintf(mountData, sizeof(mountData),
+ auto mountData = android::base::StringPrintf(
"utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed",
ownerUid, ownerGid, permMask, permMask);
- rc = mount(c_source, c_target, "vfat", flags, mountData);
+ rc = mount(c_source, c_target, "vfat", flags, mountData.c_str());
if (rc && errno == EROFS) {
- SLOGE("%s appears to be a read only filesystem - retrying mount RO", c_source);
+ LOG(ERROR) << source << " appears to be a read only filesystem - retrying mount RO";
flags |= MS_RDONLY;
- rc = mount(c_source, c_target, "vfat", flags, mountData);
+ rc = mount(c_source, c_target, "vfat", flags, mountData.c_str());
}
if (rc == 0 && createLost) {
- char *lost_path;
- asprintf(&lost_path, "%s/LOST.DIR", c_target);
- if (access(lost_path, F_OK)) {
+ auto lost_path = android::base::StringPrintf("%s/LOST.DIR", target.c_str());
+ if (access(lost_path.c_str(), F_OK)) {
/*
* Create a LOST.DIR in the root so we have somewhere to put
* lost cluster chains (fsck_msdos doesn't currently do this)
*/
- if (mkdir(lost_path, 0755)) {
- SLOGE("Unable to create LOST.DIR (%s)", strerror(errno));
+ if (mkdir(lost_path.c_str(), 0755)) {
+ PLOG(ERROR) << "Unable to create LOST.DIR";
}
}
- free(lost_path);
}
return rc;
@@ -189,16 +176,16 @@
int rc = ForkExecvp(cmd);
if (rc < 0) {
- SLOGE("Filesystem format failed due to logwrap error");
+ LOG(ERROR) << "Filesystem format failed due to logwrap error";
errno = EIO;
return -1;
}
if (rc == 0) {
- SLOGI("Filesystem formatted OK");
+ LOG(INFO) << "Filesystem formatted OK";
return 0;
} else {
- SLOGE("Format failed (unknown exit code %d)", rc);
+ LOG(ERROR) << "Format failed (unknown exit code " << rc << ")";
errno = EIO;
return -1;
}
diff --git a/main.cpp b/main.cpp
index 30f60a1..cca738e 100644
--- a/main.cpp
+++ b/main.cpp
@@ -25,9 +25,9 @@
#include "sehandle.h"
#include <android-base/logging.h>
+#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <cutils/klog.h>
-#include <cutils/properties.h>
#include <utils/Trace.h>
#include <stdio.h>
@@ -88,7 +88,7 @@
exit(1);
}
- if (property_get_bool("vold.debug", false)) {
+ if (android::base::GetBoolProperty("vold.debug", false)) {
vm->setDebug(true);
}
@@ -120,8 +120,8 @@
// This call should go after listeners are started to avoid
// a deadlock between vold and init (see b/34278978 for details)
- property_set("vold.has_adoptable", has_adoptable ? "1" : "0");
- property_set("vold.has_quota", has_quota ? "1" : "0");
+ android::base::SetProperty("vold.has_adoptable", has_adoptable ? "1" : "0");
+ android::base::SetProperty("vold.has_quota", has_quota ? "1" : "0");
// Do coldboot here so it won't block booting,
// also the cold boot is needed in case we have flash drive
@@ -240,7 +240,7 @@
*has_adoptable = true;
}
if (fs_mgr_is_noemulatedsd(rec)
- || property_get_bool("vold.debug.default_primary", false)) {
+ || android::base::GetBoolProperty("vold.debug.default_primary", false)) {
flags |= android::vold::Disk::Flags::kDefaultPrimary;
}
diff --git a/model/Disk.cpp b/model/Disk.cpp
index 5b0c981..291c2e1 100644
--- a/model/Disk.cpp
+++ b/model/Disk.cpp
@@ -26,6 +26,8 @@
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+#include <android-base/parseint.h>
#include <diskconfig/diskconfig.h>
#include <ext4_utils/ext4_crypt.h>
@@ -263,7 +265,11 @@
PLOG(WARNING) << "Failed to read manufacturer from " << path;
return -errno;
}
- uint64_t manfid = strtoll(tmp.c_str(), nullptr, 16);
+ int64_t manfid;
+ if (!android::base::ParseInt(tmp, &manfid)) {
+ PLOG(WARNING) << "Failed to parse manufacturer " << tmp;
+ return -EINVAL;
+ }
// Our goal here is to give the user a meaningful label, ideally
// matching whatever is silk-screened on the card. To reduce
// user confusion, this list doesn't contain white-label manfid.
@@ -295,7 +301,7 @@
}
status_t Disk::readPartitions() {
- int8_t maxMinors = getMaxMinors();
+ int maxMinors = getMaxMinors();
if (maxMinors < 0) {
return -ENOTSUP;
}
@@ -324,31 +330,40 @@
Table table = Table::kUnknown;
bool foundParts = false;
for (const auto& line : output) {
- char* cline = (char*) line.c_str();
- char* token = strtok(cline, kSgdiskToken);
- if (token == nullptr) continue;
+ auto split = android::base::Split(line, kSgdiskToken);
+ auto it = split.begin();
+ if (it == split.end()) continue;
- if (!strcmp(token, "DISK")) {
- const char* type = strtok(nullptr, kSgdiskToken);
- if (!strcmp(type, "mbr")) {
+ if (*it == "DISK") {
+ if (++it == split.end()) continue;
+ if (*it == "mbr") {
table = Table::kMbr;
- } else if (!strcmp(type, "gpt")) {
+ } else if (*it == "gpt") {
table = Table::kGpt;
+ } else {
+ LOG(WARNING) << "Invalid partition table " << *it;
+ continue;
}
- } else if (!strcmp(token, "PART")) {
+ } else if (*it == "PART") {
foundParts = true;
- int i = strtol(strtok(nullptr, kSgdiskToken), nullptr, 10);
- if (i <= 0 || i > maxMinors) {
- LOG(WARNING) << mId << " is ignoring partition " << i
- << " beyond max supported devices";
+
+ if (++it == split.end()) continue;
+ int i = 0;
+ if (!android::base::ParseInt(*it, &i, 1, maxMinors)) {
+ LOG(WARNING) << "Invalid partition number " << *it;
continue;
}
dev_t partDevice = makedev(major(mDevice), minor(mDevice) + i);
if (table == Table::kMbr) {
- const char* type = strtok(nullptr, kSgdiskToken);
+ if (++it == split.end()) continue;
+ int type = 0;
+ if (!android::base::ParseInt("0x" + *it, &type)) {
+ LOG(WARNING) << "Invalid partition type " << *it;
+ continue;
+ }
- switch (strtol(type, nullptr, 16)) {
+ switch (type) {
case 0x06: // FAT16
case 0x0b: // W95 FAT32 (LBA)
case 0x0c: // W95 FAT32 (LBA)
@@ -357,12 +372,14 @@
break;
}
} else if (table == Table::kGpt) {
- const char* typeGuid = strtok(nullptr, kSgdiskToken);
- const char* partGuid = strtok(nullptr, kSgdiskToken);
+ if (++it == split.end()) continue;
+ auto typeGuid = *it;
+ if (++it == split.end()) continue;
+ auto partGuid = *it;
- if (!strcasecmp(typeGuid, kGptBasicData)) {
+ if (android::base::EqualsIgnoreCase(typeGuid, kGptBasicData)) {
createPublicVolume(partDevice);
- } else if (!strcasecmp(typeGuid, kGptAndroidExpand)) {
+ } else if (android::base::EqualsIgnoreCase(typeGuid, kGptAndroidExpand)) {
createPrivateVolume(partDevice, partGuid);
}
}
@@ -375,7 +392,7 @@
std::string fsType;
std::string unused;
- if (ReadMetadataUntrusted(mDevPath, fsType, unused, unused) == OK) {
+ if (ReadMetadataUntrusted(mDevPath, &fsType, &unused, &unused) == OK) {
createPublicVolume(mDevice);
} else {
LOG(WARNING) << mId << " failed to identify, giving up";
diff --git a/model/PrivateVolume.cpp b/model/PrivateVolume.cpp
index 3152313..48d041b 100644
--- a/model/PrivateVolume.cpp
+++ b/model/PrivateVolume.cpp
@@ -53,7 +53,7 @@
}
status_t PrivateVolume::readMetadata() {
- status_t res = ReadMetadata(mDmDevPath, mFsType, mFsUuid, mFsLabel);
+ status_t res = ReadMetadata(mDmDevPath, &mFsType, &mFsUuid, &mFsLabel);
auto listener = getListener();
if (listener) listener->onVolumeMetadataChanged(getId(), mFsType, mFsUuid, mFsLabel);
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index f80f59e..98c897f 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -52,7 +52,7 @@
}
status_t PublicVolume::readMetadata() {
- status_t res = ReadMetadataUntrusted(mDevPath, mFsType, mFsUuid, mFsLabel);
+ status_t res = ReadMetadataUntrusted(mDevPath, &mFsType, &mFsUuid, &mFsLabel);
auto listener = getListener();
if (listener) listener->onVolumeMetadataChanged(getId(), mFsType, mFsUuid, mFsLabel);
diff --git a/tests/Android.mk b/tests/Android.mk
index 3127352..8f2cda7 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -12,6 +12,7 @@
LOCAL_SRC_FILES := \
cryptfs_test.cpp \
+ Utils_test.cpp \
VolumeManager_test.cpp \
LOCAL_MODULE := vold_tests
diff --git a/tests/Utils_test.cpp b/tests/Utils_test.cpp
new file mode 100644
index 0000000..ab9809e
--- /dev/null
+++ b/tests/Utils_test.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "../Utils.h"
+
+namespace android {
+namespace vold {
+
+class UtilsTest : public testing::Test {
+};
+
+TEST_F(UtilsTest, FindValueTest) {
+ std::string tmp;
+
+ ASSERT_FALSE(FindValue("", "KEY", &tmp));
+ ASSERT_FALSE(FindValue("BADKEY=\"VALUE\"", "KEY", &tmp));
+
+ ASSERT_TRUE(FindValue("KEY=\"VALUE\"", "KEY", &tmp));
+ ASSERT_EQ("VALUE", tmp);
+
+ ASSERT_TRUE(FindValue("FOO=\"BAR\" KEY=\"VALUE VALUE\" BAR=\"BAZ\"", "KEY", &tmp));
+ ASSERT_EQ("VALUE VALUE", tmp);
+
+ ASSERT_TRUE(FindValue("BADKEY=\"VALUE\" KEY=\"BAZ\"", "KEY", &tmp));
+ ASSERT_EQ("BAZ", tmp);
+}
+
+}
+}