Merge "init: use unique_fd in builtins.cpp"
am: c34afb1cd5
Change-Id: I9f1fef77ab4d3f873180f305177e586d44a22c49
This commit is contained in:
commit
76756aa1dd
1 changed files with 40 additions and 62 deletions
|
|
@ -44,7 +44,9 @@
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <android-base/parseint.h>
|
#include <android-base/parseint.h>
|
||||||
#include <android-base/properties.h>
|
#include <android-base/properties.h>
|
||||||
|
#include <android-base/stringprintf.h>
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
|
#include <android-base/unique_fd.h>
|
||||||
#include <bootloader_message/bootloader_message.h>
|
#include <bootloader_message/bootloader_message.h>
|
||||||
#include <cutils/android_reboot.h>
|
#include <cutils/android_reboot.h>
|
||||||
#include <ext4_utils/ext4_crypt.h>
|
#include <ext4_utils/ext4_crypt.h>
|
||||||
|
|
@ -66,6 +68,8 @@
|
||||||
|
|
||||||
using namespace std::literals::string_literals;
|
using namespace std::literals::string_literals;
|
||||||
|
|
||||||
|
using android::base::unique_fd;
|
||||||
|
|
||||||
#define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
|
#define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
@ -74,44 +78,36 @@ namespace init {
|
||||||
static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
|
static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
|
||||||
|
|
||||||
static int insmod(const char *filename, const char *options, int flags) {
|
static int insmod(const char *filename, const char *options, int flags) {
|
||||||
int fd = open(filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
|
unique_fd fd(TEMP_FAILURE_RETRY(open(filename, O_RDONLY | O_NOFOLLOW | O_CLOEXEC)));
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
PLOG(ERROR) << "insmod: open(\"" << filename << "\") failed";
|
PLOG(ERROR) << "insmod: open(\"" << filename << "\") failed";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int rc = syscall(__NR_finit_module, fd, options, flags);
|
int rc = syscall(__NR_finit_module, fd.get(), options, flags);
|
||||||
if (rc == -1) {
|
if (rc == -1) {
|
||||||
PLOG(ERROR) << "finit_module for \"" << filename << "\" failed";
|
PLOG(ERROR) << "finit_module for \"" << filename << "\" failed";
|
||||||
}
|
}
|
||||||
close(fd);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __ifupdown(const char *interface, int up) {
|
static int __ifupdown(const char *interface, int up) {
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int s, ret;
|
|
||||||
|
|
||||||
strlcpy(ifr.ifr_name, interface, IFNAMSIZ);
|
strlcpy(ifr.ifr_name, interface, IFNAMSIZ);
|
||||||
|
|
||||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
unique_fd s(TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_DGRAM, 0)));
|
||||||
if (s < 0)
|
if (s < 0) return -1;
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = ioctl(s, SIOCGIFFLAGS, &ifr);
|
int ret = ioctl(s, SIOCGIFFLAGS, &ifr);
|
||||||
if (ret < 0) {
|
if (ret < 0) return ret;
|
||||||
goto done;
|
|
||||||
|
if (up) {
|
||||||
|
ifr.ifr_flags |= IFF_UP;
|
||||||
|
} else {
|
||||||
|
ifr.ifr_flags &= ~IFF_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (up)
|
return ioctl(s, SIOCSIFFLAGS, &ifr);
|
||||||
ifr.ifr_flags |= IFF_UP;
|
|
||||||
else
|
|
||||||
ifr.ifr_flags &= ~IFF_UP;
|
|
||||||
|
|
||||||
ret = ioctl(s, SIOCSIFFLAGS, &ifr);
|
|
||||||
|
|
||||||
done:
|
|
||||||
close(s);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reboot_into_recovery(const std::vector<std::string>& options) {
|
static int reboot_into_recovery(const std::vector<std::string>& options) {
|
||||||
|
|
@ -319,15 +315,12 @@ static struct {
|
||||||
|
|
||||||
/* mount <type> <device> <path> <flags ...> <options> */
|
/* mount <type> <device> <path> <flags ...> <options> */
|
||||||
static int do_mount(const std::vector<std::string>& args) {
|
static int do_mount(const std::vector<std::string>& args) {
|
||||||
char tmp[64];
|
const char* options = nullptr;
|
||||||
const char *source, *target, *system;
|
|
||||||
const char *options = NULL;
|
|
||||||
unsigned flags = 0;
|
unsigned flags = 0;
|
||||||
std::size_t na = 0;
|
bool wait = false;
|
||||||
int n, i;
|
|
||||||
int wait = 0;
|
|
||||||
|
|
||||||
for (na = 4; na < args.size(); na++) {
|
for (size_t na = 4; na < args.size(); na++) {
|
||||||
|
size_t i;
|
||||||
for (i = 0; mount_flags[i].name; i++) {
|
for (i = 0; mount_flags[i].name; i++) {
|
||||||
if (!args[na].compare(mount_flags[i].name)) {
|
if (!args[na].compare(mount_flags[i].name)) {
|
||||||
flags |= mount_flags[i].flag;
|
flags |= mount_flags[i].flag;
|
||||||
|
|
@ -336,57 +329,43 @@ static int do_mount(const std::vector<std::string>& args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mount_flags[i].name) {
|
if (!mount_flags[i].name) {
|
||||||
if (!args[na].compare("wait"))
|
if (!args[na].compare("wait")) {
|
||||||
wait = 1;
|
wait = true;
|
||||||
/* if our last argument isn't a flag, wolf it up as an option string */
|
// If our last argument isn't a flag, wolf it up as an option string.
|
||||||
else if (na + 1 == args.size())
|
} else if (na + 1 == args.size()) {
|
||||||
options = args[na].c_str();
|
options = args[na].c_str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
system = args[1].c_str();
|
const char* system = args[1].c_str();
|
||||||
source = args[2].c_str();
|
const char* source = args[2].c_str();
|
||||||
target = args[3].c_str();
|
const char* target = args[3].c_str();
|
||||||
|
|
||||||
if (!strncmp(source, "loop@", 5)) {
|
if (android::base::StartsWith(source, "loop@")) {
|
||||||
int mode, loop, fd;
|
int mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
|
||||||
struct loop_info info;
|
unique_fd fd(TEMP_FAILURE_RETRY(open(source + 5, mode | O_CLOEXEC)));
|
||||||
|
if (fd < 0) return -1;
|
||||||
|
|
||||||
mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR;
|
for (size_t n = 0;; n++) {
|
||||||
fd = open(source + 5, mode | O_CLOEXEC);
|
std::string tmp = android::base::StringPrintf("/dev/block/loop%zu", n);
|
||||||
if (fd < 0) {
|
unique_fd loop(TEMP_FAILURE_RETRY(open(tmp.c_str(), mode | O_CLOEXEC)));
|
||||||
return -1;
|
if (loop < 0) return -1;
|
||||||
}
|
|
||||||
|
|
||||||
for (n = 0; ; n++) {
|
|
||||||
snprintf(tmp, sizeof(tmp), "/dev/block/loop%d", n);
|
|
||||||
loop = open(tmp, mode | O_CLOEXEC);
|
|
||||||
if (loop < 0) {
|
|
||||||
close(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
loop_info info;
|
||||||
/* if it is a blank loop device */
|
/* if it is a blank loop device */
|
||||||
if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
|
if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) {
|
||||||
/* if it becomes our loop device */
|
/* if it becomes our loop device */
|
||||||
if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
|
if (ioctl(loop, LOOP_SET_FD, fd.get()) >= 0) {
|
||||||
close(fd);
|
if (mount(tmp.c_str(), target, system, flags, options) < 0) {
|
||||||
|
|
||||||
if (mount(tmp, target, system, flags, options) < 0) {
|
|
||||||
ioctl(loop, LOOP_CLR_FD, 0);
|
ioctl(loop, LOOP_CLR_FD, 0);
|
||||||
close(loop);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
close(loop);
|
|
||||||
goto exit_success;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close(loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
|
||||||
LOG(ERROR) << "out of loopback devices";
|
LOG(ERROR) << "out of loopback devices";
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -398,7 +377,6 @@ static int do_mount(const std::vector<std::string>& args) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exit_success:
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue