1 /*
2 Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "ndb_global.h"
26 #include "ProcessInfo.hpp"
27 #include "OwnProcessInfo.hpp"
28 #include <NdbMutex.h>
29
30 const char * ndb_basename(const char *path);
31
32 extern const char * my_progname;
33
34 /* Static storage; constructor called at process startup by C++ runtime. */
35 ProcessInfo singletonInfo;
36 NdbLockable theApiMutex;
37
38 /* Public API
39 *
40 */
setOwnProcessInfoAngelPid(Uint32 pid)41 void setOwnProcessInfoAngelPid(Uint32 pid)
42 {
43 theApiMutex.lock();
44 singletonInfo.setAngelPid(pid);
45 theApiMutex.unlock();
46 }
47
setOwnProcessInfoServerAddress(struct in_addr * addr)48 void setOwnProcessInfoServerAddress(struct in_addr * addr)
49 {
50 theApiMutex.lock();
51 singletonInfo.setHostAddress(addr);
52 theApiMutex.unlock();
53 }
54
setOwnProcessInfoPort(Uint16 port)55 void setOwnProcessInfoPort(Uint16 port)
56 {
57 theApiMutex.lock();
58 singletonInfo.setPort(port);
59 theApiMutex.unlock();
60 }
61
62
63 /* Fill in missing parts of ProcessInfo before providing it to QMgr
64 or ClusterMgr
65 */
66
67 #ifdef WIN32
68 #include "psapi.h"
69
getNameFromEnvironment()70 void getNameFromEnvironment()
71 {
72 HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
73 FALSE, singletonInfo.getPid());
74 GetModuleFileNameEx(handle, 0, singletonInfo.process_name,
75 singletonInfo.ProcessNameLength);
76 }
77 #else
getNameFromEnvironment()78 void getNameFromEnvironment()
79 {
80 const char * path = getenv("_");
81 if(path)
82 {
83 singletonInfo.setProcessName(ndb_basename(path));
84 }
85 }
86 #endif
87
88
89 /* Return angel pid, or zero if no angel.
90 On unix, if we are not a daemon, and also not a process group leader,
91 set parent pid as angel pid.
92 On Windows, return MYSQLD_PARENT_PID if set in the environment.
93 */
getParentPidAsAngel()94 static Uint32 getParentPidAsAngel()
95 {
96 #ifdef WIN32
97 const char * monitor_pid = getenv("MYSQLD_PARENT_PID");
98 if(monitor_pid)
99 {
100 return atoi(monitor_pid);
101 }
102 #else
103 pid_t parent_process_id = getppid();
104 if((parent_process_id != 1) && (getpgrp() != singletonInfo.getPid()))
105 {
106 return parent_process_id;
107 }
108 #endif
109 return 0;
110 }
111
112
113 /* Public API for QMgr and ClusterMgr.
114 */
getOwnProcessInfo(Uint16 nodeId)115 ProcessInfo * getOwnProcessInfo(Uint16 nodeId) {
116 Guard locked(theApiMutex);
117 if(singletonInfo.process_id == 0)
118 {
119 /* Finalize */
120 singletonInfo.setPid();
121 singletonInfo.node_id = nodeId;
122 if(singletonInfo.angel_process_id == 0)
123 singletonInfo.angel_process_id = getParentPidAsAngel();
124 if(singletonInfo.process_name[0] == 0)
125 {
126 if(my_progname)
127 singletonInfo.setProcessName(ndb_basename(my_progname));
128 else
129 getNameFromEnvironment();
130 }
131 }
132
133 return & singletonInfo;
134 }
135