• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "host/commands/ivserver/ivserver.h"
17 
18 #include <sys/select.h>
19 #include <algorithm>
20 
21 #include <glog/logging.h>
22 
23 #include "common/libs/fs/shared_select.h"
24 #include "host/commands/ivserver/hald_client.h"
25 #include "host/commands/ivserver/qemu_client.h"
26 
27 namespace ivserver {
28 
IVServer(const IVServerOptions & options,int qemu_channel_fd,int client_channel_fd)29 IVServer::IVServer(const IVServerOptions &options, int qemu_channel_fd,
30                    int client_channel_fd)
31     : vsoc_shmem_(VSoCSharedMemory::New(options.shm_file_path)) {
32   if (qemu_channel_fd > 0) {
33     qemu_channel_ = cvd::SharedFD::Dup(qemu_channel_fd);
34   } else {
35     LOG_IF(WARNING, unlink(options.qemu_socket_path.c_str()) == 0)
36         << "Removed existing unix socket: " << options.qemu_socket_path
37         << ". We can't confirm yet whether another instance is running.";
38     qemu_channel_ = cvd::SharedFD::SocketLocalServer(
39         options.qemu_socket_path.c_str(), false, SOCK_STREAM, 0666);
40   }
41   LOG_IF(FATAL, !qemu_channel_->IsOpen())
42       << "Could not create QEmu channel: " << qemu_channel_->StrError();
43 
44   if (client_channel_fd > 0) {
45     client_channel_ = cvd::SharedFD::Dup(client_channel_fd);
46   } else {
47     LOG_IF(WARNING, unlink(options.client_socket_path.c_str()) == 0)
48         << "Removed existing unix socket: " << options.client_socket_path
49         << ". We can't confirm yet whether another instance is running.";
50     client_channel_ = cvd::SharedFD::SocketLocalServer(
51         options.client_socket_path.c_str(), false, SOCK_STREAM, 0666);
52   }
53   LOG_IF(FATAL, !client_channel_->IsOpen())
54       << "Could not create Client channel: " << client_channel_->StrError();
55 }
56 
Serve()57 void IVServer::Serve() {
58   while (true) {
59     cvd::SharedFDSet rset;
60     rset.Set(qemu_channel_);
61     rset.Set(client_channel_);
62     cvd::Select(&rset, nullptr, nullptr, nullptr);
63 
64     if (rset.IsSet(qemu_channel_)) {
65       HandleNewQemuConnection();
66     }
67 
68     if (rset.IsSet(client_channel_)) {
69       HandleNewClientConnection();
70     }
71   }
72 
73   LOG(FATAL) << "Control reached out of event loop";
74 }
75 
HandleNewClientConnection()76 void IVServer::HandleNewClientConnection() {
77   std::unique_ptr<HaldClient> res = HaldClient::New(
78       *vsoc_shmem_, cvd::SharedFD::Accept(*client_channel_, nullptr, nullptr));
79   if (!res) {
80     LOG(WARNING) << "Rejecting unsuccessful HALD connection.";
81   }
82 }
83 
HandleNewQemuConnection()84 void IVServer::HandleNewQemuConnection() {
85   std::unique_ptr<QemuClient> res = QemuClient::New(
86       *vsoc_shmem_, cvd::SharedFD::Accept(*qemu_channel_, nullptr, nullptr));
87 
88   if (!res) {
89     LOG(WARNING) << "Could not accept new QEmu client.";
90   }
91 }
92 
93 }  // namespace ivserver
94