Regarding: Bug 9586 - smbd[29175]: disk_free: sys_popen() failed" message logged in /var/log/message many times.

Kevin Cao Kevin_Cao at symantec.com
Tue May 27 18:28:51 MDT 2014


CC’ed Samba technical.

From: Kevin Cao <kevin_cao at symantec.com<mailto:kevin_cao at symantec.com>>
Date: Tuesday, May 27, 2014 at 3:38 PM
To: "jra at samba.org<mailto:jra at samba.org>" <jra at samba.org<mailto:jra at samba.org>>
Cc: "kevin_i_cao at me.com<mailto:kevin_i_cao at me.com>" <kevin_i_cao at me.com<mailto:kevin_i_cao at me.com>>
Subject: Regarding: Bug 9586 - smbd[29175]: disk_free: sys_popen() failed" message logged in /var/log/message many times.

Hi Jeremy,

I am Kevin from Symantec. First of all, thanks for providing the patch to us. However, we still face the exact issue after applying the patch, and I did further debug and found that sys_pclose() was returning ECHILD, that’s the reason we got the error “No child process” in dfree code path.

<SNIP>
/**
Load from a pipe into memory.
**/

static char *file_pload(const char *syscmd, size_t *size)
{
        int fd, n;
        char *p;
        char buf[1024];
        size_t total;

        fd = sys_popen(syscmd);
…
        while ((n = sys_read(fd, buf, sizeof(buf))) > 0) {
                p = talloc_realloc(NULL, p, char, total + n + 1);
                if (!p) {
…
        /* FIXME: Perhaps ought to check that the command completed
         * successfully (returned 0); if not the data may be
         * truncated. */
        sys_pclose(fd);   <<< ECHILD was returned here

        if (size) {
                *size = total;
        }

        return p;
</SNIP>

Looking at the code of sys_pclose(), which is saying that samba is catching and eatching child process exits, and I think that this might be the reason that the parent can not the reap the status of its child:

<SNIP>
        /*
         * As Samba is catching and eating child process
         * exits we don't really care about the child exit
         * code, a -1 with errno = ECHILD will do fine for us.
         */

        do {
                wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
        } while (wait_pid == -1 && errno == EINTR);
</SNIP>

IMHO, to avoid this, should we call function CatchChildLeaveStatus() before calling sys_fork() in sys_popen(), I think that we need the child’s status and need to stop CatchChild from eating the exit status code, and restore the signal handler in parent and after calling waitpid() in sys_pclose():

<SNIP>
int sys_popen(const char *command)
{
        int parent_end, child_end;
        int pipe_fds[2];
        popen_list *entry = NULL;
        char **argl = NULL;
…
        CatchChildLeaveStatus();
        entry->child_pid = sys_fork();

        if (entry->child_pid == -1) {
                DEBUG(0, ("---kdbg sys_popen failed to fork\n"));
                CatchChild();
                goto err_exit;
        }
</SNIP>

Any comments would be appreciated.

Thanks in advance,
-Kevin



More information about the samba-technical mailing list