1 # Unix SMB/CIFS implementation.
2 # List processes (to aid debugging on systems without setproctitle)
3 # Copyright (C) 2010-2011 Jelmer Vernooij <jelmer@samba.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Testbed for loadparm.c/params.c
20 # This module simply loads a specified configuration file and
21 # if successful, dumps it's contents to stdout. Note that the
22 # operation is performed with DEBUGLEVEL at 3.
24 # Useful for a quick 'syntax check' of a configuration file.
28 import samba
.getopt
as options
29 from samba
.netcmd
import Command
, CommandError
, Option
30 from samba
.messaging
import Messaging
33 class cmd_processes(Command
):
34 """List processes (to aid debugging on systems without setproctitle)."""
36 synopsis
= "%prog [options]"
38 takes_optiongroups
= {
39 "sambaopts": options
.SambaOptions
,
40 "versionopts": options
.VersionOptions
44 Option("--name", type=str,
45 help="Return only processes associated with one particular name"),
46 Option("--pid", type=int,
47 help="Return only names associated with one particular PID"),
53 # Get details of the samba services currently registered in irpc
54 # The prefork process model registers names in the form:
55 # prefork-master-<service> and prefork-worker-<service>-<instance>
57 # To allow this routine to identify pre-fork master and worker process
59 # returns a tuple (filtered, masters, workers)
61 # filtered - is a list of services with the prefork-* removed
62 # masters - dictionary keyed on service name of prefork master processes
63 # workers - dictionary keyed on service name containing an ordered list
64 # of worker processes.
65 def get_service_data(self
, msg_ctx
):
66 services
= msg_ctx
.irpc_all_servers()
70 for service
in services
:
71 if service
.name
.startswith("prefork-master"):
72 ns
= service
.name
.split("-")
73 name
= ns
[2] + "_server"
74 masters
[name
] = service
.ids
[0].pid
75 elif service
.name
.startswith("prefork-worker"):
76 ns
= service
.name
.split("-")
77 name
= ns
[2] + "_server"
79 pid
= service
.ids
[0].pid
80 if name
not in workers
:
82 workers
[name
][instance
] = (instance
, pid
)
84 filtered
.append(service
)
85 return (filtered
, masters
, workers
)
87 def run(self
, sambaopts
, versionopts
, section_name
=None,
90 lp
= sambaopts
.get_loadparm()
91 logger
= self
.get_logger("processes")
97 ids
= msg_ctx
.irpc_servers_byname(name
)
101 for server_id
in ids
:
102 self
.outf
.write("%d\n" % server_id
.pid
)
103 elif pid
is not None:
104 names
= msg_ctx
.irpc_all_servers()
106 for server_id
in name
.ids
:
107 if server_id
.pid
== int(pid
):
108 self
.outf
.write("%s\n" % name
.name
)
110 seen
= {} # Service entries already printed, service names can
111 # be registered multiple times against a process
112 # but we should only display them once.
113 prefork
= {} # Services running in the prefork process model
114 # want to ensure that the master process and workers
115 # are grouped to together.
116 (services
, masters
, workers
) = self
.get_service_data(msg_ctx
)
117 self
.outf
.write(" Service: PID\n")
118 self
.outf
.write("--------------------------------------\n")
120 for service
in sorted(services
, key
=lambda x
: x
.name
):
121 if service
.name
in masters
:
122 # If this service is running in a pre-forked process we
123 # want to print the master process followed by all the
125 pid
= masters
[service
.name
]
126 if pid
not in prefork
:
128 self
.outf
.write("%-26s %6d\n" %
130 if service
.name
in workers
:
131 ws
= workers
[service
.name
]
133 (instance
, pid
) = ws
[w
]
134 sn
= "{0}(worker {1})".format(
135 service
.name
, instance
)
136 self
.outf
.write("%-26s %6d\n" % (sn
, pid
))
138 for server_id
in service
.ids
:
139 if (service
.name
, server_id
.pid
) not in seen
:
140 self
.outf
.write("%-26s %6d\n"
141 % (service
.name
, server_id
.pid
))
142 seen
[(service
.name
, server_id
.pid
)] = True