*/
#include "log/logger.hpp"
+#include "libvirt/helpers.hpp"
#include "libvirt/connection.hpp"
#include "libvirt/exception.hpp"
LibvirtConnection::LibvirtConnection(const std::string& uri)
{
+ libvirtInitialize();
+
mCon = virConnectOpen(uri.c_str());
if (mCon == NULL) {
- LOGE("Failed to open connection to libvirtd");
+ LOGE("Failed to open a connection to the libvirtd:\n"
+ << libvirtFormatError());
throw LibvirtOperationException();
}
}
LibvirtConnection::~LibvirtConnection()
{
if (virConnectClose(mCon) < 0) {
- LOGE("Error while disconnecting from libvirt");
+ LOGE("Error while disconnecting from the libvirtd:\n"
+ << libvirtFormatError());
};
}
#include "log/logger.hpp"
#include "libvirt/domain.hpp"
+#include "libvirt/helpers.hpp"
#include "libvirt/exception.hpp"
#include <cassert>
mDom = virDomainDefineXML(mCon.get(), configXML.c_str());
if (mDom == NULL) {
- LOGE("Error during domain defining");
+ LOGE("Error while defining a domain:\n"
+ << libvirtFormatError());
throw LibvirtOperationException();
}
}
LibvirtDomain::~LibvirtDomain()
{
if (virDomainUndefine(mDom) < 0) {
- LOGE("Error during domain undefine");
+ LOGE("Error while undefining the domain:\n"
+ << libvirtFormatError());
}
if (virDomainFree(mDom) < 0) {
- LOGE("Error during domain destruction");
+ LOGE("Error while destroying the domain object:\n"
+ << libvirtFormatError());
}
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Lukasz Pawelczyk <l.pawelczyk@partner.samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/**
+ * @file
+ * @author Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com)
+ * @brief A function helpers for the libvirt library
+ */
+
+#include "log/logger.hpp"
+
+#include <mutex>
+#include <libvirt/virterror.h>
+
+
+namespace security_containers {
+namespace libvirt {
+
+
+namespace {
+
+std::once_flag gInitFlag;
+
+/**
+ * This function intentionally is not displaying any errors,
+ * we log them ourselves elsewhere.
+ * It is however displaying warnings for the time being so we can
+ * learn whether such situations occur.
+ */
+void libvirtErrorFunction(void* /*userData*/, virErrorPtr error)
+{
+ if (error->level == VIR_ERR_WARNING) {
+ LOGW("LIBVIRT reported a warning: \n" << error->message);
+ }
+}
+
+} // namespace
+
+void libvirtInitialize(void)
+{
+ std::call_once(gInitFlag, []() {
+ virInitialize();
+ virSetErrorFunc(NULL, &libvirtErrorFunction);
+ });
+}
+
+std::string libvirtFormatError(const std::string& domainName = std::string())
+{
+ std::string ret;
+
+ virErrorPtr error = virGetLastError();
+
+ if (error == NULL) {
+ return ret;
+ }
+
+ if (!domainName.empty()) {
+ ret += "LIBVIRT Domain: " + domainName + "\n";
+ }
+
+ if (error->message) {
+ ret += "LIBVIRT Message: " + std::string(error->message);
+ }
+
+ return ret;
+}
+
+
+} // namespace libvirt
+} // namespace security_containers
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Lukasz Pawelczyk <l.pawelczyk@partner.samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+/**
+ * @file
+ * @author Lukasz Pawelczyk (l.pawelczyk@partner.samsung.com)
+ * @brief A function helpers for the libvirt library
+ */
+
+#ifndef COMMON_LIBVIRT_HELPERS_HPP
+#define COMMON_LIBVIRT_HELPERS_HPP
+
+#include <string>
+
+
+namespace security_containers {
+namespace libvirt {
+
+
+/**
+ * Initialize libvirt library in a thread safety manner
+ */
+void libvirtInitialize(void);
+
+/**
+ * Formats libvirt's last error. Might include
+ * the affected domain's name if it exists.
+ */
+std::string libvirtFormatError(const std::string& domainName = std::string());
+
+
+} // namespace libvirt
+} // namespace security_containers
+
+
+#endif // COMMON_LIBVIRT_HELPERS_HPP
#include "container-admin.hpp"
#include "exception.hpp"
+#include "libvirt/helpers.hpp"
#include "log/logger.hpp"
#include "utils/fs.hpp"
namespace security_containers {
+namespace {
+
+std::string getDomainName(virDomainPtr dom)
+{
+ assert(dom != NULL);
+
+ const char* name;
+ if ((name = virDomainGetName(dom)) == NULL) {
+ LOGE("Failed to get the domain's id:\n"
+ << libvirt::libvirtFormatError());
+ throw DomainOperationException();
+ }
+
+ return name;
+}
+
+} // namespace
+
const std::uint64_t DEFAULT_CPU_SHARES = 1024;
const std::uint64_t DEFAULT_VCPU_PERIOD_MS = 100000;
ContainerAdmin::ContainerAdmin(ContainerConfig& config)
- : mConfig(config), mDom(utils::readFileContent(mConfig.config))
+ : mConfig(config), mDom(utils::readFileContent(mConfig.config)), mId(getDomainName(mDom.get()))
{
}
}
-std::string ContainerAdmin::getId()
+const std::string& ContainerAdmin::getId() const
{
- assert(mDom.get() != NULL);
-
- const char* id;
- if ((id = virDomainGetName(mDom.get())) == NULL) {
- LOGE("Failed to get container's id");
- throw DomainOperationException();
- }
-
- return id;
+ return mId;
}
u_int flags = VIR_DOMAIN_START_AUTODESTROY;
if (virDomainCreateWithFlags(mDom.get(), flags) < 0) {
- LOGE("Failed to start the container");
+ LOGE("Failed to start the domain:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
u_int flags = VIR_DOMAIN_DESTROY_DEFAULT;
if (virDomainDestroyFlags(mDom.get(), flags) < 0) {
- LOGE("Error during domain stopping");
+ LOGE("Error while stopping the domain:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
}
resume();
if (virDomainShutdown(mDom.get()) < 0) {
- LOGE("Error during domain shutdown");
+ LOGE("Error while shutting down the domain:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
}
}
if (virDomainSuspend(mDom.get()) < 0) {
- LOGE("Error during domain suspension");
+ LOGE("Error while suspending the domain:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
}
}
if (virDomainResume(mDom.get()) < 0) {
- LOGE("Error during domain resumming");
+ LOGE("Error while resumming the domain:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
}
int state;
if (virDomainGetState(mDom.get(), &state, NULL, 0)) {
- LOGE("Error during getting domain's state");
+ LOGE("Error whilte getting the domain's state:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
virTypedParamsAddLLong(¶msTmp, &numParamsBuff, &maxParams, VIR_DOMAIN_SCHEDULER_VCPU_QUOTA, vcpuQuota);
if (virDomainSetSchedulerParameters(mDom.get(), params.get(), numParamsBuff) < 0) {
- LOGE("Error whilte setting scheduler params");
+ LOGE("Error whilte setting the domain's scheduler params:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
}
std::unique_ptr<char, void(*)(void*)> type(virDomainGetSchedulerType(mDom.get(), &numParamsBuff), free);
if (type == NULL || numParamsBuff <= 0 || strcmp(type.get(), "posix") != 0) {
- LOGE("Error while getting scheduler type");
+ LOGE("Error while getting the domain's scheduler type:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
std::unique_ptr<virTypedParameter[]> params(new virTypedParameter[numParamsBuff]);
if (virDomainGetSchedulerParameters(mDom.get(), params.get(), &numParamsBuff) < 0) {
- LOGE("Error whilte getting scheduler parameters");
+ LOGE("Error while getting the domain's scheduler params:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
numParamsBuff,
VIR_DOMAIN_SCHEDULER_VCPU_QUOTA,
"a) <= 0) {
- LOGE("Error whilte getting scheduler quota parameter");
+ LOGE("Error while getting the domain's scheduler quota param:\n"
+ << libvirt::libvirtFormatError(mId));
throw DomainOperationException();
}
/**
* Get the container id
*/
- std::string getId();
+ const std::string& getId() const;
/**
* Boot the container to the background.
private:
ContainerConfig& mConfig;
libvirt::LibvirtDomain mDom;
+ const std::string mId;
int getState(); // get the libvirt's domain state
void setSchedulerParams(std::uint64_t cpuShares, std::uint64_t vcpuPeriod, std::int64_t vcpuQuota);