1 /*
2 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
55 // Parse line and return a newly allocated string containing the mount point if
56 // the line contains a matching filesystem and the mount point is accessible by
57 // the current user.
58 if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 ||
59 strcmp(line_filesystem, filesystem) != 0 ||
60 access(line_mountpoint, R_OK|W_OK|X_OK) != 0) {
61 // Not a matching or accessible filesystem
62 free(line_mountpoint);
63 line_mountpoint = NULL;
64 }
65
66 free(line_filesystem);
67
68 return line_mountpoint;
69 }
70
71 void ZBackingPath::get_mountpoints(const char* filesystem, ZArray<char*>* mountpoints) const {
72 FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");
73 if (fd == NULL) {
74 ZErrno err;
75 log_error(gc, init)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());
76 return;
77 }
78
79 char* line = NULL;
80 size_t length = 0;
81
82 while (getline(&line, &length, fd) != -1) {
83 char* const mountpoint = get_mountpoint(line, filesystem);
84 if (mountpoint != NULL) {
85 mountpoints->add(mountpoint);
86 }
87 }
88
89 free(line);
90 fclose(fd);
91 }
92
93 void ZBackingPath::free_mountpoints(ZArray<char*>* mountpoints) const {
94 ZArrayIterator<char*> iter(mountpoints);
95 for (char* mountpoint; iter.next(&mountpoint);) {
96 free(mountpoint);
97 }
98 mountpoints->clear();
99 }
100
101 char* ZBackingPath::find_preferred_mountpoint(const char* filesystem,
102 ZArray<char*>* mountpoints,
103 const char** preferred_mountpoints) const {
104 // Find preferred mount point
105 ZArrayIterator<char*> iter1(mountpoints);
106 for (char* mountpoint; iter1.next(&mountpoint);) {
107 for (const char** preferred = preferred_mountpoints; *preferred != NULL; preferred++) {
108 if (!strcmp(mountpoint, *preferred)) {
109 // Preferred mount point found
110 return strdup(mountpoint);
111 }
112 }
113 }
114
115 // Preferred mount point not found
116 log_error(gc, init)("More than one %s filesystem found:", filesystem);
117 ZArrayIterator<char*> iter2(mountpoints);
118 for (char* mountpoint; iter2.next(&mountpoint);) {
119 log_error(gc, init)(" %s", mountpoint);
120 }
121
122 return NULL;
123 }
124
125 char* ZBackingPath::find_mountpoint(const char* filesystem, const char** preferred_mountpoints) const {
126 char* path = NULL;
127 ZArray<char*> mountpoints;
128
129 get_mountpoints(filesystem, &mountpoints);
130
131 if (mountpoints.size() == 0) {
132 // No mount point found
133 log_error(gc, init)("Failed to find an accessible %s filesystem", filesystem);
134 } else if (mountpoints.size() == 1) {
135 // One mount point found
136 path = strdup(mountpoints.at(0));
137 } else {
138 // More than one mount point found
139 path = find_preferred_mountpoint(filesystem, &mountpoints, preferred_mountpoints);
140 }
141
142 free_mountpoints(&mountpoints);
143
144 return path;
145 }
146
147 const char* ZBackingPath::get() const {
148 return _path;
149 }
|
1 /*
2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
55 // Parse line and return a newly allocated string containing the mount point if
56 // the line contains a matching filesystem and the mount point is accessible by
57 // the current user.
58 if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 ||
59 strcmp(line_filesystem, filesystem) != 0 ||
60 access(line_mountpoint, R_OK|W_OK|X_OK) != 0) {
61 // Not a matching or accessible filesystem
62 free(line_mountpoint);
63 line_mountpoint = NULL;
64 }
65
66 free(line_filesystem);
67
68 return line_mountpoint;
69 }
70
71 void ZBackingPath::get_mountpoints(const char* filesystem, ZArray<char*>* mountpoints) const {
72 FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");
73 if (fd == NULL) {
74 ZErrno err;
75 log_error(gc)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());
76 return;
77 }
78
79 char* line = NULL;
80 size_t length = 0;
81
82 while (getline(&line, &length, fd) != -1) {
83 char* const mountpoint = get_mountpoint(line, filesystem);
84 if (mountpoint != NULL) {
85 mountpoints->add(mountpoint);
86 }
87 }
88
89 free(line);
90 fclose(fd);
91 }
92
93 void ZBackingPath::free_mountpoints(ZArray<char*>* mountpoints) const {
94 ZArrayIterator<char*> iter(mountpoints);
95 for (char* mountpoint; iter.next(&mountpoint);) {
96 free(mountpoint);
97 }
98 mountpoints->clear();
99 }
100
101 char* ZBackingPath::find_preferred_mountpoint(const char* filesystem,
102 ZArray<char*>* mountpoints,
103 const char** preferred_mountpoints) const {
104 // Find preferred mount point
105 ZArrayIterator<char*> iter1(mountpoints);
106 for (char* mountpoint; iter1.next(&mountpoint);) {
107 for (const char** preferred = preferred_mountpoints; *preferred != NULL; preferred++) {
108 if (!strcmp(mountpoint, *preferred)) {
109 // Preferred mount point found
110 return strdup(mountpoint);
111 }
112 }
113 }
114
115 // Preferred mount point not found
116 log_error(gc)("More than one %s filesystem found:", filesystem);
117 ZArrayIterator<char*> iter2(mountpoints);
118 for (char* mountpoint; iter2.next(&mountpoint);) {
119 log_error(gc)(" %s", mountpoint);
120 }
121
122 return NULL;
123 }
124
125 char* ZBackingPath::find_mountpoint(const char* filesystem, const char** preferred_mountpoints) const {
126 char* path = NULL;
127 ZArray<char*> mountpoints;
128
129 get_mountpoints(filesystem, &mountpoints);
130
131 if (mountpoints.size() == 0) {
132 // No mount point found
133 log_error(gc)("Failed to find an accessible %s filesystem", filesystem);
134 } else if (mountpoints.size() == 1) {
135 // One mount point found
136 path = strdup(mountpoints.at(0));
137 } else {
138 // More than one mount point found
139 path = find_preferred_mountpoint(filesystem, &mountpoints, preferred_mountpoints);
140 }
141
142 free_mountpoints(&mountpoints);
143
144 return path;
145 }
146
147 const char* ZBackingPath::get() const {
148 return _path;
149 }
|