@ -23,8 +23,6 @@
# include "libraptorsmiface.h"
MYSQL * conn = 0 ;
char * server = " localhost " ;
char * user = " remotelab " ;
char * password = " rlpass123 " ; /* set me first */
@ -38,7 +36,7 @@ void dprint(const char *fmt, ...)
#if 0
vprintf ( fmt , argp ) ;
# else
char debug [ 10 24 ] ;
char debug [ 5 12] ;
vsprintf ( debug , fmt , argp ) ;
FILE * fp = fopen ( " /raptorsmiface.debug " , " a " ) ;
if ( fp ! = NULL )
@ -51,14 +49,13 @@ void dprint(const char *fmt, ...)
va_end ( argp ) ;
}
void connect_if_needed ( ) {
if ( ! conn ) {
conn = mysql_init ( NULL ) ;
if ( ! mysql_real_connect ( conn , server , user , password , database , 0 , NULL , 0 ) ) {
dprint ( " [ERROR] MySQL connection FAILED [%s] \n \r " , mysql_error ( conn ) ) ;
conn = 0 ;
}
MYSQL * connect_if_needed ( ) {
MYSQL * conn = mysql_init ( NULL ) ;
if ( ! mysql_real_connect ( conn , server , user , password , database , 0 , NULL , 0 ) ) {
dprint ( " [ERROR] MySQL connection FAILED [%s] \n \r " , mysql_error ( conn ) ) ;
conn = 0 ;
}
return conn ;
}
char * get_mysql_escaped_string ( MYSQL * sqlcn , char * rawstr ) {
@ -69,6 +66,13 @@ char* get_mysql_escaped_string(MYSQL *sqlcn, char* rawstr) {
return escstr ;
}
char mutex ;
int mysql_query_internal ( MYSQL * conn , const char * query ) {
// For some reason this can hang rather badly
// It might be related to concurrent access to the same conn object though
return mysql_query ( conn , query ) ;
}
char * get_group_for_user ( char * username ) {
struct passwd * pwd ;
pwd = getpwnam ( username ) ;
@ -94,7 +98,7 @@ char raptor_sm_deallocate_session(char* username) {
MYSQL_ROW cnt_row ;
char * query ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return 1 ;
}
@ -103,13 +107,15 @@ char raptor_sm_deallocate_session(char* username) {
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " DELETE FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return 2 ;
}
else {
free ( query ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
@ -123,7 +129,7 @@ char* raptor_sm_allocate_session(char* username) {
MYSQL_ROW cnt_row ;
char * query ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return strdup ( " SQLERR001 " ) ;
}
@ -132,9 +138,10 @@ char* raptor_sm_allocate_session(char* username) {
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT servername FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( " SQLERR002 " ) ;
}
else {
@ -143,9 +150,10 @@ char* raptor_sm_allocate_session(char* username) {
if ( ( row = mysql_fetch_row ( res ) ) = = NULL ) {
// User is not on a system
// Find the least utilized node
if ( mysql_query ( conn , " SELECT name FROM servers " ) ) {
if ( mysql_query _internal ( conn , " SELECT name FROM servers WHERE online='1' " ) ) {
// Server error
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return strdup ( " SQLERR003 " ) ;
}
else {
@ -156,12 +164,13 @@ char* raptor_sm_allocate_session(char* username) {
char * safe_servername = get_mysql_escaped_string ( conn , svr_row [ 0 ] ) ;
asprintf ( & query , " SELECT username FROM sessions WHERE servername='%s' " , safe_servername ) ;
free ( safe_servername ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
free ( bestserver ) ;
mysql_free_result ( res ) ;
mysql_free_result ( svr_res ) ;
mysql_close ( conn ) ;
return strdup ( " SQLERR004 " ) ;
}
else {
@ -188,13 +197,15 @@ char* raptor_sm_allocate_session(char* username) {
asprintf ( & query , " INSERT INTO sessions (username, servername, state) VALUES ('%s', '%s', '%d') " , safe_username , safe_servername , SM_STATUS_ALLOCATED ) ;
free ( safe_servername ) ;
free ( safe_username ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( " SQLERR005 " ) ;
}
else {
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( bestserver ) ;
}
}
@ -202,6 +213,7 @@ char* raptor_sm_allocate_session(char* username) {
else {
char * ret = strdup ( row [ 0 ] ) ;
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
}
@ -234,7 +246,7 @@ char* raptor_sm_get_hostname_for_username(char* username, bool create) {
MYSQL_ROW row ;
char * query ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return strdup ( " SQLERR100 " ) ;
}
@ -242,9 +254,10 @@ char* raptor_sm_get_hostname_for_username(char* username, bool create) {
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT servername FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( " SQLERR101 " ) ;
}
else {
@ -253,15 +266,18 @@ char* raptor_sm_get_hostname_for_username(char* username, bool create) {
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
char * ret = strdup ( row [ 0 ] ) ;
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
// Nothing in the DB
mysql_free_result ( res ) ;
if ( create ) {
// Try to allocate a new session on a node
mysql_close ( conn ) ;
return raptor_sm_allocate_session ( username ) ;
}
else {
mysql_close ( conn ) ;
return strdup ( " " ) ;
}
}
@ -283,7 +299,7 @@ bool raptor_sm_sesslimit_reached(char* username) {
MYSQL_ROW row ;
char * query ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return true ;
}
@ -297,9 +313,10 @@ bool raptor_sm_sesslimit_reached(char* username) {
free ( groupname ) ;
asprintf ( & query , " SELECT sesslimit FROM groups WHERE groupname='%s' " , safe_groupname ) ;
free ( safe_groupname ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return true ;
}
else {
@ -315,9 +332,10 @@ bool raptor_sm_sesslimit_reached(char* username) {
// Figure out how many users are online from this group
int sesscount = 0 ;
asprintf ( & query , " SELECT username FROM sessions WHERE state<>'%d' " , SM_STATUS_ALLOCATED ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return true ;
}
else {
@ -335,12 +353,15 @@ bool raptor_sm_sesslimit_reached(char* username) {
mysql_free_result ( res ) ;
if ( sesscount < sesslimit ) {
mysql_close ( conn ) ;
return false ;
}
mysql_close ( conn ) ;
return true ;
}
// We should never end up here!
mysql_close ( conn ) ;
return true ;
}
@ -349,24 +370,26 @@ pid_t raptor_sm_run_remote_server(char* username, char *const argv[]) {
MYSQL_ROW row ;
char * query ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Respect maximum session number for the group for this user
if ( raptor_sm_sesslimit_reached ( username ) ) {
mysql_close ( conn ) ;
return - 5 ;
}
// Make sure a server is not already running for this user
// Return the existing PID if it is
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT pid FROM sessions WHERE username='%s' AND state<>'%d'" , safe_username , SM_STATUS_ALLOCATED ) ;
asprintf ( & query , " SELECT pid ,servername FROM sessions WHERE username='%s' AND state<>'%d'" , safe_username , SM_STATUS_ALLOCATED ) ;
free ( safe_username ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
@ -376,8 +399,31 @@ pid_t raptor_sm_run_remote_server(char* username, char *const argv[]) {
if ( row [ 0 ] ) {
int ret = atoi ( row [ 0 ] ) ;
if ( ret > = 0 ) {
mysql_free_result ( res ) ;
return ret ;
// Verify existence of PID on remote server
dprint ( " Verifying process %d on %s... \n \r " , ret , row [ 1 ] ) ;
char * ip = raptor_sm_get_ip_for_hostname ( row [ 1 ] , 0 ) ;
char * command_string ;
asprintf ( & command_string , " ssh root@%s \' ps -p %d | grep %d \' " , ip , ret , ret ) ;
FILE * fp ;
char output [ 1024 ] ;
// Open the command for reading
fp = popen ( command_string , " r " ) ;
if ( fp = = NULL ) {
mysql_close ( conn ) ;
return - 1 ;
}
// Read the output a line at a time
fgets ( output , sizeof ( output ) - 1 , fp ) ;
// Close output
pclose ( fp ) ;
free ( command_string ) ;
free ( ip ) ;
dprint ( " ...result was %s \n \r " , output ) ;
if ( strcmp ( output , " " ) ! = 0 ) {
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
}
}
}
@ -402,7 +448,7 @@ pid_t raptor_sm_run_remote_server(char* username, char *const argv[]) {
free ( origstr ) ;
}
char * origstr = command_string ;
asprintf ( & command_string , " ssh %s \' %s & echo $! & \' " , ipaddr , origstr ) ;
asprintf ( & command_string , " ssh root@ %s \' %s & echo $! & \' " , ipaddr , origstr ) ;
free ( origstr ) ;
FILE * fp ;
@ -411,6 +457,7 @@ pid_t raptor_sm_run_remote_server(char* username, char *const argv[]) {
// Open the command for reading
fp = popen ( command_string , " r " ) ;
if ( fp = = NULL ) {
mysql_close ( conn ) ;
return - 1 ;
}
@ -422,9 +469,51 @@ pid_t raptor_sm_run_remote_server(char* username, char *const argv[]) {
free ( command_string ) ;
mysql_close ( conn ) ;
return atoi ( output ) ;
}
pid_t raptor_sm_get_pid_for_username ( char * username ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Make sure a server is not already running for this user
// Return the existing PID if it is
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT pid FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
if ( row [ 0 ] ) {
int ret = atoi ( row [ 0 ] ) ;
if ( ret > = 0 ) {
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
}
}
mysql_free_result ( res ) ;
}
mysql_close ( conn ) ;
return - 3 ;
}
char * raptor_sm_server_started ( char * username , pid_t pid , int display ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
@ -432,7 +521,7 @@ char* raptor_sm_server_started(char* username, pid_t pid, int display) {
long long timestamp = time ( NULL ) ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
@ -441,13 +530,15 @@ char* raptor_sm_server_started(char* username, pid_t pid, int display) {
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " UPDATE sessions SET pid='%d', stamp_start='%lld', state='%d', display='%d', stamp_statechange='%lld' WHERE username='%s' AND state='%d' " , pid , timestamp , SM_STATUS_RUNNING , display , timestamp , safe_username , SM_STATUS_ALLOCATED ) ;
free ( safe_username ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
@ -457,7 +548,7 @@ int raptor_sm_get_display_for_username(char* username) {
MYSQL_ROW row ;
char * query ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
@ -465,9 +556,10 @@ int raptor_sm_get_display_for_username(char* username) {
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT display FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
@ -477,15 +569,18 @@ int raptor_sm_get_display_for_username(char* username) {
if ( row [ 0 ] ) {
int ret = atoi ( row [ 0 ] ) ;
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
else {
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return - 3 ;
}
}
// Nothing in the DB
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return - 4 ;
}
}
@ -494,7 +589,7 @@ void raptor_sm_wait_for_pid_exit(char* username, pid_t pid) {
char * ipaddr = raptor_sm_get_ip_for_username ( username , false ) ;
char * command_string ;
asprintf ( & command_string , " ssh %s \' while [[ `ps -p %d | grep %d` != \" \" ]]; do sleep 1; done \' " , ipaddr , pid , pid ) ;
asprintf ( & command_string , " ssh root@ %s \' while [[ `ps -p %d | grep %d` != \" \" ]]; do sleep 1; done \' " , ipaddr , pid , pid ) ;
system ( command_string ) ;
free ( command_string ) ;
}
@ -508,15 +603,16 @@ int raptor_sm_get_new_unique_display(int mindisplay, int maxdisplay) {
MYSQL_ROW row ;
char * query ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
asprintf ( & query , " SELECT display FROM sessions " ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
@ -538,6 +634,7 @@ int raptor_sm_get_new_unique_display(int mindisplay, int maxdisplay) {
}
}
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return freedisp ;
}
}
@ -549,20 +646,38 @@ char raptor_sm_set_session_state(int display, int state) {
long long timestamp = time ( NULL ) ;
connect_if_needed ( ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Update new state into the sessions database
asprintf ( & query , " UPDATE sessions SET state='%d', stamp_statechange='%lld' WHERE display='%d' " , state , timestamp , display ) ;
if ( mysql_query ( conn , query ) ) {
if ( mysql_query _internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
void raptor_sm_run_remote_desktop ( char * username , int display , char * executable ) {
char * ipaddr = raptor_sm_get_ip_for_username ( username , true ) ;
char * command_string ;
asprintf ( & command_string , " ssh root@%s \" su %s -c \' export DISPLAY=:%d && %s && exit \' &> /dev/null \" " , ipaddr , username , display , executable ) ;
system ( command_string ) ;
free ( command_string ) ;
// Terminate remote X server
pid_t pid = raptor_sm_get_pid_for_username ( username ) ;
if ( pid > 0 ) {
asprintf ( & command_string , " ssh root@%s \' kill -9 %ld \' " , ipaddr , pid ) ;
system ( command_string ) ;
free ( command_string ) ;
}
}