PDA

Bekijk Volledige Versie : Server's sluiten opeens af



vdvleon
28/03/08, 11:36
Hallo,

Ik heb zelf een programma gemaakt waar mee je cod(2&4) server mee kunt opstarten, afsluiten en restarten. Dit werkt allemaal prima. Maar is een probleem.

Dit programma roep ik via mijn phpscript aan (als gebruiker www-data, ofsow). De servers had ik gister avond gestart, en vanochtend draaide er helemaal geen enkele meer. Wat zou hier van de reden kunnen zijn, en hoe moet ik dat oplossen.

Mijn php code:

exec("codservers -start ".$csservers[$i]['id']." > /dev/null");

$csservers[$i]['id'] staat voor regel id in een bestand waarin de bestandnaam van mijn startup script staat (publicserver1.sh ofsow). > /dev/null is voor dat exec niet wacht totdat het programma is afgesloten, maar gewoon doorgaat.

Kan het zijn dat de gebruiker www-data niet goed is, of kan het iets anders zijn.

B.V.D.

Leon

Xolphin
28/03/08, 11:49
exec("codservers -start ".$csservers[$i]['id']." > /dev/null");

$csservers[$i]['id'] staat voor regel id in een bestand waarin de bestandnaam van mijn startup script staat (publicserver1.sh ofsow). > /dev/null is voor dat exec niet wacht totdat het programma is afgesloten, maar gewoon doorgaat.


Je geeft een beetje weinig code om een fout in te kunnen vinden.

vdvleon
28/03/08, 12:13
codservers (cpp):


#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <string.h>

using namespace std;

typedef vector<string> strings;
typedef struct{
string type;
string name;
int slots;
int pid;
int port;
string ip;
string arg;
string filename;
} game;
typedef vector<game> games;

strings exec(string cmd){
string tmp;
strings re;
cmd += " > Tmp.txt";
system(cmd.c_str());
ifstream is("Tmp.txt", ifstream::in);
if(is.is_open()){
while(!is.eof()){
getline(is, tmp);
re.push_back(tmp);
}
is.close();
}
return re;
}
string trim(string s){
while(s.length()>1 && s.find(" ")==0) s = s.substr(1);
while(s.length()>1 && s.find(" ", s.length()-1)==(s.length()-1)) s = s.substr(0, s.length()-2);
return s;
}
string getPart(string s, string p){
if(s.find(p)==string::npos) return "";
s = s.substr(s.find(p)+p.length()+1);
s = s.substr(0, s.find(" "));
return s;
}
games getGames(){
int i;
string tmp;
game Game;
games Games;
strings serv = exec("ps -eo pid,args | grep cod");
for(i=0; i<serv.size(); i++){
tmp = trim(serv.at(i));
if(tmp.length()>1){
Game.pid = atoi(tmp.substr(0, tmp.find(" ")).c_str());
tmp = trim(tmp.substr(tmp.find(" ")));
if(tmp.find("./cod2_lnxded")==0 || tmp.find("./cod4_lnxded")==0){
Game.type = (tmp.find("./cod4")==0)?"cod4":"cod2";
Game.type += (getPart(tmp, "cracked")=="1")?"c":"";
Game.ip = getPart(tmp, "net_ip");
Game.port = atoi(getPart(tmp, "net_port").c_str());
Game.slots = atoi(getPart(tmp, "sv_maxclients").c_str());
Game.name = getPart(tmp, "sv_hostname");
Game.filename = getPart(tmp, "filename");
Game.arg = tmp;
Games.push_back(Game);
}
}
}
return Games;
}
bool file_exists(string filename){
if(FILE* fp=fopen(filename.c_str(), "r")){
fclose(fp);
return true;
}
return false;
}
strings servers(){
strings re;
string buf;
ifstream is("/var/games/servers.txt", ifstream::in);
if(is.is_open()){
while(!is.eof()){
getline(is, buf);
if(buf.length()>4) re.push_back(buf);
}
is.close();
}
return re;
}
int main(int argc, char* argv[]){
int i;
char buf[1025];
games Games = getGames();
strings Servers = servers();

if(argc==2 && string("-o").compare(argv[1])==0){
cout << endl;
cout << "Running:" << endl;
for(i=0; i<Games.size(); i++){
cout << "\t[" << Games.at(i).pid << "] " << Games.at(i).name << ":\n";
cout << "\t\tGame: " << Games.at(i).type << "\n";
cout << "\t\tIP: " << Games.at(i).ip << "\n";
cout << "\t\tPoort: " << Games.at(i).port << "\n";
cout << "\t\tSlots: " << Games.at(i).slots << "\n";
cout << endl;
}
if(Games.size()==0) cout << "\tNo running servers...\n" << endl;
cout << "The Servers:" << endl;
for(i=0; i<Servers.size(); i++){
cout << "\t[" << (i+1) << "] " << Servers.at(i) << endl;
}
cout << endl;
}else if(argc==3 && string("-stop").compare(argv[1])==0){
for(i=0; i<Games.size(); i++){
if(Games.at(i).pid==atoi(argv[2])){
sprintf(buf, "kill %d > nul", Games.at(i).pid);
system(buf);
}
}
}else if(argc==3 && string("-start").compare(argv[1])==0){
if(atoi(argv[2])>0 && atoi(argv[2])<=Servers.size()){
sprintf(buf, "/var/games/%s", Servers.at(atoi(argv[2])-1).c_str());
if(file_exists(buf)){
system(buf);
}
}
}else if(argc==3 && string("-restart").compare(argv[1])==0){
for(i=0; i<Games.size(); i++){
if(Games.at(i).pid==atoi(argv[2])){
sprintf(buf, "kill %d > nul", Games.at(i).pid);
system(buf);
if(Games.at(i).filename.length()>0){
sprintf(buf, "/var/games/%s/%s > nul", Games.at(i).type.c_str(), Games.at(i).filename.c_str());
system(buf);
}
}
}
}else{
cout << "codservers { -o | -start id | -restart PID | -stop PID }" << endl;
}
return 0;
}


In /var/games/servers.txt staat zoiets:
cod2/publicserver1.sh
cod2/warserver1.sh
cod2c/warserver2.sh
cod2/rifles.sh
cod4/publicserver1.sh
cod4/warserver3.sh
cod4c/publicserver2.sh

en dan heb je dus de mappen cod2, cod2c, cod4, cod4c waar dan de cod binaries in staan.

Voorbeeldje van 1 zo'n .sh bestand:

cd /var/games/cod2 && LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./cod2_lnxded +set filename "publicserver.sh" +set fs_game "...." +set sv_hostname "....." ..... &

en dus het stukje php code:
exec($codserversbin." -start ".$csservers[$i]['id']." > /dev/null");

Kan je er wijs uitworden?

Michel1988
28/03/08, 13:00
Ik heb er 1 voor mijn cod2 server. ./startstop.sh
Indien hulp nodig,, contacteer mij even via msn: m.schuiling@hotmail.com

daanl
28/03/08, 14:02
waarom werken jullie niet met screen? Gewoon screen grep process en killen maar ipv die sh scriptjes

D. ter Horst
28/03/08, 17:15
ofsow = ofzo? ;)

dirk939
29/03/08, 16:13
exec("codservers -start ".$csservers[$i]['id']." > /dev/null");

Om een backgroundprocess op te starten kun je er " >/dev/null 2>&1 &" achter plaatsen.

Dus:

exec('/path/to/binary >/dev/null 2>&1 &');

In dit geval lijkt me het verstandig om te zorgen dat codservers als een andere user draait. Dit kun je bijvoorbeeld realiseren door middel van een wrapper.

vdvleon
30/03/08, 15:06
Kan je een voorbeeld geven?

dirk939
31/03/08, 19:57
Zoek eens op setuid wrapper. Je kunt ook sudo gebruiken (eenvoudiger).

vdvleon
03/04/08, 16:52
Ik heb nu zo opgelost:

heb een bestand waar alle regels in komen die moeten uitgevoerd worden. En ik heb een script geschreven die dat bestand uitvoerd (regel per regel) en dan leeg maakt. Dit script draait via crontab elke minuut.

Via php schrijf ik dan de tekst die nodig is om de server te starten, restart, etc. Dit kan je dus als elke user doen, maar doe nu als root. Nu blijven de servers wel gewoon draaien.

Beetje omslachtig, maar enige wat lukte