Path: blob/master/src/hotspot/os/linux/gc/z/zMountPoint_linux.cpp
40971 views
/*1* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "gc/shared/gcLogPrecious.hpp"25#include "gc/z/zArray.inline.hpp"26#include "gc/z/zErrno.hpp"27#include "gc/z/zMountPoint_linux.hpp"28#include "runtime/globals.hpp"2930#include <stdio.h>31#include <unistd.h>3233// Mount information, see proc(5) for more details.34#define PROC_SELF_MOUNTINFO "/proc/self/mountinfo"3536ZMountPoint::ZMountPoint(const char* filesystem, const char** preferred_mountpoints) {37if (AllocateHeapAt != NULL) {38// Use specified path39_path = strdup(AllocateHeapAt);40} else {41// Find suitable path42_path = find_mountpoint(filesystem, preferred_mountpoints);43}44}4546ZMountPoint::~ZMountPoint() {47free(_path);48_path = NULL;49}5051char* ZMountPoint::get_mountpoint(const char* line, const char* filesystem) const {52char* line_mountpoint = NULL;53char* line_filesystem = NULL;5455// Parse line and return a newly allocated string containing the mount point if56// the line contains a matching filesystem and the mount point is accessible by57// the current user.58if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 ||59strcmp(line_filesystem, filesystem) != 0 ||60access(line_mountpoint, R_OK|W_OK|X_OK) != 0) {61// Not a matching or accessible filesystem62free(line_mountpoint);63line_mountpoint = NULL;64}6566free(line_filesystem);6768return line_mountpoint;69}7071void ZMountPoint::get_mountpoints(const char* filesystem, ZArray<char*>* mountpoints) const {72FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");73if (fd == NULL) {74ZErrno err;75log_error_p(gc)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());76return;77}7879char* line = NULL;80size_t length = 0;8182while (getline(&line, &length, fd) != -1) {83char* const mountpoint = get_mountpoint(line, filesystem);84if (mountpoint != NULL) {85mountpoints->append(mountpoint);86}87}8889free(line);90fclose(fd);91}9293void ZMountPoint::free_mountpoints(ZArray<char*>* mountpoints) const {94ZArrayIterator<char*> iter(mountpoints);95for (char* mountpoint; iter.next(&mountpoint);) {96free(mountpoint);97}98mountpoints->clear();99}100101char* ZMountPoint::find_preferred_mountpoint(const char* filesystem,102ZArray<char*>* mountpoints,103const char** preferred_mountpoints) const {104// Find preferred mount point105ZArrayIterator<char*> iter1(mountpoints);106for (char* mountpoint; iter1.next(&mountpoint);) {107for (const char** preferred = preferred_mountpoints; *preferred != NULL; preferred++) {108if (!strcmp(mountpoint, *preferred)) {109// Preferred mount point found110return strdup(mountpoint);111}112}113}114115// Preferred mount point not found116log_error_p(gc)("More than one %s filesystem found:", filesystem);117ZArrayIterator<char*> iter2(mountpoints);118for (char* mountpoint; iter2.next(&mountpoint);) {119log_error_p(gc)(" %s", mountpoint);120}121122return NULL;123}124125char* ZMountPoint::find_mountpoint(const char* filesystem, const char** preferred_mountpoints) const {126char* path = NULL;127ZArray<char*> mountpoints;128129get_mountpoints(filesystem, &mountpoints);130131if (mountpoints.length() == 0) {132// No mount point found133log_error_p(gc)("Failed to find an accessible %s filesystem", filesystem);134} else if (mountpoints.length() == 1) {135// One mount point found136path = strdup(mountpoints.at(0));137} else {138// More than one mount point found139path = find_preferred_mountpoint(filesystem, &mountpoints, preferred_mountpoints);140}141142free_mountpoints(&mountpoints);143144return path;145}146147const char* ZMountPoint::get() const {148return _path;149}150151152