1 //
2 // Copyright (C) 2023 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 #include "host/commands/secure_env/worker_thread_loop_body.h"
17
18 #include "common/libs/fs/shared_select.h"
19 #include "host/commands/secure_env/suspend_resume_handler.h"
20
21 namespace cuttlefish {
22 namespace secure_env_impl {
23
WorkerInnerLoop(std::function<bool ()> process_callback,SharedFD read_fd,SharedFD snapshot_socket)24 Result<void> WorkerInnerLoop(std::function<bool()> process_callback,
25 SharedFD read_fd, SharedFD snapshot_socket) {
26 for (;;) {
27 SharedFDSet readable_fds;
28 readable_fds.Set(read_fd);
29 readable_fds.Set(snapshot_socket);
30
31 int num_fds = Select(&readable_fds, nullptr, nullptr, nullptr);
32 if (num_fds < 0) {
33 LOG(FATAL) << "Select() returned a negative value: " << num_fds
34 << strerror(errno);
35 }
36
37 if (readable_fds.IsSet(read_fd)) {
38 // if process_callback() fails, we need to reset the secure_env
39 // component.
40 if (!process_callback()) {
41 // NOTE: We don't need to worry about whether `snapshot_socket` is
42 // readable at this point. After the component is reset, we'll re-enter
43 // this loop and take care of it.
44 break;
45 }
46 continue;
47 }
48
49 if (readable_fds.IsSet(snapshot_socket)) {
50 // Read the suspend request.
51 SnapshotSocketMessage suspend_request;
52 CF_EXPECT_EQ(
53 sizeof(suspend_request),
54 snapshot_socket->Read(&suspend_request, sizeof(suspend_request)),
55 "socket read failed: " << snapshot_socket->StrError());
56 CF_EXPECT_EQ(SnapshotSocketMessage::kSuspend, suspend_request);
57 // Send the ACK response.
58 const SnapshotSocketMessage ack_response =
59 SnapshotSocketMessage::kSuspendAck;
60 CF_EXPECT_EQ(sizeof(ack_response),
61 snapshot_socket->Write(&ack_response, sizeof(ack_response)),
62 "socket write failed: " << snapshot_socket->StrError());
63 // Block until resumed.
64 SnapshotSocketMessage resume_request;
65 CF_EXPECT_EQ(
66 sizeof(resume_request),
67 snapshot_socket->Read(&resume_request, sizeof(resume_request)),
68 "socket read failed: " << snapshot_socket->StrError());
69 CF_EXPECT_EQ(SnapshotSocketMessage::kResume, resume_request);
70 }
71 }
72
73 return {};
74 }
75
76 } // namespace secure_env_impl
77 } // namespace cuttlefish
78