Hello Gerlof.
I am cc´ing this once again to the Debian bug report so that the information
gets recorded there. Feel free to drop the Cc again in case you write an
answer which is not related to the bug report.
Am Dienstag, 13. Dezember 2016, 14:50:18 CET schrieb Gerlof Langeveld:
> The reason that atopacctd does not properly work any more is related to
> the modifications in the newer kernel versions, like 4.7/4.8.
> In fact, there are two issues with the newer kernel versions:
Thank you very much for the huge amount of effort you put into this.
> 1) Sometimes process accounting does not work at all.
>
> The acct() system call (to activate process accounting) return value 0,
> which means that process accounting is activated successfully.
> However, no process accounting records are written whatsoever. This
> situation can be reproduced with the program 'acctdemo.c'
> that you can find as attachment. When this program gives the message
> "found a process accounting record!", the situation is okay
> and process accounting works fine to the file '/tmp/mypacct'. When the
> message 'No process accounting record yet....' is repeatedly given,
> process accounting does not work and will not work at all. It might be
> that you have to start this program several times before you get
> this situation (preferably start/finish lots of processes in the mean time).
> This problem is probably caused by a new mechanism introduced in the kernel
> code (..../linux/kernel/acct.c) that is called 'slow accounting' and has to
> be solved in the kernel code.
>
> I experience this problem on Debian8 with a 4.8 kernel and on CentOS7
> with a 4.8 kernel.
Okay, this is something to report a kernel bugtracker and/or LKML then. I am
currently holding a Linux performance course, but I will try to do that.
> 2) When using the NETLINK inface, the command TASKSTATS_CMD_GET
> consequently returns -EINVAL.
>
> The code that is used by the atopacctd daemon is based on the demo code
> 'getdelays.c' that can be found in the kernel source code tree
> (..../linux/Documentation/accounting/getdelays.c). Also this 'getdelays'
> program does not work any more (also -EINVAL on the same call)
> with the newer kernels. I really spent a lot of time on this issue to
> get the code running (there are many places in the kernel code where
> -EINVAL for this call can be given), but I did not succeed. It is really
> an incompatibility introduced by the kernel code.
> It would be nice if the kernel maintainers provide a working version of
> the getdelays program in the kernel source tree.
>
> I only experience this problem on Debian8 with a 4.8 kernel (virtual
> machine with 4 cores).
> On CentOS7 with a 4.8 kernel it works fine (physical machine with 4 cores).
Here it would be interesting to have the exact config files you use, in order
to
probably spot whether this is a kernel configuration issue. Do you still have
them? If so, please attach them.
> I will anyhow adapt atopacctd for this issue that it detects and logs
> the -EINVAL and terminates.
> The current version of atopacctd keeps running which is not useful at all.
I see.
> So my conclusion is that this issue (bug 833997) can not be solved in
> atopacctd.
> In fact, it can be divided into two different issues that are both
> related to the kernel.
I see. Marc, IMHO this issue should not hold back uploading new atop to Debian
unstable for inclusion into next Debian version. What do you think?
Funninly enough with the 4.9 kernel I compiled and installed today, currently
atopacctd runs just fine. Well… I will observe whether the issue still happens
with that new kernel.
Again, thank you very much.
[… previous mail exchange that lead to the conclusion that it is an issue with
the new kernel versions …]
Ciao,
--
Martin
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define ACCTFILE "/tmp/mypacct"
main()
{
int fd;
char buf[1024];
if ( (fd = open(ACCTFILE, O_RDWR|O_CREAT|O_TRUNC, 0777)) == -1)
{
perror("Open " ACCTFILE);
exit(1);
}
if (acct(ACCTFILE) == -1)
{
perror("Switch on accounting");
exit(1);
}
if ( fork() == 0 ) // fork new process
exit(0); // child process: finish
// parent process:
// wait for child to finish
wait((int *)0);
// read the process accounting record of the finished child
while (read(fd, buf, sizeof buf) == 0)
{
printf("No process accounting record yet....\n");
sleep(1);
}
printf("Yeeeeah, found a process accounting record!\n");
}