From: "Iñaki Baz Castillo" Date: 2009-12-12T18:53:06+09:00 Subject: Re: Is it possible to force a Ruby program to run as a proc name different than "ruby"? El Sábado, 12 de Diciembre de 2009, David Masover escribió: > On Friday 11 December 2009 05:33:06 pm Iñaki Baz Castillo wrote: > > The good point of using: > > > > start-stop-daemon --stop --pidfile /var/run/rb_program.pid --name > > rb_program > > > > is that it would stop the process just if it's called "rb_program" and > > its pid matches the value of /var/run/rb_program.pid, so you cannot kill > > any other process using that pid by accident (it could occur if your > > program didn't delete the pidfile and a new process has taken same pid > > value). > > That's a good point -- though I would guess that in theory, it shouldn't be > possible for a program to die in such a way that it wouldn't be able to > delete that file. The only thing that would make sense is a reboot, and on > my system, /var/run is a tmpfs (only exists in RAM/swap), so it's not > stored anywhere that would survive a reboot. Well, usually daemons are coded to deelte the pidfile upon receipt of a SIGINT signal (or some others). But if the daemon is killed with "kill -9 PID" then it terminates inmediately without deleting the piddile. In the case of a crash or segmentfault the daemon wouldn't delete the pidfile again. I've coded my Debian init script "start" action so it deletes the existing "pidfile" if it exists (it shouldn't). > I can think of a few other possibilities, like checking directly (with > fuser, for example) which process is controlling the resource your daemon > is associated with, or even talking to the old daemon over a socket, or > some sort of formal IPC like dbus. Sounds interesting, but perhaps a bit complex. I think I don't need so much as there will be an unique instance of the ruby program running in the server. > I did find a solution, though: > > #!/usr/bin/env ruby > > doesn't work. However: > > #!/usr/bin/ruby1.9.1 > > produces a process which responds both to killall and to 'start-stop-daemon > -- stop --name'. Great! this is the point. I've checked the daemon in python and it uses "/usr/bin/python" rather than "/usr/bin/env python". > But hardcoding the location of the Ruby interpreter is > antisocial, especially when there are so many of them. The whole point of > env is that I can always override PATH and point to a different Ruby > interpreter, to easily switch between 1.8, 1.9, JRuby, Rubinius, etc. Yes, and when dealing with compiled sources rather than linux distribution specific packages we could have ruby1.9 binay in /usr/local/bin/, /opt/bin/... I agree 100%. I wouldn't like to hardcode the ruby location. > I thought I'd found a workaround, and I've been getting messy with C trying > to figure out how to replace env with a more appropriate program, but I'm > not sure how to change the program name at all. That is, this isn't a Ruby > issue, it's a Linux/Unix issue. The best I could figure out was this: > > > #include > #include > #include > #include > #include > > int main(int argc, char *argv[]) { > if (argc == 1) { > fprintf(stderr, "Usage: %s PROGRAM ARGUMENTS\n", argv[0]); > return 1; > } > > char * filename = argv[1]; > argv[1] = "foo"; > > execvp(filename, argv+1); > > char * outstr = malloc(strlen(argv[0]) + strlen(argv[1]) + 2); > sprintf(outstr, "%s: %s", argv[0], argv[1]); > perror(outstr); > return errno; > } > > > Compile that, then change the Ruby script to be: > > #!/path/to/that/binary ruby > > The same should work for Python. > > Except it doesn't. > > It does indeed change the program name in /proc/self/cmdline -- it becomes > 'foo /name/of/my/program.rb'. And killall and start-stop-daemon both seem > to work, here, but only when I give them "ruby" as the name of the program > to kill. > > Notice, also, I'm explicitly setting 'foo' as the program name. If this > worked, I'd detect that dynamically -- but it doesn't. > > At this point, I'm about ready to write a script that would copy your > script (or create a wrapper for your script) and change the shebang to > match `which ruby` at the point of invocation, but that wouldn't work > either -- that will fool the program name in /proc, but it won't fool your > program -- there's $0 and probably a dozen other things I haven't thought > of to tell it that it's being loaded by a separate script. > > I don't really know what else to try. /proc/self/exe is no help; that > points to the Ruby binary no matter what. You might write your own script > that greps through /proc/*/cmdline, but I don't see a way to fool > start-stop-daemon without changing to #!/usr/bin/ruby1.9.1. Thanks a lot for all your suggestions, it's a really interesting subject. However I would prefer to keep the code as simple as possible. The only I wanted was the possibility of kill my program using "killall rb_program". To summarize this is possible in these cases: a) Hardcoding the ruby location (avoiding using "env"). Not user-friendly. b) Creating a link "rb_program" to ruby interpreter and invoke my program with "rb_program /PATH_TO_rb_program.rb". Not very beauty :) c) Replacing env with your above suggestion. It involves compiling a C program, it could break something in a not pure Linux environment... Well, I've learnt *a lot* in this thread but at this point I think is better just to leave the code as it is. Really thanks a lot. -- Iñaki Baz Castillo