2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Jan Olszak <j.olszak@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
21 * @author Jan Olszak (j.olszak@samsung.com)
22 * @brief Implementation of class for administrating one zone
27 #include "zone-admin.hpp"
28 #include "exception.hpp"
30 #include "logger/logger.hpp"
31 #include "utils/paths.hpp"
32 #include "utils/c-array.hpp"
41 // TODO: this should be in zone's configuration file
42 const int SHUTDOWN_WAIT = 10;
46 const std::uint64_t DEFAULT_CPU_SHARES = 1024;
47 const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000;
49 ZoneAdmin::ZoneAdmin(const std::string& zonesPath,
50 const std::string& lxcTemplatePrefix,
51 const ZoneConfig& config)
53 mZone(zonesPath, config.name),
58 LOGD(mId << ": Instantiating ZoneAdmin object");
60 if (!mZone.isDefined()) {
62 const std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate,
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());
70 if (!config.ipv4.empty()) {
72 args.add(config.ipv4.c_str());
74 if (!mZone.create(lxcTemplate, args.c_array())) {
75 throw ZoneOperationException("Could not create zone");
81 ZoneAdmin::~ZoneAdmin()
83 LOGD(mId << ": Destroying ZoneAdmin object...");
87 LOGE(mId << ": Failed to stop the zone");
89 if (!mZone.destroy()) {
90 LOGE(mId << ": Failed to destroy the zone");
95 // Try to forcefully stop
97 LOGE(mId << ": Failed to stop the zone");
101 LOGD(mId << ": ZoneAdmin object destroyed");
105 const std::string& ZoneAdmin::getId() const
111 void ZoneAdmin::start()
113 LOGD(mId << ": Starting...");
115 LOGD(mId << ": Already running - nothing to do...");
119 utils::CStringArrayBuilder args;
120 for (const std::string& arg : mConfig.initWithArgs) {
121 args.add(arg.c_str());
124 args.add("/sbin/init");
127 if (!mZone.start(args.c_array())) {
128 throw ZoneOperationException("Could not start zone");
131 LOGD(mId << ": Started");
135 void ZoneAdmin::stop()
137 LOGD(mId << ": Stopping procedure started...");
139 LOGD(mId << ": Already crashed/down/off - nothing to do");
143 if (!mZone.shutdown(SHUTDOWN_WAIT)) {
146 throw ZoneOperationException("Could not stop zone");
150 LOGD(mId << ": Stopping procedure ended");
154 void ZoneAdmin::destroy()
156 LOGD(mId << ": Destroying procedure started...");
158 if (!mZone.destroy()) {
159 throw ZoneOperationException("Could not destroy zone");
162 LOGD(mId << ": Destroying procedure ended");
166 bool ZoneAdmin::isRunning()
168 return mZone.getState() == lxc::LxcZone::State::RUNNING;
172 bool ZoneAdmin::isStopped()
174 return mZone.getState() == lxc::LxcZone::State::STOPPED;
178 void ZoneAdmin::suspend()
180 LOGD(mId << ": Pausing...");
181 if (!mZone.freeze()) {
182 throw ZoneOperationException("Could not pause zone");
184 LOGD(mId << ": Paused");
188 void ZoneAdmin::resume()
190 LOGD(mId << ": Resuming...");
191 if (!mZone.unfreeze()) {
192 throw ZoneOperationException("Could not resume zone");
194 LOGD(mId << ": Resumed");
198 bool ZoneAdmin::isPaused()
200 return mZone.getState() == lxc::LxcZone::State::FROZEN;
204 void ZoneAdmin::setSchedulerLevel(SchedulerLevel sched)
207 case SchedulerLevel::FOREGROUND:
208 LOGD(mId << ": Setting SchedulerLevel::FOREGROUND");
209 setSchedulerParams(DEFAULT_CPU_SHARES,
210 DEFAULT_VCPU_PERIOD_MS,
211 mConfig.cpuQuotaForeground);
213 case SchedulerLevel::BACKGROUND:
214 LOGD(mId << ": Setting SchedulerLevel::BACKGROUND");
215 setSchedulerParams(DEFAULT_CPU_SHARES,
216 DEFAULT_VCPU_PERIOD_MS,
217 mConfig.cpuQuotaBackground);
220 assert(0 && "Unknown sched parameter value");
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)
230 // int maxParams = 3;
231 // int numParamsBuff = 0;
233 // std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[maxParams]);
235 // virTypedParameterPtr paramsTmp = params.get();
237 // virTypedParamsAddULLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_CPU_SHARES, cpuShares);
238 // virTypedParamsAddULLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD, vcpuPeriod);
239 // virTypedParamsAddLLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA, vcpuQuota);
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();
248 void ZoneAdmin::setDetachOnExit()
250 mDetachOnExit = true;
253 void ZoneAdmin::setDestroyOnExit()
255 mDestroyOnExit = true;
258 std::int64_t ZoneAdmin::getSchedulerQuota()
262 // int numParamsBuff;
263 // std::unique_ptr<char, void(*)(void*)> type(virDomainGetSchedulerType(mZone.get(), &numParamsBuff), free);
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();
271 // std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[numParamsBuff]);
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();
280 // if (virTypedParamsGetLLong(params.get(),
282 // VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
284 // LOGE(mId << ": Error while getting the zone's scheduler quota param:\n"
285 // << libvirt::libvirtFormatError());
286 // throw ZoneOperationException();