EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: Channel access problem on cygwin IOC
From: "Jeff Hill" <[email protected]>
To: "'Mark Rivers'" <[email protected]>, <[email protected]>
Date: Fri, 30 Sep 2005 16:14:12 -0600
Mark,

> The copy of caRepeater that was started under
> cygwin had the unfortunate property that it had a file open that my IOC
> application had opened, and that file could not be deleted until that copy
> of caRepeater was killed.

This is a fun "feature" of POSIX. On POSIX subsystems we used to close *all*
file numbers (other than stdin/out/err) before launching the caRepeater
using exec in the process created with fork. We received a complaint that
this was too intrusive (I think that there was some issue on HPUX).
Therefore, base now open all sockets specifying the FD_CLOEXEC option and
lets the OS take care of this matter. 

You will also need to set the FD_CLOEXEC option when opening a file on POSIX
systems in any process that uses fork and exec to start a detached process.

Attached are the codes that start the caRepeater depending on if the
repeater is started with cygwin-x86 (POSIX) or with win32-x86.

> I then started medm on the Windows machine, which created a caRepeater
> task that shows up in the Windows Task Manager.  That time starting the
> IOC did not start a caRepeater task, since it must have found the one that
> was running under Windows.  However, I still got the following error at
> the IOC:
> ***
> epics> CA client library is unable to contact CA repeater a
>
> Do you understand what is going on?

Nope. My guess is that the cygwin socket subsystem somehow isn't forwarding
UDP to the win32 socket subsystem.

And I was whining about having to support both cygwin-x86 and win32-x86 when
I dint know that we could look forward to the "cygwin-x86-blend-win32-x86"
system :-)

Jeff

On POSIX:

epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI
osiSpawnDetachedProcess 
    (const char *pProcessName, const char *pBaseExecutableName)
{
    int status;
    
    /*
     * create a duplicate process
     */
    status = fork ();
    if (status < 0) {
        return osiSpawnDetachedProcessFail;
    }

    /*
     * return to the caller
     * if its in the initiating process
     */
    if (status) {
        return osiSpawnDetachedProcessSuccess;
    }

    /*
     * since all epics sockets are created with the FD_CLOEXEC
     * option then we no-longer need to blindly close all open
     * files here.
     */

    /*
     * overlay the specified executable
     */
    status = execlp (pBaseExecutableName, pBaseExecutableName, NULL);
    if ( status < 0 ) { 
        fprintf ( stderr, "**** The executable \"%s\" couldn't be
located\n", pBaseExecutableName );
        fprintf ( stderr, "**** because of errno = \"%s\".\n", strerror
(errno) );
        fprintf ( stderr, "**** You may need to modify your PATH environment
variable.\n" );
        fprintf ( stderr, "**** Unable to start \"%s\" process.\n",
pProcessName);
    }
    exit ( -1 );
}

On WIN32:

epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI
osiSpawnDetachedProcess 
    ( const char *pProcessName, const char *pBaseExecutableName )
{
	BOOL status;
	STARTUPINFO startupInfo;
	PROCESS_INFORMATION processInfo;

	GetStartupInfo ( &startupInfo ); 
	startupInfo.lpReserved = NULL;
	startupInfo.lpTitle = (char *) pProcessName;
	startupInfo.dwFlags = STARTF_USESHOWWINDOW;
	startupInfo.wShowWindow = SW_SHOWMINNOACTIVE;
	
	status =  CreateProcess ( 
		            NULL, // pointer to name of executable module
(not required if command line is specified)
		            (char *) pBaseExecutableName, // pointer to
command line string 
		            NULL, // pointer to process security attributes 
		            NULL, // pointer to thread security attributes 
		            FALSE, // handle inheritance flag 
		            CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, //
creation flags 
		            NULL, // pointer to new environment block
(defaults to caller's environement)
		            NULL, // pointer to current directory name
(defaults to caller's current directory)
		            &startupInfo, // pointer to STARTUPINFO 
		            &processInfo // pointer to PROCESS_INFORMATION 
	); 
	if ( status == 0 ) {
		DWORD W32status;
		LPVOID errStrMsgBuf;
		LPVOID complteMsgBuf;

		W32status = FormatMessage ( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
			NULL,
			GetLastError (),
			MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), //
Default language
				(LPTSTR) &errStrMsgBuf,
			0,
			NULL 
		);

		if ( W32status ) {
			char *pFmtArgs[6];
            pFmtArgs[0] = "Failed to start executable -";
            pFmtArgs[1] = (char *) pBaseExecutableName;
            pFmtArgs[2] = errStrMsgBuf;
            pFmtArgs[3] = "Changes may be required in your \"path\"
environment variable.";
            pFmtArgs[4] = "PATH = ";
            pFmtArgs[5] = getenv ("path");
			if ( pFmtArgs[5] == NULL ) {
				pFmtArgs[5] = "<empty string>";
			}

			W32status = FormatMessage( 
				FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_STRING | 
					FORMAT_MESSAGE_ARGUMENT_ARRAY | 80,
				"%1 \"%2\". %3 %4 %5 \"%6\"",
				0,
				MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
// Default language
				(LPTSTR) &complteMsgBuf,
				0,
				pFmtArgs 
			);
			if (W32status) {
				// Display the string.
				MessageBox (NULL, complteMsgBuf,
"Configuration Problem", 
					MB_OK | MB_ICONINFORMATION);
				LocalFree (complteMsgBuf);
			}
			else {
				// Display the string.
				MessageBox (NULL, errStrMsgBuf, "Failed to
start executable", 
					MB_OK | MB_ICONINFORMATION);
			}

			// Free the buffer.
			LocalFree (errStrMsgBuf);
		}
		else {
			errlogPrintf ("!!WARNING!!\n");
			errlogPrintf ("Unable to locate executable
\"%s\".\n", pBaseExecutableName);
			errlogPrintf ("You may need to modify your
environment.\n");
		}
        return osiSpawnDetachedProcessFail;
	}

    return osiSpawnDetachedProcessSuccess;

	//
	// use of spawn here causes problems when the ca repeater
	// inherits open files (and sockets) from the spawning
	// process
	//
	//status = _spawnlp (_P_DETACH, pBaseExecutableName,
pBaseExecutableName, NULL);
	//if (status<0) {
	//	errlogPrintf ("!!WARNING!!\n");
	//	errlogPrintf ("Unable to locate the EPICS executable
\"%s\".\n",
	//		pBaseExecutableName);
	//	errlogPrintf ("You may need to modify your environment.\n");
	//}
}

> -----Original Message-----
> From: Mark Rivers [mailto:[email protected]]
> Sent: Friday, September 30, 2005 3:08 PM
> To: Mark Rivers; Jeff Hill; [email protected]
> Subject: RE: Channel access problem on cygwin IOC
> 
> Jeff,
> 
> I just learned a little more about the caRepeater problem.  When I did the
> tests in my previous message I had not run any Windows CA clients that
> would have started a Windows caRepeater task.  When I started the IOC it
> started a caRepeater task that appears with "ps -a" in cygwin, but did not
> appear in the Windows Task Manager.  I got the error saying that CA could
> not find the caRepeater.  The copy of caRepeater that was started under
> cygwin had the unfortunate property that it had a file open that my IOC
> application had opened, and that file could not be deleted until that copy
> of caRepeater was killed.
> 
> I then started medm on the Windows machine, which created a caRepeater
> task that shows up in the Windows Task Manager.  That time starting the
> IOC did not start a caRepeater task, since it must have found the one that
> was running under Windows.  However, I still got the following error at
> the IOC:
> ***
> epics> CA client library is unable to contact CA repeater a
> Silence this message by starting a CA repeater daemon
> or by calling ca_pend_event() and or ca_poll() more often.
> ****
> 
> But at least this copy of caRepeater does not have the file locked that
> needs to be deleted!
> 
> Do you understand what is going on?
> 
> Thanks,
> Mark
> 
> 
> ________________________________
> 
> From: Mark Rivers
> Sent: Fri 9/30/2005 3:33 PM
> To: Jeff Hill; [email protected]
> Subject: RE: Channel access problem on cygwin IOC
> 
> 
> 
> Jeff,
> 
> The think the problem might have been caused by EPICS launching a second
> copy of my IOC instead of caRepeater one time.  So there were two copies
> of the IOC application running, causing the IP problem?
> 
> There is something else I don't understand about caRepeater behavior on
> this IOC.
> 
> Here is a list of cygwin processes before I start my IOC.
> $ ps -a
>       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
>      1364       1    1364       1364    ?   18 20:29:52 /usr/bin/cygrunsrv
>      1660    1364    1660       1672    ?   18 20:29:57 /usr/sbin/sshd
> I     460       1     460        460    0 11092 20:31:24 /usr/bin/bash
>      2280       1    2280       2280    1 11092 14:02:41 /usr/bin/bash
>      3808    2280    3808       2740    1 11092 14:03:38 /usr/bin/ps
> 
> Now I start the IOC. Note that the path to caRepeater in EPICS base is in
> my cygwin PATH.  Now list the processes again.
> 
> $ ps -a
>       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
>      1364       1    1364       1364    ?   18 20:29:52 /usr/bin/cygrunsrv
>      1660    1364    1660       1672    ?   18 20:29:57 /usr/sbin/sshd
>       460       1     460        460    0 11092 20:31:24 /usr/bin/bash
>      2280       1    2280       2280    1 11092 14:02:41 /usr/bin/bash
> I    2112     460    2112       3008    0 11092 14:03:49
> /cygdrive/j/epics/devel/dxp/2-4beta/bin/cygwin-x86/xmapApp
>       736    2112    2112       3284    0 11092 14:04:49
> /cygdrive/h/epics/base/bin/cygwin-x86/caRepeater
>      3932    2280    3932       3456    1 11092 15:14:12 /usr/bin/ps
> 
> 
> xmapApp is the IOC process.  Note that starting the IOC has started the
> caRepeater, as it should have.
> 
> However, I get the following message from iocsh on the IOC after iocInit
> is complete.
> *****
> CA client library is unable to contact CA repeater after 50
> Silence this message by starting a CA repeater daemon
> or by calling ca_pend_event() and or ca_poll() more often.
> ******
> 
> This does not seem right.  Why am I getting that error message even though
> caRepeater was in fact successfully started?
> 
> Thanks,
> Mark
> 




References:
RE: Channel access problem on cygwin IOC Mark Rivers

Navigate by Date:
Prev: RE: Channel access problem on cygwin IOC Mark Rivers
Next: Gateway 2.0.0.0 Released Kenneth Evans, Jr.
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: RE: Channel access problem on cygwin IOC Mark Rivers
Next: EPICS meeting: timetable and organization Matthias Clausen
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·