From e24a2f544d331a27e1f3b7290723dcde24bd9342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=BA=E8=83=BD=E5=A4=A7=E7=9F=B3=E5=A4=B4?= Date: Tue, 17 Oct 2023 00:06:34 +0800 Subject: [PATCH] =?UTF-8?q?[fix]=20init.d=E7=9B=AE=E5=BD=95=E4=B8=AD?= =?UTF-8?q?=E7=9A=84rcS=E4=BC=9A=E6=89=AB=E6=8F=8F=E5=BD=93=E5=89=8D?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E6=89=80=E6=9C=89S=E5=BC=80=E5=A4=B4?= =?UTF-8?q?=E7=9A=84=E6=96=87=E4=BB=B6=E5=B9=B6=E6=89=A7=E8=A1=8C=EF=BC=8C?= =?UTF-8?q?=E5=88=9A=E5=A5=BDStarAgent=E5=91=BD=E4=B8=AD=EF=BC=8CS50StarAg?= =?UTF-8?q?ent=E4=B9=9F=E5=91=BD=E4=B8=AD=EF=BC=8C=E9=80=A0=E6=88=90?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=89=A7=E8=A1=8C=E3=80=82close:=20https://g?= =?UTF-8?q?ithub.com/NewLifeX/NewLife.Agent/issues/11?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NewLife.Agent/RcInit.cs | 88 +++++++++++++++++++++++++++++------- NewLife.Agent/ServiceBase.cs | 3 -- 2 files changed, 72 insertions(+), 19 deletions(-) diff --git a/NewLife.Agent/RcInit.cs b/NewLife.Agent/RcInit.cs index bdba81f..ad542b2 100644 --- a/NewLife.Agent/RcInit.cs +++ b/NewLife.Agent/RcInit.cs @@ -72,7 +72,8 @@ public override void Run(ServiceBase service) /// public override Boolean IsInstalled(String serviceName) { - var file = _path.CombinePath($"{serviceName}"); + //var file = _path.CombinePath($"{serviceName}"); + var file = $"{serviceName}.sh".GetFullPath(); return File.Exists(file); } @@ -114,7 +115,8 @@ public static Boolean Install(String systemdPath, String serviceName, String fil { XTrace.WriteLine("{0}.Install {1}, {2}, {3}, {4}", typeof(RcInit).Name, serviceName, displayName, fileName, arguments, description); - var file = systemdPath.CombinePath($"{serviceName}"); + //var file = systemdPath.CombinePath($"{serviceName}"); + var file = $"{serviceName}.sh".GetFullPath(); XTrace.WriteLine(file); var des = !displayName.IsNullOrEmpty() ? displayName : description; @@ -125,11 +127,29 @@ public static Boolean Install(String systemdPath, String serviceName, String fil sb.AppendLine($"# description: {des}"); sb.AppendLine(); - sb.AppendLine($"cd {".".GetFullPath()}"); - sb.AppendLine($"nohup {fileName} {arguments} >/dev/null 2>&1 &"); - sb.AppendLine($"exit 0"); + //sb.AppendLine($"cd {".".GetFullPath()}"); + sb.AppendLine("case \"$1\" in"); + sb.AppendLine(" start)"); + sb.AppendLine($" nohup {fileName} {arguments} >/dev/null 2>&1 &"); + sb.AppendLine(" ;;"); + sb.AppendLine(" stop)"); + sb.AppendLine($" {fileName} {arguments.TrimEnd("-s")} -stop"); + sb.AppendLine(" ;;"); + sb.AppendLine(" restart)"); + sb.AppendLine($" $0 stop"); + sb.AppendLine($" $0 start"); + sb.AppendLine(" ;;"); + sb.AppendLine(" *)"); + sb.AppendLine(" echo \"Usage: $0 {start|stop|restart}\""); + sb.AppendLine(" exit 1"); + sb.AppendLine("esac"); + sb.AppendLine(); + sb.AppendLine($"exit $?"); //File.WriteAllText(file, sb.ToString()); + //File.WriteAllBytes(file, sb.ToString().GetBytes()); + + //!! init.d目录中的rcS会扫描当前目录所有S开头的文件并执行,刚好StarAgent命中,S50StarAgent也命中,造成重复执行 File.WriteAllBytes(file, sb.ToString().GetBytes()); // 给予可执行权限 @@ -144,9 +164,9 @@ public static Boolean Install(String systemdPath, String serviceName, String fil if (Directory.Exists(dir)) { if (i is 0 or 1 or 6) - Process.Start("ln", $"-s {systemdPath}/{serviceName} {dir}K90{serviceName}"); + CreateLink(file, $" {dir}K50{serviceName}"); else - Process.Start("ln", $"-s {systemdPath}/{serviceName} {dir}S10{serviceName}"); + CreateLink(file, $" {dir}S50{serviceName}"); flag = true; } @@ -156,22 +176,35 @@ public static Boolean Install(String systemdPath, String serviceName, String fil var dir = "/etc/rc.d/"; if (Directory.Exists(dir)) { - Process.Start("ln", $"-s {systemdPath}/{serviceName} {dir}S50{serviceName}"); + CreateLink(file, $"{dir}S50{serviceName}"); flag = true; } } // init.d 目录存在其它Sxx文件时,才创建同级链接文件 - if (!flag && systemdPath.AsDirectory().GetFiles().Any(e => e.Name.StartsWith("S"))) + if (!flag) { // 创建同级链接文件 [解决某些linux启动必须以Sxx开头的启动文件] - Process.Start("ln", $"-s {systemdPath}/{serviceName} {systemdPath}/S50{serviceName}"); + var fis = systemdPath.AsDirectory().GetFiles(); + if (fis.Any(e => e.Name[0] == 'S')) + { + CreateLink(file, $"{systemdPath}/S50{serviceName}"); + //if (fis.Any(e => e.Name[0] == 'K')) + CreateLink(file, $"{systemdPath}/K50{serviceName}"); + } } return true; } + static void CreateLink(String source, String target) + { + if (File.Exists(target)) File.Delete(target); + + Process.Start("ln", $"-s {source} {target}"); + } + /// 卸载服务 /// 服务名 /// @@ -179,12 +212,15 @@ public override Boolean Remove(String serviceName) { XTrace.WriteLine("{0}.Remove {1}", GetType().Name, serviceName); - var file = _path.CombinePath($"{serviceName}"); + //var file = _path.CombinePath($"{serviceName}"); + var file = $"{serviceName}.sh".GetFullPath(); if (File.Exists(file)) File.Delete(file); // 删除同级链接文件 file = _path.CombinePath($"S50{serviceName}"); if (File.Exists(file)) File.Delete(file); + file = _path.CombinePath($"K50{serviceName}"); + if (File.Exists(file)) File.Delete(file); // 删除链接文件 for (var i = 0; i < 7; i++) @@ -192,10 +228,10 @@ public override Boolean Remove(String serviceName) var dir = $"/etc/rc{i}.d/"; if (Directory.Exists(dir)) { - file = $"{dir}S10{serviceName}"; + file = $"{dir}S50{serviceName}"; if (File.Exists(file)) File.Delete(file); - file = $"{dir}K90{serviceName}"; + file = $"{dir}K50{serviceName}"; if (File.Exists(file)) File.Delete(file); } } @@ -219,8 +255,22 @@ public override Boolean Start(String serviceName) { XTrace.WriteLine("{0}.Start {1}", GetType().Name, serviceName); - var file = _path.CombinePath($"{serviceName}"); - Process.Start("bash", file); + // 判断服务是否已启动 + var id = 0; + var pid = $"{serviceName}.pid".GetFullPath(); + if (File.Exists(pid)) id = File.ReadAllText(pid).Trim().ToInt(); + if (id > 0) + { + var p = Process.GetProcessById(id); + if (p != null && !p.HasExited) return false; + } + + //var file = _path.CombinePath($"{serviceName}"); + var file = $"{serviceName}.sh".GetFullPath(); + if (!File.Exists(file)) return false; + + //Process.Start("bash", file); + file.ShellExecute("start"); //// 用pid文件记录进程id,方便后面杀进程 //var pid = $"{serviceName}.pid".GetFullPath(); @@ -247,7 +297,13 @@ public override Boolean Stop(String serviceName) try { - p.Kill(); + // 发命令让服务自己退出 + "kill".ShellExecute($"{id}"); + + var n = 30; + while (!p.HasExited && n-- > 0) Thread.Sleep(100); + + if (!p.HasExited) p.Kill(); File.Delete(pid); diff --git a/NewLife.Agent/ServiceBase.cs b/NewLife.Agent/ServiceBase.cs index ec2b059..28565e6 100644 --- a/NewLife.Agent/ServiceBase.cs +++ b/NewLife.Agent/ServiceBase.cs @@ -1,10 +1,7 @@ using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; using System.Security; -using System.Security.Principal; using NewLife.Log; using NewLife.Reflection;