Nuby Q: Daemonize (other materials have been read!)

R

Rogue Amateur

I've read the other references to daemonizing a process in ruby, but ...
well there's not enough to the examples to get me going properly.

I'm using Ruby 1.8 on a Linux box.

I am trying to write a function which will daemonize the current script
into one child process, which will then run isolated from the tty.
Using information found here (at the forum) and in other places, I wrote
this function:

def daemonize()
#
# process documented in
http://blog.humlab.umu.se/samuel/archives/000107.html
#
begin
exit if fork
Process.setsid
exit if fork
File.umask 0774
STDIN.reopen "/dev/null" # no stdin
STDOUT.reopen $log
STDERR.reopen STDOUT # stderr & stdout to syslog
rescue
raise "could not daemonize the process."
end
end # gvp_daemonize()

Then I read in the 2nd Ed Pragmatic Ruby that there should be a
Process.detach, if I don't care about the parent getting feedback (which
I don't)., so I changed my first "exit if fork" to "if fork {
Process.detach\nexit }"

The problem is that the process just exits. Nothing else gets done. I
know I'm doing something wrong, but I'm too much of a ruby-nuby (oh,
gee, and fork nuby too) to grok it from the examples I've seen, and the
book, and the web ... HELP please.

FYI: I also need to figure out how to reset the userid and groupid, but
I have a book. :)

Thanks for any assistance rendered.

Rogue Amateur
 
A

ara.t.howard

I've read the other references to daemonizing a process in ruby, but ...
well there's not enough to the examples to get me going properly.

I'm using Ruby 1.8 on a Linux box.

I am trying to write a function which will daemonize the current script
into one child process, which will then run isolated from the tty.
Using information found here (at the forum) and in other places, I wrote
this function:

def daemonize()
#
# process documented in
http://blog.humlab.umu.se/samuel/archives/000107.html
#
begin
exit if fork
Process.setsid
exit if fork
File.umask 0774
STDIN.reopen "/dev/null" # no stdin
STDOUT.reopen $log
STDERR.reopen STDOUT # stderr & stdout to syslog
rescue
raise "could not daemonize the process."
end
end # gvp_daemonize()

Then I read in the 2nd Ed Pragmatic Ruby that there should be a
Process.detach, if I don't care about the parent getting feedback (which
I don't)., so I changed my first "exit if fork" to "if fork {
Process.detach\nexit }"

The problem is that the process just exits. Nothing else gets done. I
know I'm doing something wrong, but I'm too much of a ruby-nuby (oh,
gee, and fork nuby too) to grok it from the examples I've seen, and the
book, and the web ... HELP please.

here is a script which can be used on the command line to daemonize any other
process:

harp:~ > cat daemon.rb
#! /usr//bin/env ruby
fork{ STDIN.reopen(STDOUT.reopen(STDERR.reopen(open('/dev/null','r+')))); fork{ system ARGV.join(' ') ? exit : abort } and exit! }


use it like

harp:~ > daemon.rb any_other_command
FYI: I also need to figure out how to reset the userid and groupid, but
I have a book. :)

you cannot do this from withint a script - a restriction placed by unix - only
binary programs may be 'setuid' programs. i have a method to do this in ruby,
which is often important for web and db related work where authentication might
be allowed for only certain reasons. in any case setuid is really only
appropriate for certain security situations and can be very, very bad for your
system health. my inclination would be to say that if you are reading about it
you shouldn't use it! ;-) that being said this will accomplish what you
seek:

http://codeforpeople.com/lib/ruby/_ruby/

regards.

-a
 
R

Rogue Amateur

First, let me say thank you for the help.
On Wed, 12 Jul 2006, Rogue Amateur wrote:
[snip]

here is a script which can be used on the command line to daemonize any
other process:

harp:~ > cat daemon.rb
#! /usr//bin/env ruby
fork{
STDIN.reopen(STDOUT.reopen(STDERR.reopen(open('/dev/null','r+'))));
fork{ system ARGV.join(' ') ? exit : abort } and exit! }

use it like

harp:~ > daemon.rb any_other_command

Ok, ignorance again:
1) this means I can't do the fork within the script itself?
2) suppose the any_other_command isn't in the default ruby library? do
I supply the full path to call? Will it allow me to pass along
arguments?
(I'll be trying it, as I await a response...)
FYI: I also need to figure out how to reset the userid and groupid, but
I have a book. :)

you cannot do this from withint a script
[snip]

my inclination would be to say that if you are reading
about it
you shouldn't use it! ;-)

Gotcha. So the follow on question is: if I need my now isolated process
to run as a particular user/group, the process is...? What? My local
guru, who speaks about 15 levels too high for me, said "set the user and
group ids." See, I can parrot! :)

I'm familiar with sudo, but... would that work with the daemon.rb? (eg:
sudo daemon.rb My_Ruby_Script.rb [arg] [arg]...)

Thanks again
Rogue Amateur
 
R

Rogue Amateur

Rogue Amateur wrote:
[snip, in follow up]
Ok, ignorance again:
1) this means I can't do the fork within the script itself?
2) suppose the any_other_command isn't in the default ruby library? do
I supply the full path to call? Will it allow me to pass along
arguments?
(I'll be trying it, as I await a response...)
[snip again]

I tried it:
/daemon.rb ./my_Script.rb
it dies without comment.

running ./my_Script.rb, however, works as expected. Notions?

RA
 
A

ara.t.howard

Rogue Amateur wrote:
[snip, in follow up]
Ok, ignorance again:
1) this means I can't do the fork within the script itself?
2) suppose the any_other_command isn't in the default ruby library? do
I supply the full path to call? Will it allow me to pass along
arguments?
(I'll be trying it, as I await a response...)
[snip again]

I tried it:
./daemon.rb ./my_Script.rb
it dies without comment.

running ./my_Script.rb, however, works as expected. Notions?

it doesn't die - it starts the script as a daemon. check in top.

regarding the setuid/gid bit - your local guru is simply wrong - you cannot do
that from withint a script. google around a bit. your options are to use
sudo, which is designed to do exactly this, or my _ruby code, which is a
specialized version that accomplishs much the same thing. in either case you
will require root privledges to setup the setuid binary or sudo permission if
you go that route.

cheers.

-a
 
R

Rogue Amateur

unknown said:
[snip again]

I tried it:
./daemon.rb ./my_Script.rb
it dies without comment.

running ./my_Script.rb, however, works as expected. Notions?

it doesn't die - it starts the script as a daemon. check in top.



Ok, then I'm really confused. Because the script is NOT running.

The script in question sends data to and receives data from a socket. I
have test code written which sends data to the appropriate socket, and
receives back, and prints the result.

When I started the listener, then daemonized the script, the listener
sat there doing nothing. ps -ef returned nothing (for the script name).
When I started the script alone, suddenly the listener has something to
do, and the ps -ef returns data. I am sure I did something wrong, I
don't doubt it a bit, but... it really doesn't look like the script is
running as a daemon. Am I using the wrong checks? Will my sockets
suddenly work differently when run as a daemon? I haven't found
anything that says that's likely so... I must be confused.

Thank you for your quick responses.

RA
 
R

Rogue Amateur

Rogue said:
unknown said:
On Fri, 14 Jul 2006, Rogue Amateur wrote:

[snip]


can all of your code run as in

./my_code.rb

??


yes. running ./my_code.rb is how I normally start the software. when
run without daemonizing of any sort, this software runs properly and to
completion. there are 2 modes: interactive and service mode. I'm
trying to make the service mode run as a daemon.
[snip]

problem solved, or so it appears. thank you, ALL of you, for your most
excellent help. A few of the lines of code referenced a hard-coded path
name. This was readily resolved by, prior to daemonizing, trap the
correct path, then after the daemonizing, be sure to be in the correct
path for proper processing, by deliberately changing to the correct path
in the child process. This seems to work properly.

FYI, there is another, slightly different and I'm not sure correct
Daemon type code at http://www.bigbold.com/snippets/posts/show/2265, for
those interested parties. I couldn't get it to work properly, but the
site says it does.

Again, Thank you All

RA
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top