pidl:Wireshark Fix the type of array of pointerse to hf_ values
[Samba.git] / python / samba / netcmd / processes.py
blob12a05a69329c46b57e65ae94a18415fdfe883b66
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.
27 import samba
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
43 takes_options = [
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"),
50 takes_args = []
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()
67 filtered = []
68 masters = {}
69 workers = {}
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"
78 instance = int(ns[3])
79 pid = service.ids[0].pid
80 if name not in workers:
81 workers[name] = {}
82 workers[name][instance] = (instance, pid)
83 else:
84 filtered.append(service)
85 return (filtered, masters, workers)
87 def run(self, sambaopts, versionopts, section_name=None,
88 name=None, pid=None):
90 lp = sambaopts.get_loadparm()
91 logger = self.get_logger("processes")
93 msg_ctx = Messaging()
95 if name is not None:
96 try:
97 ids = msg_ctx.irpc_servers_byname(name)
98 except KeyError:
99 ids = []
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()
105 for name in names:
106 for server_id in name.ids:
107 if server_id.pid == int(pid):
108 self.outf.write("%s\n" % name.name)
109 else:
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
124 # worker processes
125 pid = masters[service.name]
126 if pid not in prefork:
127 prefork[pid] = True
128 self.outf.write("%-26s %6d\n" %
129 (service.name, pid))
130 if service.name in workers:
131 ws = workers[service.name]
132 for w in ws:
133 (instance, pid) = ws[w]
134 sn = "{0}(worker {1})".format(
135 service.name, instance)
136 self.outf.write("%-26s %6d\n" % (sn, pid))
137 else:
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