perf build-id: Add check for existing link in buildid dir
[linux-2.6-microblaze.git] / tools / perf / util / build-id.c
index 8763772..4a391f1 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <linux/ctype.h>
 #include <linux/zalloc.h>
+#include <linux/string.h>
 #include <asm/bug.h>
 
 static bool no_buildid_cache;
@@ -102,6 +103,8 @@ int build_id__sprintf(const struct build_id *build_id, char *bf)
        const u8 *raw = build_id->data;
        size_t i;
 
+       bf[0] = 0x0;
+
        for (i = 0; i < build_id->size; ++i) {
                sprintf(bid, "%02x", *raw);
                ++raw;
@@ -752,8 +755,25 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
        tmp = dir_name + strlen(buildid_dir) - 5;
        memcpy(tmp, "../..", 5);
 
-       if (symlink(tmp, linkname) == 0)
+       if (symlink(tmp, linkname) == 0) {
                err = 0;
+       } else if (errno == EEXIST) {
+               char path[PATH_MAX];
+               ssize_t len;
+
+               len = readlink(linkname, path, sizeof(path) - 1);
+               if (len <= 0) {
+                       pr_err("Cant read link: %s\n", linkname);
+                       goto out_free;
+               }
+               path[len] = '\0';
+
+               if (strcmp(tmp, path)) {
+                       pr_debug("build <%s> already linked to %s\n",
+                                sbuild_id, linkname);
+               }
+               err = 0;
+       }
 
        /* Update SDT cache : error is just warned */
        if (realname &&
@@ -910,3 +930,8 @@ void build_id__init(struct build_id *bid, const u8 *data, size_t size)
        memcpy(bid->data, data, size);
        bid->size = size;
 }
+
+bool build_id__is_defined(const struct build_id *bid)
+{
+       return bid && bid->size ? !!memchr_inv(bid->data, 0, bid->size) : false;
+}