我已经设置了一个包装模板来生成FreeBSD 10.3的流浪基本图像,它至少在2016年10月3日星期一00:34:41 + 0300上运行良好。
昨天我将继续我在这个项目上的工作,事实证明这不再适用了。所以这里有详细信息。
Packer做了它必须做的事情,然后使用bsdinstall(8)
运行我的脚本来安装FreeBSD,并使用以下脚本:
PARTITIONS="ada0 { 29G freebsd-ufs /, 5G freebsd-swap, 10G freebsd-ufs /var }"
DISTRIBUTIONS="base.txz kernel.txz"
#!/bin/sh
echo 'WITHOUT_X11="YES"' >> /etc/make.conf
echo 'OPTIONS_UNSET=X11' >> /etc/make.conf
echo 'nameserver 8.8.8.8' >> /etc/resolv.conf
cat >> /etc/rc.conf <<EOF
ifconfig_em0="DHCP"
sshd_enable="YES"
dumpdev="NO"
EOF
env ASSUME_ALWAYS_YES=1 pkg bootstrap # <<stops here
pkg update
pkg install -y sudo
[.....snip.....]
reboot
这会在bootstrapping pkg处停止,并显示以下消息:
Bootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:10:amd64/quarterly, please wait...
Signature for pkg not available.
pkg: Error fetching http://pkg.FreeBSD.org/FreeBSD:10:amd64/quarterly/Latest/pkg.txz.sig: Connection reset by peer
A pre-built version of pkg could not be found for your system.
Consider changing PACKAGESITE or installing it from ports: 'ports-mgmt/pkg'.
如果我停止bsdinstall脚本并chroot /mnt /bin/sh
我可以从上面的网址中抓取pkg.txz.sig
而不会有任何问题。
任何想法可能是同伴&#34;连接重置的原因&#34;?最近在pkg.FreeBSD.org上发生了哪些变化?
我无法找到有关此问题的任何内容。
UPD1
查看captured traffic - 该网站确实回答了200OK,然后删除了pkg.txz.sig
文件的连接。
但是这个200OK数据包包含签名文件和they are identical,用于手动fetch
(成功)和pkg bootstrap
(失败)
两个会话都是相同的,因此这可能不是网络问题。
UPD2
truss
也是not helpful。
因此,作为一种解决方法,我只是修改了我的bsdinstall脚本以手动获取文件:
[.....snip.....]
#env ASSUME_ALWAYS_YES=1 pkg bootstrap
fetch http://pkg.FreeBSD.org/FreeBSD:10:amd64/quarterly/Latest/pkg.txz
fetch http://pkg.FreeBSD.org/FreeBSD:10:amd64/quarterly/Latest/pkg.txz.sig
pkg add pkg.txz
pkg update
[.....snip.....]
PS:我现在唯一可以怀疑的是虚拟机版本更新......无论如何降级都不是一个选择。 (ISO校验和被硬编码到模板中,模板和脚本都在git存储库中,因此无法进行更改)
UPD3
我已经设置了一个调试环境,目前我只隔离了引发错误的函数。
它是来自http连接的第二个缓冲区重新填充(而第一个已经读取了727个字节 - 它应该是EOF)...
Here是一个小的gdb日志,带有回溯和断点来实现。 添加了在系统上进行的tcpdump捕获(wireshark兼容)。
答案 0 :(得分:1)
正如我发现的那样,问题部分是pkg - 他们尝试从连接中读取10240个字节,期待EOF,如果文件会更小,但不知何故我的系统EOF没有设置整个远程文件已经读出。
# /release/10.3.0/usr.sbin/pkg/pkg.c
185 char buf[10240];
242 while ((r = fread(buf, 1, sizeof(buf), remote)) > 0) {
以及以下循环两次 - 第一次读取文件,第二次获取连接重置错误而不是EOF
# /release/10.3.0/lib/libc/stdio/fread.c
94 resid = count * size; # == 10240 here
100 while (resid > (r = fp->_r)) {
101 (void)memcpy((void *)p, (void *)fp->_p, (size_t)r);
102 fp->_p += r;
103 /* fp->_r = 0 ... done in __srefill */
104 p += r;
105 resid -= r;
106 if (__srefill(fp)) {
107 /* no more input: return partial result */
108 return ((total - resid) / size);
109 }
110 }
虽然手动fetch
成功,因为size
针对小块进行了调整,他们只需要727个字节来读取:
# /release/10.3.0/usr.bin/fetch/fetch.c
720 if (us.size != -1 && us.size - count < B_size &&
721 us.size - count >= 0)
722 size = us.size - count;
723 else
724 size = B_size;
733 if ((readcnt = fread(buf, 1, size, f)) < size) {
...但是为什么没有设置EOF仍然是一个问题。
将此帖子发布到freebsd-pkg邮件列表。
UPD1
将Virtualbox从5.028降级为5.026且设置了EOF,_sread()
上的libc/stdio/refill.c:135
返回0,并在第138行设置了EOF。
因此,Virtualbox网络也发生了一些变化。将Virtualbox 5.026的pcap文件添加到gist。 5.028确实是连接重置的罪魁祸首 - 这里是捕获comparison。
Virtualbox 5.1.8也有这个bug。版本5.1.6工作正常。
在他们的bugtracker中打开ticket #16141。