Stubs for creating netdev
[platform/core/security/vasum.git] / server / zone-admin.cpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Jan Olszak <j.olszak@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19 /**
20  * @file
21  * @author  Jan Olszak (j.olszak@samsung.com)
22  * @brief   Implementation of class for administrating one zone
23  */
24
25 #include "config.hpp"
26
27 #include "zone-admin.hpp"
28 #include "exception.hpp"
29
30 #include "logger/logger.hpp"
31 #include "utils/paths.hpp"
32 #include "utils/c-array.hpp"
33
34 #include <cassert>
35
36
37 namespace vasum {
38
39 namespace {
40
41 // TODO: this should be in zone's configuration file
42 const int SHUTDOWN_WAIT = 10;
43
44 } // namespace
45
46 const std::uint64_t DEFAULT_CPU_SHARES = 1024;
47 const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000;
48
49 ZoneAdmin::ZoneAdmin(const std::string& zoneId,
50                      const std::string& zonesPath,
51                      const std::string& lxcTemplatePrefix,
52                      const ZoneConfig& config,
53                      const ZoneDynamicConfig& dynamicConfig)
54     : mConfig(config),
55       mZone(zonesPath, zoneId),
56       mId(zoneId),
57       mDetachOnExit(false),
58       mDestroyOnExit(false)
59 {
60     LOGD(mId << ": Instantiating ZoneAdmin object");
61
62     if (!mZone.isDefined()) {
63
64         const std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate,
65                                                                lxcTemplatePrefix);
66         LOGI(mId << ": Creating zone from template: " << lxcTemplate);
67         utils::CStringArrayBuilder args;
68         if (!dynamicConfig.ipv4Gateway.empty()) {
69             args.add("--ipv4-gateway");
70             args.add(dynamicConfig.ipv4Gateway.c_str());
71         }
72         if (!dynamicConfig.ipv4.empty()) {
73             args.add("--ipv4");
74             args.add(dynamicConfig.ipv4.c_str());
75         }
76         const std::string vt = std::to_string(dynamicConfig.vt);
77         if (dynamicConfig.vt > 0) {
78             args.add("--vt");
79             args.add(vt.c_str());
80         }
81         if (!mZone.create(lxcTemplate, args.c_array())) {
82             throw ZoneOperationException("Could not create zone");
83         }
84     }
85 }
86
87
88 ZoneAdmin::~ZoneAdmin()
89 {
90     LOGD(mId << ": Destroying ZoneAdmin object...");
91
92     if (mDestroyOnExit) {
93         if (!mZone.stop()) {
94             LOGE(mId << ": Failed to stop the zone");
95         }
96         if (!mZone.destroy()) {
97             LOGE(mId << ": Failed to destroy the zone");
98         }
99     }
100
101     if (!mDetachOnExit) {
102         // Try to forcefully stop
103         if (!mZone.stop()) {
104             LOGE(mId << ": Failed to stop the zone");
105         }
106     }
107
108     LOGD(mId << ": ZoneAdmin object destroyed");
109 }
110
111
112 const std::string& ZoneAdmin::getId() const
113 {
114     return mId;
115 }
116
117
118 void ZoneAdmin::start()
119 {
120     LOGD(mId << ": Starting...");
121     if (isRunning()) {
122         LOGD(mId << ": Already running - nothing to do...");
123         return;
124     }
125
126     utils::CStringArrayBuilder args;
127     for (const std::string& arg : mConfig.initWithArgs) {
128         args.add(arg.c_str());
129     }
130     if (args.empty()) {
131         args.add("/sbin/init");
132     }
133
134     if (!mZone.start(args.c_array())) {
135         throw ZoneOperationException("Could not start zone");
136     }
137
138     LOGD(mId << ": Started");
139 }
140
141
142 void ZoneAdmin::stop()
143 {
144     LOGD(mId << ": Stopping procedure started...");
145     if (isStopped()) {
146         LOGD(mId << ": Already crashed/down/off - nothing to do");
147         return;
148     }
149
150     if (!mZone.shutdown(SHUTDOWN_WAIT)) {
151         // force stop
152         if (!mZone.stop()) {
153             throw ZoneOperationException("Could not stop zone");
154         }
155     }
156
157     LOGD(mId << ": Stopping procedure ended");
158 }
159
160
161 void ZoneAdmin::destroy()
162 {
163     LOGD(mId << ": Destroying procedure started...");
164
165     if (!mZone.destroy()) {
166         throw ZoneOperationException("Could not destroy zone");
167     }
168
169     LOGD(mId << ": Destroying procedure ended");
170 }
171
172
173 bool ZoneAdmin::isRunning()
174 {
175     return mZone.getState() == lxc::LxcZone::State::RUNNING;
176 }
177
178
179 bool ZoneAdmin::isStopped()
180 {
181     return mZone.getState() == lxc::LxcZone::State::STOPPED;
182 }
183
184
185 void ZoneAdmin::suspend()
186 {
187     LOGD(mId << ": Pausing...");
188     if (!mZone.freeze()) {
189         throw ZoneOperationException("Could not pause zone");
190     }
191     LOGD(mId << ": Paused");
192 }
193
194
195 void ZoneAdmin::resume()
196 {
197     LOGD(mId << ": Resuming...");
198     if (!mZone.unfreeze()) {
199         throw ZoneOperationException("Could not resume zone");
200     }
201     LOGD(mId << ": Resumed");
202 }
203
204
205 bool ZoneAdmin::isPaused()
206 {
207     return mZone.getState() == lxc::LxcZone::State::FROZEN;
208 }
209
210
211 void ZoneAdmin::setSchedulerLevel(SchedulerLevel sched)
212 {
213     switch (sched) {
214     case SchedulerLevel::FOREGROUND:
215         LOGD(mId << ": Setting SchedulerLevel::FOREGROUND");
216         setSchedulerParams(DEFAULT_CPU_SHARES,
217                            DEFAULT_VCPU_PERIOD_MS,
218                            mConfig.cpuQuotaForeground);
219         break;
220     case SchedulerLevel::BACKGROUND:
221         LOGD(mId << ": Setting SchedulerLevel::BACKGROUND");
222         setSchedulerParams(DEFAULT_CPU_SHARES,
223                            DEFAULT_VCPU_PERIOD_MS,
224                            mConfig.cpuQuotaBackground);
225         break;
226     default:
227         assert(0 && "Unknown sched parameter value");
228     }
229 }
230
231
232 void ZoneAdmin::setSchedulerParams(std::uint64_t, std::uint64_t, std::int64_t)
233 //void ZoneAdmin::setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota)
234 {
235 //    assert(mZone);
236 //
237 //    int maxParams = 3;
238 //    int numParamsBuff = 0;
239 //
240 //    std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[maxParams]);
241 //
242 //    virTypedParameterPtr paramsTmp = params.get();
243 //
244 //    virTypedParamsAddULLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_CPU_SHARES, cpuShares);
245 //    virTypedParamsAddULLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD, vcpuPeriod);
246 //    virTypedParamsAddLLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA, vcpuQuota);
247 //
248 //    if (virDomainSetSchedulerParameters(mZone.get(), params.get(), numParamsBuff) < 0) {
249 //        LOGE(mId << ": Error while setting the zone's scheduler params:\n"
250 //             << libvirt::libvirtFormatError());
251 //        throw ZoneOperationException();
252 //    }
253 }
254
255 void ZoneAdmin::setDetachOnExit()
256 {
257     mDetachOnExit = true;
258 }
259
260 void ZoneAdmin::setDestroyOnExit()
261 {
262     mDestroyOnExit = true;
263 }
264
265 std::int64_t ZoneAdmin::getSchedulerQuota()
266 {
267 //    assert(mZone);
268 //
269 //    int numParamsBuff;
270 //    std::unique_ptr<char, void(*)(void*)> type(virDomainGetSchedulerType(mZone.get(), &numParamsBuff), free);
271 //
272 //    if (type == NULL || numParamsBuff <= 0 || strcmp(type.get(), "posix") != 0) {
273 //        LOGE(mId << ": Error while getting the zone's scheduler type:\n"
274 //             << libvirt::libvirtFormatError());
275 //        throw ZoneOperationException();
276 //    }
277 //
278 //    std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[numParamsBuff]);
279 //
280 //    if (virDomainGetSchedulerParameters(mZone.get(), params.get(), &numParamsBuff) < 0) {
281 //        LOGE(mId << ": Error while getting the zone's scheduler params:\n"
282 //             << libvirt::libvirtFormatError());
283 //        throw ZoneOperationException();
284 //    }
285 //
286 //    long long quota;
287 //    if (virTypedParamsGetLLong(params.get(),
288 //                               numParamsBuff,
289 //                               VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
290 //                               &quota) <= 0) {
291 //        LOGE(mId << ": Error while getting the zone's scheduler quota param:\n"
292 //             << libvirt::libvirtFormatError());
293 //        throw ZoneOperationException();
294 //    }
295 //
296 //    return quota;
297     return 0;
298 }
299
300 void ZoneAdmin::createNetdevVeth(const std::string& /* zoneDev */,
301                                  const std::string& /* hostDev */)
302 {
303     throw ZoneOperationException("Not implemented");
304 }
305
306 void ZoneAdmin::createNetdevMacvlan(const std::string& /* zoneDev */,
307                                     const std::string& /* hostDev */,
308                                     const uint32_t& /* mode */)
309 {
310     throw ZoneOperationException("Not implemented");
311 }
312
313 void ZoneAdmin::moveNetdev(const std::string& /* devId */)
314 {
315     throw ZoneOperationException("Not implemented");
316 }
317
318 } // namespace vasum