Rename all not associated with LXC stuff.
[platform/core/security/vasum.git] / server / zone-admin.cpp
index 46c4974..473a11c 100644 (file)
 
 #include "zone-admin.hpp"
 #include "exception.hpp"
+#include "netdev.hpp"
 
 #include "logger/logger.hpp"
 #include "utils/paths.hpp"
 #include "utils/c-array.hpp"
+#include "lxc/cgroup.hpp"
 
 #include <cassert>
+#include <climits>
+#include <thread>
+#include <chrono>
 
 
 namespace vasum {
 
-namespace {
-
-// TODO: this should be in zone's configuration file
-const int SHUTDOWN_WAIT = 10;
-
-} // namespace
-
 const std::uint64_t DEFAULT_CPU_SHARES = 1024;
 const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000;
 
-ZoneAdmin::ZoneAdmin(const std::string& zonesPath,
-                               const std::string& lxcTemplatePrefix,
-                               const ZoneConfig& config)
+ZoneAdmin::ZoneAdmin(const std::string& zoneId,
+                     const std::string& zonesPath,
+                     const std::string& zoneTemplatePrefix,
+                     const ZoneConfig& config,
+                     const ZoneDynamicConfig& dynamicConfig)
     : mConfig(config),
-      mZone(zonesPath, config.name),
-      mId(mZone.getName()),
+      mDynamicConfig(dynamicConfig),
+      mZone(zonesPath, zoneId),
+      mId(zoneId),
       mDetachOnExit(false),
       mDestroyOnExit(false)
 {
@@ -59,24 +60,24 @@ ZoneAdmin::ZoneAdmin(const std::string& zonesPath,
 
     if (!mZone.isDefined()) {
 
-        const std::string lxcTemplate = utils::getAbsolutePath(config.lxcTemplate,
-                                                               lxcTemplatePrefix);
-        LOGI(mId << ": Creating zone from template: " << lxcTemplate);
+        const std::string zoneTemplate = utils::getAbsolutePath(config.zoneTemplate,
+                                                               zoneTemplatePrefix);
+        LOGI(mId << ": Creating zone from template: " << zoneTemplate);
         utils::CStringArrayBuilder args;
-        if (!config.ipv4Gateway.empty()) {
+        if (!dynamicConfig.ipv4Gateway.empty()) {
             args.add("--ipv4-gateway");
-            args.add(config.ipv4Gateway.c_str());
+            args.add(dynamicConfig.ipv4Gateway.c_str());
         }
-        if (!config.ipv4.empty()) {
+        if (!dynamicConfig.ipv4.empty()) {
             args.add("--ipv4");
-            args.add(config.ipv4.c_str());
+            args.add(dynamicConfig.ipv4.c_str());
         }
-        const std::string vt = std::to_string(config.vt);
-        if (config.vt > 0) {
+        const std::string vt = std::to_string(dynamicConfig.vt);
+        if (dynamicConfig.vt > 0) {
             args.add("--vt");
             args.add(vt.c_str());
         }
-        if (!mZone.create(lxcTemplate, args.c_array())) {
+        if (!mZone.create(zoneTemplate, args.c_array())) {
             throw ZoneOperationException("Could not create zone");
         }
     }
@@ -133,6 +134,16 @@ void ZoneAdmin::start()
         throw ZoneOperationException("Could not start zone");
     }
 
+    // Wait until the full platform launch with graphical stack.
+    // VT should be activated by a graphical stack.
+    // If we do it with 'zoneToFocus.activateVT' before starting the graphical stack,
+    // graphical stack initialization failed and we finally switch to the black screen.
+    // Skip waiting when graphical stack is not running (unit tests).
+    if (mDynamicConfig.vt > 0) {
+        // TODO, timeout is a temporary solution
+        std::this_thread::sleep_for(std::chrono::milliseconds(4000));
+    }
+
     LOGD(mId << ": Started");
 }
 
@@ -145,7 +156,7 @@ void ZoneAdmin::stop()
         return;
     }
 
-    if (!mZone.shutdown(SHUTDOWN_WAIT)) {
+    if (!mZone.shutdown(mConfig.shutdownTimeout)) {
         // force stop
         if (!mZone.stop()) {
             throw ZoneOperationException("Could not stop zone");
@@ -208,6 +219,8 @@ bool ZoneAdmin::isPaused()
 
 void ZoneAdmin::setSchedulerLevel(SchedulerLevel sched)
 {
+    assert(isRunning());
+
     switch (sched) {
     case SchedulerLevel::FOREGROUND:
         LOGD(mId << ": Setting SchedulerLevel::FOREGROUND");
@@ -227,27 +240,21 @@ void ZoneAdmin::setSchedulerLevel(SchedulerLevel sched)
 }
 
 
-void ZoneAdmin::setSchedulerParams(std::uint64_t, std::uint64_t, std::int64_t)
-//void ZoneAdmin::setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota)
+void ZoneAdmin::setSchedulerParams(std::uint64_t cpuShares,
+                                   std::uint64_t vcpuPeriod,
+                                   std::int64_t vcpuQuota)
 {
-//    assert(mZone);
-//
-//    int maxParams = 3;
-//    int numParamsBuff = 0;
-//
-//    std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[maxParams]);
-//
-//    virTypedParameterPtr paramsTmp = params.get();
-//
-//    virTypedParamsAddULLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_CPU_SHARES, cpuShares);
-//    virTypedParamsAddULLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_PERIOD, vcpuPeriod);
-//    virTypedParamsAddLLong(&paramsTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA, vcpuQuota);
-//
-//    if (virDomainSetSchedulerParameters(mZone.get(), params.get(), numParamsBuff) < 0) {
-//        LOGE(mId << ": Error while setting the zone's scheduler params:\n"
-//             << libvirt::libvirtFormatError());
-//        throw ZoneOperationException();
-//    }
+    assert(vcpuPeriod >= 1000 && vcpuPeriod <= 1000000);
+    assert(vcpuQuota == -1 ||
+           (vcpuQuota >= 1000 && vcpuQuota <= static_cast<std::int64_t>(ULLONG_MAX / 1000)));
+
+    if (!lxc::setCgroup(mId, "cpu", "cpu.shares", std::to_string(cpuShares)) ||
+        !lxc::setCgroup(mId, "cpu", "cpu.cfs_period_us", std::to_string(vcpuPeriod)) ||
+        !lxc::setCgroup(mId, "cpu", "cpu.cfs_quota_us", std::to_string(vcpuQuota))) {
+
+        LOGE(mId << ": Error while setting the zone's scheduler params");
+        throw ZoneOperationException("Could not set scheduler params");
+    }
 }
 
 void ZoneAdmin::setDetachOnExit()
@@ -262,38 +269,55 @@ void ZoneAdmin::setDestroyOnExit()
 
 std::int64_t ZoneAdmin::getSchedulerQuota()
 {
-//    assert(mZone);
-//
-//    int numParamsBuff;
-//    std::unique_ptr<char, void(*)(void*)> type(virDomainGetSchedulerType(mZone.get(), &numParamsBuff), free);
-//
-//    if (type == NULL || numParamsBuff <= 0 || strcmp(type.get(), "posix") != 0) {
-//        LOGE(mId << ": Error while getting the zone's scheduler type:\n"
-//             << libvirt::libvirtFormatError());
-//        throw ZoneOperationException();
-//    }
-//
-//    std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[numParamsBuff]);
-//
-//    if (virDomainGetSchedulerParameters(mZone.get(), params.get(), &numParamsBuff) < 0) {
-//        LOGE(mId << ": Error while getting the zone's scheduler params:\n"
-//             << libvirt::libvirtFormatError());
-//        throw ZoneOperationException();
-//    }
-//
-//    long long quota;
-//    if (virTypedParamsGetLLong(params.get(),
-//                               numParamsBuff,
-//                               VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
-//                               &quota) <= 0) {
-//        LOGE(mId << ": Error while getting the zone's scheduler quota param:\n"
-//             << libvirt::libvirtFormatError());
-//        throw ZoneOperationException();
-//    }
-//
-//    return quota;
-    return 0;
+    std::string ret;
+    if (!lxc::getCgroup(mId, "cpu", "cpu.cfs_quota_us", ret)) {
+        LOGE(mId << ": Error while getting the zone's scheduler quota param");
+        throw ZoneOperationException("Could not get scheduler quota param");
+    }
+    return std::stoll(ret);
+}
+
+void ZoneAdmin::createNetdevVeth(const std::string& zoneDev,
+                                 const std::string& hostDev)
+{
+    netdev::createVeth(mZone.getInitPid(), zoneDev, hostDev);
 }
 
+void ZoneAdmin::createNetdevMacvlan(const std::string& zoneDev,
+                                    const std::string& hostDev,
+                                    const uint32_t& mode)
+{
+    netdev::createMacvlan(mZone.getInitPid(), zoneDev, hostDev, static_cast<macvlan_mode>(mode));
+}
+
+void ZoneAdmin::moveNetdev(const std::string& devId)
+{
+    netdev::movePhys(mZone.getInitPid(), devId);
+}
+
+void ZoneAdmin::destroyNetdev(const std::string& devId)
+{
+    netdev::destroyNetdev(devId, mZone.getInitPid());
+}
+
+void ZoneAdmin::setNetdevAttrs(const std::string& netdev, const NetdevAttrs& attrs)
+{
+    netdev::setAttrs(mZone.getInitPid(), netdev, attrs);
+}
+
+ZoneAdmin::NetdevAttrs ZoneAdmin::getNetdevAttrs(const std::string& netdev)
+{
+    return netdev::getAttrs(mZone.getInitPid(), netdev);
+}
+
+std::vector<std::string> ZoneAdmin::getNetdevList()
+{
+    return netdev::listNetdev(mZone.getInitPid());
+}
+
+void ZoneAdmin::deleteNetdevIpAddress(const std::string& netdev, const std::string& ip)
+{
+    netdev::deleteIpAddress(mZone.getInitPid(), netdev, ip);
+}
 
 } // namespace vasum