Przeglądaj źródła

Merge pull request #615 from prodatakey/foreground-logging

Merge PR #615: Foreground logging
Ilya Shipitsin 7 lat temu
rodzic
commit
d65f292888

+ 278 - 214
src/Cedar/Logging.c

@@ -133,6 +133,10 @@ static char *delete_targets[] =
 static UINT eraser_check_interval = DISK_FREE_CHECK_INTERVAL_DEFAULT;
 static UINT64 logger_max_log_size = MAX_LOG_SIZE_DEFAULT;
 
+static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *log_date_changed, char *current_logfile_datename, char *current_file_name);
+static bool LogThreadWriteStdout(LOG *log_object, BUF *buffer, IO *io);
+static IO *GetIO4Stdout();
+
 // Send with syslog
 void SendSysLog(SLOG *g, wchar_t *str)
 {
@@ -2621,7 +2625,6 @@ void LogThread(THREAD *thread, void *param)
 	bool flag = false;
 	char current_file_name[MAX_SIZE];
 	char current_logfile_datename[MAX_SIZE];
-	bool last_priority_flag = false;
 	bool log_date_changed = false;
 	// Validate arguments
 	if (thread == NULL || param == NULL)
@@ -2634,7 +2637,7 @@ void LogThread(THREAD *thread, void *param)
 
 	g = (LOG *)param;
 
-	io = NULL;
+	io = g_foreground ? GetIO4Stdout() : NULL;
 	b = NewBuf();
 
 #ifdef	OS_WIN32
@@ -2648,293 +2651,354 @@ void LogThread(THREAD *thread, void *param)
 
 	while (true)
 	{
-		RECORD *rec;
 		UINT64 s = Tick64();
 
 		while (true)
 		{
-			char file_name[MAX_SIZE];
+			if (g_foreground)
+			{
+				if (! LogThreadWriteStdout(g, b, io))
+				{
+					break;
+				}
+			}
+			else
+			{
+				if (! LogThreadWriteGeneral(g, b, &io, &log_date_changed, current_logfile_datename, current_file_name))
+				{
+					break;
+				}
+			}
+		}
+
+		if (g->Halt)
+		{
+			// Break after finishing to save all records
+			// when the stop flag stood
 			UINT num;
 
-			// Retrieve a record from the head of the queue
+			if (flag == false)
+			{
+#ifdef	OS_WIN32
+				MsSetThreadPriorityRealtime();
+#endif	// OS_WIN32
+				flag = true;
+			}
+
 			LockQueue(g->RecordQueue);
 			{
-				rec = GetNext(g->RecordQueue);
 				num = g->RecordQueue->num_item;
 			}
 			UnlockQueue(g->RecordQueue);
 
-#ifdef	OS_WIN32
-			if (num >= LOG_ENGINE_SAVE_START_CACHE_COUNT)
+			if (num == 0 || io == NULL)
 			{
-				// Raise the priority
-				if (last_priority_flag == false)
-				{
-					Debug("LOG_THREAD: MsSetThreadPriorityRealtime\n");
-					MsSetThreadPriorityRealtime();
-					last_priority_flag = true;
-				}
+				break;
 			}
+		}
+		else
+		{
+			Wait(g->Event, 9821);
+		}
+	}
+
+	if (io != NULL && !g_foreground)
+	{
+		FileCloseEx(io, true);
+	}
+
+	FreeBuf(b);
+}
+
+static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *log_date_changed, char *current_logfile_datename, char *current_file_name)
+{
+	RECORD *rec;
+	char file_name[MAX_SIZE];
+	UINT num;
+
+	// Retrieve a record from the head of the queue
+	LockQueue(log_object->RecordQueue);
+	{
+		rec = GetNext(log_object->RecordQueue);
+		num = log_object->RecordQueue->num_item;
+	}
+	UnlockQueue(log_object->RecordQueue);
+
+#ifdef	OS_WIN32
+	if (num >= LOG_ENGINE_SAVE_START_CACHE_COUNT)
+	{
+		// Raise the priority
+		Debug("LOG_THREAD: MsSetThreadPriorityRealtime\n");
+		MsSetThreadPriorityRealtime();
+	}
+
+	if (num < (LOG_ENGINE_SAVE_START_CACHE_COUNT / 2))
+	{
+		// Restore the priority
+		Debug("LOG_THREAD: MsSetThreadPriorityIdle\n");
+		MsSetThreadPriorityIdle();
+	}
+#endif	// OS_WIN32
 
-			if (num < (LOG_ENGINE_SAVE_START_CACHE_COUNT / 2))
+	if (buffer->Size > GetMaxLogSize())
+	{
+		// Erase if the size of the buffer is larger than the maximum log file size
+		ClearBuf(buffer);
+	}
+
+	if (buffer->Size >= LOG_ENGINE_BUFFER_CACHE_SIZE_MAX)
+	{
+		// Write the contents of the buffer to the file
+		if (*io != NULL)
+		{
+			if ((log_object->CurrentFilePointer + (UINT64)buffer->Size) > GetMaxLogSize())
 			{
-				// Restore the priority
-				if (last_priority_flag)
+				if (log_object->log_number_incremented == false)
 				{
-					Debug("LOG_THREAD: MsSetThreadPriorityIdle\n");
-					MsSetThreadPriorityIdle();
-					last_priority_flag = false;
+					log_object->CurrentLogNumber++;
+					log_object->log_number_incremented = true;
 				}
 			}
-#endif	// OS_WIN32
-
-			if (b->Size > GetMaxLogSize())
+			else
 			{
-				// Erase if the size of the buffer is larger than the maximum log file size
-				ClearBuf(b);
+				if (FileWrite(*io, buffer->Buf, buffer->Size) == false)
+				{
+					FileCloseEx(*io, true);
+					// If it fails to write to the file,
+					// erase the buffer and give up
+					ClearBuf(buffer);
+					*io = NULL;
+				}
+				else
+				{
+					log_object->CurrentFilePointer += (UINT64)buffer->Size;
+					ClearBuf(buffer);
+				}
 			}
+		}
+	}
 
-			if (b->Size >= LOG_ENGINE_BUFFER_CACHE_SIZE_MAX)
+	if (rec == NULL)
+	{
+		if (buffer->Size != 0)
+		{
+			// Write the contents of the buffer to the file
+			if (*io != NULL)
 			{
-				// Write the contents of the buffer to the file
-				if (io != NULL)
+				if ((log_object->CurrentFilePointer + (UINT64)buffer->Size) > GetMaxLogSize())
 				{
-					if ((g->CurrentFilePointer + (UINT64)b->Size) > GetMaxLogSize())
+					if (log_object->log_number_incremented == false)
 					{
-						if (g->log_number_incremented == false)
-						{
-							g->CurrentLogNumber++;
-							g->log_number_incremented = true;
-						}
+						log_object->CurrentLogNumber++;
+						log_object->log_number_incremented = true;
+					}
+				}
+				else
+				{
+					if (FileWrite(*io, buffer->Buf, buffer->Size) == false)
+					{
+						FileCloseEx(*io, true);
+						// If it fails to write to the file,
+						// erase the buffer and give up
+						ClearBuf(buffer);
+						*io = NULL;
 					}
 					else
 					{
-						if (FileWrite(io, b->Buf, b->Size) == false)
-						{
-							FileCloseEx(io, true);
-							// If it fails to write to the file,
-							// erase the buffer and give up
-							ClearBuf(b);
-							io = NULL;
-						}
-						else
-						{
-							g->CurrentFilePointer += (UINT64)b->Size;
-							ClearBuf(b);
-						}
+						log_object->CurrentFilePointer += (UINT64)buffer->Size;
+						ClearBuf(buffer);
 					}
 				}
 			}
+		}
 
-			if (rec == NULL)
-			{
-				if (b->Size != 0)
-				{
-					// Write the contents of the buffer to the file
-					if (io != NULL)
-					{
-						if ((g->CurrentFilePointer + (UINT64)b->Size) > GetMaxLogSize())
-						{
-							if (g->log_number_incremented == false)
-							{
-								g->CurrentLogNumber++;
-								g->log_number_incremented = true;
-							}
-						}
-						else
-						{
-							if (FileWrite(io, b->Buf, b->Size) == false)
-							{
-								FileCloseEx(io, true);
-								// If it fails to write to the file,
-								// erase the buffer and give up
-								ClearBuf(b);
-								io = NULL;
-							}
-							else
-							{
-								g->CurrentFilePointer += (UINT64)b->Size;
-								ClearBuf(b);
-							}
-						}
-					}
-				}
+		Set(log_object->FlushEvent);
+		return false;
+	}
 
-				Set(g->FlushEvent);
-				break;
-			}
+	// Generate a log file name
+	LockLog(log_object);
+	{
+		*log_date_changed = MakeLogFileName(log_object, file_name, sizeof(file_name),
+			log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, log_object->CurrentLogNumber, current_logfile_datename);
+
+		if (*log_date_changed)
+		{
+			UINT i;
 
-			// Generate a log file name
-			LockLog(g);
+			log_object->CurrentLogNumber = 0;
+			MakeLogFileName(log_object, file_name, sizeof(file_name),
+				log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, 0, current_logfile_datename);
+			for (i = 0;;i++)
 			{
-				log_date_changed = MakeLogFileName(g, file_name, sizeof(file_name),
-					g->DirName, g->Prefix, rec->Tick, g->SwitchType, g->CurrentLogNumber, current_logfile_datename);
+				char tmp[MAX_SIZE];
+				MakeLogFileName(log_object, tmp, sizeof(tmp),
+					log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, i, current_logfile_datename);
 
-				if (log_date_changed)
+				if (IsFileExists(tmp) == false)
 				{
-					UINT i;
-
-					g->CurrentLogNumber = 0;
-					MakeLogFileName(g, file_name, sizeof(file_name),
-						g->DirName, g->Prefix, rec->Tick, g->SwitchType, 0, current_logfile_datename);
-					for (i = 0;;i++)
-					{
-						char tmp[MAX_SIZE];
-						MakeLogFileName(g, tmp, sizeof(tmp),
-							g->DirName, g->Prefix, rec->Tick, g->SwitchType, i, current_logfile_datename);
-
-						if (IsFileExists(tmp) == false)
-						{
-							break;
-						}
-						StrCpy(file_name, sizeof(file_name), tmp);
-						g->CurrentLogNumber = i;
-					}
+					break;
 				}
+				StrCpy(file_name, sizeof(file_name), tmp);
+				log_object->CurrentLogNumber = i;
 			}
-			UnlockLog(g);
+		}
+	}
+	UnlockLog(log_object);
 
-			if (io != NULL)
+	if (*io != NULL)
+	{
+		if (StrCmp(current_file_name, file_name) != 0)
+		{
+			// If a log file is currently opened and writing to another log
+			// file is needed for this time, write the contents of the 
+			//buffer and close the log file. Write the contents of the buffer
+			if (*io != NULL)
 			{
-				if (StrCmp(current_file_name, file_name) != 0)
+				if (*log_date_changed)
 				{
-					// If a log file is currently opened and writing to another log
-					// file is needed for this time, write the contents of the 
-					//buffer and close the log file. Write the contents of the buffer
-					if (io != NULL)
+					if ((log_object->CurrentFilePointer + (UINT64)buffer->Size) <= GetMaxLogSize())
 					{
-						if (log_date_changed)
+						if (FileWrite(*io, buffer->Buf, buffer->Size) == false)
 						{
-							if ((g->CurrentFilePointer + (UINT64)b->Size) <= GetMaxLogSize())
-							{
-								if (FileWrite(io, b->Buf, b->Size) == false)
-								{
-									FileCloseEx(io, true);
-									ClearBuf(b);
-									io = NULL;
-								}
-								else
-								{
-									g->CurrentFilePointer += (UINT64)b->Size;
-									ClearBuf(b);
-								}
-							}
+							FileCloseEx(*io, true);
+							ClearBuf(buffer);
+							*io = NULL;
 						}
-						// Close the file
-						FileCloseEx(io, true);
-					}
-
-					g->log_number_incremented = false;
-
-					// Open or create a new log file
-					StrCpy(current_file_name, sizeof(current_file_name), file_name);
-					io = FileOpen(file_name, true);
-					if (io == NULL)
-					{
-						// Create a log file
-						LockLog(g);
+						else
 						{
-							MakeDir(g->DirName);
-
-#ifdef	OS_WIN32
-							Win32SetFolderCompress(g->DirName, true);
-#endif	// OS_WIN32
+							log_object->CurrentFilePointer += (UINT64)buffer->Size;
+							ClearBuf(buffer);
 						}
-						UnlockLog(g);
-						io = FileCreate(file_name);
-						g->CurrentFilePointer = 0;
-					}
-					else
-					{
-						// Seek to the end of the log file
-						g->CurrentFilePointer = FileSize64(io);
-						FileSeek(io, SEEK_END, 0);
 					}
 				}
+				// Close the file
+				FileCloseEx(*io, true);
 			}
-			else
+
+			log_object->log_number_incremented = false;
+
+			// Open or create a new log file
+			StrCpy(current_file_name, sizeof(current_file_name), file_name);
+			*io = FileOpen(file_name, true);
+			if (*io == NULL)
 			{
-				// Open or create a new log file
-				StrCpy(current_file_name, sizeof(current_file_name), file_name);
-				io = FileOpen(file_name, true);
-				if (io == NULL)
+				// Create a log file
+				LockLog(log_object);
 				{
-					// Create a log file
-					LockLog(g);
-					{
-						MakeDir(g->DirName);
+					MakeDir(log_object->DirName);
+
 #ifdef	OS_WIN32
-						Win32SetFolderCompress(g->DirName, true);
+					Win32SetFolderCompress(log_object->DirName, true);
 #endif	// OS_WIN32
-					}
-					UnlockLog(g);
-					io = FileCreate(file_name);
-					g->CurrentFilePointer = 0;
-					if (io == NULL)
-					{
-						//Debug("Logging.c: SleepThread(30);\n");
-						SleepThread(30);
-					}
-				}
-				else
-				{
-					// Seek to the end of the log file
-					g->CurrentFilePointer = FileSize64(io);
-					FileSeek(io, SEEK_END, 0);
 				}
-
-				g->log_number_incremented = false;
+				UnlockLog(log_object);
+				*io = FileCreate(file_name);
+				log_object->CurrentFilePointer = 0;
 			}
-
-			// Write the contents of the log to the buffer
-			WriteRecordToBuffer(b, rec);
-
-			// Release the memory of record
-			Free(rec);
-
-			if (io == NULL)
+			else
 			{
-				break;
+				// Seek to the end of the log file
+				log_object->CurrentFilePointer = FileSize64(*io);
+				FileSeek(*io, SEEK_END, 0);
 			}
 		}
-
-		if (g->Halt)
+	}
+	else
+	{
+		// Open or create a new log file
+		StrCpy(current_file_name, sizeof(current_file_name), file_name);
+		*io = FileOpen(file_name, true);
+		if (*io == NULL)
 		{
-			// Break after finishing to save all records
-			// when the stop flag stood
-			UINT num;
-
-			if (flag == false)
+			// Create a log file
+			LockLog(log_object);
 			{
+				MakeDir(log_object->DirName);
 #ifdef	OS_WIN32
-				MsSetThreadPriorityRealtime();
+				Win32SetFolderCompress(log_object->DirName, true);
 #endif	// OS_WIN32
-				flag = true;
-			}
-
-			LockQueue(g->RecordQueue);
-			{
-				num = g->RecordQueue->num_item;
 			}
-			UnlockQueue(g->RecordQueue);
-
-			if (num == 0 || io == NULL)
+			UnlockLog(log_object);
+			*io = FileCreate(file_name);
+			log_object->CurrentFilePointer = 0;
+			if (*io == NULL)
 			{
-				break;
+				//Debug("Logging.c: SleepThread(30);\n");
+				SleepThread(30);
 			}
 		}
 		else
 		{
-			Wait(g->Event, 9821);
+			// Seek to the end of the log file
+			log_object->CurrentFilePointer = FileSize64(*io);
+			FileSeek(*io, SEEK_END, 0);
 		}
+
+		log_object->log_number_incremented = false;
 	}
 
-	if (io != NULL)
+	// Write the contents of the log to the buffer
+	WriteRecordToBuffer(buffer, rec);
+
+	// Release the memory of record
+	Free(rec);
+
+	return (*io != NULL);
+}
+
+static bool LogThreadWriteStdout(LOG *log_object, BUF *buffer, IO *io)
+{
+	RECORD *rec;
+
+	// Retrieve a record from the head of the queue
+	LockQueue(log_object->RecordQueue);
 	{
-		FileCloseEx(io, true);
+		rec = GetNext(log_object->RecordQueue);
 	}
+	UnlockQueue(log_object->RecordQueue);
 
-	FreeBuf(b);
+	if (rec == NULL)
+	{
+		Set(log_object->FlushEvent);
+		return false;
+	}
+
+	ClearBuf(buffer);
+	WriteRecordToBuffer(buffer, rec);
+	if (!FileWrite(io, buffer->Buf, buffer->Size))
+	{
+		ClearBuf(buffer);
+	}
+	Free(rec);
+
+	return true;
+}
+
+static IO *GetIO4Stdout()
+{
+#ifndef UNIX
+	return NULL;
+#else // UNIX
+	static IO IO4Stdout =
+	{
+		.Name = {0},
+		.NameW = {0},
+		.pData = NULL,
+		.WriteMode = true,
+		.HamMode = false,
+		.HamBuf = NULL,
+	};
+
+	if (!g_foreground)
+	{
+		return NULL;
+	}
+
+	IO4Stdout.pData = GetUnixio4Stdout();
+
+	return &IO4Stdout;
+#endif // UNIX
 }
 
 // Write the contents of the log to the buffer

+ 7 - 0
src/Mayaqua/Mayaqua.c

@@ -133,6 +133,7 @@ BOOL kernel_status_inited = false;				// Kernel state initialization flag
 bool g_little_endian = true;
 char *cmdline = NULL;							// Command line
 wchar_t *uni_cmdline = NULL;					// Unicode command line
+bool g_foreground = false;					// Execute service in foreground mode
 
 // Static variable
 static char *exename = NULL;						// EXE file name (ANSI)
@@ -513,6 +514,12 @@ void InitMayaqua(bool memcheck, bool debug, int argc, char **argv)
 		setbuf(stdout, NULL);
 	}
 
+#ifdef OS_UNIX
+	g_foreground = (argc >= 3 && StrCmpi(argv[2], UNIX_SVC_ARG_FOREGROUND) == 0);
+#else
+	g_foreground = false;
+#endif // OS_UNIX
+
 	// Acquisition whether NT
 #ifdef	OS_WIN32
 	is_nt = Win32IsNt();

+ 1 - 0
src/Mayaqua/Mayaqua.h

@@ -395,6 +395,7 @@ extern char *cmdline;
 extern wchar_t *uni_cmdline;
 extern bool g_little_endian;
 extern LOCK *tick_manual_lock;
+extern bool g_foreground;
 
 // Kernel state
 #define	NUM_KERNEL_STATUS	128

+ 23 - 0
src/Mayaqua/Unix.c

@@ -1703,6 +1703,23 @@ void *UnixFileOpen(char *name, bool write_mode, bool read_lock)
 	return (void *)p;
 }
 
+// Get UNIXIO object for stdout
+void* GetUnixio4Stdout()
+{
+	static UNIXIO unixio =
+	{
+		.fd = -1,
+		.write_mode = true
+	};
+
+	if (g_foreground)
+	{
+		unixio.fd = STDOUT_FILENO;
+		return &unixio;
+	}
+	return NULL;
+}
+
 // Return the current thread ID
 UINT UnixThreadId()
 {
@@ -2849,6 +2866,12 @@ RESTART_PROCESS:
 			}
 		}
 	}
+	else if (argc >= 3 && StrCmpi(argv[1], UNIX_SVC_ARG_START) == 0 && StrCmpi(argv[2], UNIX_SVC_ARG_FOREGROUND) == 0)
+	{
+		InitMayaqua(false, false, argc, argv);
+		UnixExecService(name, start, stop);
+		FreeMayaqua();
+	}
 	else
 	{
 		// Start normally

+ 2 - 0
src/Mayaqua/Unix.h

@@ -141,6 +141,7 @@ typedef void (SERVICE_FUNCTION)();
 #define	UNIX_SVC_ARG_STOP				"stop"
 #define	UNIX_SVC_ARG_EXEC_SVC			"execsvc"
 #define	UNIX_ARG_EXIT					"exit"
+#define UNIX_SVC_ARG_FOREGROUND				"--foreground"
 
 #define	UNIX_SVC_MODE_START				1
 #define	UNIX_SVC_MODE_STOP				2
@@ -178,6 +179,7 @@ void *UnixFileOpen(char *name, bool write_mode, bool read_lock);
 void *UnixFileOpenW(wchar_t *name, bool write_mode, bool read_lock);
 void *UnixFileCreate(char *name);
 void *UnixFileCreateW(wchar_t *name);
+void *GetUnixio4Stdout();
 bool UnixFileWrite(void *pData, void *buf, UINT size);
 bool UnixFileRead(void *pData, void *buf, UINT size);
 void UnixFileClose(void *pData, bool no_flush);

+ 1 - 1
src/bin/hamcore/strtable_en.stb

@@ -1072,7 +1072,7 @@ SVC_HIDE_TRAY_MSG		This will hide the tasktray icons when starting %S in user mo
 
 
 # Concerning services (UNIX)
-UNIX_SVC_HELP			%S service program\nCopyright (c) SoftEther VPN Project. All Rights Reserved.\n\n%S command usage:\n %S start  - Start the %S service.\n %S stop   - Stop the %S service if the service has been already started.\n\n
+UNIX_SVC_HELP			%S service program\nCopyright (c) SoftEther VPN Project. All Rights Reserved.\n\n%S command usage:\n %S start [--foreground] - Start the %S service. '--foreground' parameter prevents switching to daemon mode.\n %S stop   - Stop the %S service if the service has been already started.\n\n
 UNIX_SVC_STARTED		The %S service has been started.\n
 UNIX_SVC_STOPPING		Stopping the %S service ...\n
 UNIX_SVC_STOPPED		%S service has been stopped.\n