{"id":12352,"date":"2019-04-13T12:00:41","date_gmt":"2019-04-13T10:00:41","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/"},"modified":"2025-10-24T09:32:15","modified_gmt":"2025-10-24T07:32:15","slug":"how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/","title":{"rendered":"How to stop Documentum processes in a docker container, and more (part I)"},"content":{"rendered":"<p>Ideally, but not mandatorily, the management of Documentum processes is performed at the service level, e.g. by systemd. In my blog <a title=\"systemd configurations for Documentum\" href=\"https:\/\/www.dbi-services.com\/blog\/systemd-configurations-for-documentum\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>, I showed how to configure init files for Documentum under systemd. But containers don&#8217;t have systemd, yet. They just run processes, often only one, sometimes more if they are closely related together (e.g. the docbroker, the method server and the content servers), so how to replicate the same functionality with containers ?<br \/>\nThe topic of stopping processes in a docker container is abundantly discussed on-line (see for example the excellent article <a title=\"Gracefully Stopping Docker Containers\" href=\"https:\/\/www.ctl.io\/developers\/blog\/post\/gracefully-stopping-docker-containers\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a>). O\/S signals are the magic solution so much so that I should have entitled this blog &#8220;Fun with the Signals&#8221; really !<br \/>\nI&#8217;ll simply see here if the presented approach can be applied in the particular case of a dockerized Documentum server. However, in order to keep things simple and quick, I won&#8217;t test such a real dockerized Documentum installation but rather use a script to simulate the Documentum processes, or any other processes at that since it is so generic.<br \/>\nBut first, why bother with this matter ? During all the years that I have been administrating repositories I&#8217;ve never noticed anything going wrong after restarting a suddenly stopped server, be it after an intentional kill, a pesky crash or an unplanned database unavailability. Evidently, the content server (CS henceforth) seems quite robust in this respect. Or maybe we were simply lucky so far. Personally, I don&#8217;t feel confident if I don&#8217;t shut down cleanly a process or service that must be stopped; some data might be still buffered in the CS&#8217; memory and not flushing them properly might introduce inconsistencies or even corruptions. The same goes when an unsuspected multi-step operation is started and aborted abruptly in the middle; ideally, transactions, if they are used, exist for this purpose but anything can go wrong during rollback. Killing a process is like slamming a door, it produces a lot of noise, vibrations in the walls, even damages in the long run and always leaves a bad impression behind. Isn&#8217;t it more comforting to clean up and shut the door gently ? Even then something can go wrong but at least it will be through no fault of our own.<\/p>\n<h2>A few Reminders<\/h2>\n<p>When a &#8220;docker container stop&#8221; is issued, docker sends the SIGTERM signal to the process with PID == 1 running inside the container. That process, if programmed to do so, can then react to the signal and do anything seen fit, typically shutting the running processes down cleanly. After a 10 seconds grace period, the container is stopped manu militari. In the case of Documentum processes, to put it politely, they don&#8217;t give a hoot to signals, except of course to the well-known, unceremonious SIGKILL one. Thus, a proxy process must be introduced which will accept the signal and invoke the proper shutdown scripts to stop the CS processes, usually the dm_shutdown_* and dm_stop_* scripts, or a generic one that takes care of everything, at start up and at shut down time.<br \/>\nSaid proxy must run with PID == 1 i.e. it must be the first one started in the container. Sort of, but even if it is not the very first, its PID 1 parent can pass it the control by using one of the exec() family functions; unlike forking a process, those in effect allow a child process to replace its parent under the latter&#8217;s PID, kind of like in the Matrix movies the agents Smith inject themselves into someone else&#8217;s persona, if you will ;-). The main thing being that at one point the proxy becomes PID 1. Luckily for us, we don&#8217;t have to bother with this complexity for the dockerfile&#8217;s ENTRYPOINT[] clause takes care of everything.<br \/>\nThe proxy also will be the one that starts the CS. In addition, since it must wait for the SIGTERM signal, it must never exit. It can indefinitely wait listening on a fake input (e.g. tail -f \/dev\/null), or wait for an illusory input in a detached container (e.g. while true; do read; done) or, better yet, do something useful like some light-weight monitoring.<br \/>\nWhile at it, the proxy process can listen to several conventional signals and react accordingly. For instance, a SIGUSR1 could mean &#8220;give me a docbroker docbase map&#8221; and a SIGUSR2 &#8220;restart the method server&#8221;. Admittedly, these actions could be done directly by just executing the relevant commands inside the container or from the outside command-line but the signal way is cheaper and, OK, funnier. So, let&#8217;s see how we can set all this up !<\/p>\n<h2>The implementation<\/h2>\n<p>As said, in order to focus on our topic, i.e. signal trapping, we&#8217;ve replaced the CS part with a simple simulation script, dctm.sh, that starts, stops and queries the status of dummy processes. It uses the bash shell and has been written under linux.  Here it is:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [17,18,19,20,21,22]\">\n#!\/bin\/bash\n# launches in the background, or stops or queries the status of, a command with a conventional identification string in the prompt;\n# the id is a random number determined during the start;\n# it should be passed to enquiry the status of the started process or to stop it;\n# Usage:\n#   .\/dctm.sh stop  | start | status \n# e.g.:\n# $ .\/dctm.sh start\n# | process started with pid 13562 and random value 33699963\n# $ psg 33699963\n# | docker   13562     1  0 23:39 pts\/0    00:00:00 I am number 33699963\n# $ .\/dctm.sh status 33699963\n# $ .\/dctm.sh stop 33699963\n#\n# cec - dbi-services - April 2019\n#\ntrap 'help'         SIGURG\ntrap 'start_all'    SIGPWR\ntrap 'start_one'    SIGUSR1\ntrap 'status_all'   SIGUSR2\ntrap 'stop_all'     SIGINT SIGABRT\ntrap 'shutdown_all' SIGHUP SIGQUIT SIGTERM\n\nverb=\"sleep\"\nexport id_prefix=\"I am number\"\n\nfunc() {\n   cmd=\"$1\"\n   case $cmd in\n      start)\n         # do something that sticks forever-ish, min ca. 20mn;\n         (( params = 1111 * $RANDOM ))\n         exec -a \"$id_prefix\" $verb $params &amp;\n         echo \"process started with pid $! and random value $params\"\n         ;;\n      stop)\n         params=\" $2\"\n         pid=$(ps -ajxf | gawk -v params=\"$params\" '{if (match($0, \" \" ENVIRON[\"id_prefix\"] params \"$\")) pid = $2} END {print (pid ? pid : \"\")}')\n         if [[ ! -z $pid ]]; then\n            kill -9 ${pid} &amp;&gt; \/dev\/null\n            wait ${pid} &amp;&gt; \/dev\/null\n         fi\n         ;;\n      status)\n         params=\" $2\"\n         read pid gid &lt; &lt;(ps -ajxf | gawk -v params=&quot;$params&quot; &#039;{if (match($0, &quot; &quot; ENVIRON[&quot;id_prefix&quot;] params &quot;$&quot;)) pid = $2 &quot; &quot; $3} END {print (pid ? pid : &quot;&quot;)}&#039;)\n         if [[ ! -z $pid ]]; then\n            echo &quot;random value${params} is used by process with pid $pid and pgid $gid&quot;\n         else\n            echo &quot;no such process running&quot;\n         fi\n         ;;\n   esac\n}\n\nhelp() {\n   echo\n   echo &quot;send signal SIGURG for help&quot;\n   echo &quot;send signal SIGPWR to start a few processes&quot;\n   echo &quot;send signal SIGUSR1 to start a new process&quot;\n   echo &quot;send signal SIGUSR2 for the list of started processes&quot;\n   echo &quot;send signal SIGINT | SIGABRT  to stop all the processes&quot;\n   echo &quot;send signal SIGHUP | SIGQUIT | SIGTERM to shutdown the processes and exit the container&quot;\n}\n\nstart_all() {\n   echo; echo \"starting a few processes at $(date +\"%Y\/%m\/%d %H:%M:%S\")\"\n   for loop in $(seq 5); do\n      func start\n   done\n\n   # show them;\n   echo; echo &quot;started processes&quot;\n   ps -ajxf | grep &quot;$id_prefix&quot; | grep -v grep\n}\n\nstart_one() {\n   echo; echo \"starting a new process at $(date +\"%Y\/%m\/%d %H:%M:%S\")\"\n   func start\n}\n\nstatus_all() {\n   echo; echo \"status of running processes at $(date +\"%Y\/%m\/%d %H:%M:%S\")\"\n   for no in $(ps -ef | grep &quot;I am number &quot; | grep -v grep | gawk &#039;{print $NF}&#039;); do\n      echo &quot;showing $no&quot;\n      func status $no\n   done\n}\n\nstop_all() {\n   echo; echo \"shutting down the processes at $(date +\"%Y\/%m\/%d %H:%M:%S\")\"\n   for no in $(ps -ef | grep &quot;I am number &quot; | grep -v grep | gawk &#039;{print $NF}&#039;); do\n      echo &quot;stopping $no&quot;\n      func stop $no\n   done\n}\n\nshutdown_all() {\n   echo; echo \"shutting down the container at $(date +\"%Y\/%m\/%d %H:%M:%S\")\"\n   stop_all\n   exit 0\n}\n\n# -----------\n# main;\n# -----------\n\n# starts a few dummy processes;\nstart_all\n\n# display some usage explanation;\nhelp\n\n# make sure the container stays up and waits for signals;\nwhile true; do read; done\n<\/pre>\n<p>The main part of the script starts a few processes, displays a help screen and then waits for input from stdin.<br \/>\nThe script can be first tested outside a container as follows.<br \/>\nRun the script:<br \/>\n<code><br \/>\n.\/dctm.sh<br \/>\n<\/code><br \/>\nIt will start a few easily distinguishable processes and display a help screen:<br \/>\n<code><br \/>\nstarting a few processes at 2019\/04\/06 16:05:35<br \/>\nprocess started with pid 17621 and random value 19580264<br \/>\nprocess started with pid 17622 and random value 19094757<br \/>\nprocess started with pid 17623 and random value 18211512<br \/>\nprocess started with pid 17624 and random value 3680743<br \/>\nprocess started with pid 17625 and random value 18198180<br \/>\n&nbsp;<br \/>\nstarted processes<br \/>\n17619 17621 17619  1994 pts\/0    17619 S+    1000   0:00  |       _ I am number 19580264<br \/>\n17619 17622 17619  1994 pts\/0    17619 S+    1000   0:00  |       _ I am number 19094757<br \/>\n17619 17623 17619  1994 pts\/0    17619 S+    1000   0:00  |       _ I am number 18211512<br \/>\n17619 17624 17619  1994 pts\/0    17619 S+    1000   0:00  |       _ I am number 3680743<br \/>\n17619 17625 17619  1994 pts\/0    17619 S+    1000   0:00  |       _ I am number 18198180<br \/>\n&nbsp;<br \/>\nsend signal SIGURG for help<br \/>\nsend signal SIGPWR to start a few processes<br \/>\nsend signal SIGUSR1 to start a new process<br \/>\nsend signal SIGUSR2 for the list of started processes<br \/>\nsend signal SIGINT | SIGABRT to stop all the processes<br \/>\nsend signal SIGHUP | SIGQUIT | SIGTERM to shutdown the processes and exit the container<br \/>\n<\/code><br \/>\nThen, it will simply sit there and wait until it is asked to quit.<br \/>\nFrom another terminal, let&#8217;s check the started processes:<br \/>\n<code><br \/>\nps -ef | grep \"I am number \" | grep -v grep<br \/>\ndocker   17621 17619  0 14:40 pts\/0    00:00:00 I am number 19580264<br \/>\ndocker   17622 17619  0 14:40 pts\/0    00:00:00 I am number 19094757<br \/>\ndocker   17623 17619  0 14:40 pts\/0    00:00:00 I am number 18211512<br \/>\ndocker   17624 17619  0 14:40 pts\/0    00:00:00 I am number 3680743<br \/>\ndocker   17625 17619  0 14:40 pts\/0    00:00:00 I am number 18198180<br \/>\n<\/code><br \/>\nThose processes could be Documentum ones or anything else, the point here is to control them from the outside, e.g. another terminal session, in or out of a docker container. We will do that though O\/S signals. The bash shell lets a script listen and react to signals through the trap command. On top of the script, we have listed all the signals we&#8217;d like the script to react upon:<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: []\">\ntrap 'help'         SIGURG\ntrap 'start_all'    SIGPWR\ntrap 'start_one'    SIGUSR1\ntrap 'status_all'   SIGUSR2\ntrap 'stop_all'     SIGINT SIGABRT\ntrap 'shutdown_all' SIGHUP SIGQUIT SIGTERM\n<\/pre>\n<p>It&#8217;s really a feast of traps !<br \/>\nThe first line for example says that on receiving the SIGURG signal, the script&#8217;s function help() should be executed, no matter what the script was doing at that time, which in our case is just waiting for input from stdin.<br \/>\nThe SIGPWR signal is interpreted as start in the background another suite of five processes with the same naming convention &#8220;I am number &#8221; followed with a random number. The function start_all() is called on receiving this signal.<br \/>\nThe SIGUSR1 signal starts one new process in the background. Function start_one() does just this.<br \/>\nThe SIGUSR2 signal displays all the started processes so far by invoking function status_all().<br \/>\nThe SIGINT and SIGABRT signals shut down all the started processes so far. Function stop_all() is called to this purpose.<br \/>\nFinally, signals SIGHUP, SIGQUIT, or SIGTERM all invokes function shutdown_all() to stop all the processes and exit the script.<br \/>\nAdmittedly, those signal&#8217;s choice is a bit stretched out but this is for the sake of the demonstration so bear with us. Feel free to remap the signals to the functions any way you prefer.<br \/>\nNow, how to send those signals ? The ill-named kill command or program is here for this. Despite its name, nobody will be killed here fortunately; signals will be sent and processes decide to react opportunely. Here, of course, we do react opportunely.<br \/>\nHere is its syntax (let&#8217;s use the &minus;&minus;long-options for clarity):<br \/>\n<code><br \/>\n\/bin\/kill --signal <em>pid<\/em><br \/>\n<\/code><br \/>\nSince bash has a built-in kill command that behaves differently, make sure to call the right program by specifying  its full path name, \/bin\/kill.<br \/>\nExample of use:<br \/>\n<code><br \/>\n\/bin\/kill --signal SIGURG $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n# or shorter:<br \/>\n\/bin\/kill --signal SIGURG $(pgrep ^dctm.sh$)<br \/>\n<\/code><br \/>\nThe signal&#8217;s target is our test program dctm.sh, which is identified vis a vis kill through its PID.<br \/>\nSignals can be specified by their full name, e.g. SIGURG, SIGPWR, etc&#8230; or without the SIG prefix such as URG, PWR, etc &#8230; or even through their numeric value as shown below:<br \/>\n<code><br \/>\n<strong>\/bin\/kill -L<\/strong><br \/>\n 1 HUP      2 INT      3 QUIT     4 ILL      5 TRAP     6 ABRT     7 BUS<br \/>\n 8 FPE      9 KILL    10 USR1    11 SEGV    12 USR2    13 PIPE    14 ALRM<br \/>\n15 TERM    16 STKFLT  17 CHLD    18 CONT    19 STOP    20 TSTP    21 TTIN<br \/>\n22 TTOU    23 URG     24 XCPU    25 XFSZ    26 VTALRM  27 PROF    28 WINCH<br \/>\n29 POLL    30 PWR     31 SYS<br \/>\n&nbsp;<br \/>\nor:<br \/>\n&nbsp;<br \/>\n<strong>kill -L<\/strong><br \/>\n 1) SIGHUP\t 2) SIGINT\t 3) SIGQUIT\t 4) SIGILL\t 5) SIGTRAP<br \/>\n 6) SIGABRT\t 7) SIGBUS\t 8) SIGFPE\t 9) SIGKILL\t10) SIGUSR1<br \/>\n11) SIGSEGV\t12) SIGUSR2\t13) SIGPIPE\t14) SIGALRM\t15) SIGTERM<br \/>\n16) SIGSTKFLT\t17) SIGCHLD\t18) SIGCONT\t19) SIGSTOP\t20) SIGTSTP<br \/>\n21) SIGTTIN\t22) SIGTTOU\t23) SIGURG\t24) SIGXCPU\t25) SIGXFSZ<br \/>\n26) SIGVTALRM\t27) SIGPROF\t28) SIGWINCH\t29) SIGIO\t30) SIGPWR<br \/>\n31) SIGSYS\t34) SIGRTMIN\t35) SIGRTMIN+1\t36) SIGRTMIN+2\t37) SIGRTMIN+3<br \/>\n38) SIGRTMIN+4\t39) SIGRTMIN+5\t40) SIGRTMIN+6\t41) SIGRTMIN+7\t42) SIGRTMIN+8<br \/>\n43) SIGRTMIN+9\t44) SIGRTMIN+10\t45) SIGRTMIN+11\t46) SIGRTMIN+12\t47) SIGRTMIN+13<br \/>\n48) SIGRTMIN+14\t49) SIGRTMIN+15\t50) SIGRTMAX-14\t51) SIGRTMAX-13\t52) SIGRTMAX-12<br \/>\n53) SIGRTMAX-11\t54) SIGRTMAX-10\t55) SIGRTMAX-9\t56) SIGRTMAX-8\t57) SIGRTMAX-7<br \/>\n58) SIGRTMAX-6\t59) SIGRTMAX-5\t60) SIGRTMAX-4\t61) SIGRTMAX-3\t62) SIGRTMAX-2<br \/>\n63) SIGRTMAX-1\t64) SIGRTMAX<br \/>\n<\/code><br \/>\nThus, the following incantations are equivalent:<br \/>\n<code><br \/>\n\/bin\/kill --signal SIGURG $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal    URG $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal     23 $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n<\/code><br \/>\nOn receiving the supported signals, the related function is invoked and thereafter the script returns to its former activity, namely the loop that waits for a fake input. The loop is needed otherwise the script would exit on returning from a trap handler. In effect, the trap is processed like a function call and, on returning, the next statement at the point the trap occurred is given control. If there is none, then the script terminates. Hence the loop.<br \/>\nHere is the output after sending a few signals; for clarity, the signals sent from another terminal have been manually inserted as highlighted comments before the output they caused.<br \/>\nOutput terminal:<br \/>\n<code><br \/>\n<strong># SIGUSR2:<\/strong><br \/>\nstatus of running processes at 2019\/04\/06 16:12:46<br \/>\nshowing 28046084<br \/>\nrandom value 28046084 is used by process with pid 29248 and pgid 29245<br \/>\nshowing 977680<br \/>\nrandom value 977680 is used by process with pid 29249 and pgid 29245<br \/>\nshowing 26299592<br \/>\nrandom value 26299592 is used by process with pid 29250 and pgid 29245<br \/>\nshowing 25982957<br \/>\nrandom value 25982957 is used by process with pid 29251 and pgid 29245<br \/>\nshowing 27830550<br \/>\nrandom value 27830550 is used by process with pid 29252 and pgid 29245<br \/>\n5 processes found<br \/>\n&nbsp;<br \/>\n<strong># SIGUSR1:<\/strong><br \/>\nstarting a new process at 2019\/04\/06 16:18:56<br \/>\nprocess started with pid 29618 and random value 22120010<br \/>\n&nbsp;<br \/>\n<strong># SIGUSR2:<\/strong><br \/>\nstatus of running processes at 2019\/04\/06 16:18:56<br \/>\nshowing 28046084<br \/>\nrandom value 28046084 is used by process with pid 29248 and pgid 29245<br \/>\nshowing 977680<br \/>\nrandom value 977680 is used by process with pid 29249 and pgid 29245<br \/>\nshowing 26299592<br \/>\nrandom value 26299592 is used by process with pid 29250 and pgid 29245<br \/>\nshowing 25982957<br \/>\nrandom value 25982957 is used by process with pid 29251 and pgid 29245<br \/>\nshowing 27830550<br \/>\nrandom value 27830550 is used by process with pid 29252 and pgid 29245<br \/>\nshowing 22120010<br \/>\nrandom value 22120010 is used by process with pid 29618 and pgid 29245<br \/>\n6 processes found<br \/>\n&nbsp;<br \/>\n<strong># SIGURG:<\/strong><br \/>\nsend signal SIGURG for help<br \/>\nsend signal SIGPWR to start a few processes<br \/>\nsend signal SIGUSR1 to start a new process<br \/>\nsend signal SIGUSR2 for the list of started processes<br \/>\nsend signal SIGINT | SIGABRT to stop all the processes<br \/>\nsend signal SIGHUP | SIGQUIT | SIGTERM to shutdown the processes and exit the container<br \/>\n&nbsp;<br \/>\n<strong># SIGINT:<\/strong><br \/>\nshutting down the processes at 2019\/04\/06 16:20:17<br \/>\nstopping 28046084<br \/>\nstopping 977680<br \/>\nstopping 26299592<br \/>\nstopping 25982957<br \/>\nstopping 27830550<br \/>\nstopping 22120010<br \/>\n6 processes stopped<br \/>\n&nbsp;<br \/>\n<strong># SIGUSR2:<\/strong><br \/>\nstatus of running processes at 2019\/04\/06 16:20:18<br \/>\n0 processes found<br \/>\n&nbsp;<br \/>\n<strong># SIGPWR:<\/strong><br \/>\nstarting a few processes at 2019\/04\/06 16:20:50<br \/>\nprocess started with pid 29959 and random value 2649735<br \/>\nprocess started with pid 29960 and random value 14971836<br \/>\nprocess started with pid 29961 and random value 14339677<br \/>\nprocess started with pid 29962 and random value 4460665<br \/>\nprocess started with pid 29963 and random value 12688731<br \/>\n5 processes started<br \/>\n&nbsp;<br \/>\nstarted processes:<br \/>\n29245 29959 29245  1994 pts\/0    29245 S+    1000   0:00  |       _ I am number 2649735<br \/>\n29245 29960 29245  1994 pts\/0    29245 S+    1000   0:00  |       _ I am number 14971836<br \/>\n29245 29961 29245  1994 pts\/0    29245 S+    1000   0:00  |       _ I am number 14339677<br \/>\n29245 29962 29245  1994 pts\/0    29245 S+    1000   0:00  |       _ I am number 4460665<br \/>\n29245 29963 29245  1994 pts\/0    29245 S+    1000   0:00  |       _ I am number 12688731<br \/>\n&nbsp;<br \/>\n<strong># SIGUSR2:<\/strong><br \/>\nstatus of running processes at 2019\/04\/06 16:20:53<br \/>\nshowing 2649735<br \/>\nrandom value 2649735 is used by process with pid 29959 and pgid 29245<br \/>\nshowing 14971836<br \/>\nrandom value 14971836 is used by process with pid 29960 and pgid 29245<br \/>\nshowing 14339677<br \/>\nrandom value 14339677 is used by process with pid 29961 and pgid 29245<br \/>\nshowing 4460665<br \/>\nrandom value 4460665 is used by process with pid 29962 and pgid 29245<br \/>\nshowing 12688731<br \/>\nrandom value 12688731 is used by process with pid 29963 and pgid 29245<br \/>\n5 processes found<br \/>\n&nbsp;<br \/>\n<strong># SIGTERM:<\/strong><br \/>\nshutting down the container at 2019\/04\/06 16:21:42<br \/>\n&nbsp;<br \/>\nshutting down the processes at 2019\/04\/06 16:21:42<br \/>\nstopping 2649735<br \/>\nstopping 14971836<br \/>\nstopping 14339677<br \/>\nstopping 4460665<br \/>\nstopping 12688731<br \/>\n5 processes stopped<br \/>\n<\/code><br \/>\nIn the command terminal:<br \/>\n<code><br \/>\n\/bin\/kill --signal SIGUSR2 $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal SIGUSR1 $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal SIGUSR2 $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal SIGURG  $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal SIGINT  $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal SIGUSR2 $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal SIGPWR  $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal SIGUSR2 $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n\/bin\/kill --signal SIGTERM $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<br \/>\n<\/code><br \/>\nOf course, sending the untrappable SIGKILL signal will abort the process that executes dctm.sh. However, its children processes will survive and be reparented to the root process:<br \/>\n<code><br \/>\n...<br \/>\nstatus of running processes at 2019\/04\/10 22:38:25<br \/>\nshowing 19996889<br \/>\nrandom value 19996889 is used by process with pid 24520 and pgid 24398<br \/>\nshowing 5022831<br \/>\nrandom value 5022831 is used by process with pid 24521 and pgid 24398<br \/>\nshowing 1363197<br \/>\nrandom value 1363197 is used by process with pid 24522 and pgid 24398<br \/>\nshowing 18185959<br \/>\nrandom value 18185959 is used by process with pid 24523 and pgid 24398<br \/>\nshowing 10996678<br \/>\nrandom value 10996678 is used by process with pid 24524 and pgid 24398<br \/>\n5 processes found<br \/>\n<strong># \/bin\/kill --signal SIGKILL $(ps -ef | grep dctm.sh | grep -v grep | gawk '{print $2}')<\/strong><br \/>\n<strong>Killed<\/strong><br \/>\n&nbsp;<br \/>\n<strong>ps -ef | grep number | grep -v grep<\/strong><br \/>\ndocker   24520     1  0 22:38 pts\/1    00:00:00 I am number 19996889<br \/>\ndocker   24521     1  0 22:38 pts\/1    00:00:00 I am number 5022831<br \/>\ndocker   24522     1  0 22:38 pts\/1    00:00:00 I am number 1363197<br \/>\ndocker   24523     1  0 22:38 pts\/1    00:00:00 I am number 18185959<br \/>\ndocker   24524     1  0 22:38 pts\/1    00:00:00 I am number 10996678<br \/>\n&nbsp;<br \/>\n<strong># manual killing those processes;<br \/>\nps -ef | grep number | grep -v grep | gawk '{print $2}' | xargs kill -9<\/strong><br \/>\n&nbsp;<br \/>\n<strong>ps -ef | grep number | grep -v grep<\/strong><br \/>\n&lt;<em>empty<\/em>&gt;<br \/>\n&nbsp;<br \/>\n# this works too:<br \/>\n<strong>kill -9 $(pgrep -f \"I am number [0-9]+$\")<\/strong><br \/>\n# or, shorter:<br \/>\n<strong>pkill -f \"I am number [0-9]+$\"<\/strong><br \/>\n<\/code><br \/>\nNote that there is a simpler way to kill those related processes: by using their PGID, or process group id:<br \/>\n<code><br \/>\n<strong>ps -ax<strong>j<\/strong>f | grep number | grep -v grep<\/strong><br \/>\n    1 25248 <strong>25221<\/strong> 24997 pts\/1    24997 S     1000   0:00 I am number 3489651<br \/>\n    1 25249 <strong>25221<\/strong> 24997 pts\/1    24997 S     1000   0:00 I am number 6789321<br \/>\n    1 25250 <strong>25221<\/strong> 24997 pts\/1    24997 S     1000   0:00 I am number 15840638<br \/>\n    1 25251 <strong>25221<\/strong> 24997 pts\/1    24997 S     1000   0:00 I am number 19059205<br \/>\n    1 25252 <strong>25221<\/strong> 24997 pts\/1    24997 S     1000   0:00 I am number 12857603<br \/>\n# processes have been reparented to PPID == 1;<br \/>\n# highlighted columns 3 is the PGID;<br \/>\n# kill them using negative-PGID;<br \/>\n<strong>kill -9 -25221<\/strong><br \/>\n<strong>ps -axjf | grep number | grep -v grep<\/strong><br \/>\n&lt;<em>empty<\/em>&gt;<br \/>\n<\/code><br \/>\nThis is why the status() commands displays the PGID.<br \/>\nIn order to tell kill that the given PID is actually a PGID, it has to be prefixed with a minus sign. Alternatively, the command:<br \/>\n<code><br \/>\npkill -g <em>pgid<\/em><br \/>\n<\/code><br \/>\ndoes that too.<br \/>\nAll this looks quite promising so far !<br \/>\nPlease, join me now to <a title=\"How to stop Documentum processes in a docker container, and more (part II)\" href=\"https:\/\/www.dbi-services.com\/blog\/?p=31971&amp;preview=true\" target=\"_blank\" rel=\"noopener noreferrer\">part II of this article<\/a> for the dockerization of the test script.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ideally, but not mandatorily, the management of Documentum processes is performed at the service level, e.g. by systemd. In my blog here, I showed how to configure init files for Documentum under systemd. But containers don&#8217;t have systemd, yet. They just run processes, often only one, sometimes more if they are closely related together (e.g. [&hellip;]<\/p>\n","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197,525,42],"tags":[],"type_dbi":[],"class_list":["post-12352","post","type-post","status-publish","format-standard","hentry","category-application-integration-middleware","category-enterprise-content-management","category-operating-systems"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to stop Documentum processes in a docker container, and more (part I) - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to stop Documentum processes in a docker container, and more (part I)\" \/>\n<meta property=\"og:description\" content=\"Ideally, but not mandatorily, the management of Documentum processes is performed at the service level, e.g. by systemd. In my blog here, I showed how to configure init files for Documentum under systemd. But containers don&#8217;t have systemd, yet. They just run processes, often only one, sometimes more if they are closely related together (e.g. [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2019-04-13T10:00:41+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-24T07:32:15+00:00\" \/>\n<meta name=\"author\" content=\"Middleware Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Middleware Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/\"},\"author\":{\"name\":\"Middleware Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\"},\"headline\":\"How to stop Documentum processes in a docker container, and more (part I)\",\"datePublished\":\"2019-04-13T10:00:41+00:00\",\"dateModified\":\"2025-10-24T07:32:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/\"},\"wordCount\":1544,\"commentCount\":0,\"articleSection\":[\"Application integration &amp; Middleware\",\"Enterprise content management\",\"Operating systems\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/\",\"name\":\"How to stop Documentum processes in a docker container, and more (part I) - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2019-04-13T10:00:41+00:00\",\"dateModified\":\"2025-10-24T07:32:15+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to stop Documentum processes in a docker container, and more (part I)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1\",\"name\":\"Middleware Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g\",\"caption\":\"Middleware Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/middleware-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to stop Documentum processes in a docker container, and more (part I) - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/","og_locale":"en_US","og_type":"article","og_title":"How to stop Documentum processes in a docker container, and more (part I)","og_description":"Ideally, but not mandatorily, the management of Documentum processes is performed at the service level, e.g. by systemd. In my blog here, I showed how to configure init files for Documentum under systemd. But containers don&#8217;t have systemd, yet. They just run processes, often only one, sometimes more if they are closely related together (e.g. [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/","og_site_name":"dbi Blog","article_published_time":"2019-04-13T10:00:41+00:00","article_modified_time":"2025-10-24T07:32:15+00:00","author":"Middleware Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Middleware Team","Est. reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/"},"author":{"name":"Middleware Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1"},"headline":"How to stop Documentum processes in a docker container, and more (part I)","datePublished":"2019-04-13T10:00:41+00:00","dateModified":"2025-10-24T07:32:15+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/"},"wordCount":1544,"commentCount":0,"articleSection":["Application integration &amp; Middleware","Enterprise content management","Operating systems"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/","url":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/","name":"How to stop Documentum processes in a docker container, and more (part I) - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2019-04-13T10:00:41+00:00","dateModified":"2025-10-24T07:32:15+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/how-to-stop-documentum-processes-in-a-docker-container-and-more-part-i\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to stop Documentum processes in a docker container, and more (part I)"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d8563acfc6e604cce6507f45bac0ea1","name":"Middleware Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ddcae7ba0f9d1a0e7ae707f0e689e4a9c95bb48ec49c8e6d9cc86d43f4121cb6?s=96&d=mm&r=g","caption":"Middleware Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/middleware-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/12352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=12352"}],"version-history":[{"count":1,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/12352\/revisions"}],"predecessor-version":[{"id":41187,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/12352\/revisions\/41187"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=12352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=12352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=12352"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=12352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}