blob: ca274cc2ad6dfd0f3974aaa332171fe47201a0fb [file] [log] [blame]
Cody Schuffelen134ff032019-11-22 00:25:32 -08001/*
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
27namespace ivserver {
28
29IVServer::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
57void 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
76void 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
84void 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