namespace {
const char *PRIVILEGE_PLATFORM = "http://tizen.org/privilege/internal/default/platform";
+const std::vector<std::string> blackListSystemdUnits = {
+ "samsung-log-mgr.service",
+};
// watches systemd jobs
class JobWatch {
{
dbus::Connection& systemDBus = dbus::Connection::getSystem();
std::set<std::string> unitsToStop;
- pid_t p = -1;
for (pid_t pid : runtime::FileUser::getList(INTERNAL_PATH, true)) {
try {
.get("(o)", &unit);
auto unescapedName = getDecodedPath(unit, "/org/freedesktop/systemd1/unit/");
- if (unescapedName == "samsung-log-mgr.service")
- p = pid;
- else
- unitsToStop.insert(unescapedName);
+ unitsToStop.insert(unescapedName);
} catch (runtime::Exception &e) {
INFO(SINK, "Killing process: " + std::to_string(pid));
::kill(pid, SIGKILL);
}
JobWatch watch(systemDBus);
+ for (auto unit : blackListSystemdUnits) {
+ unitsToStop.erase(unitsToStop.find(unit));
+ }
for (const std::string& unit : unitsToStop) {
INFO(SINK, "Stopping unit: " + unit);
if (!watch.waitForJob(job))
throw runtime::Exception("Stopping unit: " + unit + " failed");
}
-
- if (::umount2("/sys/fs/cgroup", MNT_FORCE | MNT_DETACH) != 0)
- INFO(SINK, "Failed to unmount cgroup");
-
- if (p != -1)
- ::kill(p, SIGKILL);
}
void showProgressUI(const std::string type)
::vconf_set_bool(VCONFKEY_ODE_FAST_ENCRYPTION, value);
}
-void unmountInternalStorage(const std::string& source)
+void execAndWait(const std::string &path, std::vector<std::string> &args)
{
- while(true) {
- auto mntPaths = findMountPointsByDevice(source);
- if(mntPaths.empty())
- break;
+ runtime::Process proc(path, args);
+ int ret = proc.execute();
+ if (ret < 0)
+ ERROR(SINK, path + " failed for " + args.back());
+
+ ret = proc.waitForFinished();
+ if (ret < 0 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0)
+ ERROR(SINK, path + " failed for " + args.back());
+}
- bool unmounted = true;
- for(const auto& path : mntPaths) {
- INFO(SINK, "Unmounting " + path);
- if (::umount(path.c_str()) == -1) {
- // If it's busy or was already unmounted ignore the error
- if (errno != EBUSY && errno != EINVAL) {
- throw runtime::Exception("umount() error: " + runtime::GetSystemErrorMessage());
- }
- unmounted = false;
- }
+bool isPartitionTerminated(const std::string &partition)
+{
+ bool ret = true;
+ const std::string cmd("fuser -m " + partition + " | grep -o '[0-9]*'");
+ char *line = nullptr;
+ size_t len = 0;
+
+ FILE *fp = ::popen(cmd.c_str(), "r");
+ if (fp == nullptr) {
+ ERROR(SINK, "Failed to get processes on partition");
+ return false;
+ }
+
+ if (::getline(&line, &len, fp) != -1)
+ ret = false;
+
+ ::free(line);
+ ::pclose(fp);
+
+ return ret;
+}
+
+void unmountInternalStorage(const std::string& source)
+{
+ if (::umount2("/opt/usr", MNT_DETACH) == -1) {
+ if (errno != EBUSY && errno != EINVAL) {
+ throw runtime::Exception("umount() error : " + runtime::GetSystemErrorMessage());
}
- if (!unmounted)
- stopDependedSystemdUnits();
}
+
+ do {
+ ::sync();
+ static const char *fuserPath = "/usr/bin/fuser";
+ std::vector<std::string> args = {
+ fuserPath, "-m", "-k", "-s", "-SIGTERM", source,
+ };
+ execAndWait(fuserPath, args);
+ ::usleep((useconds_t)((unsigned int)(500)*1000));
+
+ args[4] = "-SIGKILL";
+ execAndWait(fuserPath, args);
+ ::usleep((useconds_t)((unsigned int)(200)*1000));
+ } while (!isPartitionTerminated(source));
}
}
INFO(SINK, "Closing all processes using internal storage.");
try {
+ stopKnownSystemdUnits();
stopDependedSystemdUnits();
INFO(SINK, "Umounting internal storage.");
+ unmountInternalStorage("/dev/mapper/userdata");
engine->umount();
} catch (runtime::Exception &e) {
ERROR(SINK, "Umount failed: " + std::string(e.what()));
stopDependedSystemdUnits();
INFO(SINK, "Umounting internal storage.");
- while (1) {
- try {
- engine->umount();
- break;
- } catch (runtime::Exception& e) {
- stopDependedSystemdUnits();
- }
- }
+ unmountInternalStorage("/dev/mapper/userdata");
+ engine->umount();
}
INFO(SINK, "Decryption started.");