• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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