Closed claos closed 13 years ago
The problem here is that Starcraft forks into some child processes and the kills the original process... And I'm having a hard time finding out how to detect these children..
you should be able to launch the game by:
sudo /etc/init.d/bumblebee enable vglrun -c xv -d :1 -ld /usr/lib32/nvidia-current "wine Starcraft\ II.exe"
Now I get this message:
vglrun -c xv -d :1 -ld /usr/lib32/nvidia-current wine ./StarCraft\ II.exe
[VGL] ERROR: Could not open display :1. [VGL] ERROR: Could not open display :1. [VGL] ERROR: Could not open display :1.
Another try with the +v option:
vglrun +v -c xv -d :1 -ld /usr/lib32/nvidia-current wine ./StarCraft\ II.exe
[VGL] NOTICE: Replacing dlopen("/lib32/libdl.so.2") with dlopen("libdlfaker.so") [VGL] NOTICE: Replacing dlopen("/lib32/libdl.so.2") with dlopen("libdlfaker.so") [VGL] NOTICE: Replacing dlopen("/lib32/libdl.so.2") with dlopen("libdlfaker.so") [VGL] NOTICE: Replacing dlopen("/lib32/libdl.so.2") with dlopen("libdlfaker.so") [VGL] NOTICE: Replacing dlopen("/lib32/libdl.so.2") with dlopen("libdlfaker.so") [VGL] NOTICE: Replacing dlopen("/lib32/libdl.so.2") with dlopen("libdlfaker.so") [VGL] NOTICE: Replacing dlopen("/lib32/libdl.so.2") with dlopen("libdlfaker.so") [VGL] Shared memory segment ID for vglconfig: 4554763 [VGL] Opening local display :1 [VGL] ERROR: Could not open display :1. [VGL] NOTICE: Replacing dlopen("/lib32/libdl.so.2") with dlopen("libdlfaker.so") [VGL] Shared memory segment ID for vglconfig: 4587531 [VGL] Opening local display :1 [VGL] ERROR: Could not open display :1. [VGL] Shared memory segment ID for vglconfig: 4620299 [VGL] Opening local display :1 [VGL] ERROR: Could not open display :1.
I get exactly the same thing. It's odd, I could have sworn I had it running successfully in the early days of bumblebee.
Is there a way to tell all new programs to run with vglrun by default? ie so that when the SC2 process forks a new child it gets run with vglrun?
are you sure that you have executed:
sudo /etc/init.d/bumblebee enable
before running the vglrun command???
I also think it worked earlier, I think maybe an update to wine or/and starcraft has changed the way starcraft forks it's processes....
OK, I did some more checking and with the original version of StarCraft 2:
On my system starcraft2 runs a child process for SC2.exe. The child process always has a parent process with pid 1, which is /sbin/init. I guess this means it is created as a parentless process.
Is it possible to query vgl server to see which processes have tried to access display :1 recently? If so, a solution for starcraft2 could be to make optirun wait for a few seconds to allow child processes to start, then check with vglserver, then wait until all processes have finished before shutting down the vgl server, rather than shutting it down once the initial process has terminated. Or just not shut it down if it is still active.
@rockorequin
I've been trying to find a way to detect the child processes... but I really haven't found a way to do it..
"wait" doesn't work because, as you say, the "childs" are parentless... xlsclients doesn't work, because it only show the processes shown on the selected x server.. not the ones executed there...
So right now, I'm really stuck here... if someone has got a good idea.. please shout :D...
@MrMEEE:
Here's an idea for a hack in optirun that captures child processes (I have tested it works with SC2, and it doesn't break other wine games):
It doesn't cater for the case where the user manually creates a new process in the interim, but I figure this is unlikely and the worst case is that optirun will not terminate until this manually-created process finishes, so all it means is that the user may have to manually terminate optirun and possibly shut down bumblebee.
The amount of time to sleep is probably important as it might vary from program to program (or PC to PC). One second is enough for SC2 on my L502x.
Here's the code I used in optirun32:
Immediately before vglrun:
# Store pids, with LF replaced with spaces. Include a trailing space for matching purposes later
ps1="$(ps -a -o pid=)"
ps1=$(echo "$ps1 " | tr '\n' ' ')
Immediately after vglrun:
# Store new set of pids. Sleep first to give the child processes time to run
sleep 1
ps2="$(ps -a -o pid=)"
# Remove pids common to both sets to pids created since vglrun was run
# This will always match the pid of the ps command itself but that isn't important since it has already terminated
newpids=""
for pid in $ps2; do
# Note: check for trailing space ("$pid ") to avoid incorrectly matching "123" with process "1234"
if ! [[ $ps1 =~ "$pid " ]]; then newpids+="$pid "; fi
done
if [ "$STOP_SERVICE_ON_EXIT" != "NO" ]; then
# Wait for newpids to complete
for pid in $newpids; do
while true; do
# Break if no longer running
if [ "$(ps -o pid= $pid)" == "" ]; then break; fi
sleep 0.5
done
done
if [ `ps aux |grep optirun |wc -l` -lt 4 ]; then
By the way, that last line detecting other bumblebee processes also catches the command "gedit /usr/local/bin/optirun32" and so optirun doesn't shut down bumblebee if you are editing it!
Something that might improve the hack is to time the vglrun command, and only wait for newly-created child processes if it has run for a short period of time (10 seconds? 30 seconds?). That way if you run an app that lasts for hours, optirun won't then wait for any new processes you might have started in the interim. Having said that, ps -a run from a gnome-terminal seems to only show processes opened from that gnome-terminal or other gnome-terminals, so it might not be all that important.
This is probably naive, but why not have a popup on screen that says, click here when you are done with the game?
I think the idea is to make the power handling code automatic so the user doesn't have to worry about it, and having a popup would require extra user intervention that in most cases would be unnecessary. And since the optirun script can be modified to handle rapidly-forked parentless child processes, it isn't even really needed for SC2.
This problem is fixed in newest version (1.6.31)...
Please reopen if problem persists...
The server keeps running, but the solution could be made more elegant. There are two issues with it:
These two error messages continually get spewed out:
lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system /root/.gvfs
Output information may be incomplete.
Another bumblebee powered application is running, keeping bumblebee alive.
I guess the first could be fixed by sending stderr to /dev/null, and the second could be fixed by only reporting it the first time through the loop.
This could be fixed by looking for new child processes and only waiting on these before finishing.
I think latest update should fix both problems...
Thanks, it does!
It does always say "Another bumblebee powered application is running, keeping bumblebee alive.", every time (and then shuts down the server). I think this must be because libnvidia-glcore stays running a bit longer than the application. Perhaps it should sleep for a second before the first lsof check?
Hi,
Have done the usual test with glxgears and everything works fine. The problem is that I get this "Could not open display :1." message when trying to run SC2 through wine:
optirun32 wine ./StarCraft\ II.exe
_PS0 Enabling nVidia Card Succeded. [ OK ] fixme:wininet:InternetSetOptionW Option INTERNET_OPTION_CONNECT_TIMEOUT (2000): STUB fixme:wininet:InternetSetOptionW INTERNET_OPTION_SEND/RECEIVE_TIMEOUT 2000 fixme:win:EnumDisplayDevicesW ((null),0,0x107c0ec,0x00000000), stub! fixme:ddraw:DirectDrawEnumerateExA flags 0x00000003 not handled fixme:wininet:InternetSetOptionW Option INTERNET_OPTION_CONNECT_TIMEOUT (3000): STUB fixme:wininet:InternetSetOptionW INTERNET_OPTION_SEND/RECEIVE_TIMEOUT 3000
[VGL] ERROR: Could not open display :1.
_PS0 Disabling nVidia Card Succeded. [ OK ]
BTW, thanks for the great job!