[ZBX-19274] Opened semaphores are not closing if UserParameter is failed due to the timeout Created: 2021 Apr 22  Updated: 2024 Apr 10  Resolved: 2021 May 11

Status: Closed
Project: ZABBIX BUGS AND ISSUES
Component/s: Agent (G)
Affects Version/s: 5.0.10, 5.2.6, 5.4.0beta2
Fix Version/s: 5.0.12rc1, 5.2.7rc1, 5.4.0rc1, 5.4 (plan)

Type: Problem report Priority: Critical
Reporter: Edgar Akhmetshin Assignee: Vladislavs Sokurenko
Resolution: Fixed Votes: 0
Labels: AIX, BSD, UNIX, agent, linux, semaphores, sender, solaris10, solaris11
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File ZBX-19274.diff    
Issue Links:
Causes
caused by ZBXNEXT-4967 Zabbix sender does not send to all IP... Closed
Duplicate
Sub-task
part of ZBX-18886 Huge number of open semaphores, AIX V... Closed
Team: Team A
Sprint: Sprint 75 (Apr 2021)
Story Points: 0.5

 Description   

Steps to reproduce:

  1. Tested on Solaris 11/SPARC
  2. Install agent:
    pkg install -g file:////export/home/src/zabbix_agent-5.0.10-solaris-11-sparc-openssl.p5p zabbix-agent
    
  3. Configure Agent to use UserParameter which invokes bash script with zabbix_sender execution, default timeout option is OK.
  4. On Server compile and start the following code snippet:
    #include <stdio.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #define MAX 80
    #define PORT 8080
    #define SA struct sockaddr
    
    // Function designed for chat between client and server.
    void func(int sockfd)
    {
    	char buff[MAX];
    	int n;
    	// infinite loop for chat
    	for (;;) {
    		bzero(buff, MAX);
    
    		// read the message from client and copy it in buffer
    		read(sockfd, buff, sizeof(buff));
    		// print buffer which contains the client contents
    		printf("From client: %s\t To client : ", buff);
    		bzero(buff, MAX);
    		n = 0;
    		// copy server message in the buffer
    		while ((buff[n++] = getchar()) != '\n')
    			;
    
    		// and send that buffer to client
    		write(sockfd, buff, sizeof(buff));
    
    		// if msg contains "Exit" then server exit and chat ended.
    		if (strncmp("exit", buff, 4) == 0) {
    			printf("Server Exit...\n");
    			break;
    		}
    	}
    }
    
    // Driver function
    int main()
    {
    	int sockfd, connfd, len;
    	struct sockaddr_in servaddr, cli;
    
    	// socket create and verification
    	sockfd = socket(AF_INET, SOCK_STREAM, 0);
    	if (sockfd == -1) {
    		printf("socket creation failed...\n");
    		exit(0);
    	}
    	else
    		printf("Socket successfully created..\n");
    	bzero(&servaddr, sizeof(servaddr));
    
    	// assign IP, PORT
    	servaddr.sin_family = AF_INET;
    	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    	servaddr.sin_port = htons(PORT);
    
    	// Binding newly created socket to given IP and verification
    	if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
    		printf("socket bind failed...\n");
    		exit(0);
    	}
    	else
    		printf("Socket successfully binded..\n");
    
    	// Now server is ready to listen and verification
    	if ((listen(sockfd, 5)) != 0) {
    		printf("Listen failed...\n");
    		exit(0);
    	}
    	else
    		printf("Server listening..\n");
    	len = sizeof(cli);
    
    	// Accept the data packet from client and verification
    	connfd = accept(sockfd, (SA*)&cli, &len);
    	if (connfd < 0) {
    		printf("server acccept failed...\n");
    		exit(0);
    	}
    	else
    		printf("server acccept the client...\n");
    
    	// Function for chatting between client and server
            sleep(600);
    	func(connfd);
    
    	// After chatting close the socket
    	close(sockfd);
    }
    
  5. Using Zabbix get request UserParameter (on port 8080 for zabbix_sender inside script of the example of the fake server), check list of the semaphores:
    root@sol11:~# ipcs -a
    IPC status from <running system> as of Thursday, April 22, 2021 12:48:42 PM EEST
    T         ID      KEY        MODE        OWNER    GROUP  CREATOR   CGROUP CBYTES  QNUM QBYTES LSPID LRPID   STIME    RTIME    CTIME 
    Message Queues:
    T         ID      KEY        MODE        OWNER    GROUP  CREATOR   CGROUP NATTCH      SEGSZ   CPID  LPID   ATIME    DTIME    CTIME 
    Shared Memory:
    T         ID      KEY        MODE        OWNER    GROUP  CREATOR   CGROUP NSEMS   OTIME    CTIME 
    Semaphores:
    s          8   0x0        --ra-------   zabbix   zabbix   zabbix   zabbix    16 no-entry 12:48:36
    s          7   0x0        --ra-------   zabbix   zabbix   zabbix   zabbix    16 no-entry 12:48:16
    s          6   0x0        --ra-------   zabbix   zabbix   zabbix   zabbix    16 12:48:41 12:47:52
    

Expected:
No semaphores left.



 Comments   
Comment by Vladislavs Sokurenko [ 2021 Apr 22 ]

Zabbix sender receives SIGTERM, this interrupts waitpid and error is written to stderr:

zbx_error("Error waiting for process with PID %d: %s", (int)thread, zbx_strerror(errno));

Once error is written Zabbix sender seems to be killed, if not writing to stderr it can continue execution and cleanup resources.

Solution is to check for EINTR and retry waitpid to avoid writing to stderr for no reason.

Comment by Vladislavs Sokurenko [ 2021 Apr 29 ]

Fixed in:

  • pre-5.0.12rc1 df31374fad6
  • pre-5.2.7rc1 227ba3d4db8
  • pre-5.4.0rc1 (master) d98d75b8f54
Generated at Tue Jan 07 17:01:12 EET 2025 using Jira 9.12.4#9120004-sha1:625303b708afdb767e17cb2838290c41888e9ff0.