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& zoneId,
50 const std::string& zonesPath,
51 const std::string& lxcTemplatePrefix,
52 const ZoneConfig& config,
53 const ZoneDynamicConfig& dynamicConfig)
55 mZone(zonesPath, zoneId),
60 LOGD(mId << ": Instantiating ZoneAdmin object");
62 if (!mZone.isDefined()) {
64 const std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate,
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());
72 if (!dynamicConfig.ipv4.empty()) {
74 args.add(dynamicConfig.ipv4.c_str());
76 const std::string vt = std::to_string(dynamicConfig.vt);
77 if (dynamicConfig.vt > 0) {
81 if (!mZone.create(lxcTemplate, args.c_array())) {
82 throw ZoneOperationException("Could not create zone");
88 ZoneAdmin::~ZoneAdmin()
90 LOGD(mId << ": Destroying ZoneAdmin object...");
94 LOGE(mId << ": Failed to stop the zone");
96 if (!mZone.destroy()) {
97 LOGE(mId << ": Failed to destroy the zone");
101 if (!mDetachOnExit) {
102 // Try to forcefully stop
104 LOGE(mId << ": Failed to stop the zone");
108 LOGD(mId << ": ZoneAdmin object destroyed");
112 const std::string& ZoneAdmin::getId() const
118 void ZoneAdmin::start()
120 LOGD(mId << ": Starting...");
122 LOGD(mId << ": Already running - nothing to do...");
126 utils::CStringArrayBuilder args;
127 for (const std::string& arg : mConfig.initWithArgs) {
128 args.add(arg.c_str());
131 args.add("/sbin/init");
134 if (!mZone.start(args.c_array())) {
135 throw ZoneOperationException("Could not start zone");
138 LOGD(mId << ": Started");
142 void ZoneAdmin::stop()
144 LOGD(mId << ": Stopping procedure started...");
146 LOGD(mId << ": Already crashed/down/off - nothing to do");
150 if (!mZone.shutdown(SHUTDOWN_WAIT)) {
153 throw ZoneOperationException("Could not stop zone");
157 LOGD(mId << ": Stopping procedure ended");
161 void ZoneAdmin::destroy()
163 LOGD(mId << ": Destroying procedure started...");
165 if (!mZone.destroy()) {
166 throw ZoneOperationException("Could not destroy zone");
169 LOGD(mId << ": Destroying procedure ended");
173 bool ZoneAdmin::isRunning()
175 return mZone.getState() == lxc::LxcZone::State::RUNNING;
179 bool ZoneAdmin::isStopped()
181 return mZone.getState() == lxc::LxcZone::State::STOPPED;
185 void ZoneAdmin::suspend()
187 LOGD(mId << ": Pausing...");
188 if (!mZone.freeze()) {
189 throw ZoneOperationException("Could not pause zone");
191 LOGD(mId << ": Paused");
195 void ZoneAdmin::resume()
197 LOGD(mId << ": Resuming...");
198 if (!mZone.unfreeze()) {
199 throw ZoneOperationException("Could not resume zone");
201 LOGD(mId << ": Resumed");
205 bool ZoneAdmin::isPaused()
207 return mZone.getState() == lxc::LxcZone::State::FROZEN;
211 void ZoneAdmin::setSchedulerLevel(SchedulerLevel sched)
214 case SchedulerLevel::FOREGROUND:
215 LOGD(mId << ": Setting SchedulerLevel::FOREGROUND");
216 setSchedulerParams(DEFAULT_CPU_SHARES,
217 DEFAULT_VCPU_PERIOD_MS,
218 mConfig.cpuQuotaForeground);
220 case SchedulerLevel::BACKGROUND:
221 LOGD(mId << ": Setting SchedulerLevel::BACKGROUND");
222 setSchedulerParams(DEFAULT_CPU_SHARES,
223 DEFAULT_VCPU_PERIOD_MS,
224 mConfig.cpuQuotaBackground);
227 assert(0 && "Unknown sched parameter value");
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)
237 // int maxParams = 3;
238 // int numParamsBuff = 0;
240 // std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[maxParams]);
242 // virTypedParameterPtr paramsTmp = params.get();
244 // virTypedParamsAddULLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_CPU_SHARES, cpuShares);
245 // virTypedParamsAddULLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD, vcpuPeriod);
246 // virTypedParamsAddLLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA, vcpuQuota);
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();
255 void ZoneAdmin::setDetachOnExit()
257 mDetachOnExit = true;
260 void ZoneAdmin::setDestroyOnExit()
262 mDestroyOnExit = true;
265 std::int64_t ZoneAdmin::getSchedulerQuota()
269 // int numParamsBuff;
270 // std::unique_ptr<char, void(*)(void*)> type(virDomainGetSchedulerType(mZone.get(), &numParamsBuff), free);
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();
278 // std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[numParamsBuff]);
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();
287 // if (virTypedParamsGetLLong(params.get(),
289 // VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
291 // LOGE(mId << ": Error while getting the zone's scheduler quota param:\n"
292 // << libvirt::libvirtFormatError());
293 // throw ZoneOperationException();
300 void ZoneAdmin::createNetdevVeth(const std::string& /* zoneDev */,
301 const std::string& /* hostDev */)
303 throw ZoneOperationException("Not implemented");
306 void ZoneAdmin::createNetdevMacvlan(const std::string& /* zoneDev */,
307 const std::string& /* hostDev */,
308 const uint32_t& /* mode */)
310 throw ZoneOperationException("Not implemented");
313 void ZoneAdmin::moveNetdev(const std::string& /* devId */)
315 throw ZoneOperationException("Not implemented");