1 /*
2 * Copyright (C) 2019 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 <gflags/gflags.h>
18 #include <android-base/logging.h>
19
20 #include <chrono>
21 #include <fstream>
22 #include <iomanip>
23 #include <sstream>
24
25 #include "host/libs/config/logging.h"
26 #include "common/libs/fs/shared_fd.h"
27
28 DEFINE_int32(
29 server_fd, -1,
30 "File descriptor to an already created vsock server. If negative a new "
31 "server will be created at the port specified on the config file");
32 DEFINE_string(tombstone_dir, "", "directory to write out tombstones in");
33
34 static uint num_tombstones_in_last_second = 0;
35 static std::string last_tombstone_name = "";
36
next_tombstone_path()37 static std::string next_tombstone_path() {
38 auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
39 std::stringstream ss;
40 ss << FLAGS_tombstone_dir << "/tombstone_" <<
41 std::put_time(std::gmtime(&in_time_t), "%Y-%m-%d-%H%M%S");
42 auto retval = ss.str();
43
44 // Gives tombstones unique names
45 if(retval == last_tombstone_name) {
46 num_tombstones_in_last_second++;
47 retval += "_" + std::to_string(num_tombstones_in_last_second);
48 } else {
49 last_tombstone_name = retval;
50 num_tombstones_in_last_second = 0;
51 }
52
53 LOG(DEBUG) << "Creating " << retval;
54 return retval;
55 }
56
57 #define CHUNK_RECV_MAX_LEN (1024)
main(int argc,char ** argv)58 int main(int argc, char** argv) {
59 cuttlefish::DefaultSubprocessLogging(argv);
60 google::ParseCommandLineFlags(&argc, &argv, true);
61
62 cuttlefish::SharedFD server_fd = cuttlefish::SharedFD::Dup(FLAGS_server_fd);
63 close(FLAGS_server_fd);
64
65 CHECK(server_fd->IsOpen()) << "Error inheriting tombstone server: "
66 << server_fd->StrError();
67 LOG(DEBUG) << "Host is starting server on port "
68 << server_fd->VsockServerPort();
69
70 // Server loop
71 while (true) {
72 auto conn = cuttlefish::SharedFD::Accept(*server_fd);
73 std::ofstream file(next_tombstone_path(),
74 std::ofstream::out | std::ofstream::binary);
75
76 while (file.is_open()) {
77 char buff[CHUNK_RECV_MAX_LEN];
78 auto bytes_read = conn->Read(buff, sizeof(buff));
79 if (bytes_read <= 0) {
80 // reset the other side if it's still connected
81 break;
82 } else {
83 file.write(buff, bytes_read);
84 }
85 }
86 }
87
88 return 0;
89 }
90