2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Lukasz Pawelczyk <l.pawelczyk@partner.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 Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com)
22 * @brief Implementation of class for managing one zone
28 #include "base-exception.hpp"
30 #include "logger/logger.hpp"
31 #include "utils/paths.hpp"
32 #include "utils/vt.hpp"
33 #include "config/manager.hpp"
35 #include <boost/filesystem.hpp>
42 namespace fs = boost::filesystem;
46 typedef std::lock_guard<std::recursive_mutex> Lock;
48 // TODO: move constants to the config file when default values are implemented there
49 const int RECONNECT_RETRIES = 15;
50 const int RECONNECT_DELAY = 1 * 1000;
54 Zone::Zone(const utils::Worker::Pointer& worker,
55 const std::string& zonesPath,
56 const std::string& zoneConfigPath,
57 const std::string& lxcTemplatePrefix,
58 const std::string& baseRunMountPointPath)
61 config::loadFromJsonFile(zoneConfigPath, mConfig);
63 for (std::string r: mConfig.permittedToSend) {
64 mPermittedToSend.push_back(boost::regex(r));
66 for (std::string r: mConfig.permittedToRecv) {
67 mPermittedToRecv.push_back(boost::regex(r));
70 if (!mConfig.runMountPoint.empty()) {
71 mRunMountPoint = fs::absolute(mConfig.runMountPoint, baseRunMountPointPath).string();
74 mAdmin.reset(new ZoneAdmin(zonesPath, lxcTemplatePrefix, mConfig));
75 const fs::path zonePath = fs::path(zonesPath) / mAdmin->getId();
76 mProvision.reset(new ZoneProvision(zonePath.string(), mConfig.validLinkPrefixes));
81 // Make sure all OnNameLostCallbacks get finished and no new will
82 // get called before proceeding further. This guarantees no race
83 // condition on the reconnect thread.
85 Lock lock(mReconnectMutex);
88 // wait for all tasks to complete
92 const std::vector<boost::regex>& Zone::getPermittedToSend() const
94 return mPermittedToSend;
97 const std::vector<boost::regex>& Zone::getPermittedToRecv() const
99 return mPermittedToRecv;
102 const std::string& Zone::getId() const
104 Lock lock(mReconnectMutex);
105 return mAdmin->getId();
108 int Zone::getPrivilege() const
110 return mConfig.privilege;
115 Lock lock(mReconnectMutex);
117 if (mConfig.enableDbusIntegration) {
118 mConnectionTransport.reset(new ZoneConnectionTransport(mRunMountPoint));
121 if (mConfig.enableDbusIntegration) {
125 // Send to the background only after we're connected, otherwise it'd take ages.
126 LOGD(getId() << ": sending to the background");
130 void Zone::startAsync(const StartAsyncResultCallback& callback)
132 auto startWrapper = [this, callback]() {
133 bool succeeded = false;
138 } catch(std::exception& e) {
139 LOGE(getId() << ": failed to start: " << e.what());
147 mWorker->addTask(startWrapper);
152 Lock lock(mReconnectMutex);
155 mConnectionTransport.reset();
161 // assume called under reconnect lock
162 mDbusAddress = mConnectionTransport->acquireAddress();
163 mConnection.reset(new ZoneConnection(mDbusAddress,
164 std::bind(&Zone::onNameLostCallback, this)));
165 if (mNotifyCallback) {
166 mConnection->setNotifyActiveZoneCallback(mNotifyCallback);
168 if (mDisplayOffCallback) {
169 mConnection->setDisplayOffCallback(mDisplayOffCallback);
171 if (mFileMoveCallback) {
172 mConnection->setFileMoveRequestCallback(mFileMoveCallback);
174 if (mProxyCallCallback) {
175 mConnection->setProxyCallCallback(mProxyCallCallback);
177 if (mDbusStateChangedCallback) {
178 mDbusStateChangedCallback(mDbusAddress);
182 void Zone::disconnect()
184 // assume called under reconnect lock
187 mDbusAddress.clear();
188 if (mDbusStateChangedCallback) {
189 // notify about invalid dbusAddress for this zone
190 mDbusStateChangedCallback(std::string());
195 std::string Zone::getDbusAddress() const
197 Lock lock(mReconnectMutex);
201 int Zone::getVT() const
206 std::string Zone::getRootPath() const
208 return mProvision->getRootPath();
212 bool Zone::activateVT()
214 Lock lock(mReconnectMutex);
216 if (mConfig.vt >= 0) {
217 return utils::activateVT(mConfig.vt);
223 void Zone::goForeground()
225 Lock lock(mReconnectMutex);
226 mAdmin->setSchedulerLevel(SchedulerLevel::FOREGROUND);
229 void Zone::goBackground()
231 Lock lock(mReconnectMutex);
232 mAdmin->setSchedulerLevel(SchedulerLevel::BACKGROUND);
235 void Zone::setDetachOnExit()
237 Lock lock(mReconnectMutex);
238 mAdmin->setDetachOnExit();
239 if (mConnectionTransport) {
240 mConnectionTransport->setDetachOnExit();
244 void Zone::setDestroyOnExit()
246 Lock lock(mReconnectMutex);
247 mAdmin->setDestroyOnExit();
250 bool Zone::isRunning()
252 Lock lock(mReconnectMutex);
253 return mAdmin->isRunning();
256 bool Zone::isStopped()
258 Lock lock(mReconnectMutex);
259 return mAdmin->isStopped();
264 Lock lock(mReconnectMutex);
270 Lock lock(mReconnectMutex);
274 bool Zone::isPaused()
276 Lock lock(mReconnectMutex);
277 return mAdmin->isPaused();
280 bool Zone::isSwitchToDefaultAfterTimeoutAllowed() const
282 return mConfig.switchToDefaultAfterTimeout;
285 void Zone::onNameLostCallback()
287 LOGI(getId() << ": A connection to the DBUS server has been lost, reconnecting...");
289 mWorker->addTask(std::bind(&Zone::reconnectHandler, this));
292 void Zone::reconnectHandler()
295 Lock lock(mReconnectMutex);
299 for (int i = 0; i < RECONNECT_RETRIES; ++i) {
300 // This sleeps even before the first try to give DBUS some time to come back up
301 std::this_thread::sleep_for(std::chrono::milliseconds(RECONNECT_DELAY));
303 Lock lock(mReconnectMutex);
305 LOGI(getId() << ": Has stopped, nothing to reconnect to, bailing out");
310 LOGT(getId() << ": Reconnect try " << i + 1);
312 LOGI(getId() << ": Reconnected");
314 } catch (VasumException&) {
315 LOGT(getId() << ": Reconnect try " << i + 1 << " has been unsuccessful");
319 LOGE(getId() << ": Reconnecting to the DBUS has failed, stopping the zone");
323 void Zone::setNotifyActiveZoneCallback(const NotifyActiveZoneCallback& callback)
325 Lock lock(mReconnectMutex);
326 mNotifyCallback = callback;
328 mConnection->setNotifyActiveZoneCallback(mNotifyCallback);
332 void Zone::sendNotification(const std::string& zone,
333 const std::string& application,
334 const std::string& message)
336 Lock lock(mReconnectMutex);
338 mConnection->sendNotification(zone, application, message);
340 LOGE(getId() << ": Can't send notification, no connection to DBUS");
344 void Zone::setDisplayOffCallback(const DisplayOffCallback& callback)
346 Lock lock(mReconnectMutex);
348 mDisplayOffCallback = callback;
350 mConnection->setDisplayOffCallback(callback);
354 void Zone::setFileMoveRequestCallback(const FileMoveRequestCallback& callback)
356 Lock lock(mReconnectMutex);
358 mFileMoveCallback = callback;
360 mConnection->setFileMoveRequestCallback(callback);
364 void Zone::setProxyCallCallback(const ProxyCallCallback& callback)
366 Lock lock(mReconnectMutex);
368 mProxyCallCallback = callback;
370 mConnection->setProxyCallCallback(callback);
374 void Zone::setDbusStateChangedCallback(const DbusStateChangedCallback& callback)
376 mDbusStateChangedCallback = callback;
379 void Zone::proxyCallAsync(const std::string& busName,
380 const std::string& objectPath,
381 const std::string& interface,
382 const std::string& method,
383 GVariant* parameters,
384 const dbus::DbusConnection::AsyncMethodCallCallback& callback)
386 Lock lock(mReconnectMutex);
388 mConnection->proxyCallAsync(busName,
395 LOGE(getId() << ": Can't do a proxy call, no connection to DBUS");
399 void Zone::declareFile(const int32_t& type,
400 const std::string& path,
401 const int32_t& flags,
404 mProvision->declareFile(type, path, flags, mode);
407 void Zone::declareMount(const std::string& source,
408 const std::string& target,
409 const std::string& type,
410 const int64_t& flags,
411 const std::string& data)
413 mProvision->declareMount(source, target, type, flags, data);
416 void Zone::declareLink(const std::string& source,
417 const std::string& target)
419 mProvision->declareLink(source, target);