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 #include "checkpoint_handling.h"
18 #include "log.h"
19 
20 #include <fstab/fstab.h>
21 #include <cstring>
22 #include <string>
23 
24 namespace {
25 
26 bool checkpointingDoneForever = false;
27 
28 }  // namespace
29 
is_data_checkpoint_active(bool * active)30 int is_data_checkpoint_active(bool* active) {
31     if (!active) {
32         ALOGE("active out parameter is null");
33         return 0;
34     }
35 
36     *active = false;
37 
38     if (checkpointingDoneForever) {
39         return 0;
40     }
41 
42     android::fs_mgr::Fstab procMounts;
43     bool success = android::fs_mgr::ReadFstabFromFile("/proc/mounts", &procMounts);
44     if (!success) {
45         ALOGE("Could not parse /proc/mounts\n");
46         /* Really bad. Tell the caller to abort the write. */
47         return -1;
48     }
49 
50     android::fs_mgr::FstabEntry* dataEntry =
51             android::fs_mgr::GetEntryForMountPoint(&procMounts, "/data");
52     if (dataEntry == NULL) {
53         ALOGE("/data is not mounted yet\n");
54         return 0;
55     }
56 
57     /* We can't handle e.g., ext4. Nothing we can do about it for now. */
58     if (dataEntry->fs_type != "f2fs") {
59         ALOGW("Checkpoint status not supported for filesystem %s\n", dataEntry->fs_type.c_str());
60         checkpointingDoneForever = true;
61         return 0;
62     }
63 
64     /*
65      * The data entry looks like "... blah,checkpoint=disable:0,blah ...".
66      * checkpoint=disable means checkpointing is on (yes, arguably reversed).
67      */
68     size_t checkpointPos = dataEntry->fs_options.find("checkpoint=disable");
69     if (checkpointPos == std::string::npos) {
70         /* Assumption is that once checkpointing turns off, it stays off */
71         checkpointingDoneForever = true;
72     } else {
73         *active = true;
74     }
75 
76     return 0;
77 }
78