Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have some users on my machine that I allow to run small Mumble voice servers. I would like for them to be able to start/stop their voice server from a website (being ran by Apache). With the current set up, I have each server being run as a different user (the person's specific user account).

What I can't figure out is the best way to start/stop the server without delay. Currently, I have the website make an entry into a database whenever they want to start/stop their service. Then, I have a cron script that runs every minute look in the database for these starts/stops. That cron script will switch to the users account and run the server as that user. My issue with this is that it can take up to around 1 minute for the action to happen.

Is there a more responsive way to accomplish this?

share|improve this question
    
Is it really needed to start/stop the services? A service that is not used doesn't use much resources... –  sr_ May 22 '12 at 14:58
add comment

5 Answers

Instead of, or in addition to, writing to a database, have you considered writing to a named pipe? You could create one named pipe per user and then create a process to watch each named pipe. When the 'restart' command comes, immediately restart the process.

This is not a complete solution and can be improved upon, but it should give you an idea of how you could monitor the named pipe and restart the process.

while read line <$pipe
 do
  if [[ "$line" == 'restart' ]]; then
    restart_some_service
  fi
done
share|improve this answer
    
do you need a sleep in there, or will the absence of data on the named-pipe not consume system CPU? –  shellter May 23 '12 at 0:10
1  
pipe reads will be blocking, so no CPU consumption when no data is available, @shellter. –  Mat May 23 '12 at 5:24
add comment

If these people you are hosting servers for are trustworthy and wont spam/hack the server, why not just program the web interface to directly pass the start/stop to the shell

For example, in PHP you could program this into the page:

<?php
  // checks, templating, blah, blah, blah
  $status = exec('/path/to/service/mumbled status')

  if ($status == "stopped")
    // display start button, hook exec('mumbled stop') command to it

  if ($status == "running")
    // display stop button, hook exec('mumbled start') command to it
?>

If it was me I would go that route, but that's just me.

share|improve this answer
1  
One of the downsides of this method is that your mumbled and httpd will have to be run as the same user. –  rjewell May 24 '12 at 6:57
    
good point. that can be super disorganizing too. –  snnth May 26 '12 at 4:37
add comment

This might be overkill, but have you considered Usermin? They list a process plugin in the standard plugins, that lets your users

View all processes running on the system, kill those belonging to [them], and start new ones.

(Never tried this, just thought it might be pretty, uhm, "professional".)

(Edit Concerning "Mumble", there seem to be some web interfaces already, but I have no idea if they help in your situation.)

share|improve this answer
add comment

I set up something like this on one of my webservers that had a problem of sshd dying occasionally -- I wanted to manually restart sshd from an authenticated web interface. This was intended (in my case) to be a short-term solution, as a full OS upgrade was not too far off anyway.

I set up a php page similar to what nonplus suggested, using shell_exec to execute a specific command via sudo:

  $output = shell_exec("/usr/local/bin/sudo /usr/local/etc/rc.d/sshd.sh restart");
  echo "<pre>$output</pre>";

This way, I could edit the local sudoers file to give my apache user the appropriate access to specific commands. I needed to grant it the root-level privilege of starting sshd; you could limit it to starting/stopping the appropriate services as the appropriate users.

share|improve this answer
add comment

Your cron method is the on the right track.. most other methods have various security concerns. To make that same idea faster, you could touch a file, and use inotify to detect that it was modified. inotify is extraordinarily fast. 'inotify-tools' is a readily available set of commandline tools that use inotify. There are some good examples on the github site for inotify-tools.

From: https://github.com/rvoicilas/inotify-tools/wiki/#wiki-info

#!/bin/sh
EVENT=$(inotifywait --format '%e' ~/file1)
[ $? != 0 ] && exit
[ "$EVENT" = "MODIFY" ] && echo 'file modified!'
[ "$EVENT" = "DELETE_SELF" ] && echo 'file deleted!'

It is basically instant - inotify is a kernel feature that these tools take advantage of which requests of the kernel notification on very specific file system events.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.