1 /* 2 * Copyright (C) 2017 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.cts.storageapp; 18 19 import static com.android.cts.storageapp.Utils.TAG; 20 import static com.android.cts.storageapp.Utils.makeUniqueFile; 21 22 import android.os.SystemClock; 23 import android.system.ErrnoException; 24 import android.system.Os; 25 import android.system.OsConstants; 26 import android.system.StructStatVfs; 27 import android.util.Log; 28 29 import java.io.File; 30 import java.io.FileDescriptor; 31 import java.io.IOException; 32 33 /** 34 * Utility that tries its hardest to use all possible disk resources. 35 */ 36 public class Hoarder { 37 private static final String BLOCKS = "blocks"; 38 private static final String INODES = "inodes"; 39 40 public static void main(String[] args) { 41 final File dir = new File(args[2]); 42 try { 43 switch (args[0]) { 44 case BLOCKS: 45 doBlocks(dir, false); 46 break; 47 case INODES: 48 doInodes(dir, false); 49 break; 50 } 51 } catch (IOException e) { 52 System.out.println("Failed to allocate: " + e.getMessage()); 53 System.exit(1); 54 } 55 56 Log.d(TAG, "Directory gone; giving up"); 57 System.exit(0); 58 } 59 60 public static void doBlocks(File dir, boolean oneshot) throws IOException { 61 int failures = 0; 62 while (dir.exists()) { 63 final File target = makeUniqueFile(dir); 64 FileDescriptor fd = null; 65 try { 66 final long size; 67 if (failures == 0) { 68 final StructStatVfs stat = Os.statvfs(dir.getAbsolutePath()); 69 size = (stat.f_bfree * stat.f_frsize) / 2; 70 } else { 71 size = 65536; 72 } 73 Log.d(TAG, "Attempting to allocate " + size); 74 75 fd = Os.open(target.getAbsolutePath(), 76 OsConstants.O_RDWR | OsConstants.O_CREAT, 0700); 77 Os.posix_fallocate(fd, 0, size); 78 } catch (ErrnoException e) { 79 if (e.errno == OsConstants.ENOSPC || e.errno == OsConstants.EDQUOT) { 80 failures = Math.min(failures + 1, 32); 81 if (oneshot && failures >= 4) { 82 Log.d(TAG, "Full!"); 83 return; 84 } else { 85 Log.d(TAG, "Failed to allocate; trying again"); 86 SystemClock.sleep(1000); 87 } 88 } else { 89 throw new IOException(e); 90 } 91 } finally { 92 try { 93 if (fd != null) Os.close(fd); 94 } catch (ErrnoException ignored) { 95 } 96 } 97 } 98 } 99 100 public static void doInodes(File dir, boolean oneshot) throws IOException { 101 int failures = 0; 102 while (dir.exists()) { 103 try { 104 final int size = (failures == 0) ? 512 : 16; 105 Log.d(TAG, "Attempting to allocate " + size + " inodes"); 106 107 final File a = makeUniqueFile(dir); 108 Os.mkdir(a.getAbsolutePath(), 0700); 109 for (int i = 0; i < size; i++) { 110 final File b = makeUniqueFile(a); 111 Os.mkdir(b.getAbsolutePath(), 0700); 112 } 113 } catch (ErrnoException e) { 114 if (e.errno == OsConstants.ENOSPC || e.errno == OsConstants.EDQUOT) { 115 failures = Math.min(failures + 1, 32); 116 if (oneshot && failures >= 4) { 117 Log.d(TAG, "Full!"); 118 return; 119 } else { 120 Log.d(TAG, "Failed to allocate; trying again"); 121 SystemClock.sleep(1000); 122 } 123 } else { 124 throw new IOException(e); 125 } 126 } 127 } 128 } 129 } 130