Search code examples
csignalsforkexec

Forking and running dhclient (with params -nw -w) in exec creates a defunct process and a daemon process


I am seeing a zombie process and the dhclient process when I fork from my parent process and then exec the dhclient process with its arguments

Here is the output

root     31298  0.0  0.0      0     0 pts/2    Z    09:22   0:00 [dhclientForData] <defunct>
root     31410  0.0  0.0  24260  9108 ?        Ss   09:23   0:00 -nw -w -sf etc/dhclient-script -pf /var/run/dhclient-vEth0.pid -lf /var/lib/dhcp/dhclient-vEth0.leases -cf /etc/sysconfig/dhclient.conf vEth0

I have renamed the linux system dhclient to dhclientForData in my parent process. Notice the second line in the above output I dont see the dhclient process name just the argurmnts I am not sure why, anyone?

my code

func_parent()
{
       pid_t child = 0;
        child = fork();
        if (child < 0)
        {   
            return 0;
        }
        if (child == 0)
        {   
            wanIntfDhclientHandlerProcessChildAdd ();
        }
        shmWlanTunMonitrConfig->childProcs[index].procId = child;
        sleep(1);
    }

    uint8_t wanIntfDhclientHandlerProcessChildAdd ()
    {
        pid_t mypid = getpid();
        uint8_t idx = gindex;
        //for (; idx < MAX_WAN_PORTS; idx++)
        {   
            if (!shmWlanTunMonitrConfig->childProcs[idx].isRunning && shmWlanTunMonitrConfig->childProcs[idx].cmdIdx != 0xFF)
            {   
                shmWlanTunMonitrConfig->childProcs[idx].isRunning = 1;

                char *const argV[] = {commands[idx].cmd[0],
                commands[idx].cmd[1],
                commands[idx].cmd[2],
                commands[idx].cmd[3],
                commands[idx].cmd[4],
                commands[idx].cmd[5],
                commands[idx].cmd[6],
                commands[idx].cmd[7],
                commands[idx].cmd[8],
                commands[idx].cmd[9],
                commands[idx].cmd[10],
                NULL};
                int ret = execvp(WAN_EXECUTABLE, argV);
    }
    }
    }

I have registered to the sigchld and will waitpid on that process. I have multiple processes running

pid_t pid = waitpid(shmWlanTunMonitrConfig->childProcs[index].procId, &status, WNOHANG);

I just delete the process from my parent process if the job is no longer required.

char cmd[512] = {0};
sprintf(cmd, "for KILLPID in `ps ax | grep \'/var/run/dhclient\' | grep \'%s\' | awk \' { print $1;}\'`; do kill -9 $KILLPID; done", portIntfAr[index].intfName);
system (cmd);

Can anyone please point me at what am I doing wrong.

Syed


Solution

  • The zombie process 31298 exists as long as the parent process did not yet wait for it, so probably there is something wrong with your process table or your waitpid call. I cannot check because your code is incomplete.

    Instead of waiting for a specific PID you could also wait for any child or for a process group and find out from the resultuing siginfo_t structure which process just reported its state change.

    I don't know which string you assign with

    char *const argV[] = {commands[idx].cmd[0],
    /* ... */
    

    argv[0] should be the file name of the program, i.e. the same as WAN_EXECUTABLE