Auto-reload of dynamic libraries

Started by Gavin Sherryover 23 years ago2 messages
#1Gavin Sherry
swm@linuxworld.com.au
1 attachment(s)

This small patch reloads dynamic libraries whose modification time is
greater than that at the time it was initially loaded. This means that
connections do not need to be reinitialised when a library is recompiled.

There is a problem with this, however: if dlopen()'ing the new patch
fails, the functions registered in the system against this patch will also
presumably break. This is, of course, what would happened if, a new
connection came in after the library was broken and it attempted to use
any of the functions in it.

Any ideas about ways around this? Need there be? Is this desired
behaviour?

Gavin

Attachments:

dfmgr.c.difftext/plain; charset=US-ASCII; name=dfmgr.c.diffDownload
*** src/backend/utils/fmgr/dfmgr.c.orig	Sat May  4 20:36:59 2002
--- src/backend/utils/fmgr/dfmgr.c	Sat May  4 20:40:05 2002
***************
*** 33,38 ****
--- 33,39 ----
  	dev_t		device;			/* Device file is on */
  	ino_t		inode;			/* Inode number of file */
  	void	   *handle;			/* a handle for pg_dl* functions */
+ 	time_t		mtime;			/* modification time of the lib */
  	char		filename[1];	/* Full pathname of file */
  
  	/*
***************
*** 89,96 ****
  		 strcmp(fullname, file_scanner->filename) != 0;
  		 file_scanner = file_scanner->next)
  		;
! 	if (file_scanner == (DynamicFileList *) NULL)
! 	{
  		/*
  		 * Check for same files - different paths (ie, symlink or link)
  		 */
--- 90,118 ----
  		 strcmp(fullname, file_scanner->filename) != 0;
  		 file_scanner = file_scanner->next)
  		;
! 	if(file_scanner) {
! 
! 		/*
! 		 * Check to make sure the currently loaded lib the most recently
! 		 * compiled.
! 		 */
! 
! 		stat(fullname,&stat_buf);
! 
! 		if(stat_buf.st_mtime > file_scanner->mtime) {
! 
! 			pg_dlclose(file_scanner->handle);
! 	        file_scanner->handle = pg_dlopen(fullname);
! 
! 	        if (file_scanner->handle == (void *) NULL) {
! 	            load_error = (char *) pg_dlerror();
!     	        free((char *) file_scanner);
!         	    elog(ERROR, "Load of file %s failed: %s", fullname, load_error);
! 			} else {
! 				file_scanner->mtime = stat_buf.st_mtime;
! 			}
!         }
! 	} else if (file_scanner == (DynamicFileList *) NULL) {
  		/*
  		 * Check for same files - different paths (ie, symlink or link)
  		 */
***************
*** 119,125 ****
  		file_scanner->device = stat_buf.st_dev;
  		file_scanner->inode = stat_buf.st_ino;
  		file_scanner->next = (DynamicFileList *) NULL;
! 
  		file_scanner->handle = pg_dlopen(fullname);
  		if (file_scanner->handle == (void *) NULL)
  		{
--- 141,147 ----
  		file_scanner->device = stat_buf.st_dev;
  		file_scanner->inode = stat_buf.st_ino;
  		file_scanner->next = (DynamicFileList *) NULL;
! 		file_scanner->mtime = stat_buf.st_mtime;
  		file_scanner->handle = pg_dlopen(fullname);
  		if (file_scanner->handle == (void *) NULL)
  		{
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gavin Sherry (#1)
Re: [PATCHES] Auto-reload of dynamic libraries

Gavin Sherry <swm@linuxworld.com.au> writes:

This small patch reloads dynamic libraries whose modification time is
greater than that at the time it was initially loaded. This means that
connections do not need to be reinitialised when a library is recompiled.

Is that a good idea? It's easy to imagine cases where a library is not
designed to be unloaded (eg, it hooks into things in the main backend
and doesn't have a way to unhook). I'd rather stick with the current
behavior of unload/reload only when specifically commanded to.

The patch as given fails in the same inode/different path case, btw.
I think you wanted to make the test further down.

regards, tom lane