From: Gary Lockyer Date: Thu, 13 Sep 2018 21:38:56 +0000 (+1200) Subject: samba-tool processes: display pre-fork masters and workers X-Git-Tag: tdb-1.3.17~648 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2db38370e3f6f4c91e87c8c469f3b3c59c0f3a68;p=thirdparty%2Fsamba.git samba-tool processes: display pre-fork masters and workers Tag prefork work processes with "(worker 0)", and sort the process list on server name to get a consistent order. Service: PID -------------------------------------- cldap_server 15588 ... ldap_server 15584 ldap_server(worker 0) 15627 ldap_server(worker 1) 15630 ldap_server(worker 2) 15632 ldap_server(worker 3) 15634 nbt_server 15576 notify-daemon 15638 ... samba 0 ... wrepl_server 15580 Signed-off-by: Gary Lockyer Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/netcmd/processes.py b/python/samba/netcmd/processes.py index d04a548abd7..0406b1859ca 100644 --- a/python/samba/netcmd/processes.py +++ b/python/samba/netcmd/processes.py @@ -49,6 +49,42 @@ class cmd_processes(Command): takes_args = [] + # + # Get details of the samba services currently registered in irpc + # The prefork process model registers names in the form: + # prefork-master- and prefork-worker-- + # + # To allow this routine to identify pre-fork master and worker process + # + # returns a tuple (filtered, masters, workers) + # + # filtered - is a list of services with the prefork-* removed + # masters - dictionary keyed on service name of prefork master processes + # workers - dictionary keyed on service name containing an ordered list + # of worker processes. + def get_service_data(self, msg_ctx): + services = msg_ctx.irpc_all_servers() + filtered = [] + masters = {} + workers = {} + for service in services: + for id in service.ids: + if service.name.startswith("prefork-master"): + ns = service.name.split("-") + name = ns[2] + "_server" + masters[name] = service.ids[0].pid + elif service.name.startswith("prefork-worker"): + ns = service.name.split("-") + name = ns[2] + "_server" + instance = int(ns[3]) + pid = service.ids[0].pid + if name not in workers: + workers[name] = {} + workers[name][instance] = (instance, pid) + else: + filtered.append(service) + return (filtered, masters, workers) + def run(self, sambaopts, versionopts, section_name=None, name=None, pid=None): @@ -72,9 +108,36 @@ class cmd_processes(Command): if server_id.pid == int(pid): self.outf.write("%s\n" % name.name) else: - names = msg_ctx.irpc_all_servers() - self.outf.write(" Service: PID \n") - self.outf.write("-----------------------------\n") - for name in names: - for server_id in name.ids: - self.outf.write("%-16s %6d\n" % (name.name, server_id.pid)) + seen = {} # Service entries already printed, service names can + # be registered multiple times against a process + # but we should only display them once. + prefork = {} # Services running in the prefork process model + # want to ensure that the master process and workers + # are grouped to together. + (services, masters, workers) = self.get_service_data(msg_ctx) + self.outf.write(" Service: PID\n") + self.outf.write("--------------------------------------\n") + + for service in sorted(services, key=lambda x: x.name): + if service.name in masters: + # If this service is running in a pre-forked process we + # want to print the master process followed by all the + # worker processes + pid = masters[service.name] + if pid not in prefork: + prefork[pid] = True + self.outf.write("%-26s %6d\n" % + (service.name, pid)) + if service.name in workers: + ws = workers[service.name] + for w in ws: + (instance, pid) = ws[w] + sn = "{0}(worker {1})".format( + service.name, instance) + self.outf.write("%-26s %6d\n" % (sn, pid)) + else: + for server_id in service.ids: + if (service.name, server_id.pid) not in seen: + self.outf.write("%-26s %6d\n" + % (service.name, server_id.pid)) + seen[(service.name, server_id.pid)] = True