blob: 6ad5d16f1c755268c531771acc0d8c10bddaee91 [file] [log] [blame]
Jeff Sharkeydeb24052015-03-02 21:01:40 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Vold"
18
19#include "sehandle.h"
20#include "Utils.h"
21#include "Process.h"
22
23#include <cutils/fs.h>
24#include <cutils/log.h>
Jeff Sharkeydeb24052015-03-02 21:01:40 -080025#include <private/android_filesystem_config.h>
26
27#include <fcntl.h>
28#include <linux/fs.h>
29#include <stdlib.h>
30#include <sys/mount.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <sys/wait.h>
34
35#ifndef UMOUNT_NOFOLLOW
36#define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */
37#endif
38
39namespace android {
40namespace vold {
41
42status_t CreateDeviceNode(const std::string& path, dev_t dev) {
43 const char* cpath = path.c_str();
44 status_t res = 0;
45
46 char* secontext = nullptr;
47 if (sehandle) {
48 if (!selabel_lookup(sehandle, &secontext, cpath, S_IFBLK)) {
49 setfscreatecon(secontext);
50 }
51 }
52
53 mode_t mode = 0660 | S_IFBLK;
54 if (mknod(cpath, mode, dev) < 0) {
55 if (errno != EEXIST) {
56 ALOGW("Failed to create device node for %ud:%ud at %s: %s",
57 major(dev), minor(dev), cpath, strerror(errno));
58 res = -errno;
59 }
60 }
61
62 if (secontext) {
63 setfscreatecon(nullptr);
64 freecon(secontext);
65 }
66
67 return res;
68}
69
70status_t DestroyDeviceNode(const std::string& path) {
71 const char* cpath = path.c_str();
72 if (TEMP_FAILURE_RETRY(unlink(cpath))) {
73 return -errno;
74 } else {
75 return OK;
76 }
77}
78
79status_t ForceUnmount(const std::string& path) {
80 const char* cpath = path.c_str();
81 if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
82 return OK;
83 }
84 ALOGW("Failed to unmount %s (%s), sending SIGTERM", cpath, strerror(errno));
85 Process::killProcessesWithOpenFiles(cpath, SIGTERM);
86 sleep(1);
87
88 if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
89 return OK;
90 }
91 ALOGW("Failed to unmount %s (%s), sending SIGKILL", cpath, strerror(errno));
92 Process::killProcessesWithOpenFiles(cpath, SIGKILL);
93 sleep(1);
94
95 if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
96 return OK;
97 }
98 ALOGW("Failed to unmount %s (%s)", cpath, strerror(errno));
99 return -errno;
100}
101
102} // namespace vold
103} // namespace android