blob: 24668d37f227e4742df50de6d0612f1854ed6722 [file] [log] [blame]
Elliott Hughes63a31922016-06-09 17:41:22 -07001/*
2 * Copyright (C) 2007 The Android Open Source Project
Tom Marshalla08c6f12019-01-04 14:37:31 -08003 * Copyright (C) 2019 The LineageOS Project
Elliott Hughes63a31922016-06-09 17:41:22 -07004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include "mounts.h"
19
20#include <errno.h>
21#include <fcntl.h>
22#include <mntent.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/mount.h>
27
28#include <string>
29#include <vector>
30
Tao Bao5f85d1f2017-03-28 21:12:36 -070031#include <android-base/logging.h>
32
Elliott Hughes63a31922016-06-09 17:41:22 -070033struct MountedVolume {
34 std::string device;
35 std::string mount_point;
36 std::string filesystem;
37 std::string flags;
38};
39
40std::vector<MountedVolume*> g_mounts_state;
41
42bool scan_mounted_volumes() {
43 for (size_t i = 0; i < g_mounts_state.size(); ++i) {
44 delete g_mounts_state[i];
45 }
46 g_mounts_state.clear();
47
48 // Open and read mount table entries.
49 FILE* fp = setmntent("/proc/mounts", "re");
50 if (fp == NULL) {
51 return false;
52 }
53 mntent* e;
54 while ((e = getmntent(fp)) != NULL) {
55 MountedVolume* v = new MountedVolume;
56 v->device = e->mnt_fsname;
57 v->mount_point = e->mnt_dir;
58 v->filesystem = e->mnt_type;
59 v->flags = e->mnt_opts;
60 g_mounts_state.push_back(v);
61 }
62 endmntent(fp);
63 return true;
64}
65
Elliott Hughes63a31922016-06-09 17:41:22 -070066MountedVolume* find_mounted_volume_by_mount_point(const char* mount_point) {
67 for (size_t i = 0; i < g_mounts_state.size(); ++i) {
68 if (g_mounts_state[i]->mount_point == mount_point) return g_mounts_state[i];
69 }
70 return nullptr;
71}
72
73int unmount_mounted_volume(MountedVolume* volume) {
Tao Bao5f85d1f2017-03-28 21:12:36 -070074 // Intentionally pass the empty string to umount if the caller tries to unmount a volume they
75 // already unmounted using this function.
76 std::string mount_point = volume->mount_point;
77 volume->mount_point.clear();
78 int result = umount(mount_point.c_str());
79 if (result == -1) {
80 PLOG(WARNING) << "Failed to umount " << mount_point;
81 }
82 return result;
Elliott Hughes63a31922016-06-09 17:41:22 -070083}
Tom Marshalla08c6f12019-01-04 14:37:31 -080084
85int unmount_mounted_volume_detach(MountedVolume* volume) {
86 // Intentionally pass the empty string to umount if the caller tries to unmount a volume they
87 // already unmounted using this function.
88 std::string mount_point = volume->mount_point;
89 volume->mount_point.clear();
90 int result = umount2(mount_point.c_str(), MNT_DETACH);
91 if (result == -1) {
92 PLOG(WARNING) << "Failed to umount " << mount_point;
93 }
94 return result;
95}