Merge changes I8a2764a6,I6e8b9d63,I6e041dfc

* changes:
  Canonicalize cgroup paths
  Micro-optimize MergeCgroupToDescriptors()
  Fix support for optional cgroup attributes
diff --git a/libprocessgroup/setup/cgroup_map_write.cpp b/libprocessgroup/setup/cgroup_map_write.cpp
index 992cc2e..3831ef2 100644
--- a/libprocessgroup/setup/cgroup_map_write.cpp
+++ b/libprocessgroup/setup/cgroup_map_write.cpp
@@ -147,12 +147,17 @@
 static void MergeCgroupToDescriptors(std::map<std::string, CgroupDescriptor>* descriptors,
                                      const Json::Value& cgroup, const std::string& name,
                                      const std::string& root_path, int cgroups_version) {
+    const std::string cgroup_path = cgroup["Path"].asString();
     std::string path;
 
     if (!root_path.empty()) {
-        path = root_path + "/" + cgroup["Path"].asString();
+        path = root_path;
+        if (cgroup_path != ".") {
+            path += "/";
+            path += cgroup_path;
+        }
     } else {
-        path = cgroup["Path"].asString();
+        path = cgroup_path;
     }
 
     uint32_t controller_flags = 0;
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index 78a316a..7a04100 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -207,7 +207,7 @@
     }
 
     if (!WriteStringToFile(value_, path)) {
-        if (errno == ENOENT) {
+        if (access(path.c_str(), F_OK) < 0) {
             if (optional_) {
                 return true;
             } else {