ports/emulators/linux_base on amd64
Jung-uk Kim
jkim at niksun.com
Mon Dec 27 11:33:11 PST 2004
On Wednesday 15 December 2004 05:26 am, Ruslan Ermilov wrote:
> On Tue, Dec 14, 2004 at 03:15:41PM -0800, Sean McNeil wrote:
> > On Tue, 2004-12-14 at 14:13 -0800, Sean McNeil wrote:
> > > On Tue, 2004-12-14 at 23:54 +0200, Ruslan Ermilov wrote:
> > > > On Tue, Dec 14, 2004 at 10:34:06AM -0800, Sean McNeil wrote:
> > > > [...]
> > > >
> > > > > rpm scripts should also be fixed. It seems like a bug in
> > > > > the rpm port that no one has addressed.
> > > >
> > > > rpm port is not guilty -- running the postinstall script
> > > > manually on amd64 returns 1, but on i386 it returns 0:
> > > >
> > > > Script started on Tue Dec 14 23:10:31 2004
> > > > hammer# /compat/linux/bin/sh
> > > > sh-2.04# uname -srm
> > > > Linux 2.4.2 amd64
> > > > sh-2.04# /usr/sbin/glibc_post_upgrade
> > > > sh-2.04# echo $?
> > > > 1
> > > > Script done on Tue Dec 14 23:10:53 2004
> > >
> > > Yes, I just got to this point. Thanks for the confirmation.
> > > I'm trying to find sources to glibc_post_upgrade to take a
> > > look.
> >
> > Here is what I have so far....
> >
> > The source looks like this:
> >
> > #ifdef ARCH_386
> > /* Work around rpm bug */
> > char *remove_file[] = {
> > "/lib/i686/libc-" VERSION ".so",
> > "/lib/i686/libm-" VERSION ".so",
> > "/lib/i686/libpthread-" PVERSION ".so",
> > "/lib/i686/libc.so.6",
> > "/lib/i686/libm.so.6",
> > "/lib/i686/libpthread.so.0",
> > NULL };
> > int i;
> >
> > for (i = 0; remove_file[i]; i++)
> > unlink (remove_file[i]);
> > #endif
> > pid = vfork ();
> > if (pid == 0) {
> > execl ("/sbin/ldconfig", "/sbin/ldconfig", NULL);
> > _exit (1);
> > } else if (pid < 0) {
> > _exit (1);
> > }
> > if (waitpid (0, &status, 0) != pid || !WIFEXITED (status)) {
> > _exit (1);
> > }
> > if (WEXITSTATUS (status))
> > _exit (WEXITSTATUS (status));
> >
> > ktrace shows:
> >
> > 2018 ktrace RET ktrace 0
> > 2018 ktrace CALL
> > execve(0x7fffffffee0f,0x7fffffffec60,0x7fffffffec70)
> > 2018 ktrace NAMI "/compat/linux/usr/sbin/glibc_post_upgrade"
> > 2018 glibc_post_upgrade RET execve 0
> > 2018 glibc_post_upgrade CALL unlink(0x8048788)
> > 2018 glibc_post_upgrade NAMI
> > "/compat/linux/lib/i686/libc-2.2.4.so" 2018 glibc_post_upgrade
> > NAMI "/lib/i686/libc-2.2.4.so" 2018 glibc_post_upgrade RET
> > unlink JUSTRETURN
> > 2018 glibc_post_upgrade CALL unlink(0x80487a0)
> > 2018 glibc_post_upgrade NAMI
> > "/compat/linux/lib/i686/libm-2.2.4.so" 2018 glibc_post_upgrade
> > NAMI "/lib/i686/libm-2.2.4.so" 2018 glibc_post_upgrade RET
> > unlink JUSTRETURN
> > 2018 glibc_post_upgrade CALL unlink(0x80487b8)
> > 2018 glibc_post_upgrade NAMI
> > "/compat/linux/lib/i686/libpthread-0.9.so"
> > 2018 glibc_post_upgrade NAMI "/lib/i686/libpthread-0.9.so"
> > 2018 glibc_post_upgrade RET unlink JUSTRETURN
> > 2018 glibc_post_upgrade CALL unlink(0x80487d4)
> > 2018 glibc_post_upgrade NAMI
> > "/compat/linux/lib/i686/libc.so.6" 2018 glibc_post_upgrade NAMI
> > "/lib/i686/libc.so.6"
> > 2018 glibc_post_upgrade RET unlink JUSTRETURN
> > 2018 glibc_post_upgrade CALL unlink(0x80487e8)
> > 2018 glibc_post_upgrade NAMI
> > "/compat/linux/lib/i686/libm.so.6" 2018 glibc_post_upgrade NAMI
> > "/lib/i686/libm.so.6"
> > 2018 glibc_post_upgrade RET unlink JUSTRETURN
> > 2018 glibc_post_upgrade CALL unlink(0x80487fc)
> > 2018 glibc_post_upgrade NAMI
> > "/compat/linux/lib/i686/libpthread.so.0" 2018 glibc_post_upgrade
> > NAMI "/lib/i686/libpthread.so.0" 2018 glibc_post_upgrade RET
> > unlink JUSTRETURN
> > 2018 glibc_post_upgrade CALL lstat
> > 2018 glibc_post_upgrade RET lstat 2019/0x7e3
> > 2018 glibc_post_upgrade CALL old.sendmsg(0,0xffffdb8c,0,0)
> > 2018 glibc_post_upgrade RET old.sendmsg 2019/0x7e3
> > 2018 glibc_post_upgrade CALL exit(0x1)
> >
> > Looks like there is a mismatch in kernel entry points here.
> >
> > lstat instead of vfork and old.sendmsg instead of (maybe)
> > waitpid.
> >
> > Does ktrace work with linux abi?
>
> On i386 it looks identical, except that sendmsg doesn't result in
> exit(0x1):
>
> 20167 ktrace RET ktrace 0
> 20167 ktrace CALL execve(0xbfbfec77,0xbfbfeb60,0xbfbfeb68)
> 20167 ktrace NAMI "/compat/linux/usr/sbin/glibc_post_upgrade"
> 20167 glibc_post_upgrade RET execve 0
> 20167 glibc_post_upgrade CALL unlink(0x8048788)
> 20167 glibc_post_upgrade NAMI
> "/compat/linux/lib/i686/libc-2.2.4.so" 20167 glibc_post_upgrade
> NAMI "/lib/i686/libc-2.2.4.so"
> 20167 glibc_post_upgrade RET unlink JUSTRETURN
> 20167 glibc_post_upgrade CALL unlink(0x80487a0)
> 20167 glibc_post_upgrade NAMI
> "/compat/linux/lib/i686/libm-2.2.4.so" 20167 glibc_post_upgrade
> NAMI "/lib/i686/libm-2.2.4.so"
> 20167 glibc_post_upgrade RET unlink JUSTRETURN
> 20167 glibc_post_upgrade CALL unlink(0x80487b8)
> 20167 glibc_post_upgrade NAMI
> "/compat/linux/lib/i686/libpthread-0.9.so" 20167 glibc_post_upgrade
> NAMI "/lib/i686/libpthread-0.9.so" 20167 glibc_post_upgrade RET
> unlink JUSTRETURN
> 20167 glibc_post_upgrade CALL unlink(0x80487d4)
> 20167 glibc_post_upgrade NAMI "/compat/linux/lib/i686/libc.so.6"
> 20167 glibc_post_upgrade NAMI "/lib/i686/libc.so.6"
> 20167 glibc_post_upgrade RET unlink JUSTRETURN
> 20167 glibc_post_upgrade CALL unlink(0x80487e8)
> 20167 glibc_post_upgrade NAMI "/compat/linux/lib/i686/libm.so.6"
> 20167 glibc_post_upgrade NAMI "/lib/i686/libm.so.6"
> 20167 glibc_post_upgrade RET unlink JUSTRETURN
> 20167 glibc_post_upgrade CALL unlink(0x80487fc)
> 20167 glibc_post_upgrade NAMI
> "/compat/linux/lib/i686/libpthread.so.0" 20167 glibc_post_upgrade
> NAMI "/lib/i686/libpthread.so.0" 20167 glibc_post_upgrade RET
> unlink JUSTRETURN
> 20167 glibc_post_upgrade CALL lstat
> 20167 glibc_post_upgrade RET lstat 20168/0x4ec8
> 20167 glibc_post_upgrade CALL old.sendmsg(0,0xbfbfea1c,0,0)
> 20167 glibc_post_upgrade RET old.sendmsg 20168/0x4ec8
> 20167 glibc_post_upgrade CALL accept(0x8048880,0)
> 20167 glibc_post_upgrade NAMI
> "/compat/linux/usr/lib/gconv/gconv-modules.cache" 20167
> glibc_post_upgrade NAMI "/compat/linux"
> 20167 glibc_post_upgrade NAMI
> "/compat/linux/usr/lib/gconv/gconv-modules.cache" 20167
> glibc_post_upgrade RET accept 0
> 20167 glibc_post_upgrade CALL lstat
> 20167 glibc_post_upgrade RET lstat 20171/0x4ecb
> 20167 glibc_post_upgrade CALL old.sendmsg(0,0xbfbfea1c,0,0)
> 20167 glibc_post_upgrade RET old.sendmsg 20171/0x4ecb
> 20167 glibc_post_upgrade CALL access(0x804883b,0x1)
> 20167 glibc_post_upgrade NAMI "/compat/linux/sbin/telinit"
> 20167 glibc_post_upgrade NAMI "/sbin/telinit"
> 20167 glibc_post_upgrade RET access JUSTRETURN
> 20167 glibc_post_upgrade CALL exit(0)
>
> The reason for this is as follows:
>
> hammer# grep -C3 TJR /sys/compat/linux/linux_socket.c
> struct iovec *iov;
> int error;
>
> /* XXXTJR sendmsg is broken on amd64 */
>
> error = copyin(args, &linux_args, sizeof(linux_args));
> if (error)
> --
> struct cmsghdr *cmsg;
> int error;
>
> /* XXXTJR recvmsg is broken on amd64 */
>
> if ((error = copyin(args, &linux_args,
> sizeof(linux_args)))) return (error);
I thought sendmsg was the culprit too but it wasn't. You guys
forgot '-i' option for krace (to trace children). The problem
is in linux_execve() from src/sys/amd64/linux32/linux32_machdep.c.
888 glibc_post_upgrade RET fork 0
888 glibc_post_upgrade CALL obs_execv(0x80490ee,0xffffb644,0)
888 glibc_post_upgrade NAMI "/compat/linux/sbin/ldconfig"
888 glibc_post_upgrade NAMI "/compat/linux"
888 glibc_post_upgrade NAMI "/compat/linux/sbin/ldconfig"
888 glibc_post_upgrade RET obs_execv -1 errno -14 Unknown error: -14
888 glibc_post_upgrade CALL exit(0x6e)
One of copyin/copyout is failing from linux_execve() with EFAULT.
On i386, it returns 0, of course. Parent exited because child
failed. Full ktrace dump and glibc_post_upgrade.c (with RedHat
8.0's local patch) attached.
Thanks,
Jung-uk Kim
-------------- next part --------------
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <dirent.h>
#include <stddef.h>
#include <fcntl.h>
#include <string.h>
int main(void)
{
pid_t pid;
int status;
char initpath[256];
#ifdef ARCH_386
char buffer[4096];
char *remove_file[] = {
"/lib/i686/libc-" VERSION ".so",
"/lib/i686/libm-" VERSION ".so",
"/lib/i686/librt-" VERSION ".so",
"/lib/i686/libpthread-" PVERSION ".so",
"/lib/i686/libc.so.6",
"/lib/i686/libm.so.6",
"/lib/i686/librt.so.1",
"/lib/i686/libpthread.so.0",
NULL };
struct pref {
char *p;
int len;
} prefix[] = { { "libc-", 5 }, { "libm-", 5 },
{ "librt-", 6 }, { "libpthread-", 11 } };
int i, fd;
off_t base;
ssize_t ret;
for (i = 0; remove_file[i]; i++)
unlink (remove_file[i]);
fd = open ("/lib/i686", O_RDONLY);
if (fd >= 0
&& (ret = getdirentries (fd, buffer, sizeof (buffer), &base))
>= (ssize_t) offsetof (struct dirent, d_name))
{
for (base = 0; base + offsetof (struct dirent, d_name) < ret; )
{
struct dirent *d = (struct dirent *) (buffer + base);
for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
if (! strncmp (d->d_name, prefix[i].p, prefix[i].len))
{
char *p = d->d_name + prefix[i].len;
while (*p == '.' || (*p >= '0' && *p <= '9')) p++;
if (p[0] == 's' && p[1] == 'o' && p[2] == '\0'
&& p + 3 - d->d_name < sizeof (initpath) - strlen ("/lib/i686/"))
{
strcpy (initpath, "/lib/i686/");
strcpy (initpath + strlen ("/lib/i686/"), d->d_name);
unlink (initpath);
break;
}
}
base += d->d_reclen;
}
close (fd);
}
#endif
pid = vfork ();
if (pid == 0)
{
execl ("/sbin/ldconfig", "/sbin/ldconfig", NULL);
_exit (110);
}
else if (pid < 0)
_exit (111);
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
_exit (112);
if (WEXITSTATUS (status))
_exit (WEXITSTATUS (status));
if (! utimes (GCONV_MODULES_CACHE, NULL))
{
pid = vfork ();
if (pid == 0)
{
execl ("/usr/sbin/iconvconfig", "/usr/sbin/iconvconfig", NULL);
_exit (113);
}
else if (pid < 0)
_exit (114);
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
_exit (115);
if (WEXITSTATUS (status))
_exit (WEXITSTATUS (status));
}
/* Check if telinit is available and the init fifo as well. */
if (access ("/sbin/telinit", X_OK) || access ("/dev/initctl", F_OK))
_exit (0);
/* Check if we are not inside of some chroot, because we'd just
timeout and leave /etc/initrunlvl. */
if (readlink ("/proc/1/exe", initpath, 256) <= 0 ||
readlink ("/proc/1/root", initpath, 256) <= 0)
_exit (0);
pid = vfork ();
if (pid == 0)
{
execl ("/sbin/telinit", "/sbin/telinit", "u", NULL);
_exit (116);
}
else if (pid < 0)
_exit (117);
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
_exit (118);
/* Check if we can safely condrestart sshd. */
if (access ("/sbin/service", X_OK) == 0
&& access ("/usr/sbin/sshd", X_OK) == 0
&& access ("/bin/bash", X_OK) == 0)
{
pid = vfork ();
if (pid == 0)
{
execl ("/sbin/service", "/sbin/service", "sshd", "condrestart", NULL);
_exit (119);
}
else if (pid < 0)
_exit (120);
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
_exit (121);
}
_exit(0);
}
int __libc_multiple_threads;
int __libc_enable_asynccancel (void) { return 0; }
void __libc_disable_asynccancel (int x) { }
void __libc_csu_init (void) { }
void __libc_csu_fini (void) { }
pid_t __fork (void) { return -1; }
char thr_buf[8192];
#ifndef __powerpc__
int __libc_start_main (int (*main) (void), int argc, char **argv,
void (*init) (void), void (*fini) (void),
void (*rtld_fini) (void), void * stack_end)
#else
struct startup_info
{
void *sda_base;
int (*main) (int, char **, char **, void *);
int (*init) (int, char **, char **, void *);
void (*fini) (void);
};
int __libc_start_main (int argc, char **ubp_av,
char **ubp_ev,
void *auxvec, void (*rtld_fini) (void),
struct startup_info *stinfo,
char **stack_on_entry)
#endif
{
#if defined __ia64__ || defined __powerpc64__
register void *r13 __asm ("r13") = thr_buf + 4096;
__asm ("" : : "r" (r13));
#elif defined __sparc__
register void *g6 __asm ("g6") = thr_buf + 4096;
register void *g7 __asm ("g7") = thr_buf + 4096;
__asm ("" : : "r" (g6), "r" (g7));
#elif defined __s390__ && !defined __s390x__
__asm ("sar %%a0,%0" : : "d" (thr_buf + 4096));
#elif defined __s390x__
__asm ("sar %%a1,%0; srlg 0,%0,32; sar %%a0,0" : : "d" (thr_buf + 4096) : "0");
#elif defined __powerpc__ && !defined __powerpc64__
register void *r2 __asm ("r2") = thr_buf + 4096;
__asm ("" : : "r" (r2));
#endif
main();
return 0;
}
-------------- next part --------------
887 ktrace RET ktrace 0
887 ktrace CALL execve(0x7fffffffe963,0x7fffffffe750,0x7fffffffe760)
887 ktrace NAMI "/usr/compat/linux/usr/sbin/glibc_post_upgrade"
887 glibc_post_upgrade RET execve 0
887 glibc_post_upgrade CALL unlink(0x8049008)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686/libc-2.3.2.so"
887 glibc_post_upgrade NAMI "/lib/i686/libc-2.3.2.so"
887 glibc_post_upgrade RET unlink JUSTRETURN
887 glibc_post_upgrade CALL unlink(0x8049020)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686/libm-2.3.2.so"
887 glibc_post_upgrade NAMI "/lib/i686/libm-2.3.2.so"
887 glibc_post_upgrade RET unlink JUSTRETURN
887 glibc_post_upgrade CALL unlink(0x8049038)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686/librt-2.3.2.so"
887 glibc_post_upgrade NAMI "/lib/i686/librt-2.3.2.so"
887 glibc_post_upgrade RET unlink JUSTRETURN
887 glibc_post_upgrade CALL unlink(0x8049051)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686/libpthread-0.10.so"
887 glibc_post_upgrade NAMI "/lib/i686/libpthread-0.10.so"
887 glibc_post_upgrade RET unlink JUSTRETURN
887 glibc_post_upgrade CALL unlink(0x804906e)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686/libc.so.6"
887 glibc_post_upgrade NAMI "/lib/i686/libc.so.6"
887 glibc_post_upgrade RET unlink JUSTRETURN
887 glibc_post_upgrade CALL unlink(0x8049082)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686/libm.so.6"
887 glibc_post_upgrade NAMI "/lib/i686/libm.so.6"
887 glibc_post_upgrade RET unlink JUSTRETURN
887 glibc_post_upgrade CALL unlink(0x8049096)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686/librt.so.1"
887 glibc_post_upgrade NAMI "/lib/i686/librt.so.1"
887 glibc_post_upgrade RET unlink JUSTRETURN
887 glibc_post_upgrade CALL unlink(0x80490ab)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686/libpthread.so.0"
887 glibc_post_upgrade NAMI "/lib/i686/libpthread.so.0"
887 glibc_post_upgrade RET unlink JUSTRETURN
887 glibc_post_upgrade CALL open(0x80490e4,0,0)
887 glibc_post_upgrade NAMI "/compat/linux/lib/i686"
887 glibc_post_upgrade NAMI "/lib/i686"
887 glibc_post_upgrade RET open JUSTRETURN
887 glibc_post_upgrade CALL lstat
888 glibc_post_upgrade RET fork 0
888 glibc_post_upgrade CALL obs_execv(0x80490ee,0xffffb644,0)
888 glibc_post_upgrade NAMI "/compat/linux/sbin/ldconfig"
888 glibc_post_upgrade NAMI "/compat/linux"
888 glibc_post_upgrade NAMI "/compat/linux/sbin/ldconfig"
888 glibc_post_upgrade RET obs_execv -1 errno -14 Unknown error: -14
888 glibc_post_upgrade CALL exit(0x6e)
887 glibc_post_upgrade RET lstat 888/0x378
887 glibc_post_upgrade CALL old.sendmsg(0,0xffffc68c,0,0)
887 glibc_post_upgrade RET old.sendmsg 888/0x378
887 glibc_post_upgrade CALL exit(0x6e)
More information about the freebsd-amd64
mailing list