xref: /aosp_15_r20/cts/hostsidetests/appsecurity/test-apps/StorageApp/src/com/android/cts/storageapp/Hoarder.java (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
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 
main(String[] args)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 
doBlocks(File dir, boolean oneshot)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 
doInodes(File dir, boolean oneshot)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