Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

portable : rpi2, opensmtpd 5.7.3 doesn't return anything and start to consume all available memory #642

Closed
Zarla opened this issue Oct 17, 2015 · 13 comments
Assignees
Labels

Comments

@Zarla
Copy link

Zarla commented Oct 17, 2015

@mail:$ uname -a
Linux mail 4.2.0-v7+ #1 SMP PREEMPT Sun Sep 13 21:17:20 AST 2015 armv7l GNU/Linux
@mail:
$

@mail:$ cat /etc/debian_version
8.2
@mail:
$

No error were reported after the ./configure and the make.

ompat.a -lasr -levent -lcrypto -lssl -lz -lnsl -lcrypt -lresolv
libtool: link: gcc -g -O2 -fPIC -DPIC -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -fno-builtin-memset -o encrypt encrypt.o ../../../smtpd/log.o -L/usr/lib ../../../openbsd-compat/libopenbsd-compat.a -lasr -levent -lcrypto -lssl -lz -lnsl -lcrypt -lresolv
make[4]: Leaving directory '/home/opensmtpd-5.7.3p1/contrib/libexec/encrypt'
make[4]: Entering directory '/home/opensmtpd-5.7.3p1/contrib/libexec'
make[4]: Nothing to be done for 'all-am'.
make[4]: Leaving directory '/home/opensmtpd-5.7.3p1/contrib/libexec'
make[3]: Leaving directory '/home/opensmtpd-5.7.3p1/contrib/libexec'
make[3]: Entering directory '/home/opensmtpd-5.7.3p1/contrib'
make[3]: Nothing to be done for 'all-am'.
make[3]: Leaving directory '/home/opensmtpd-5.7.3p1/contrib'
make[2]: Leaving directory '/home/opensmtpd-5.7.3p1/contrib'
make[2]: Entering directory '/home/opensmtpd-5.7.3p1'
make[2]: Leaving directory '/home/opensmtpd-5.7.3p1'
make[1]: Leaving directory '/home/opensmtpd-5.7.3p1'
@mail:~/opensmtpd-5.7.3p1$

mail:/usr/local/lib$ ldd -v libasr.so
linux-vdso.so.1 (0x7eb63000)
libresolv.so.2 => /lib/arm-linux-gnueabihf/libresolv.so.2 (0x76eef000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76e00000)
/lib/ld-linux-armhf.so.3 (0x54b28000)

Version information:
./libasr.so:
    libresolv.so.2 (GLIBC_2.4) => /lib/arm-linux-gnueabihf/libresolv.so.2
    libc.so.6 (GLIBC_2.17) => /lib/arm-linux-gnueabihf/libc.so.6
    libc.so.6 (GLIBC_2.4) => /lib/arm-linux-gnueabihf/libc.so.6
/lib/arm-linux-gnueabihf/libresolv.so.2:
    ld-linux-armhf.so.3 (GLIBC_2.4) => /lib/ld-linux-armhf.so.3
    libc.so.6 (GLIBC_PRIVATE) => /lib/arm-linux-gnueabihf/libc.so.6
    libc.so.6 (GLIBC_2.4) => /lib/arm-linux-gnueabihf/libc.so.6
/lib/arm-linux-gnueabihf/libc.so.6:
    ld-linux-armhf.so.3 (GLIBC_2.4) => /lib/ld-linux-armhf.so.3
    ld-linux-armhf.so.3 (GLIBC_PRIVATE) => /lib/ld-linux-armhf.so.3

@mail:/usr/local/lib$

By example, I launch a command smtpd -nv to verify the OpenSMTPD configuration file. The command never return anything.
root@mail:~# smtpd -nv

In another terminal, the top command shows the smtpd process uses 100% of CPU and start to consume all available memory :

top - 20:38:17 up 33 days, 22:46, 2 users, load average: 0,63, 0,19, 0,10
Tasks: 98 total, 2 running, 96 sleeping, 0 stopped, 0 zombie
%Cpu(s): 7,2 us, 18,2 sy, 0,0 ni, 74,6 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
KiB Mem: 948016 total, 517032 used, 430984 free, 111684 buffers
KiB Swap: 0 total, 0 used, 0 free. 195844 cached Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29457 root 20 0 37656 31924 2692 R 100,0 3,4 1:00.14 smtpd -nv
29458 root 20 0 4820 2128 1768 R 1,0 0,2 0:00.17 top -c

top - 20:45:03 up 33 days, 22:52, 2 users, load average: 1,03, 0,82, 0,43
Tasks: 98 total, 2 running, 96 sleeping, 0 stopped, 0 zombie
%Cpu(s): 8,1 us, 17,1 sy, 0,0 ni, 74,8 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
KiB Mem: 948016 total, 711572 used, 236444 free, 111696 buffers
KiB Swap: 0 total, 0 used, 0 free. 195848 cached Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29457 root 20 0 267032 225812 2692 R 99,8 23,8 7:45.67 smtpd -nv
29458 root 20 0 4820 2128 1768 R 0,7 0,2 0:03.35 top -c

@poolpOrg
Copy link
Member

I will order a raspberry pi 2 and have a look at this, can't reproduce otherwise :-/

@poolpOrg poolpOrg self-assigned this Oct 28, 2015
@poolpOrg poolpOrg added the bug label Oct 28, 2015
@poolpOrg
Copy link
Member

oh, can you confirm that you experience this with previous releases too ?

@mjb2010
Copy link

mjb2010 commented Oct 29, 2015

This sounds like the same problem I reported on the opensmtpd-misc list. In my case, I'm using OpenSMTPD 5.7.3p1 from the FreeBSD ports collection on a BeagleBone Black (ARMv6). A minimal config works OK (listen on 127.0.0.1 and accept for any relay), but if I add table aliases file:/usr/local/etc/mail/aliases, smtpd consumes all available memory for over 20 minutes. The content of the aliases file makes no difference. Eventually smtpd starts up and the system becomes usable again, but not until after various essential services have been interrupted by the memory churn.

I learned about truss(1), so I gave it a try, and hit ctrl-C when smtpd got into the memory allocation hole:

open("/usr/local/etc/mail/aliases",O_RDONLY,0666) = 5 (0x5)
fstat(5,{ mode=-rw-r--r-- ,inode=753053,size=11,blksize=32768 }) = 0 (0x0)
read(5,"root: mike\n",32768)                     = 11 (0xb)
read(5,0x20c91000,32768)                         = 0 (0x0)
mmap(0x0,4194304,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x400000) = 553648128 (0x21000000)
madvise(0x20c99000,0x201000,0x5,0xfffff000,0x20c00000,0x0) = 0 (0x0)
madvise(0x20c2e000,0x1000,0x5,0xfffff000,0x20c00000,0x0) = 0 (0x0)
madvise(0x20c63000,0x1000,0x5,0x20c00204,0x20c00000,0x0) = 0 (0x0)
mmap(0x0,8388608,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x800000) = 557842432 (0x21400000)
munmap(0x21000000,4194304)                       = 0 (0x0)
mmap(0x0,16777216,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x1000000) = 566231040 (0x21c00000)
munmap(0x21400000,8388608)                       = 0 (0x0)
mmap(0x0,33554432,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x2000000) = 583008256 (0x22c00000)
munmap(0x21c00000,16777216)                      = 0 (0x0)
mmap(0x0,67108864,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x4000000) = 616562688 (0x24c00000)
^CSIGNAL 2 (SIGINT)

For this test, the aliases file has just one line, the "root: mike" + newline as you see in the truss output.

poolpOrg suggested I try the db backend. I'll do that and will post another comment.

@mjb2010
Copy link

mjb2010 commented Oct 30, 2015

I am unable to create a .db file because makemap(8) gets into the same loop:

# cd /usr/local/etc/mail
# truss /usr/local/libexec/opensmtpd/makemap aliases
[...]
open("aliases.db.3uWiCBFwKqf",O_RDWR|O_EXLOCK|O_TRUNC|O_CLOEXEC,0644) = 4 (0x4)
fstat(4,{ mode=---------- ,inode=752997,size=0,blksize=32768 }) = 0 (0x0)
stat("aliases.db.3uWiCBFwKqf",{ mode=---------- ,inode=752997,size=0,blksize=32768 }) = 0 (0x0)
fchmod(0x4,0x81a4,0x61,0x2d,0x0,0x0)             = 0 (0x0)
fchown(0x4,0x0,0x0,0x2d,0x0,0x0)                 = 0 (0x0)
open("aliases",O_RDONLY,0666)                    = 5 (0x5)
ioctl(5,TIOCGETA,0xbfffeb48)                     ERR#25 'Inappropriate ioctl for device'
flock(0x5,0x5,0x20c03300,0x1,0x0,0x0)            = 0 (0x0)
fstat(5,{ mode=-rw-r--r-- ,inode=753053,size=11,blksize=32768 }) = 0 (0x0)
read(5,"root: mike\n",32768)                     = 11 (0xb)
read(5,0x20c30000,32768)                         = 0 (0x0)
mmap(0x0,4194304,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x400000) = 553648128 (0x21000000)
madvise(0x20c42000,0x200000,0x5,0xfffff000,0x20c00000,0x0) = 0 (0x0)
madvise(0x20c38000,0x1000,0x5,0xfffff000,0x20c00000,0x0) = 0 (0x0)
mmap(0x0,8388608,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x800000) = 557842432 (0x21400000)
munmap(0x21000000,4194304)                       = 0 (0x0)
mmap(0x0,16777216,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x1000000) = 566231040 (0x21c00000)
munmap(0x21400000,8388608)                       = 0 (0x0)
mmap(0x0,33554432,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x2000000) = 583008256 (0x22c00000)
munmap(0x21c00000,16777216)                      = 0 (0x0)
mmap(0x0,67108864,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x4000000) = 616562688 (0x24c00000)
munmap(0x22c00000,33554432)                      = 0 (0x0)
mmap(0x0,134217728,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x8000000) = 683671552 (0x28c00000)
munmap(0x24c00000,67108864)                      = 0 (0x0)
mmap(0x0,268435456,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,4194304,0x10000000) = 817889280 (0x30c00000)
^CSIGNAL 2 (SIGINT)

@eohland
Copy link

eohland commented Nov 5, 2015

Hi,
I got the same probem after a system upgrade on my Raspberry Pi B model.

% uname -a
Linux alarmpi 4.1.12-1-ARCH #1 PREEMPT Tue Oct 27 19:16:04 MDT 2015 armv6l GNU/Linux
% pacman -Qi opensmtpd
Name           : opensmtpd
Version        : 5.7.3p1-1
Description    : Free implementation of the server-side SMTP protocol
Architecture   : armv6h
URL            : http://www.opensmtpd.org/
Licenses       : custom
Groups         : None
Provides       : smtp-server  smtp-forwarder
Depends On     : libasr  libevent  openssl  pam
Optional Deps  : None
Required By    : None
Optional For   : s-nail
Conflicts With : smtp-server  smtp-forwarder
Replaces       : None
Installed Size : 635.00 KiB
Packager       : Arch Linux ARM Build System <builder+xu4@archlinuxarm.org>
Build Date     : Thu 08 Oct 2015 08:54:12 PM CEST
Install Date   : Thu 05 Nov 2015 11:08:40 AM CET
Install Reason : Explicitly installed
Install Script : Yes
Validated By   : SHA256 Sum
% strace smtpd
execve("/usr/bin/smtpd", ["smtpd"], [/* 27 vars */]) = 0
brk(0)                                  = 0x1ebd000
uname({sysname="Linux", nodename="alarmpi", ...}) = 0
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
[...]
socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 5
connect(5, {sa_family=AF_INET6, sin6_port=htons(0), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
getsockname(5, {sa_family=AF_INET6, sin6_port=htons(44902), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
close(5)                                = 0
brk(0x1eff000)                          = 0x1eff000
open("/etc/smtpd/aliases", O_RDONLY)    = 5
fstat64(5, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f19000
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
[...]
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, "", 4096)                       = 0
read(5, ^CProcess 2246 detached
 <detached ...>

The infinite loop occurs only with the table aliases file:/etc/smtpd/aliases set in the config file.

@tdonovan2
Copy link

The problem is in openbsd-compat/fgetln.c
(c = getc(fp)) != EOF will never be true on a platform where char is unsigned by default.
char variables on ARM/Linux and PowerPC platforms are unsigned by default, while Intel/gcc and Windows char variables are signed.

c should be an int. Patch attached. 692.patch.txt

See the GlibC note about character input : "...always use an int for the result of getc..."

@poolpOrg
Copy link
Member

Sorry for the long delay, we've been working hard on logistics ;-)

So, part of the work involved removing fgetln() altogether from OpenSMTPD which means that the openbsd-compat buggy code is going to bite the dust.

I'm currently working on fixing build for portable after all the merging and a snaspshot should be available very soon that fixes your issue.

I'll leave the ticket open until the snapshot is generated and you can confirm the issue is gone.

@Zarla
Copy link
Author

Zarla commented Dec 24, 2015

Hello,
Don't worry. Take the time, you do a great job. I'm currently in holidays without connection to my computers. I will compile again your release in my rpi2 when you will be ready.Merry Christmas and Happy New Year.
François 

Envoyé depuis mon appareil Samsung

-------- Message d'origine --------
De : Gilles Chehade notifications@github.com
Date : 22/12/2015 13:20 (GMT+01:00)
À : OpenSMTPD/OpenSMTPD OpenSMTPD@noreply.github.com
Cc : Zarla zarla@redarmor.net
Objet : Re: [OpenSMTPD] portable : rpi2, opensmtpd 5.7.3 doesn't return
anything and start to consume all available memory (#642)

Sorry for the long delay, we've been working hard on logistics ;-)

So, part of the work involved removing fgetln() altogether from OpenSMTPD which means that the openbsd-compat buggy code is going to bite the dust.

I'm currently working on fixing build for portable after all the merging and a snaspshot should be available very soon that fixes your issue.

I'll leave the ticket open until the snapshot is generated and you can confirm the issue is gone.


Reply to this email directly or view it on GitHub.

@bzhpwr
Copy link

bzhpwr commented Dec 26, 2015

Hi,
Same trouble one rpi2 with freebsd-11 current and OpenSMTPD 5.7.3.
I look in dmesg and find this:
"rpi2 kernel: pid 700 (smtpd), uid 0, was killed: out of swap space"
So I create 1g swap with this help: https://www.freebsd.org/doc/handbook/adding-swap-space.html
Then I try smptd -vd without success.
smtpd run and use full swap file.

Hope it's help you. Tank you for you're great jobs.

@poolpOrg
Copy link
Member

poolpOrg commented Jan 5, 2016

I have pushed a new snapshot which contains the fgetln() fix that causes the 100% cpu issue.

Can you guys give it a try and confirm the issue is resolved ?

http://www.opensmtpd.org/archives/opensmtpd-201601051911p1.tar.gz

@bzhpwr
Copy link

bzhpwr commented Jan 6, 2016

Hi,
I can't wait !!!
I'll try it today after work :)

Thanks

@tdonovan2
Copy link

Success! When built with this snapshot, smtpd starts up and runs on ARM/Linux.

Apparently one of the changes (in smtpd/queue_backend.c) adds a new requirement for a queue group, in addition to the queue username. It might be good to document this change a bit more. This new requirement slowed me down a bit, but once I figured it out; Yes, fgetln() in this snapshot no longer exhibits the 100%-cpu startup problem on ARM.

FYI, I built and tested on Arch Linux running on a Raspberry-Pi 2 machine.

I will try it on Debian (Jessie) too, and also do some additional testing over the next few days.

@poolpOrg
Copy link
Member

poolpOrg commented Jan 7, 2016

Awesome, the problem was architecture related so if there's a problem on Jessie it's not related to this ticket and you can open another one, thanks for the reporting ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants