
{"id":16000,"date":"2014-10-24T14:03:32","date_gmt":"2014-10-24T14:03:32","guid":{"rendered":"http:\/\/www.beautifulwork.org\/?p=16000"},"modified":"2014-10-24T14:03:32","modified_gmt":"2014-10-24T14:03:32","slug":"hacking-with-runit-and-sv-commands","status":"publish","type":"post","link":"https:\/\/www.trueangle.org\/index.php\/2014\/10\/24\/hacking-with-runit-and-sv-commands\/","title":{"rendered":"Hacking with runit and sv (  sv &#8211; control and manage services monitored by runsv(8)  ) commands"},"content":{"rendered":"<p><u>ABOUT runit<\/u><\/p>\n<pre>\nrunit is a cross-platform Unix init scheme with service supervision, a replacement for sysvinit, and other init schemes. It runs on GNU\/Linux, *BSD, MacOSX, Solaris, and can easily be adapted to other Unix operating systems\n<\/pre>\n<p><u>ABOUT sv<\/u><\/p>\n<pre>\nThe sv program reports the current status and controls the state of services monitored by the runsv(8) supervisor.\nservices consists of one or more arguments, each argument naming a directory service used by runsv(8). If service doesn\u2019t start with a dot or slash and doesn\u2019t end with a slash, it is searched in the default services directory \/service\/, otherwise relative to the current directory.\n<\/pre>\n<p><u>A TYPICAL SHELL EXPOSURE<\/u><br \/>\n[bash]<br \/>\n$pwd<br \/>\n\/etc\/service<br \/>\n$ls<br \/>\nhello.sh<br \/>\n$mkdir new<br \/>\nmkdir: cannot create directory \u2018new\u2019: Permission denied<br \/>\n$sudo mkdir new<br \/>\n$mv hello.sh new\/run<br \/>\nmv: cannot move \u2018hello.sh\u2019 to \u2018new\/run\u2019: Permission denied<br \/>\n$sudo mv hello.sh new\/run<br \/>\n$ls<br \/>\nnew<br \/>\n$cd new\/<br \/>\n$ls<br \/>\nrun  supervise<br \/>\n$ls -l<br \/>\ntotal 8<br \/>\n-rw-r&#8211;r&#8211; 1 root root   11 Oct 24 18:55 run<br \/>\ndrwx&#8212;&#8212; 2 root root 4096 Oct 24 18:57 supervise<br \/>\n$cd supervise\/<br \/>\nbash: cd: supervise\/: Permission denied<br \/>\n$sudo cd supervise\/<br \/>\nsudo: cd: command not found<br \/>\n$sudo sv start \/etc\/service\/new<br \/>\ntimeout: down: \/etc\/service\/new: 1s, normally up, want up<br \/>\n$sudo sv status \/etc\/service\/new<br \/>\ndown: \/etc\/service\/new: 0s, normally up, want up<br \/>\n$sudo sv restart \/etc\/service\/new<br \/>\ntimeout: down: \/etc\/service\/new: 0s, normally up, want up<br \/>\n$sudo emacs \/etc\/service\/new\/run<br \/>\n$sudo sv restart \/etc\/service\/new<br \/>\ntimeout: down: \/etc\/service\/new: 0s, normally up, want up<br \/>\n$sudo sv stop \/etc\/service\/new<br \/>\nok: down: \/etc\/service\/new: 0s, normally up, want up<br \/>\n$sudo chmod +x \/etc\/service\/new\/run<br \/>\n$sudo sv start \/etc\/service\/new<br \/>\ntimeout: down: \/etc\/service\/new: 0s, normally up, want up<br \/>\n$sudo sv start \/etc\/service\/new\/<br \/>\ntimeout: down: \/etc\/service\/new\/: 1s, normally up, want up<br \/>\n$su<br \/>\nPassword:<br \/>\nroot&gt;sv start \/etc\/service\/new\/<br \/>\nrun        run~       supervise\/<br \/>\nroot&gt;sv start \/etc\/service\/new\/run<br \/>\nfail: \/etc\/service\/new\/run: unable to change to service directory: not a directory<br \/>\nroot&gt;sv start \/etc\/service\/new\/<br \/>\ntimeout: down: \/etc\/service\/new\/: 1s, normally up, want up<br \/>\nroot&gt;exit<br \/>\n$echo $?<br \/>\n1<br \/>\n$sudo sv stop \/etc\/service\/new\/<br \/>\nok: down: \/etc\/service\/new\/: 1s, normally up, want up<br \/>\n$echo $?<br \/>\n0<br \/>\n$sudo runit<br \/>\n&#8211; runit: fatal: must be run as process no 1.<br \/>\n$sudo runit enable<br \/>\n&#8211; runit: fatal: must be run as process no 1.<br \/>\n$<\/p>\n<p>[\/bash]<br \/>\n<u>TYPICAL SOURCE CODE EXPOSURE<\/u><br \/>\n[c]<\/p>\n<p>int main(int argc, char **argv) {<br \/>\n  unsigned int i, done;<br \/>\n  char *x;<\/p>\n<p>  progname =*argv;<br \/>\n  for (i =str_len(*argv); i; &#8211;i) if ((*argv)[i -1] == &#8216;\/&#8217;) break;<br \/>\n  *argv +=i;<br \/>\n  optprogname =progname =*argv;<br \/>\n  service =argv;<br \/>\n  services =1;<br \/>\n  lsb =(str_diff(progname, &quot;sv&quot;));<br \/>\n  if ((x =env_get(&quot;SVDIR&quot;))) varservice =x;<br \/>\n  if ((x =env_get(&quot;SVWAIT&quot;))) scan_ulong(x, &amp;wait);<br \/>\n  while ((i =getopt(argc, (const char* const*)argv, &quot;w:vV&quot;)) != opteof) {<br \/>\n    switch(i) {<br \/>\n    case &#8216;w&#8217;: scan_ulong(optarg, &amp;wait);<br \/>\n    case &#8216;v&#8217;: verbose =1; break;<br \/>\n    case &#8216;V&#8217;: strerr_warn1(VERSION, 0);<br \/>\n    case &#8216;?&#8217;: usage();<br \/>\n    }<br \/>\n  }<br \/>\n  argv +=optind; argc -=optind;<br \/>\n  if (!(action =*argv++)) usage(); &#8211;argc;<br \/>\n  if (!lsb) { service =argv; services =argc; }<br \/>\n  if (!*service) usage();<\/p>\n<p>  taia_now(&amp;tnow); tstart =tnow;<br \/>\n  if ((curdir =open_read(&quot;.&quot;)) == -1)<br \/>\n    fatal(&quot;unable to open current directory&quot;);<\/p>\n<p>  act =&amp;control; acts =&quot;s&quot;;<br \/>\n  if (verbose) cbk =&amp;check;<br \/>\n  switch (*action) {<br \/>\n  case &#8216;x&#8217;: case &#8216;e&#8217;:<br \/>\n    acts =&quot;x&quot;; break;<br \/>\n  case &#8216;X&#8217;: case &#8216;E&#8217;:<br \/>\n    acts =&quot;x&quot;; kll =1; cbk =&amp;check; break;<br \/>\n  case &#8216;D&#8217;:<br \/>\n    acts =&quot;d&quot;; kll =1; cbk =&amp;check; break;<br \/>\n  case &#8216;T&#8217;:<br \/>\n    acts =&quot;tc&quot;; kll =1; cbk =&amp;check; break;<br \/>\n  case &#8216;t&#8217;:<br \/>\n    if (!str_diff(action, &quot;try-restart&quot;)) { acts =&quot;tc&quot;; cbk =&amp;check; break; }<br \/>\n  case &#8216;c&#8217;:<br \/>\n    if (!str_diff(action, &quot;check&quot;)) { act =0; acts =&quot;C&quot;; cbk =&amp;check; break; }<br \/>\n  case &#8216;u&#8217;: case &#8216;d&#8217;: case &#8216;o&#8217;: case &#8216;p&#8217;: case &#8216;h&#8217;:<br \/>\n  case &#8216;a&#8217;: case &#8216;i&#8217;: case &#8216;k&#8217;: case &#8216;q&#8217;: case &#8216;1&#8217;: case &#8216;2&#8217;:<br \/>\n    action[1] =0; acts =action; break;<br \/>\n  case &#8216;s&#8217;:<br \/>\n    if (!str_diff(action, &quot;shutdown&quot;)) { acts =&quot;x&quot;; cbk =&amp;check; break; }<br \/>\n    if (!str_diff(action, &quot;start&quot;)) { acts =&quot;u&quot;; cbk =&amp;check; break; }<br \/>\n    if (!str_diff(action, &quot;stop&quot;)) { acts =&quot;d&quot;; cbk =&amp;check; break; }<br \/>\n    if (lsb &amp;&amp; str_diff(action, &quot;status&quot;)) usage();<br \/>\n    act =&amp;status; cbk =0; break;<br \/>\n  case &#8216;r&#8217;:<br \/>\n    if (!str_diff(action, &quot;restart&quot;)) { acts =&quot;tcu&quot;; cbk =&amp;check; break; }<br \/>\n    if (!str_diff(action, &quot;reload&quot;)) { acts =&quot;h&quot;; cbk =&amp;check; break; }<br \/>\n    usage();<br \/>\n  case &#8216;f&#8217;:<br \/>\n    if (!str_diff(action, &quot;force-reload&quot;))<br \/>\n      { acts =&quot;tc&quot;; kll =1; cbk =&amp;check; break; }<br \/>\n    if (!str_diff(action, &quot;force-restart&quot;))<br \/>\n      { acts =&quot;tcu&quot;; kll =1; cbk =&amp;check; break; }<br \/>\n    if (!str_diff(action, &quot;force-shutdown&quot;))<br \/>\n      { acts =&quot;x&quot;; kll =1; cbk =&amp;check; break; }<br \/>\n    if (!str_diff(action, &quot;force-stop&quot;))<br \/>\n      { acts =&quot;d&quot;; kll =1; cbk =&amp;check; break; }<br \/>\n  default:<br \/>\n    usage();<br \/>\n  }<\/p>\n<p>  servicex =service;<br \/>\n  for (i =0; i &lt; services; ++i) {<br \/>\n    if ((**service != &#8216;\/&#8217;) &amp;&amp; (**service != &#8216;.&#8217;) &amp;&amp; **service &amp;&amp;<br \/>\n        ((*service)[str_len(*service) -1] != &#8216;\/&#8217;)) {<br \/>\n      if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {<br \/>\n        fail(&quot;unable to change to service directory&quot;);<br \/>\n        *service =0;<br \/>\n      }<br \/>\n    }<br \/>\n    else<br \/>\n      if (chdir(*service) == -1) {<br \/>\n        fail(&quot;unable to change to service directory&quot;);<br \/>\n        *service =0;<br \/>\n      }<br \/>\n    if (*service) if (act &amp;&amp; (act(acts) == -1)) *service =0;<br \/>\n    if (fchdir(curdir) == -1) fatal(&quot;unable to change to original directory&quot;);<br \/>\n    service++;<br \/>\n  }<\/p>\n<p>[\/c]<\/p>\n<p>SOURCE CODE TAKEN FROM DEBIAN SOURCE PACKAGE NAMED runit<\/p>\n<p>RELATED LINKS<br \/>\n<a href=\"http:\/\/smarden.org\/runit\/\">http:\/\/smarden.org\/runit\/<\/a><br \/>\n<a href=\"http:\/\/smarden.org\/runit\/sv.8.html\">http:\/\/smarden.org\/runit\/sv.8.html<\/a><br \/>\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/Runit\">https:\/\/en.wikipedia.org\/wiki\/Runit<\/a><br \/>\n<a href=\"https:\/\/docs.ansible.com\/ansible\/2.5\/modules\/runit_module.html\">https:\/\/docs.ansible.com\/ansible\/2.5\/modules\/runit_module.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>ABOUT runit runit is a cross-platform Unix init scheme with service supervision, a replacement for sysvinit, and other init schemes. It runs on GNU\/Linux, *BSD, MacOSX, Solaris, and can easily be adapted to other Unix operating systems ABOUT sv The sv program reports the current status and controls the state of services monitored by the &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.trueangle.org\/index.php\/2014\/10\/24\/hacking-with-runit-and-sv-commands\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Hacking with runit and sv (  sv &#8211; control and manage services monitored by runsv(8)  ) commands&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7,83,91],"tags":[1403,1624],"_links":{"self":[{"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/posts\/16000"}],"collection":[{"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/comments?post=16000"}],"version-history":[{"count":0,"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/posts\/16000\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/media?parent=16000"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/categories?post=16000"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.trueangle.org\/index.php\/wp-json\/wp\/v2\/tags?post=16000"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}