File: resource_manager.h

package info (click to toggle)
android-cuttlefish 1.0.1-0~exp2
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 7,192 kB
  • sloc: cpp: 39,149; sh: 2,523; javascript: 242; exp: 152; python: 125; makefile: 88
file content (155 lines) | stat: -rw-r--r-- 4,516 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <sys/types.h>

#include <atomic>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <set>

#include "alloc_utils.h"
#include "common/libs/fs/shared_fd.h"
#include "request.h"
#include "resource.h"
#include "utils.h"

namespace cuttlefish {

class Session {
 public:
  explicit Session(uint32_t session_id, uid_t uid)
      : session_id_(session_id), uid_(uid) {}
  ~Session() { ReleaseAllResources(); }

  uint32_t GetSessionID() { return session_id_; }
  uid_t GetUID() { return uid_; }

  const std::set<std::string>& GetActiveInterfaces() {
    return active_interfaces_;
  }

  void Insert(
      const std::map<uint32_t, std::shared_ptr<StaticResource>>& resources) {
    managed_resources_.insert(resources.begin(), resources.end());
  }

  bool ReleaseAllResources() {
    bool success = true;
    for (auto& res : managed_resources_) {
      success &= res.second->ReleaseResource();
    }
    managed_resources_.clear();

    return success;
  }

  bool ReleaseResource(uint32_t resource_id) {
    auto it = managed_resources_.find(resource_id);
    if (it == managed_resources_.end()) {
      return false;
    }

    auto success = it->second->ReleaseResource();
    if (success) {
      managed_resources_.erase(it);
    }

    return success;
  }

 private:
  uint32_t session_id_{};
  uid_t uid_{};
  std::set<std::string> active_interfaces_;
  std::map<uint32_t, std::shared_ptr<StaticResource>> managed_resources_;
};

/* Manages static resources while the daemon is running.
 * When resources, such as network interfaces are requested the ResourceManager
 * allocates the resources and takes ownership of them. It will keep maintain
 * the resource, until requested to release it(i.e. destroy it and/or tear down
 * related config). When the daemon is stopped, it will walk its list of owned
 * resources, and deallocate them from the system.
 *
 * Clients can request new resources by connecting to a socket, and sending a
 * JSON request, detailing the type of resource required.
 */
struct ResourceManager {
 public:
  ResourceManager() = default;

  ~ResourceManager();

  void SetSocketLocation(const std::string& sock_name);

  void SetUseEbtablesLegacy(bool use_legacy);

  void JsonServer();

 private:
  uint32_t AllocateResourceID();
  uint32_t AllocateSessionID();

  bool AddInterface(const std::string& iface, IfaceType ty, uint32_t id,
                    uid_t uid);

  bool RemoveInterface(const std::string& iface, IfaceType ty);

  bool ValidateRequest(const Json::Value& request);

  bool ValidateRequestList(const Json::Value& config);

  bool ValidateConfigRequest(const Json::Value& config);

  Json::Value JsonHandleIdRequest();

  Json::Value JsonHandleShutdownRequest(SharedFD client_socket);

  Json::Value JsonHandleCreateInterfaceRequest(SharedFD client_socket,
                                               const Json::Value& request);

  Json::Value JsonHandleDestroyInterfaceRequest(const Json::Value& request);

  Json::Value JsonHandleStopSessionRequest(const Json::Value& request,
                                           uid_t uid);

  bool CheckCredentials(SharedFD client_socket, uid_t uid);

  void SetUseIpv4Bridge(bool ipv4) { use_ipv4_bridge_ = ipv4; }

  void SetUseIpv6Bridge(bool ipv6) { use_ipv6_bridge_ = ipv6; }

  std::optional<std::shared_ptr<Session>> FindSession(uint32_t id);

 private:
  std::atomic_uint32_t global_resource_id_ = 0;
  std::atomic_uint32_t session_id_ = 0;
  std::set<std::string> active_interfaces_;
  std::map<uint32_t, std::shared_ptr<Session>> managed_sessions_;
  std::map<uint32_t, std::shared_ptr<StaticResource>> pending_add_;
  std::string location_ = kDefaultLocation;
  bool use_ipv4_bridge_ = true;
  bool use_ipv6_bridge_ = true;
  bool use_ebtables_legacy_ = false;
  cuttlefish::SharedFD shutdown_socket_;
};

}  // namespace cuttlefish