You are not logged in.

#1 2009-11-04 22:12:51

pyther
Member
Registered: 2008-01-21
Posts: 1,395
Website

OSS Start/Stop Script [For Suspend/Hibernate]

With Kernel 2.6.26.32-rc6 suspend-2-ram (aka sleep/standby) finally works on my machine! However OSSv4 does not support suspend/hibernate which means that OSS must be unloaded.

This scripts does the following:
    * Stop/Start specific Daemons
    * Stop/Starts specific Programs
    * Informs you of any programs that are preventing OSS from unloading

In my case I have the script stop mpd. Then it kills ossxmix and attempts to unload oss. On spawn it starts mpd again and loads ossxmix.

Here it is:
oss_s.py

#!/usr/bin/env python

import subprocess
import sys
import os

#Daemons that need to be stopped
daemons=('mpd',)

#Programs that are safe to kill
kill_apps=('ossxmix','vlc','mplayer','xine','xmms','audacious',)

#Programs to load on spawn/resume
load_apps=('ossxmix -xb',)

#User to start apps as
user='pyther'

def start():
    p=subprocess.Popen(['soundon'])
    p.wait()    

    for d in daemons:
        p=subprocess.Popen(['/etc/rc.d/' + d, 'start'])
        p.wait()

    for a in load_apps:
        #Load the program as a user, not root
        os.system('sudo su -c \'' + a + ' &\' ' + user)

    return

def stop():
    for d in daemons:
        p=subprocess.Popen(['/etc/rc.d/' + d, 'stop'])
        p.wait()

    for a in kill_apps:
        p=subprocess.Popen(['killall',a])
        p.wait()

    o=subprocess.Popen(['soundoff'],stdout=subprocess.PIPE)
    output=o.stdout.readlines()
  
    list=[]

    for line in output:
        
        #If the line is empty skip it
        line = line.rstrip("\n")
        if line == '':
            pass
        #Otherwise lets split the line by spaces
        else: 
            line=line.rsplit(' ')
            
            #Going to see if the first word is an int
            try:
                pid=int(line[0])
            except ValueError:
                #Must not be an int
                pass 
            #Good it is an int... lets continue
            else:
                app=line[1] #The second word is the name of the app
                
                #If the list has no values, we will add the first running program
                if len(list) == 0:
                    list.append([pid,app])
                #Now lets check and see if the pid is already in the list
                else:
                    inList=0 #Set to False by default
                    #Scanning items already in the list
                    #If we find a match we set inList to True and break out of the loop
                    for x in list:
                        if int(x[0]) == int(pid):
                            inList=1
                            break
                    if not inList:
                        list.append([pid,app])

    if list:
        print("Apps that need to be killed:")
        for x in list:
            pid=x[0]
            app=x[1]

            subprocess.Popen(['notify-send', '-u', 'normal', '-i', 'audio-card', '-t', '120000', 'PID: ' + str(pid) + ' is using OSS', str(pid) + ' - ' + app + '\nPlease kill this application.' ])
            print("PID: " + str(pid) + " - " + app) 

            #Exit abnormally
            sys.exit(1)
         
    return

if __name__ == "__main__":
    if len(sys.argv) <= 1:
        print("Usage: start or stop")
        sys.exit(1)

    if os.geteuid() != 0:
        print "You must be root to run this script."
        sys.exit(1)



    if sys.argv[1] == "start":
        start()
    elif sys.argv[1] == "stop":
        stop()
    else:
        print "Usage: start or stop"

Usage is simple enough:
./oss_s.py start
./oss_s.py stop

Then to get the script to run on suspend/wake:
Save this as /etc/pm/sleep.d/48oss

#!/bin/bash

case $1 in
    hibernate)
        /home/pyther/bin/oss_s.py stop
    ;;
    suspend)
       /home/pyther/bin/oss_s.py stop
    ;;
    thaw)
        /home/pyther/bin/oss_s.py start
    ;;
    resume)
        /home/pyther/bin/oss_s.py start
    ;;
esac

Then make it executable

chmod +x /etc/pm/sleep.d/48oss

Of course you will have to modify the code as necessary.

Hopefully someone finds this script useful.

Also I would appreciate feedback on how I could clean up the code and make it more efficient.


Website - Blog - arch-home
Arch User since March 2005

Offline

#2 2009-11-05 00:53:11

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

Re: OSS Start/Stop Script [For Suspend/Hibernate]

Hey, nice work pyther.  Definitely better than the generic one we have on the wiki.  I remember playing with a script that would detect running oss applications (used lsof /dev/dsp or was it fuser?) to shutdown oss apps and then restart them.  Never could get it to work though.


Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

#3 2009-11-05 15:43:10

pyther
Member
Registered: 2008-01-21
Posts: 1,395
Website

Re: OSS Start/Stop Script [For Suspend/Hibernate]

Thanks!

I'm guessing you were playing with /usr/lib/oss/scripts/killprocs.sh script
The one issue I had with that script is that it would kill firefox if I had flash loaded which was inconvenient.


Website - Blog - arch-home
Arch User since March 2005

Offline

#4 2009-11-13 13:13:36

Gen2ly
Member
From: Sevierville, TN
Registered: 2009-03-06
Posts: 1,529
Website

Re: OSS Start/Stop Script [For Suspend/Hibernate]

Following up on my previous idea of creating a script that would reload programs the were previously closed.  Since then, I kinda figured out that this isn't really possible since root cannot start a Xorg server program.  I had to settle for the pm shutdown script (50osssound) to create a list of closed programs.  This is what I came up with:

#!/bin/sh
. "${PM_FUNCTIONS}"


suspend_osssound()
{

procs=$(fuser /dev/mixer* /dev/dsp* /dev/audio* /dev/sequencer /dev/music /dev/midi* 2> /dev/null | sed 's/  /\n/g' | sort -u | sed 1d)
user=todd
restorefile=/home/$user/Desktop/restore-oss-programs

  echo '#!/bin/sh' > $restorefile
  for pid in $procs; do
    prog=$(top -b -n1 | grep " $pid " | grep -v grep | awk '{print $12}')
    echo 'nohup '$prog' &> /dev/null' >> $restorefile
  done
  chown $user:users $restorefile
  chmod +x $restorefile

  /usr/lib/oss/scripts/killprocs.sh
  /usr/sbin/soundoff

}

resume_osssound()
{
  /usr/sbin/soundon
}

case "$1" in
  hibernate|suspend)
  suspend_osssound
  ;;
  thaw|resume)
  resume_osssound
  ;;
esac

The script itself creates another script on the desktop (that can be clicked on and will open closed programs).  I.e. if I type './50osssound' it does create a script on the desktop that I can click on open the programs with.  However, if I try to actually go to sleep with it, it gets caught in the loop and will only show '#!/bin/sh' in the file.  Have no idea why it is doing this, looks like I got all excited over nothing sad.  Any ideas?


Setting Up a Scripting Environment | Proud donor to wikipedia - link

Offline

#5 2010-07-13 12:59:42

jck
Member
From: USA
Registered: 2009-05-08
Posts: 98

Re: OSS Start/Stop Script [For Suspend/Hibernate]

you don't need to stop mpd, you just need to pause it...

Offline

#6 2010-07-13 13:29:15

Inxsible
Forum Fellow
From: Chicago
Registered: 2008-06-09
Posts: 9,183

Re: OSS Start/Stop Script [For Suspend/Hibernate]

@jck Please don't revive threads older than 6 months
http://wiki.archlinux.org/index.php/For … Bumping.27


Forum Rules

There's no such thing as a stupid question, but there sure are a lot of inquisitive idiots !

Offline

Board footer

Powered by FluxBB