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