Browse Source

dracut-install: install libs also from one dir above

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.
master
Harald Hoyer 12 years ago
parent
commit
791532b0ce
  1. 89
      install/dracut-install.c
  2. 92
      install/util.c
  3. 2
      install/util.h

89
install/dracut-install.c

@ -254,6 +254,72 @@ static int cp(const char *src, const char *dst) @@ -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) @@ -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);

}
}


92
install/util.c

@ -185,3 +185,95 @@ static const char *const log_level_table[] = { @@ -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;
}

2
install/util.h

@ -560,4 +560,6 @@ bool in_initrd(void); @@ -560,4 +560,6 @@ bool in_initrd(void);

void warn_melody(void);

char *strjoin(const char *x, ...) _sentinel_;

#endif

Loading…
Cancel
Save