1 /* 2 * Copyright (C) 2021 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 package com.android.internal.os; 18 19 import com.android.internal.util.ProcFileReader; 20 21 import java.io.FileInputStream; 22 import java.io.IOException; 23 24 /** 25 * Reads and parses {@code locks} files in the {@code proc} filesystem. 26 * A typical example of /proc/locks 27 * 28 * 1: POSIX ADVISORY READ 18403 fd:09:9070 1073741826 1073742335 29 * 2: POSIX ADVISORY WRITE 18292 fd:09:34062 0 EOF 30 * 2: -> POSIX ADVISORY WRITE 18291 fd:09:34062 0 EOF 31 * 2: -> POSIX ADVISORY WRITE 18293 fd:09:34062 0 EOF 32 * 3: POSIX ADVISORY READ 3888 fd:09:13992 128 128 33 * 4: POSIX ADVISORY READ 3888 fd:09:14230 1073741826 1073742335 34 */ 35 public class ProcLocksReader { 36 private final String mPath; 37 private ProcFileReader mReader = null; 38 ProcLocksReader()39 public ProcLocksReader() { 40 mPath = "/proc/locks"; 41 } 42 ProcLocksReader(String path)43 public ProcLocksReader(String path) { 44 mPath = path; 45 } 46 47 /** 48 * This interface is for AMS to run callback function on every processes one by one 49 * that hold file locks blocking other processes. 50 */ 51 public interface ProcLocksReaderCallback { 52 /** 53 * Call the callback function of handleBlockingFileLocks(). 54 * @param pid Each process that hold file locks blocking other processes. 55 */ onBlockingFileLock(int pid)56 void onBlockingFileLock(int pid); 57 } 58 59 /** 60 * Checks if a process corresponding to a specific pid owns any file locks. 61 * @param callback Callback function, accepting pid as the input parameter. 62 * @throws IOException if /proc/locks can't be accessed or correctly parsed. 63 */ handleBlockingFileLocks(ProcLocksReaderCallback callback)64 public void handleBlockingFileLocks(ProcLocksReaderCallback callback) throws IOException { 65 long last = -1; 66 long id; // ordinal position of the lock in the list 67 int owner = -1; // the PID of the process that owns the lock 68 int pid = -1; // the PID of the process blocking others 69 70 if (mReader == null) { 71 mReader = new ProcFileReader(new FileInputStream(mPath)); 72 } else { 73 mReader.rewind(); 74 } 75 76 while (mReader.hasMoreData()) { 77 id = mReader.nextLong(true); // lock id 78 if (id == last) { 79 mReader.finishLine(); // blocked lock 80 if (pid < 0) { 81 pid = owner; // get pid from the previous line 82 callback.onBlockingFileLock(pid); 83 } 84 continue; 85 } else { 86 pid = -1; // a new lock 87 } 88 89 mReader.nextIgnored(); // lock type: POSIX? 90 mReader.nextIgnored(); // lock type: MANDATORY? 91 mReader.nextIgnored(); // lock type: RW? 92 93 owner = mReader.nextInt(); // pid 94 mReader.finishLine(); 95 last = id; 96 } 97 } 98 } 99