Rename containers to zones
[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& zonesPath,
50                                const std::string& lxcTemplatePrefix,
51                                const ZoneConfig& config)
52     : mConfig(config),
53       mZone(zonesPath, config.name),
54       mId(mZone.getName()),
55       mDetachOnExit(false),
56       mDestroyOnExit(false)
57 {
58     LOGD(mId << ": Instantiating ZoneAdmin object");
59
60     if (!mZone.isDefined()) {
61
62         const std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate,
63                                                                lxcTemplatePrefix);
64         LOGI(mId << ": Creating zone from template: " << lxcTemplate);
65         utils::CStringArrayBuilder args;
66         if (!config.ipv4Gateway.empty()) {
67             args.add("--ipv4-gateway");
68             args.add(config.ipv4Gateway.c_str());
69         }
70         if (!config.ipv4.empty()) {
71             args.add("--ipv4");
72             args.add(config.ipv4.c_str());
73         }
74         if (!mZone.create(lxcTemplate, args.c_array())) {
75             throw ZoneOperationException("Could not create zone");
76         }
77     }
78 }
79
80
81 ZoneAdmin::~ZoneAdmin()
82 {
83     LOGD(mId << ": Destroying ZoneAdmin object...");
84
85     if (mDestroyOnExit) {
86         if (!mZone.stop()) {
87             LOGE(mId << ": Failed to stop the zone");
88         }
89         if (!mZone.destroy()) {
90             LOGE(mId << ": Failed to destroy the zone");
91         }
92     }
93
94     if (!mDetachOnExit) {
95         // Try to forcefully stop
96         if (!mZone.stop()) {
97             LOGE(mId << ": Failed to stop the zone");
98         }
99     }
100
101     LOGD(mId << ": ZoneAdmin object destroyed");
102 }
103
104
105 const std::string& ZoneAdmin::getId() const
106 {
107     return mId;
108 }
109
110
111 void ZoneAdmin::start()
112 {
113     LOGD(mId << ": Starting...");
114     if (isRunning()) {
115         LOGD(mId << ": Already running - nothing to do...");
116         return;
117     }
118
119     utils::CStringArrayBuilder args;
120     for (const std::string& arg : mConfig.initWithArgs) {
121         args.add(arg.c_str());
122     }
123     if (args.empty()) {
124         args.add("/sbin/init");
125     }
126
127     if (!mZone.start(args.c_array())) {
128         throw ZoneOperationException("Could not start zone");
129     }
130
131     LOGD(mId << ": Started");
132 }
133
134
135 void ZoneAdmin::stop()
136 {
137     LOGD(mId << ": Stopping procedure started...");
138     if (isStopped()) {
139         LOGD(mId << ": Already crashed/down/off - nothing to do");
140         return;
141     }
142
143     if (!mZone.shutdown(SHUTDOWN_WAIT)) {
144         // force stop
145         if (!mZone.stop()) {
146             throw ZoneOperationException("Could not stop zone");
147         }
148     }
149
150     LOGD(mId << ": Stopping procedure ended");
151 }
152
153
154 void ZoneAdmin::destroy()
155 {
156     LOGD(mId << ": Destroying procedure started...");
157
158     if (!mZone.destroy()) {
159         throw ZoneOperationException("Could not destroy zone");
160     }
161
162     LOGD(mId << ": Destroying procedure ended");
163 }
164
165
166 bool ZoneAdmin::isRunning()
167 {
168     return mZone.getState() == lxc::LxcZone::State::RUNNING;
169 }
170
171
172 bool ZoneAdmin::isStopped()
173 {
174     return mZone.getState() == lxc::LxcZone::State::STOPPED;
175 }
176
177
178 void ZoneAdmin::suspend()
179 {
180     LOGD(mId << ": Pausing...");
181     if (!mZone.freeze()) {
182         throw ZoneOperationException("Could not pause zone");
183     }
184     LOGD(mId << ": Paused");
185 }
186
187
188 void ZoneAdmin::resume()
189 {
190     LOGD(mId << ": Resuming...");
191     if (!mZone.unfreeze()) {
192         throw ZoneOperationException("Could not resume zone");
193     }
194     LOGD(mId << ": Resumed");
195 }
196
197
198 bool ZoneAdmin::isPaused()
199 {
200     return mZone.getState() == lxc::LxcZone::State::FROZEN;
201 }
202
203
204 void ZoneAdmin::setSchedulerLevel(SchedulerLevel sched)
205 {
206     switch (sched) {
207     case SchedulerLevel::FOREGROUND:
208         LOGD(mId << ": Setting SchedulerLevel::FOREGROUND");
209         setSchedulerParams(DEFAULT_CPU_SHARES,
210                            DEFAULT_VCPU_PERIOD_MS,
211                            mConfig.cpuQuotaForeground);
212         break;
213     case SchedulerLevel::BACKGROUND:
214         LOGD(mId << ": Setting SchedulerLevel::BACKGROUND");
215         setSchedulerParams(DEFAULT_CPU_SHARES,
216                            DEFAULT_VCPU_PERIOD_MS,
217                            mConfig.cpuQuotaBackground);
218         break;
219     default:
220         assert(0 && "Unknown sched parameter value");
221     }
222 }
223
224
225 void ZoneAdmin::setSchedulerParams(std::uint64_t, std::uint64_t, std::int64_t)
226 //void ZoneAdmin::setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota)
227 {
228 //    assert(mZone);
229 //
230 //    int maxParams = 3;
231 //    int numParamsBuff = 0;
232 //
233 //    std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[maxParams]);
234 //
235 //    virTypedParameterPtr paramsTmp = params.get();
236 //
237 //    virTypedParamsAddULLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_CPU_SHARES, cpuShares);
238 //    virTypedParamsAddULLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD, vcpuPeriod);
239 //    virTypedParamsAddLLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA, vcpuQuota);
240 //
241 //    if (virDomainSetSchedulerParameters(mZone.get(), params.get(), numParamsBuff) < 0) {
242 //        LOGE(mId << ": Error while setting the zone's scheduler params:\n"
243 //             << libvirt::libvirtFormatError());
244 //        throw ZoneOperationException();
245 //    }
246 }
247
248 void ZoneAdmin::setDetachOnExit()
249 {
250     mDetachOnExit = true;
251 }
252
253 void ZoneAdmin::setDestroyOnExit()
254 {
255     mDestroyOnExit = true;
256 }
257
258 std::int64_t ZoneAdmin::getSchedulerQuota()
259 {
260 //    assert(mZone);
261 //
262 //    int numParamsBuff;
263 //    std::unique_ptr<char, void(*)(void*)> type(virDomainGetSchedulerType(mZone.get(), &numParamsBuff), free);
264 //
265 //    if (type == NULL || numParamsBuff <= 0 || strcmp(type.get(), "posix") != 0) {
266 //        LOGE(mId << ": Error while getting the zone's scheduler type:\n"
267 //             << libvirt::libvirtFormatError());
268 //        throw ZoneOperationException();
269 //    }
270 //
271 //    std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[numParamsBuff]);
272 //
273 //    if (virDomainGetSchedulerParameters(mZone.get(), params.get(), &numParamsBuff) < 0) {
274 //        LOGE(mId << ": Error while getting the zone's scheduler params:\n"
275 //             << libvirt::libvirtFormatError());
276 //        throw ZoneOperationException();
277 //    }
278 //
279 //    long long quota;
280 //    if (virTypedParamsGetLLong(params.get(),
281 //                               numParamsBuff,
282 //                               VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
283 //                               &quota) <= 0) {
284 //        LOGE(mId << ": Error while getting the zone's scheduler quota param:\n"
285 //             << libvirt::libvirtFormatError());
286 //        throw ZoneOperationException();
287 //    }
288 //
289 //    return quota;
290     return 0;
291 }
292
293
294 } // namespace vasum