⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 miscinit.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 3 页
字号:
			}		}		/*		 * No, the creating process did not exist.	However, it could be that		 * the postmaster crashed (or more likely was kill -9'd by a clueless		 * admin) but has left orphan backends behind.	Check for this by		 * looking to see if there is an associated shmem segment that is		 * still in use.		 */		if (isDDLock)		{			char	   *ptr;			unsigned long id1,						id2;			ptr = strchr(buffer, '\n');			if (ptr != NULL &&				(ptr = strchr(ptr + 1, '\n')) != NULL)			{				ptr++;				if (sscanf(ptr, "%lu %lu", &id1, &id2) == 2)				{					if (PGSharedMemoryIsInUse(id1, id2))						ereport(FATAL,								(errcode(ERRCODE_LOCK_FILE_EXISTS),								 errmsg("pre-existing shared memory block "										"(key %lu, ID %lu) is still in use",										id1, id2),								 errhint("If you're sure there are no old "									"server processes still running, remove "										 "the shared memory block with "									  "the command \"ipcclean\", \"ipcrm\", "										 "or just delete the file \"%s\".",										 filename)));				}			}		}		/*		 * Looks like nobody's home.  Unlink the file and try again to create		 * it.	Need a loop because of possible race condition against other		 * would-be creators.		 */		if (unlink(filename) < 0)			ereport(FATAL,					(errcode_for_file_access(),					 errmsg("could not remove old lock file \"%s\": %m",							filename),					 errhint("The file seems accidentally left over, but "						   "it could not be removed. Please remove the file "							 "by hand and try again.")));	}	/*	 * Successfully created the file, now fill it.	 */	snprintf(buffer, sizeof(buffer), "%d\n%s\n",			 amPostmaster ? (int) my_pid : -((int) my_pid),			 DataDir);	errno = 0;	if (write(fd, buffer, strlen(buffer)) != strlen(buffer))	{		int			save_errno = errno;		close(fd);		unlink(filename);		/* if write didn't set errno, assume problem is no disk space */		errno = save_errno ? save_errno : ENOSPC;		ereport(FATAL,				(errcode_for_file_access(),				 errmsg("could not write lock file \"%s\": %m", filename)));	}	if (close(fd))	{		int			save_errno = errno;		unlink(filename);		errno = save_errno;		ereport(FATAL,				(errcode_for_file_access(),				 errmsg("could not write lock file \"%s\": %m", filename)));	}	/*	 * Arrange for automatic removal of lockfile at proc_exit.	 */	on_proc_exit(UnlinkLockFile, PointerGetDatum(strdup(filename)));}/* * Create the data directory lockfile. * * When this is called, we must have already switched the working * directory to DataDir, so we can just use a relative path.  This * helps ensure that we are locking the directory we should be. */voidCreateDataDirLockFile(bool amPostmaster){	CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, true, DataDir);}/* * Create a lockfile for the specified Unix socket file. */voidCreateSocketLockFile(const char *socketfile, bool amPostmaster){	char		lockfile[MAXPGPATH];	snprintf(lockfile, sizeof(lockfile), "%s.lock", socketfile);	CreateLockFile(lockfile, amPostmaster, false, socketfile);	/* Save name of lockfile for TouchSocketLockFile */	strcpy(socketLockFile, lockfile);}/* * TouchSocketLockFile -- mark socket lock file as recently accessed * * This routine should be called every so often to ensure that the lock file * has a recent mod or access date.  That saves it * from being removed by overenthusiastic /tmp-directory-cleaner daemons. * (Another reason we should never have put the socket file in /tmp...) */voidTouchSocketLockFile(void){	/* Do nothing if we did not create a socket... */	if (socketLockFile[0] != '\0')	{		/*		 * utime() is POSIX standard, utimes() is a common alternative; if we		 * have neither, fall back to actually reading the file (which only		 * sets the access time not mod time, but that should be enough in		 * most cases).  In all paths, we ignore errors.		 */#ifdef HAVE_UTIME		utime(socketLockFile, NULL);#else							/* !HAVE_UTIME */#ifdef HAVE_UTIMES		utimes(socketLockFile, NULL);#else							/* !HAVE_UTIMES */		int			fd;		char		buffer[1];		fd = open(socketLockFile, O_RDONLY | PG_BINARY, 0);		if (fd >= 0)		{			read(fd, buffer, sizeof(buffer));			close(fd);		}#endif   /* HAVE_UTIMES */#endif   /* HAVE_UTIME */	}}/* * Append information about a shared memory segment to the data directory * lock file. * * This may be called multiple times in the life of a postmaster, if we * delete and recreate shmem due to backend crash.	Therefore, be prepared * to overwrite existing information.  (As of 7.1, a postmaster only creates * one shm seg at a time; but for the purposes here, if we did have more than * one then any one of them would do anyway.) */voidRecordSharedMemoryInLockFile(unsigned long id1, unsigned long id2){	int			fd;	int			len;	char	   *ptr;	char		buffer[BLCKSZ];	fd = open(DIRECTORY_LOCK_FILE, O_RDWR | PG_BINARY, 0);	if (fd < 0)	{		ereport(LOG,				(errcode_for_file_access(),				 errmsg("could not open file \"%s\": %m",						DIRECTORY_LOCK_FILE)));		return;	}	len = read(fd, buffer, sizeof(buffer) - 100);	if (len < 0)	{		ereport(LOG,				(errcode_for_file_access(),				 errmsg("could not read from file \"%s\": %m",						DIRECTORY_LOCK_FILE)));		close(fd);		return;	}	buffer[len] = '\0';	/*	 * Skip over first two lines (PID and path).	 */	ptr = strchr(buffer, '\n');	if (ptr == NULL ||		(ptr = strchr(ptr + 1, '\n')) == NULL)	{		elog(LOG, "bogus data in \"%s\"", DIRECTORY_LOCK_FILE);		close(fd);		return;	}	ptr++;	/*	 * Append key information.	Format to try to keep it the same length	 * always (trailing junk won't hurt, but might confuse humans).	 */	sprintf(ptr, "%9lu %9lu\n", id1, id2);	/*	 * And rewrite the data.  Since we write in a single kernel call, this	 * update should appear atomic to onlookers.	 */	len = strlen(buffer);	errno = 0;	if (lseek(fd, (off_t) 0, SEEK_SET) != 0 ||		(int) write(fd, buffer, len) != len)	{		/* if write didn't set errno, assume problem is no disk space */		if (errno == 0)			errno = ENOSPC;		ereport(LOG,				(errcode_for_file_access(),				 errmsg("could not write to file \"%s\": %m",						DIRECTORY_LOCK_FILE)));		close(fd);		return;	}	if (close(fd))	{		ereport(LOG,				(errcode_for_file_access(),				 errmsg("could not write to file \"%s\": %m",						DIRECTORY_LOCK_FILE)));	}}/*------------------------------------------------------------------------- *				Version checking support *------------------------------------------------------------------------- *//* * Determine whether the PG_VERSION file in directory `path' indicates * a data version compatible with the version of this program. * * If compatible, return. Otherwise, ereport(FATAL). */voidValidatePgVersion(const char *path){	char		full_path[MAXPGPATH];	FILE	   *file;	int			ret;	long		file_major,				file_minor;	long		my_major = 0,				my_minor = 0;	char	   *endptr;	const char *version_string = PG_VERSION;	my_major = strtol(version_string, &endptr, 10);	if (*endptr == '.')		my_minor = strtol(endptr + 1, NULL, 10);	snprintf(full_path, sizeof(full_path), "%s/PG_VERSION", path);	file = AllocateFile(full_path, "r");	if (!file)	{		if (errno == ENOENT)			ereport(FATAL,					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),					 errmsg("\"%s\" is not a valid data directory",							path),					 errdetail("File \"%s\" is missing.", full_path)));		else			ereport(FATAL,					(errcode_for_file_access(),					 errmsg("could not open file \"%s\": %m", full_path)));	}	ret = fscanf(file, "%ld.%ld", &file_major, &file_minor);	if (ret != 2)		ereport(FATAL,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("\"%s\" is not a valid data directory",						path),				 errdetail("File \"%s\" does not contain valid data.",						   full_path),				 errhint("You may need to initdb.")));	FreeFile(file);	if (my_major != file_major || my_minor != file_minor)		ereport(FATAL,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("database files are incompatible with server"),				 errdetail("The data directory was initialized by PostgreSQL version %ld.%ld, "						   "which is not compatible with this version %s.",						   file_major, file_minor, version_string)));}/*------------------------------------------------------------------------- *				Library preload support *------------------------------------------------------------------------- */typedef void (*func_ptr) ();/* * process any libraries that should be preloaded and * optionally pre-initialized */voidprocess_preload_libraries(char *preload_libraries_string){	char	   *rawstring;	List	   *elemlist;	ListCell   *l;	if (preload_libraries_string == NULL)		return;	/* Need a modifiable copy of string */	rawstring = pstrdup(preload_libraries_string);	/* Parse string into list of identifiers */	if (!SplitIdentifierString(rawstring, ',', &elemlist))	{		/* syntax error in list */		pfree(rawstring);		list_free(elemlist);		ereport(LOG,				(errcode(ERRCODE_SYNTAX_ERROR),		 errmsg("invalid list syntax for parameter \"preload_libraries\"")));		return;	}	foreach(l, elemlist)	{		char	   *tok = (char *) lfirst(l);		char	   *sep = strstr(tok, ":");		char	   *filename = NULL;		char	   *funcname = NULL;		func_ptr	initfunc;		if (sep)		{			/*			 * a colon separator implies there is an initialization function			 * that we need to run in addition to loading the library			 */			size_t		filename_len = sep - tok;			size_t		funcname_len = strlen(tok) - filename_len - 1;			filename = (char *) palloc(filename_len + 1);			memcpy(filename, tok, filename_len);			filename[filename_len] = '\0';			funcname = (char *) palloc(funcname_len + 1);			strcpy(funcname, sep + 1);		}		else		{			/*			 * no separator -- just load the library			 */			filename = pstrdup(tok);			funcname = NULL;		}		canonicalize_path(filename);		initfunc = (func_ptr) load_external_function(filename, funcname,													 true, NULL);		if (initfunc)			(*initfunc) ();		if (funcname)			ereport(LOG,					(errmsg("preloaded library \"%s\" with initialization function \"%s\"",							filename, funcname)));		else			ereport(LOG,					(errmsg("preloaded library \"%s\"",							filename)));		pfree(filename);		if (funcname)			pfree(funcname);	}	pfree(rawstring);	list_free(elemlist);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -