]> git.ipfire.org Git - thirdparty/dracut.git/commitdiff
dracut-install: install libs also from one dir above
authorHarald Hoyer <harald@redhat.com>
Thu, 6 Jun 2013 09:06:55 +0000 (11:06 +0200)
committerHarald Hoyer <harald@redhat.com>
Thu, 6 Jun 2013 09:06:55 +0000 (11:06 +0200)
some HW has different flavors of basic libs

$ ldconfig -p|fgrep libc.so
libc.so.6 (libc6,64bit, hwcap: 0x0000001000000000, OS ABI: Linux 2.6.32) => /lib64/power6/libc.so.6
libc.so.6 (libc6,64bit, hwcap: 0x0000000000000200, OS ABI: Linux 2.6.32) => /lib64/power6x/libc.so.6
libc.so.6 (libc6,64bit, OS ABI: Linux 2.6.32) => /lib64/libc.so.6

because setting LD_HWCAP_MASK=0 does not work, we have to workaround
this.

$ LD_TRACE_LOADED_OBJECTS=1  LD_HWCAP_MASK=0 /lib64/ld64.so.1 /bin/sh | fgrep libc.so
libc.so.6 => /lib64/power6/libc.so.6 (0x000000804e260000)

Now we try to install the same library from one directory above the one
we installed also.

install/dracut-install.c
install/util.c
install/util.h

index a1c64619d7e9a759e78c9a0dd886938f9b3d57fc..6b9c613b8f741898884c4fb4789ac666978ff178 100644 (file)
@@ -254,6 +254,72 @@ static int cp(const char *src, const char *dst)
         return ret;
 }
 
+static int library_install(const char *src, const char *lib)
+{
+        _cleanup_free_ char *p = NULL;
+        _cleanup_free_ char *pdir = NULL, *ppdir = NULL, *clib = NULL;
+        char *q;
+        int r, ret = 0;
+
+        p = strdup(lib);
+
+        r = dracut_install(p, p, false, false, true);
+        if (r != 0)
+                log_error("ERROR: failed to install '%s' for '%s'", p, src);
+        else
+                log_debug("Lib install: '%s'", p);
+        ret += r;
+
+        /* also install lib.so for lib.so.* files */
+        q = strstr(p, ".so.");
+        if (q) {
+                q[3] = '\0';
+
+                /* ignore errors for base lib symlink */
+                if (dracut_install(p, p, false, false, true) == 0)
+                        log_debug("Lib install: '%s'", p);
+        }
+
+        /* Also try to install the same library from one directory above.
+           This fixes the case, where only the HWCAP lib would be installed
+           # ldconfig -p|fgrep libc.so
+           libc.so.6 (libc6,64bit, hwcap: 0x0000001000000000, OS ABI: Linux 2.6.32) => /lib64/power6/libc.so.6
+           libc.so.6 (libc6,64bit, hwcap: 0x0000000000000200, OS ABI: Linux 2.6.32) => /lib64/power6x/libc.so.6
+           libc.so.6 (libc6,64bit, OS ABI: Linux 2.6.32) => /lib64/libc.so.6
+        */
+
+        free(p);
+        p = strdup(lib);
+
+        pdir = dirname(p);
+        if (!pdir)
+                return ret;
+
+        pdir = strdup(pdir);
+        ppdir = dirname(pdir);
+        if (!ppdir)
+                return ret;
+
+        ppdir = strdup(ppdir);
+
+        strcpy(p, lib);
+
+        clib = strjoin(ppdir, "/", basename(p), NULL);
+        if (dracut_install(clib, clib, false, false, true) == 0)
+                log_debug("Lib install: '%s'", clib);
+        /* also install lib.so for lib.so.* files */
+        q = strstr(clib, ".so.");
+        if (q) {
+                q[3] = '\0';
+
+                /* ignore errors for base lib symlink */
+                if (dracut_install(clib, clib, false, false, true) == 0)
+                        log_debug("Lib install: '%s'", p);
+        }
+
+        return ret;
+}
+
 static int resolve_deps(const char *src)
 {
         int ret = 0;
@@ -325,28 +391,13 @@ static int resolve_deps(const char *src)
                 if (strstr(buf, destrootdir))
                         break;
 
-                p = strstr(buf, "/");
+                p = strchr(buf, '/');
                 if (p) {
-                        int r;
                         for (q = p; *q && *q != ' ' && *q != '\n'; q++) ;
                         *q = '\0';
-                        r = dracut_install(p, p, false, false, true);
-                        if (r != 0)
-                                log_error("ERROR: failed to install '%s' for '%s'", p, src);
-                        else
-                                log_debug("Lib install: '%s'", p);
-                        ret += r;
-
-                        /* also install lib.so for lib.so.* files */
-                        q = strstr(p, ".so.");
-                        if (q) {
-                                q += 3;
-                                *q = '\0';
-
-                                /* ignore errors for base lib symlink */
-                                if (dracut_install(p, p, false, false, true) == 0)
-                                        log_debug("Lib install: '%s'", p);
-                        }
+
+                        ret += library_install(src, p);
+
                 }
         }
 
index 0247184b8e205e0beb7ce565ed7838c1b394f399..9aa131f8ecdeb42262be80f8c63430ce6fd51188 100644 (file)
@@ -185,3 +185,95 @@ static const char *const log_level_table[] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
+
+char *strnappend(const char *s, const char *suffix, size_t b) {
+        size_t a;
+        char *r;
+
+        if (!s && !suffix)
+                return strdup("");
+
+        if (!s)
+                return strndup(suffix, b);
+
+        if (!suffix)
+                return strdup(s);
+
+        assert(s);
+        assert(suffix);
+
+        a = strlen(s);
+        if (b > ((size_t) -1) - a)
+                return NULL;
+
+        r = new(char, a+b+1);
+        if (!r)
+                return NULL;
+
+        memcpy(r, s, a);
+        memcpy(r+a, suffix, b);
+        r[a+b] = 0;
+
+        return r;
+}
+
+char *strappend(const char *s, const char *suffix) {
+        return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
+}
+
+char *strjoin(const char *x, ...) {
+        va_list ap;
+        size_t l;
+        char *r, *p;
+
+        va_start(ap, x);
+
+        if (x) {
+                l = strlen(x);
+
+                for (;;) {
+                        const char *t;
+                        size_t n;
+
+                        t = va_arg(ap, const char *);
+                        if (!t)
+                                break;
+
+                        n = strlen(t);
+                        if (n > ((size_t) -1) - l) {
+                                va_end(ap);
+                                return NULL;
+                        }
+
+                        l += n;
+                }
+        } else
+                l = 0;
+
+        va_end(ap);
+
+        r = new(char, l+1);
+        if (!r)
+                return NULL;
+
+        if (x) {
+                p = stpcpy(r, x);
+
+                va_start(ap, x);
+
+                for (;;) {
+                        const char *t;
+
+                        t = va_arg(ap, const char *);
+                        if (!t)
+                                break;
+
+                        p = stpcpy(p, t);
+                }
+
+                va_end(ap);
+        } else
+                r[0] = 0;
+
+        return r;
+}
index e86b2f2a2a404d63b41573a01e927e34112895bc..3d7c23204462b76983d465a03d7bf854ef90d745 100644 (file)
@@ -560,4 +560,6 @@ bool in_initrd(void);
 
 void warn_melody(void);
 
+char *strjoin(const char *x, ...) _sentinel_;
+
 #endif