mirror of https://github.com/BOINC/boinc.git
Merge branch 'master' of ssh://boinc.berkeley.edu/boinc
This commit is contained in:
commit
f728f4e9d4
|
@ -1,55 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is part of BOINC.
|
||||
http://boinc.berkeley.edu
|
||||
Copyright (C) 2012 University of California
|
||||
|
||||
BOINC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation,
|
||||
either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
BOINC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/status_error"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:onClick="reinitClient" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="30dip"
|
||||
android:layout_marginTop="30dip"
|
||||
android:contentDescription="@string/status_error"
|
||||
android:src="@drawable/reloadw48"
|
||||
android:onClick="reinitClient" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dip"
|
||||
android:layout_marginRight="20dip"
|
||||
android:gravity="center"
|
||||
android:text="@string/status_error_long"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:onClick="reinitClient" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is part of BOINC.
|
||||
http://boinc.berkeley.edu
|
||||
Copyright (C) 2012 University of California
|
||||
|
||||
BOINC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation,
|
||||
either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
BOINC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="20dip"
|
||||
android:text="@string/status_launching"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar1"
|
||||
style="?android:attr/progressBarStyleLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
|
@ -1,108 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
This file is part of BOINC.
|
||||
http://boinc.berkeley.edu
|
||||
Copyright (C) 2012 University of California
|
||||
|
||||
BOINC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation,
|
||||
either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
BOINC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
See the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dip"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/status_noproject"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dip"
|
||||
android:layout_marginRight="20dip"
|
||||
android:layout_marginTop="20dip"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/status_noproject_long"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="50dip"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="70dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:text="@string/status_noproject_email"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/emailIn"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginRight="20dip"
|
||||
android:ems="10"
|
||||
android:inputType="textEmailAddress" >
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dip"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:layout_width="70dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:text="@string/status_noproject_pwd"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/pwdIn"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginRight="20dip"
|
||||
android:ems="10"
|
||||
android:inputType="textPassword" >
|
||||
<requestFocus />
|
||||
</EditText>
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/loginConfirmButton"
|
||||
android:layout_width="150dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="30dip"
|
||||
android:onClick="loginButtonClicked"
|
||||
android:text="@string/status_noproject_button" />
|
||||
|
||||
</LinearLayout>
|
|
@ -30,5 +30,5 @@
|
|||
<bool name="tab_preferences">true</bool>
|
||||
<bool name="tab_projects">true</bool>
|
||||
<bool name="tab_messages">false</bool>
|
||||
<bool name="tab_debug">true</bool>
|
||||
<bool name="tab_debug">false</bool>
|
||||
</resources>
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<!-- path and file configuration -->
|
||||
<string name="client_name">boinc</string>
|
||||
<string name="client_path">/data/data/edu.berkeley.boinc/client/</string>
|
||||
<string name="client_cabundle">ca-bundle.crt</string>
|
||||
<string name="auth_file_name">gui_rpc_auth.cfg</string>
|
||||
|
||||
<!-- login activity -->
|
||||
|
@ -105,15 +106,15 @@
|
|||
<!-- preferences tab strings -->
|
||||
<string name="prefs_unbound">Reading preferences…</string>
|
||||
<string name="prefs_submit_button">OK</string>
|
||||
<string name="prefs_run_on_battery_header">Battery</string>
|
||||
<string name="prefs_run_on_battery_header">Calculate on Battery</string>
|
||||
<string name="prefs_run_on_battery_true">Calculation while running on battery</string>
|
||||
<string name="prefs_run_on_battery_false">Calculation only when connected to charger</string>
|
||||
<string name="prefs_disk_max_pct_header">Maximal used storage space (in %)</string>
|
||||
<string name="prefs_disk_min_free_gb_header">Storage left unused (in GB)</string>
|
||||
<string name="prefs_daily_xfer_limit_mb_header">Data transfer limit (daily, in MB)</string>
|
||||
<string name="prefs_network_wifi_only_header">Use only WiFi</string>
|
||||
<string name="prefs_network_wifi_only_true">Transfer only on WiFi</string>
|
||||
<string name="prefs_network_wifi_only_false">Transfer on all networks</string>
|
||||
<string name="prefs_network_wifi_only_header">Fetch work only on WiFi</string>
|
||||
<string name="prefs_network_wifi_only_true">Transfer project work only on WiFi connection</string>
|
||||
<string name="prefs_network_wifi_only_false">Transfer project work on all networks</string>
|
||||
<string name="prefs_autostart_header">Autostart</string>
|
||||
<string name="prefs_autostart_true">BOINC starts on boot up</string>
|
||||
<string name="prefs_autostart_false">Start BOINC manually</string>
|
||||
|
@ -153,17 +154,5 @@
|
|||
<string name="debug_refresh">Refresh</string>
|
||||
<string name="debug_manager_header">AndroidBOINC manager messages:</string>
|
||||
<string name="debug_client_header">BOINC Client messages:</string>
|
||||
<string name="status_error">error</string>
|
||||
<string name="status_error_long">error</string>
|
||||
<string name="status_launching">Launching</string>
|
||||
<string name="status_noproject_button">no project</string>
|
||||
<string name="status_noproject_email">email</string>
|
||||
<string name="status_noproject_long">long</string>
|
||||
<string name="status_noproject_pwd">Password</string>
|
||||
<string name="status_noproject">Project</string>
|
||||
<string name="client_cabundle">ca-bundle.crt</string>
|
||||
|
||||
|
||||
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,174 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* This file is part of BOINC.
|
||||
* http://boinc.berkeley.edu
|
||||
* Copyright (C) 2012 University of California
|
||||
*
|
||||
* BOINC is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* BOINC is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
package edu.berkeley.boinc;
|
||||
|
||||
import edu.berkeley.boinc.client.ClientStatus;
|
||||
import edu.berkeley.boinc.client.Monitor;
|
||||
import android.app.TabActivity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TabHost.TabSpec;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class AndroidBOINCActivity extends TabActivity {
|
||||
|
||||
private final String TAG = "AndroidBOINCActivity";
|
||||
|
||||
private Monitor monitor;
|
||||
public static ClientStatus client;
|
||||
|
||||
private Boolean mIsBound;
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
// This is called when the connection with the service has been established, getService returns the Monitor object that is needed to call functions.
|
||||
monitor = ((Monitor.LocalBinder)service).getService();
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
// This should not happen
|
||||
monitor = null;
|
||||
Toast.makeText(getApplicationContext(), "service disconnected", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
};
|
||||
|
||||
private void doBindService() {
|
||||
// Service has to be started "sticky" by the first instance that uses it. It causes the service to stay around, even when all Activities are destroyed (on purpose or by the system)
|
||||
// check whether service already started by BootReceiver is done within the service.
|
||||
startService(new Intent(this,Monitor.class));
|
||||
|
||||
// Establish a connection with the service, onServiceConnected gets called when
|
||||
bindService(new Intent(this, Monitor.class), mConnection, 0);
|
||||
mIsBound = true;
|
||||
}
|
||||
|
||||
private void doUnbindService() {
|
||||
if (mIsBound) {
|
||||
// Detach existing connection.
|
||||
unbindService(mConnection);
|
||||
mIsBound = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.d(TAG, "onDestroy");
|
||||
doUnbindService();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
Log.d(TAG, "onCreate");
|
||||
|
||||
//bind monitor service
|
||||
doBindService();
|
||||
|
||||
//setup tab layout
|
||||
setupTabLayout();
|
||||
}
|
||||
|
||||
public static void logMessage(Context ctx, String tag, String message) {
|
||||
Intent testLog = new Intent();
|
||||
testLog.setAction("edu.berkeley.boinc.log");
|
||||
testLog.putExtra("message", message);
|
||||
testLog.putExtra("tag", tag);
|
||||
ctx.sendBroadcast(testLog);
|
||||
}
|
||||
|
||||
/*
|
||||
* setup tab layout.
|
||||
* which tabs should be set up is defined in resources file: /res/values/configuration.xml
|
||||
*/
|
||||
private void setupTabLayout() {
|
||||
|
||||
Resources res = getResources();
|
||||
TabHost tabHost = getTabHost();
|
||||
|
||||
if(res.getBoolean(R.bool.tab_status)) {
|
||||
TabSpec statusSpec = tabHost.newTabSpec(getResources().getString(R.string.tab_status));
|
||||
statusSpec.setIndicator(getResources().getString(R.string.tab_status), getResources().getDrawable(R.drawable.icon_status_tab));
|
||||
Intent statusIntent = new Intent(this,StatusActivity.class);
|
||||
statusSpec.setContent(statusIntent);
|
||||
tabHost.addTab(statusSpec);
|
||||
}
|
||||
|
||||
if(res.getBoolean(R.bool.tab_tasks)) {
|
||||
TabSpec tasksSpec = tabHost.newTabSpec(getResources().getString(R.string.tab_tasks));
|
||||
tasksSpec.setIndicator(getResources().getString(R.string.tab_tasks), getResources().getDrawable(R.drawable.icon_tasks_tab));
|
||||
Intent tasksIntent = new Intent(this,TasksActivity.class);
|
||||
tasksSpec.setContent(tasksIntent);
|
||||
tabHost.addTab(tasksSpec);
|
||||
}
|
||||
|
||||
if(res.getBoolean(R.bool.tab_transfers)) {
|
||||
TabSpec transSpec = tabHost.newTabSpec(getResources().getString(R.string.tab_transfers));
|
||||
transSpec.setIndicator(getResources().getString(R.string.tab_transfers), getResources().getDrawable(R.drawable.icon_trans_tab));
|
||||
Intent transIntent = new Intent(this,TransActivity.class);
|
||||
transSpec.setContent(transIntent);
|
||||
tabHost.addTab(transSpec);
|
||||
}
|
||||
|
||||
if(res.getBoolean(R.bool.tab_preferences)) {
|
||||
TabSpec prefsSpec = tabHost.newTabSpec(getResources().getString(R.string.tab_preferences));
|
||||
prefsSpec.setIndicator(getResources().getString(R.string.tab_preferences), getResources().getDrawable(R.drawable.icon_prefs_tab));
|
||||
Intent prefsIntent = new Intent(this,PrefsActivity.class);
|
||||
prefsSpec.setContent(prefsIntent);
|
||||
tabHost.addTab(prefsSpec);
|
||||
}
|
||||
|
||||
if(res.getBoolean(R.bool.tab_projects)) {
|
||||
TabSpec projectsSpec = tabHost.newTabSpec(getResources().getString(R.string.tab_projects));
|
||||
projectsSpec.setIndicator(getResources().getString(R.string.tab_projects), getResources().getDrawable(R.drawable.icon_projects_tab));
|
||||
Intent projectsIntent = new Intent(this,ProjectsActivity.class);
|
||||
projectsSpec.setContent(projectsIntent);
|
||||
tabHost.addTab(projectsSpec);
|
||||
}
|
||||
|
||||
if(res.getBoolean(R.bool.tab_messages)) {
|
||||
TabSpec msgsSpec = tabHost.newTabSpec(getResources().getString(R.string.tab_messages));
|
||||
msgsSpec.setIndicator(getResources().getString(R.string.tab_messages), getResources().getDrawable(R.drawable.icon_msgs_tab));
|
||||
Intent msgsIntent = new Intent(this,MsgsActivity.class);
|
||||
msgsSpec.setContent(msgsIntent);
|
||||
tabHost.addTab(msgsSpec);
|
||||
}
|
||||
|
||||
if(res.getBoolean(R.bool.tab_debug)) {
|
||||
TabSpec debugSpec = tabHost.newTabSpec(getResources().getString(R.string.tab_debug));
|
||||
debugSpec.setIndicator(getResources().getString(R.string.tab_debug), getResources().getDrawable(R.drawable.icon_debug_tab));
|
||||
Intent debugIntent = new Intent(this,DebugActivity.class);
|
||||
debugSpec.setContent(debugIntent);
|
||||
tabHost.addTab(debugSpec);
|
||||
}
|
||||
|
||||
Log.d(TAG,"tab layout setup done");
|
||||
|
||||
AndroidBOINCActivity.logMessage(this, TAG, "tab setup finished");
|
||||
}
|
||||
}
|
|
@ -71,7 +71,7 @@ public class PrefsActivity extends Activity implements OnClickListener {
|
|||
private BroadcastReceiver mClientStatusChangeRec = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context,Intent intent) {
|
||||
Log.d(TAG+"-localClientStatusRecNoisy","received");
|
||||
//Log.d(TAG+"-localClientStatusRecNoisy","received");
|
||||
if(dataOutdated) { //cause activity to re-init layout
|
||||
Log.d(TAG, "data was outdated, go directly to reinitPrefsLayout");
|
||||
dataOutdated = false;
|
||||
|
@ -150,7 +150,7 @@ public class PrefsActivity extends Activity implements OnClickListener {
|
|||
Log.d(TAG, "readPrefs: null, return false");
|
||||
return false;
|
||||
}
|
||||
Log.d(TAG, "readPrefs done");
|
||||
//Log.d(TAG, "readPrefs done");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ public class PrefsActivity extends Activity implements OnClickListener {
|
|||
//init layout instead
|
||||
reinitPrefsLayout();
|
||||
} else {
|
||||
Log.d(TAG, "loadSettings outdated: " + dataOutdated );
|
||||
//Log.d(TAG, "loadSettings outdated: " + dataOutdated );
|
||||
if(dataOutdated) { //data is not present or not current, show loading instead!
|
||||
setContentView(R.layout.prefs_layout_loading);
|
||||
} else {
|
||||
|
@ -178,6 +178,8 @@ public class PrefsActivity extends Activity implements OnClickListener {
|
|||
((PrefsListItemWrapperDouble)data.get(5)).status = clientPrefs.daily_xfer_limit_mb;
|
||||
|
||||
listAdapter.notifyDataSetChanged(); //force list adapter to refresh
|
||||
|
||||
//Log.d(TAG,"max used pct: " + clientPrefs.disk_max_used_pct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +312,7 @@ public class PrefsActivity extends Activity implements OnClickListener {
|
|||
break;
|
||||
case R.string.prefs_disk_min_free_gb_header:
|
||||
tmp=tmp.replaceAll(",","."); //replace e.g. European decimal seperator "," by "."
|
||||
clientPrefs.disk_max_used_gb = Double.parseDouble(tmp);
|
||||
clientPrefs.disk_min_free_gb = Double.parseDouble(tmp);
|
||||
monitor.setPrefs(clientPrefs);
|
||||
dataOutdated = true; //async write of client prefs started, data out dated until broadcast
|
||||
break;
|
||||
|
|
|
@ -25,8 +25,10 @@ import java.io.FileOutputStream;
|
|||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
|
@ -490,19 +492,23 @@ public class Monitor extends Service{
|
|||
|
||||
private Boolean startUp() {
|
||||
|
||||
//kill client of previous life-cycle
|
||||
Integer clientPid = getPidForProcessName(getResources().getString(R.string.client_path) + getResources().getString(R.string.client_name));
|
||||
if(clientPid!=null) { //client process exists
|
||||
Log.d(TAG, "client process exists with pid: " + clientPid);
|
||||
android.os.Process.killProcess(clientPid);
|
||||
}
|
||||
|
||||
Boolean connect = connectClient(); //try to connect, if client got started in previous life-cycle
|
||||
|
||||
if(!connect) { //if connect did not work, start new client instance and run connect attempts in loop
|
||||
|
||||
Integer counter = 0;
|
||||
//install and execute client
|
||||
Boolean setup = setupClient();
|
||||
if(!setup) {
|
||||
return false; //setup failed
|
||||
}
|
||||
|
||||
//try to connect to executed Client in loop
|
||||
while(!(connect=connectClient()) && (counter<retryAttempts)) { //re-trys setting up the client several times, before giving up.
|
||||
Boolean connected = false;
|
||||
Integer counter = 0;
|
||||
while(!(connected=connectClient()) && (counter<retryAttempts)) { //re-trys setting up the client several times, before giving up.
|
||||
MainActivity.logMessage(getApplicationContext(), TAG, "--- restart setup ---");
|
||||
counter++;
|
||||
try {
|
||||
|
@ -510,13 +516,7 @@ public class Monitor extends Service{
|
|||
}catch (Exception e) {}
|
||||
}
|
||||
|
||||
if(!connect) { //connect still not succeeded.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//client is connected.
|
||||
return true;
|
||||
return connected;
|
||||
}
|
||||
|
||||
private Boolean connectClient() {
|
||||
|
@ -551,7 +551,7 @@ public class Monitor extends Service{
|
|||
|
||||
publishProgress("Client setup.");
|
||||
|
||||
success = installClient(false);
|
||||
success = installClient(true);
|
||||
if(success) {
|
||||
publishProgress("installed. (1/2)");
|
||||
}
|
||||
|
@ -671,7 +671,41 @@ public class Monitor extends Service{
|
|||
return rpc.authorize(authKey);
|
||||
}
|
||||
|
||||
// get PID for process name using native 'ps' console command
|
||||
private Integer getPidForProcessName(String processName) {
|
||||
|
||||
//run ps and read output
|
||||
StringBuffer sb = new StringBuffer();
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec("ps");
|
||||
p.waitFor();
|
||||
InputStreamReader isr = new InputStreamReader(p.getInputStream());
|
||||
int ch;
|
||||
char [] buf = new char[1024];
|
||||
while((ch = isr.read(buf)) != -1)
|
||||
{
|
||||
sb.append(buf, 0, ch);
|
||||
}
|
||||
}catch (Exception e) {Log.e(TAG, "getPidForProcessName", e);}
|
||||
|
||||
//parse output into hashmap
|
||||
HashMap<String,Integer> pMap = new HashMap<String, Integer>();
|
||||
String [] processLinesAr = sb.toString().split("\n");
|
||||
for(String line : processLinesAr)
|
||||
{
|
||||
Integer pid;
|
||||
String packageName;
|
||||
String [] comps = line.split("[\\s]+");
|
||||
if(comps.length != 9) {continue;}
|
||||
pid = Integer.parseInt(comps[1]);
|
||||
packageName = comps[8];
|
||||
pMap.put(packageName, pid);
|
||||
//Log.d(TAG,"added: " + packageName + pid);
|
||||
}
|
||||
|
||||
//find required pid
|
||||
return pMap.get(processName);
|
||||
}
|
||||
}
|
||||
|
||||
private final class ProjectAttachAsync extends AsyncTask<String,String,Boolean> {
|
||||
|
@ -785,6 +819,7 @@ public class Monitor extends Service{
|
|||
Log.d(TAG, "doInBackground");
|
||||
Boolean retval1 = rpc.setGlobalPrefsOverrideStruct(params[0]); //set new override settings
|
||||
Boolean retval2 = rpc.readGlobalPrefsOverride(); //trigger reload of override settings
|
||||
Log.d(TAG,retval1.toString() + retval2);
|
||||
if(retval1 && retval2) {
|
||||
Log.d(TAG, "successful.");
|
||||
return true;
|
||||
|
|
|
@ -20,8 +20,8 @@ package edu.berkeley.boinc.debug;
|
|||
|
||||
public class Logging {
|
||||
|
||||
static public Boolean DEBUG = true;
|
||||
static public Boolean INFO = true;
|
||||
static public Boolean DEBUG = false;
|
||||
static public Boolean INFO = false;
|
||||
static public Boolean ERROR = true;
|
||||
static public Boolean WARNING = true;
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* This file is part of BOINC.
|
||||
* http://boinc.berkeley.edu
|
||||
* Copyright (C) 2012 University of California
|
||||
*
|
||||
* BOINC is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* BOINC is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
package edu.berkeley.boinc.receiver;
|
||||
|
||||
import edu.berkeley.boinc.client.ClientStatus;
|
||||
import edu.berkeley.boinc.client.Monitor;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
public class ClientStatusChangeReceiver extends BroadcastReceiver {
|
||||
|
||||
private ClientStatus status;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d("ClientStatusChangeReceiver", "onReceive");
|
||||
|
||||
//set status of client
|
||||
status = Monitor.getClientStatus();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -420,8 +420,9 @@ void ACTIVE_TASK::handle_exited_app(int stat) {
|
|||
strcpy(buf, "");
|
||||
if (temporary_exit_file_present(x, buf)) {
|
||||
handle_temporary_exit(will_restart, x, buf);
|
||||
}
|
||||
} else {
|
||||
handle_premature_exit(will_restart);
|
||||
}
|
||||
break;
|
||||
case 0xc000013a: // control-C??
|
||||
case 0x40010004: // vista shutdown?? can someone explain this?
|
||||
|
|
|
@ -768,6 +768,13 @@ bool CLIENT_STATE::poll_slow_events() {
|
|||
start_cpu_benchmarks();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (have_sysmon_msg) {
|
||||
msg_printf(NULL, MSG_INFO, sysmon_msg);
|
||||
have_sysmon_msg = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool old_user_active = user_active;
|
||||
user_active = !host_info.users_idle(
|
||||
check_all_logins, global_prefs.idle_time_to_run
|
||||
|
@ -836,7 +843,10 @@ bool CLIENT_STATE::poll_slow_events() {
|
|||
//
|
||||
first = false;
|
||||
if (suspend_reason) {
|
||||
print_suspend_tasks_message(suspend_reason);
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"Suspending computation - %s",
|
||||
suspend_reason_string(suspend_reason)
|
||||
);
|
||||
}
|
||||
}
|
||||
tasks_suspended = (suspend_reason != 0);
|
||||
|
|
|
@ -501,9 +501,6 @@ extern double calculate_exponential_backoff(
|
|||
int n, double MIN, double MAX
|
||||
);
|
||||
|
||||
extern void print_suspend_tasks_message(int);
|
||||
|
||||
|
||||
//////// TIME-RELATED CONSTANTS ////////////
|
||||
|
||||
//////// CLIENT INTERNAL
|
||||
|
|
|
@ -285,33 +285,34 @@ int CLIENT_STATE::check_suspend_processing() {
|
|||
}
|
||||
}
|
||||
|
||||
if (log_flags.cpu_sched) {
|
||||
if (old_gpu_suspend_reason && !gpu_suspend_reason) {
|
||||
msg_printf(NULL, MSG_INFO, "[cpu_sched] resuming GPU activity");
|
||||
if (log_flags.task) {
|
||||
msg_printf(NULL, MSG_INFO, "[task] resuming GPU activity");
|
||||
}
|
||||
request_schedule_cpus("GPU resumption");
|
||||
} else if (!old_gpu_suspend_reason && gpu_suspend_reason) {
|
||||
msg_printf(NULL, MSG_INFO, "[cpu_sched] suspending GPU activity");
|
||||
request_schedule_cpus("GPU suspension");
|
||||
if (log_flags.task) {
|
||||
msg_printf(NULL, MSG_INFO, "[task] suspending GPU activity");
|
||||
}
|
||||
request_schedule_cpus("GPU suspension");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void print_suspend_tasks_message(int reason) {
|
||||
msg_printf(NULL, MSG_INFO, "Suspending computation - %s", suspend_reason_string(reason));
|
||||
}
|
||||
|
||||
|
||||
int CLIENT_STATE::suspend_tasks(int reason) {
|
||||
if (reason == SUSPEND_REASON_CPU_THROTTLE) {
|
||||
if (log_flags.cpu_sched) {
|
||||
msg_printf(NULL, MSG_INFO, "[cpu_sched] Suspending - CPU throttle");
|
||||
}
|
||||
} else {
|
||||
print_suspend_tasks_message(reason);
|
||||
if (log_flags.task) {
|
||||
msg_printf(NULL, MSG_INFO,
|
||||
"[task] Suspending computation - %s",
|
||||
suspend_reason_string(reason)
|
||||
);
|
||||
}
|
||||
}
|
||||
active_tasks.suspend_all(reason);
|
||||
return 0;
|
||||
|
@ -324,7 +325,9 @@ int CLIENT_STATE::resume_tasks(int reason) {
|
|||
}
|
||||
active_tasks.unsuspend_all();
|
||||
} else {
|
||||
msg_printf(NULL, MSG_INFO, "Resuming computation");
|
||||
if (log_flags.task) {
|
||||
msg_printf(NULL, MSG_INFO, "[task] Resuming computation");
|
||||
}
|
||||
active_tasks.unsuspend_all();
|
||||
request_schedule_cpus("Resuming computation");
|
||||
}
|
||||
|
|
|
@ -63,21 +63,27 @@
|
|||
// if value cant be read, default return false
|
||||
//
|
||||
bool HOST_INFO::host_wifi_online() {
|
||||
char wifipath[1024];
|
||||
snprintf(wifipath, sizeof(wifipath), "/sys/class/net/eth0/operstate");
|
||||
char wifipath_pri[1024];
|
||||
snprintf(wifipath_pri, sizeof(wifipath_pri), "/sys/class/net/eth0/operstate"); //location in Android 2.3
|
||||
char wifipath_sec[1024];
|
||||
snprintf(wifipath_sec, sizeof(wifipath_sec), "/sys/class/net/wlan0/operstate"); //location in Android 4
|
||||
|
||||
FILE *fsyswifi = fopen(wifipath_pri, "r");
|
||||
if(!fsyswifi) { //primary location not available, try _sec
|
||||
fsyswifi = fopen(wifipath_sec, "r");
|
||||
}
|
||||
|
||||
FILE *fsyswifi = fopen(wifipath, "r");
|
||||
char wifi_state[64];
|
||||
|
||||
bool wifi_online = false;
|
||||
|
||||
if (fsyswifi) {
|
||||
(void) fscanf(fsyswifi, "%s", &wifi_state);
|
||||
fclose(fsyswifi);
|
||||
} else {
|
||||
LOGD("wifi adapter not found!");
|
||||
}
|
||||
|
||||
if ((strcmp(wifi_state,"up")) == 0) { //operstate = up
|
||||
LOGD("wifi is online");
|
||||
wifi_online = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,4 +131,4 @@ alter table assignment
|
|||
add index asgn_target(target_type, target_id);
|
||||
|
||||
alter table job_file
|
||||
add index md5(md5);
|
||||
add unique jf_md5(md5);
|
||||
|
|
|
@ -34,7 +34,12 @@ $info_sites = array(
|
|||
"(survey of volunteer computing, including non-BOINC projects)"
|
||||
),
|
||||
array(
|
||||
"http://www.kd-web.info/clanky.php",
|
||||
"http://www.rechenkraft.net/wiki/",
|
||||
"Rechenkraft.net wiki",
|
||||
"(German, English, Portuguese)"
|
||||
),
|
||||
array(
|
||||
"http://www.kd-web.info/#%21/boinc",
|
||||
"Flash-based BOINC tutorials", "(in Czech, English, and Slovak)"
|
||||
),
|
||||
//array(
|
||||
|
@ -56,21 +61,21 @@ $info_sites = array(
|
|||
"BOINC Argentina",
|
||||
"(in Spanish)",
|
||||
),
|
||||
array(
|
||||
"http://faq.boinc.de/",
|
||||
"Deutsche BOINC FAQ",
|
||||
"(in German)",
|
||||
),
|
||||
array(
|
||||
"http://www.boincfrance.org/",
|
||||
"BOINCFrance.org",
|
||||
"(in French)",
|
||||
),
|
||||
array(
|
||||
"http://www.crunching-family.at/wiki/",
|
||||
"Crunching Family Wiki",
|
||||
"(In German)",
|
||||
),
|
||||
//array(
|
||||
// "http://faq.boinc.de/",
|
||||
// "Deutsche BOINC FAQ",
|
||||
// "(in German)",
|
||||
//),
|
||||
//array(
|
||||
// "http://www.boincfrance.org/",
|
||||
// "BOINCFrance.org",
|
||||
// "(in French)",
|
||||
//),
|
||||
//array(
|
||||
// "http://www.crunching-family.at/wiki/",
|
||||
// "Crunching Family Wiki",
|
||||
// "(In German)",
|
||||
//),
|
||||
array(
|
||||
"http://www.angelfire.com/jkoulouris-boinc/",
|
||||
"The Big BOINC! Projects and Chronology Page",
|
||||
|
@ -356,9 +361,7 @@ If you'd like to add a web site to this list, please
|
|||
<h2>BOINC-related videos</h2>
|
||||
|
||||
<ul>
|
||||
<li> <a href=http://www.liftconference.com/distributed-computing-distributed-thinking> Francois Grey at Lift, Feb 2008</a>
|
||||
<li> <a href=http://www.youtube.com/watch?v=8iSRLIK-x6A>David Anderson talks about BOINC</a> (2006)
|
||||
<li> <a href=http://video.google.com/videoplay?docid=5863868341014543476&hl=en>David Anderson talks at CPDN Open Day (2004)</a> (33 minutes).
|
||||
<li> <a href=http://www.youtube.com/watch?v=GzATbET3g54>David Baker talks about Rosetta@home</a>
|
||||
</ul>
|
||||
";
|
||||
|
|
|
@ -98,15 +98,15 @@ $stats_sites = array(
|
|||
$team_stats_sites = array(
|
||||
array("http://stats.czechnationalteam.cz/", "Czech National Team", "(in Czech)"),
|
||||
array("http://www.boincitaly.org/", "BOINC.Italy"),
|
||||
array("http://www.spacepage.be/component/option,com_boinc/", "Spacepage"),
|
||||
//array("http://www.spacepage.be/component/option,com_boinc/", "Spacepage"),
|
||||
array("http://boinc.radax.net/de_boinc.htm", "BOINC@Austria"),
|
||||
array("http://www.myboinc.com/scores/", "L'Alliance Francophone"),
|
||||
//array("http://www.myboinc.com/scores/", "L'Alliance Francophone"),
|
||||
array("http://boincdenmark.dk/", "BOINC@Denmark", "(Danish)"),
|
||||
array("http://boincdenmark.dk/default_en.html", "BOINC@Denmark", "(English)"),
|
||||
array("http://www.bigbee.be/comp/boinc/index.php",
|
||||
"Boinc.be team stats",
|
||||
""
|
||||
),
|
||||
//array("http://www.bigbee.be/comp/boinc/index.php",
|
||||
// "Boinc.be team stats",
|
||||
// ""
|
||||
//),
|
||||
array("http://www.seti-teamartbell.com/", "Team Art Bell", ""),
|
||||
array("http://www.crunchers-freiburg.de/", "crunchers@freiburg", "(German)"),
|
||||
);
|
||||
|
@ -131,10 +131,10 @@ $sig_sites = array(
|
|||
"http://boinc.mundayweb.com",
|
||||
"(User-configurable stats counters. Cool!)"
|
||||
),
|
||||
array("http://www.bigbee.be/comp/boinc/",
|
||||
"boinc.be",
|
||||
""
|
||||
),
|
||||
//array("http://www.bigbee.be/comp/boinc/",
|
||||
// "boinc.be",
|
||||
// ""
|
||||
//),
|
||||
array("http://www.boincstats.com/page/faq.php#3",
|
||||
"BOINCstats",
|
||||
"by Willy de Zutter"
|
||||
|
|
|
@ -21,6 +21,29 @@
|
|||
|
||||
require_once("../inc/submit_db.inc");
|
||||
|
||||
function error($s) {
|
||||
echo "error: $s\n";
|
||||
echo "<error>\n<message>$s</message>\n</error>\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
function authenticate_user($r, $app) {
|
||||
$auth = (string)$r->authenticator;
|
||||
if (!$auth) error("no authenticator");
|
||||
$auth = BoincDb::escape_string($auth);
|
||||
$user = BoincUser::lookup("authenticator='$auth'");
|
||||
if (!$user) error("bad authenticator");
|
||||
$user_submit = BoincUserSubmit::lookup_userid($user->id);
|
||||
if (!$user_submit) error("no submit access");
|
||||
if ($app && !$user_submit->submit_all) {
|
||||
$usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$app->id");
|
||||
if (!$usa) {
|
||||
error("no submit access");
|
||||
}
|
||||
}
|
||||
return array($user, $user_submit);
|
||||
}
|
||||
|
||||
// given its WUs, compute params of a batch
|
||||
// NOTE: eventually this should be done by server components
|
||||
// (transitioner, validator etc.) as jobs complete or time out
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
<?php
|
||||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2013 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
// as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// BOINC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Web RPCs for managing job input files on the server.
|
||||
//
|
||||
// Issues:
|
||||
//
|
||||
// 1) how are files named?
|
||||
// Their name is a function of their MD5.
|
||||
// This eliminates issues related to file immutability
|
||||
//
|
||||
// 2) how do we keep track of the files?
|
||||
// In the MySQL database, in a table called job_files.
|
||||
// Each row describes a file currently on the server.
|
||||
// In addition, we maintain a table batch_file_assoc to record
|
||||
// that a file is used by a particular batch.
|
||||
// (Note: the association could be at the job level instead.
|
||||
// but this way is more efficient if all the jobs in a batch use
|
||||
// a particular file.)
|
||||
//
|
||||
// 3) how do we clean up unused files?
|
||||
// A daemon (job_file_deleter) deletes files for which
|
||||
// - the delete date (if given) is in the past, and
|
||||
// - there are no associations to active batches
|
||||
//
|
||||
// 4) what are the RPC operations?
|
||||
// query_files
|
||||
// in:
|
||||
// authenticator
|
||||
// list of MD5s
|
||||
// batch ID (optional)
|
||||
// new delete time (optional)
|
||||
// out:
|
||||
// error message,
|
||||
// or list of files (indices in the MD5 list) not present on server
|
||||
// action: for each MD5 in in the input list:
|
||||
// if present on server
|
||||
// update delete time
|
||||
// create batch/file association
|
||||
// add MD5 to output list
|
||||
// upload_files
|
||||
// in:
|
||||
// authenticator
|
||||
// delete time (optional)
|
||||
// batch ID (optional)
|
||||
// list of MD5s
|
||||
// files (as multipart attachments)
|
||||
// out:
|
||||
// error message, or success
|
||||
// action:
|
||||
// for each file in list
|
||||
// move to project download dir w/ appropriate name
|
||||
// create job_files record
|
||||
// create batch_file_assoc record if needed
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', true);
|
||||
ini_set('display_startup_errors', true);
|
||||
|
||||
require_once("../inc/boinc_db.inc");
|
||||
require_once("../inc/dir_hier.inc");
|
||||
require_once("../inc/xml.inc");
|
||||
require_once("../inc/submit_util.inc");
|
||||
|
||||
// the physical name of a file is jf_(md5).
|
||||
// Prepend the jf_ to make the source of the file clear
|
||||
//
|
||||
function job_file_name($md5) {
|
||||
return "jf_$md5";
|
||||
}
|
||||
|
||||
function query_files($r) {
|
||||
list($user, $user_submit) = authenticate_user($r, null);
|
||||
$absent_files = array();
|
||||
$now = time();
|
||||
$delete_time = (int)$r->delete_time;
|
||||
$batch_id = (int)$r->delete_time;
|
||||
$fanout = parse_config(get_config(), "<uldl_dir_fanout>");
|
||||
$i = 0;
|
||||
foreach($r->md5 as $f) {
|
||||
$md5 = (string)$f;
|
||||
echo "processing $md5\n";
|
||||
$fname = job_file_name($md5);
|
||||
$path = dir_hier_path($fname, "../../download", $fanout);
|
||||
|
||||
// if the job_file record is there,
|
||||
// update the delete time first to avoid race condition
|
||||
// with job file deleter
|
||||
//
|
||||
$job_file = BoincJobFile::lookup_md5($md5);
|
||||
if ($job_file && $job_file->delete_time < $delete_time) {
|
||||
$retval = $job_file::update("delete_time=$delete_time");
|
||||
if ($retval) {
|
||||
xml_error(-1, "job_file::update() failed");
|
||||
}
|
||||
}
|
||||
if (file_exists($path)) {
|
||||
// create the DB record if needed
|
||||
//
|
||||
if (!$job_file) {
|
||||
BoincJobFile::insert(
|
||||
"(md5, create_time, delete_time) values ('$md5', $now, $delete_time)"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if ($job_file) {
|
||||
$job_file->delete();
|
||||
}
|
||||
$absent_files[] = $i;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
echo "<absent_files>\n";
|
||||
foreach ($absent_files as $i) {
|
||||
echo "<file>$i</file>\n";
|
||||
}
|
||||
echo "</absent_files>\n";
|
||||
}
|
||||
|
||||
// upload_files
|
||||
// in: list of MD5s, and the files themselves as multipart attachment
|
||||
// out: error code
|
||||
//
|
||||
function upload_files($r) {
|
||||
list($user, $user_submit) = authenticate_user($r, null);
|
||||
$fanout = parse_config(get_config(), "<uldl_dir_fanout>");
|
||||
$delete_time = (int)$r->delete_time;
|
||||
print_r($_FILES);
|
||||
$i = 0;
|
||||
foreach ($r->md5 as $f) {
|
||||
$md5 = (string)$f;
|
||||
$name = "file_$i";
|
||||
$tmp_name = $_FILES[$name]['tmp_name'];
|
||||
if (!is_uploaded_file($tmp_name)) {
|
||||
xml_error(-1, "$tmp_name is not an uploaded file");
|
||||
}
|
||||
$fname = job_file_name($md5);
|
||||
$path = dir_hier_path($fname, "../../download", $fanout);
|
||||
rename($tmp_name, $path);
|
||||
$now = time();
|
||||
$id = BoincJobFile::insert(
|
||||
"(md5, create_time, delete_time) values ('$md5', $now, $delete_time)"
|
||||
);
|
||||
if (!$id) {
|
||||
xml_error(-1, "BoincJobFile::insert() failed");
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
echo "<success/>\n";
|
||||
}
|
||||
|
||||
if (0) {
|
||||
$r = simplexml_load_string("<query_files>\n<batch_id>0</batch_id>\n <md5>80bf244b43fb5d39541ea7011883b7e0</md5>\n <md5>a6037b05afb05f36e6a85a7c5138cbc1</md5>\n</query_files>\n ");
|
||||
submit_batch($r);
|
||||
exit;
|
||||
}
|
||||
if (0) {
|
||||
$r = simplexml_load_string("<upload_files>\n<authenticator>157f96a018b0b2f2b466e2ce3c7f54db</authenticator>\n<batch_id>1</batch_id>\n<md5>80bf244b43fb5d39541ea7011883b7e0</md5>\n<md5>a6037b05afb05f36e6a85a7c5138cbc1</md5>\n</upload_files>");
|
||||
upload_files($r);
|
||||
exit;
|
||||
}
|
||||
|
||||
xml_header();
|
||||
$r = simplexml_load_string($_POST['request']);
|
||||
if (!$r) {
|
||||
xml_error(-1, "can't parse request message");
|
||||
}
|
||||
|
||||
switch($r->getName()) {
|
||||
case 'query_files':
|
||||
query_files($r);
|
||||
break;
|
||||
case 'upload_files':
|
||||
echo "foo\n";
|
||||
upload_files($r);
|
||||
break;
|
||||
default:
|
||||
xml_error(-1, "no such action");
|
||||
}
|
||||
|
||||
?>
|
|
@ -30,28 +30,6 @@ error_reporting(E_ALL);
|
|||
ini_set('display_errors', true);
|
||||
ini_set('display_startup_errors', true);
|
||||
|
||||
function error($s) {
|
||||
echo "<error>\n<message>$s</message>\n</error>\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
function authenticate_user($r, $app) {
|
||||
$auth = (string)$r->authenticator;
|
||||
if (!$auth) error("no authenticator");
|
||||
$auth = BoincDb::escape_string($auth);
|
||||
$user = BoincUser::lookup("authenticator='$auth'");
|
||||
if (!$user) error("bad authenticator");
|
||||
$user_submit = BoincUserSubmit::lookup_userid($user->id);
|
||||
if (!$user_submit) error("no submit access");
|
||||
if ($app && !$user_submit->submit_all) {
|
||||
$usa = BoincUserSubmitApp::lookup("user_id=$user->id and app_id=$app->id");
|
||||
if (!$usa) {
|
||||
error("no submit access");
|
||||
}
|
||||
}
|
||||
return array($user, $user_submit);
|
||||
}
|
||||
|
||||
function get_app($r) {
|
||||
$name = (string)($r->batch->app_name);
|
||||
$name = BoincDb::escape_string($name);
|
||||
|
@ -183,16 +161,13 @@ function submit_batch($r) {
|
|||
if ($batch_id) {
|
||||
$batch = BoincBatch::lookup_id($batch_id);
|
||||
if (!$batch) {
|
||||
echo "<error>no batch $batch_id</error>\n";
|
||||
exit;
|
||||
error("no batch $batch_id");
|
||||
}
|
||||
if ($batch->user_id != $user->id) {
|
||||
echo "<error>not owner</error>\n";
|
||||
exit;
|
||||
error("not owner");
|
||||
}
|
||||
if ($batch->state != BATCH_STATE_INIT) {
|
||||
echo "<error>batch not in init state</error>\n";
|
||||
exit;
|
||||
error("batch not in init state");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,8 +183,7 @@ function submit_batch($r) {
|
|||
$cmd = "cd ../../bin; ./adjust_user_priority --user $user->id --flops $total_flops --app $app->name";
|
||||
$x = system($cmd);
|
||||
if (!is_numeric($x) || (double)$x == 0) {
|
||||
echo "<error>adjust_user_priority returned $x</error>\n";
|
||||
exit;
|
||||
error("adjust_user_priority returned $x");
|
||||
}
|
||||
$let = (double)$x;
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ struct LOG_FLAGS {
|
|||
bool sched_ops;
|
||||
// interactions with schedulers
|
||||
bool task;
|
||||
// task start and finish
|
||||
// task start and finish, and suspend/resume
|
||||
|
||||
// off by default; intended for developers and testers
|
||||
//
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
all: boinc_gahp
|
||||
|
||||
boinc_gahp: boinc_gahp.cpp curl.cpp
|
||||
boinc_gahp: boinc_gahp.cpp boinc_gahp.h curl.cpp curl.h
|
||||
g++ -g -O0 -I../../lib \
|
||||
-o boinc_gahp boinc_gahp.cpp curl.cpp \
|
||||
-L../../lib -lboinc -lpthread -lcurl
|
||||
|
||||
curl_test: curl.cpp
|
||||
g++ -o curl_test curl.cpp -lcurl
|
||||
test: test.cpp curl.cpp
|
||||
g++ -g -o test -I../../lib \
|
||||
test.cpp curl.cpp -lcurl
|
||||
|
|
|
@ -58,74 +58,10 @@ struct COMMAND {
|
|||
typedef map<int, COMMAND*> COMMANDS;
|
||||
COMMANDS commands;
|
||||
|
||||
struct INFILE {
|
||||
char src_path[256];
|
||||
char dst_path[256];
|
||||
};
|
||||
|
||||
struct JOB {
|
||||
char job_name[256];
|
||||
string cmdline_args;
|
||||
vector<INFILE> infiles;
|
||||
bool all_output_files;
|
||||
vector<string> outfiles;
|
||||
};
|
||||
|
||||
struct LOCAL_FILE {
|
||||
char md5[64];
|
||||
double nbytes;
|
||||
};
|
||||
|
||||
struct SUBMIT_REQ {
|
||||
char batch_name[256];
|
||||
char app_name[256];
|
||||
vector<JOB> jobs;
|
||||
map<string, LOCAL_FILE> local_files;
|
||||
// maps local path to info about file
|
||||
int batch_id;
|
||||
};
|
||||
|
||||
int compute_md5(string path, LOCAL_FILE& f) {
|
||||
return md5_file(path.c_str(), f.md5, f.nbytes);
|
||||
}
|
||||
|
||||
int create_batch(SUBMIT_REQ& sr) {
|
||||
char request[1024];
|
||||
char url[1024];
|
||||
sprintf(request,
|
||||
"<create_batch>\n"
|
||||
" <authenticator>%s</authenticator>\n"
|
||||
" <batch>\n"
|
||||
" <batch_name>%s</batch_name>\n"
|
||||
" <app_name>%s</app_name>\n"
|
||||
" </batch>\n"
|
||||
"</create_batch>\n",
|
||||
authenticator,
|
||||
sr.batch_name,
|
||||
sr.app_name
|
||||
);
|
||||
sprintf(url, "%ssubmit_rpc_handler.php", project_url);
|
||||
FILE* reply = tmpfile();
|
||||
vector<string> x;
|
||||
int retval = do_http_post(url, request, reply, x);
|
||||
if (retval) {
|
||||
fclose(reply);
|
||||
return retval;
|
||||
}
|
||||
char buf[256];
|
||||
sr.batch_id = 0;
|
||||
fseek(reply, 0, SEEK_SET);
|
||||
while (fgets(buf, 256, reply)) {
|
||||
if (parse_int(buf, "<batch_id>", sr.batch_id)) break;
|
||||
}
|
||||
fclose(reply);
|
||||
if (sr.batch_id == 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Get a list of the input files used by the batch.
|
||||
// Get their MD5s.
|
||||
// See if they're already on the server.
|
||||
|
@ -148,7 +84,7 @@ int process_input_files(SUBMIT_REQ& req) {
|
|||
}
|
||||
|
||||
// compute the MD5s of these files,
|
||||
// and make a map from filename to MD5 and other info (LOCAL_FILE)
|
||||
// and make a map from path to MD5 and size (LOCAL_FILE)
|
||||
//
|
||||
set<string>::iterator iter = unique_paths.begin();
|
||||
while (iter != unique_paths.end()) {
|
||||
|
@ -161,69 +97,43 @@ int process_input_files(SUBMIT_REQ& req) {
|
|||
}
|
||||
|
||||
// ask the server which files it doesn't already have.
|
||||
// We send it the batch ID and a list of (filename, MD5) pairs.
|
||||
// It
|
||||
// - creates batch_file_assoc records for all the files
|
||||
// (to avoid race condition w/ file deletion)
|
||||
// - returns the list of filenames it doesn't have.
|
||||
//
|
||||
string req_msg;
|
||||
req_msg = "<query_files>\n";
|
||||
map<string, LOCAL_FILE>::iterator map_iter;
|
||||
map_iter = req.local_files.begin();
|
||||
sprintf(buf, "<batch_id>%d</batch_id>\n", req.batch_id);
|
||||
req_msg += string(buf);
|
||||
vector<string> md5s, paths;
|
||||
vector<int> absent_files;
|
||||
while (map_iter != req.local_files.end()) {
|
||||
LOCAL_FILE lf = map_iter->second;
|
||||
string name = map_iter->first;
|
||||
sprintf(buf,
|
||||
"<file>\n"
|
||||
" <name>%s</name>\n"
|
||||
" <md5>%s</md5>\n"
|
||||
"</file>\n",
|
||||
name.c_str(),
|
||||
lf.md5
|
||||
);
|
||||
req_msg += string(buf);
|
||||
paths.push_back(map_iter->first);
|
||||
md5s.push_back(lf.md5);
|
||||
iter++;
|
||||
}
|
||||
req_msg += "</query_files>\n";
|
||||
vector<string> send_files;
|
||||
FILE* reply = tmpfile();
|
||||
retval = do_http_post(project_url, req_msg.c_str(), reply, send_files);
|
||||
fseek(reply, 0, SEEK_SET);
|
||||
vector<string> missing_files;
|
||||
string missing_file;
|
||||
while (fgets(buf, 256, reply)) {
|
||||
if (parse_str(buf, "<missing_file>", missing_file)) {
|
||||
missing_files.push_back(missing_file);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fclose(reply);
|
||||
retval = query_files(
|
||||
project_url,
|
||||
authenticator,
|
||||
req.batch_id,
|
||||
md5s,
|
||||
paths,
|
||||
absent_files
|
||||
);
|
||||
if (retval) return retval;
|
||||
|
||||
// upload the missing files.
|
||||
// Send a list of the MD5s so the server doesn't have to compute them.
|
||||
//
|
||||
req_msg = "<upload_files>\n";
|
||||
for (i=0; i<missing_files.size(); i++) {
|
||||
map_iter = req.local_files.find(missing_files[i]);
|
||||
LOCAL_FILE& lf = map_iter->second;
|
||||
sprintf(buf, "<md5>%s</md5>\n", lf.md5);
|
||||
req_msg += string(buf);
|
||||
vector<string> upload_md5s, upload_paths;
|
||||
for (unsigned int i=0; i<absent_files.size(); i++) {
|
||||
int j = absent_files[i];
|
||||
upload_md5s.push_back(md5s[j]);
|
||||
upload_paths.push_back(paths[j]);
|
||||
}
|
||||
req_msg = "</upload_files>\n";
|
||||
reply = tmpfile();
|
||||
retval = do_http_post(project_url, req_msg.c_str(), reply, missing_files);
|
||||
bool success = false;
|
||||
while (fgets(buf, 256, reply)) {
|
||||
if (strstr(buf, "success")) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(reply);
|
||||
if (!success) return -1;
|
||||
retval = upload_files(
|
||||
project_url,
|
||||
authenticator,
|
||||
req.batch_id,
|
||||
upload_md5s,
|
||||
upload_paths
|
||||
);
|
||||
if (retval) return retval;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -264,56 +174,6 @@ int parse_boinc_submit(COMMAND& c, char* p, SUBMIT_REQ& req) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// batch has been created and files staged.
|
||||
// Create the jobs, and flag batch as IN_PROGRESS
|
||||
//
|
||||
int submit_jobs(SUBMIT_REQ req) {
|
||||
char buf[1024], url[1024];
|
||||
sprintf(buf,
|
||||
"<create_batch>\n"
|
||||
"<authenticator>%s</authenticator>\n"
|
||||
"<batch_id>%d</batch_id>\n",
|
||||
authenticator,
|
||||
req.batch_id
|
||||
);
|
||||
string request = buf;
|
||||
for (unsigned int i=0; i<req.jobs.size(); i++) {
|
||||
JOB job=req.jobs[i];
|
||||
request += "<job>\n";
|
||||
if (!job.cmdline_args.empty()) {
|
||||
request += "<command_line>" + job.cmdline_args + "</command_line>\n";
|
||||
}
|
||||
for (unsigned int j=0; j<job.infiles.size(); j++) {
|
||||
INFILE infile = job.infiles[i];
|
||||
map<string, LOCAL_FILE>::iterator iter = req.local_files.find(infile.src_path);
|
||||
LOCAL_FILE& lf = iter->second;
|
||||
sprintf(buf,
|
||||
"<input_file>\n"
|
||||
"<mode>local</mode>\n"
|
||||
"<path>%s</path>\n"
|
||||
"</input_file>\n",
|
||||
lf.md5
|
||||
);
|
||||
request += buf;
|
||||
}
|
||||
request += "</job>\n";
|
||||
}
|
||||
request += "</create_batch>\n";
|
||||
sprintf(url, "%ssubmit_rpc_handler.php", project_url);
|
||||
FILE* reply = tmpfile();
|
||||
vector<string> x;
|
||||
int retval = do_http_post(url, request.c_str(), reply, x);
|
||||
if (retval) {
|
||||
fclose(reply);
|
||||
return retval;
|
||||
}
|
||||
fseek(reply, 0, SEEK_SET);
|
||||
while (fgets(buf, 256, reply)) {
|
||||
}
|
||||
fclose(reply);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// To avoid a race condition with file deletion:
|
||||
// - create a batch record
|
||||
// - create batch/file associations, and upload files
|
||||
|
@ -327,7 +187,7 @@ void handle_boinc_submit(COMMAND& c, char* p) {
|
|||
printf("error parsing request: %d\n", retval);
|
||||
return;
|
||||
}
|
||||
retval = create_batch(req);
|
||||
retval = create_batch(project_url, authenticator, req);
|
||||
if (retval) {
|
||||
printf("error creating batch: %d\n", retval);
|
||||
return;
|
||||
|
@ -337,7 +197,7 @@ void handle_boinc_submit(COMMAND& c, char* p) {
|
|||
printf("error processing input files: %d\n", retval);
|
||||
return;
|
||||
}
|
||||
retval = submit_jobs(req);
|
||||
retval = submit_jobs(project_url, authenticator, req);
|
||||
if (retval) {
|
||||
printf("error submitting jobs: %d\n", retval);
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// This file is part of BOINC.
|
||||
// http://boinc.berkeley.edu
|
||||
// Copyright (C) 2013 University of California
|
||||
//
|
||||
// BOINC is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License
|
||||
// as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// BOINC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::map;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
struct INFILE {
|
||||
char src_path[256];
|
||||
char dst_path[256];
|
||||
};
|
||||
|
||||
struct JOB {
|
||||
char job_name[256];
|
||||
string cmdline_args;
|
||||
vector<INFILE> infiles;
|
||||
bool all_output_files;
|
||||
vector<string> outfiles;
|
||||
};
|
||||
|
||||
struct LOCAL_FILE {
|
||||
char md5[64];
|
||||
double nbytes;
|
||||
};
|
||||
|
||||
struct SUBMIT_REQ {
|
||||
char batch_name[256];
|
||||
char app_name[256];
|
||||
vector<JOB> jobs;
|
||||
map<string, LOCAL_FILE> local_files;
|
||||
// maps local path to info about file
|
||||
int batch_id;
|
||||
};
|
|
@ -19,6 +19,9 @@
|
|||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
#include "parse.h"
|
||||
|
||||
#include "curl.h"
|
||||
|
||||
|
@ -28,7 +31,7 @@ using std::string;
|
|||
// send an HTTP POST request,
|
||||
// with an optional set of multi-part file attachments
|
||||
//
|
||||
int do_http_post(
|
||||
static int do_http_post(
|
||||
const char* url,
|
||||
const char* request,
|
||||
FILE* reply,
|
||||
|
@ -80,17 +83,184 @@ int do_http_post(
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int main() {
|
||||
FILE* reply = fopen("reply", "w");
|
||||
vector<string> send_files;
|
||||
send_files.push_back("curl.cpp");
|
||||
send_files.push_back("boinc_gahp.cpp");
|
||||
do_http_post(
|
||||
"http://isaac.ssl.berkeley.edu/foobar.php",
|
||||
"<req>foo</req>",
|
||||
reply,
|
||||
send_files
|
||||
);
|
||||
int query_files(
|
||||
const char* project_url,
|
||||
const char* authenticator,
|
||||
int batch_id,
|
||||
vector<string> &md5s,
|
||||
vector<string> &paths,
|
||||
vector<int> &absent_files
|
||||
) {
|
||||
string req_msg;
|
||||
char buf[256];
|
||||
req_msg = "<query_files>\n";
|
||||
sprintf(buf, "<authenticator>%s</authenticator>\n", authenticator);
|
||||
req_msg += string(buf);
|
||||
if (batch_id) {
|
||||
sprintf(buf, "<batch_id>%d</batch_id>\n", batch_id);
|
||||
req_msg += string(buf);
|
||||
}
|
||||
for (unsigned int i=0; i<md5s.size(); i++) {
|
||||
sprintf(buf, " <md5>%s</md5>\n", md5s[i].c_str());
|
||||
req_msg += string(buf);
|
||||
}
|
||||
req_msg += "</query_files>\n";
|
||||
FILE* reply = tmpfile();
|
||||
char url[256];
|
||||
sprintf(url, "%sjob_file.php", project_url);
|
||||
int retval = do_http_post(url, req_msg.c_str(), reply, paths);
|
||||
if (retval) {
|
||||
fclose(reply);
|
||||
return retval;
|
||||
}
|
||||
fseek(reply, 0, SEEK_SET);
|
||||
int x;
|
||||
while (fgets(buf, 256, reply)) {
|
||||
printf("reply: %s", buf);
|
||||
if (strstr(buf, "error")) {
|
||||
retval = -1;
|
||||
}
|
||||
if (parse_int(buf, "<absent_file>", x)) {
|
||||
absent_files.push_back(x);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fclose(reply);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int upload_files (
|
||||
const char* project_url,
|
||||
const char* authenticator,
|
||||
int batch_id,
|
||||
vector<string> &md5s,
|
||||
vector<string> &paths
|
||||
) {
|
||||
char buf[1024];
|
||||
string req_msg = "<upload_files>\n";
|
||||
sprintf(buf, "<authenticator>%s</authenticator>\n", authenticator);
|
||||
req_msg += string(buf);
|
||||
if (batch_id) {
|
||||
sprintf(buf, "<batch_id>%d</batch_id>\n", batch_id);
|
||||
req_msg += string(buf);
|
||||
}
|
||||
for (unsigned int i=0; i<md5s.size(); i++) {
|
||||
sprintf(buf, "<md5>%s</md5>\n", md5s[i].c_str());
|
||||
req_msg += string(buf);
|
||||
}
|
||||
req_msg += "</upload_files>\n";
|
||||
FILE* reply = tmpfile();
|
||||
char url[256];
|
||||
sprintf(url, "%sjob_file.php", project_url);
|
||||
int retval = do_http_post(url, req_msg.c_str(), reply, paths);
|
||||
if (retval) {
|
||||
fclose(reply);
|
||||
return retval;
|
||||
}
|
||||
fseek(reply, 0, SEEK_SET);
|
||||
bool success = false;
|
||||
while (fgets(buf, 256, reply)) {
|
||||
printf("reply: %s", buf);
|
||||
if (strstr(buf, "success")) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(reply);
|
||||
if (!success) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create_batch(
|
||||
const char* project_url,
|
||||
const char* authenticator,
|
||||
const char* batch_name,
|
||||
const char* app_name,
|
||||
int& batch_id
|
||||
) {
|
||||
char request[1024];
|
||||
char url[1024];
|
||||
sprintf(request,
|
||||
"<create_batch>\n"
|
||||
" <authenticator>%s</authenticator>\n"
|
||||
" <batch>\n"
|
||||
" <batch_name>%s</batch_name>\n"
|
||||
" <app_name>%s</app_name>\n"
|
||||
" </batch>\n"
|
||||
"</create_batch>\n",
|
||||
authenticator,
|
||||
batch_name,
|
||||
app_name
|
||||
);
|
||||
sprintf(url, "%ssubmit_rpc_handler.php", project_url);
|
||||
FILE* reply = tmpfile();
|
||||
vector<string> x;
|
||||
int retval = do_http_post(url, request, reply, x);
|
||||
if (retval) {
|
||||
fclose(reply);
|
||||
return retval;
|
||||
}
|
||||
char buf[256];
|
||||
batch_id = 0;
|
||||
fseek(reply, 0, SEEK_SET);
|
||||
while (fgets(buf, 256, reply)) {
|
||||
printf("reply: %s", buf);
|
||||
if (parse_int(buf, "<batch_id>", batch_id)) break;
|
||||
}
|
||||
fclose(reply);
|
||||
if (batch_id == 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int submit_jobs(
|
||||
const char* project_url,
|
||||
const char* authenticator,
|
||||
SUBMIT_REQ req
|
||||
) {
|
||||
char buf[1024], url[1024];
|
||||
sprintf(buf,
|
||||
"<create_batch>\n"
|
||||
"<authenticator>%s</authenticator>\n"
|
||||
"<batch_id>%d</batch_id>\n",
|
||||
authenticator,
|
||||
req.batch_id
|
||||
);
|
||||
string request = buf;
|
||||
for (unsigned int i=0; i<req.jobs.size(); i++) {
|
||||
JOB job=req.jobs[i];
|
||||
request += "<job>\n";
|
||||
if (!job.cmdline_args.empty()) {
|
||||
request += "<command_line>" + job.cmdline_args + "</command_line>\n";
|
||||
}
|
||||
for (unsigned int j=0; j<job.infiles.size(); j++) {
|
||||
INFILE infile = job.infiles[i];
|
||||
map<string, LOCAL_FILE>::iterator iter = req.local_files.find(infile.src_path);
|
||||
LOCAL_FILE& lf = iter->second;
|
||||
sprintf(buf,
|
||||
"<input_file>\n"
|
||||
"<mode>local</mode>\n"
|
||||
"<path>%s</path>\n"
|
||||
"</input_file>\n",
|
||||
lf.md5
|
||||
);
|
||||
request += buf;
|
||||
}
|
||||
request += "</job>\n";
|
||||
}
|
||||
request += "</create_batch>\n";
|
||||
sprintf(url, "%ssubmit_rpc_handler.php", project_url);
|
||||
FILE* reply = tmpfile();
|
||||
vector<string> x;
|
||||
int retval = do_http_post(url, request.c_str(), reply, x);
|
||||
if (retval) {
|
||||
fclose(reply);
|
||||
return retval;
|
||||
}
|
||||
fseek(reply, 0, SEEK_SET);
|
||||
while (fgets(buf, 256, reply)) {
|
||||
}
|
||||
fclose(reply);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
<stdout_filename>stdout</stdout_filename>
|
||||
<command_line>10</command_line>
|
||||
</task>
|
||||
<unzip_input>
|
||||
<zipfilename>in.zip</zipfilename>
|
||||
</unzip_input>
|
||||
<zip_output>
|
||||
<zipfilename>foo.zip</zipfilename>
|
||||
<filename>out</filename>
|
||||
</zip_output>
|
||||
<task>
|
||||
<application>worker</application>
|
||||
<stdin_filename>stdin</stdin_filename>
|
||||
<stdout_filename>stdout</stdout_filename>
|
||||
<command_line>10</command_line>
|
||||
</task>
|
||||
</job_desc>
|
||||
|
|
|
@ -66,11 +66,14 @@
|
|||
|
||||
#include "regexp.h"
|
||||
|
||||
//#define DEBUG
|
||||
#if 1
|
||||
#define debug_msg(x)
|
||||
#else
|
||||
inline void debug_msg(const char* x) {
|
||||
#if 0
|
||||
fprintf(stderr, "%s\n", x);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define JOB_FILENAME "job.xml"
|
||||
#define CHECKPOINT_FILENAME "wrapper_checkpoint.txt"
|
||||
|
@ -120,6 +123,7 @@ struct TASK {
|
|||
#else
|
||||
int pid;
|
||||
struct stat last_stat;
|
||||
double start_rusage; // getrusage() CPU time at start of task
|
||||
#endif
|
||||
bool stat_first;
|
||||
|
||||
|
@ -699,6 +703,10 @@ int TASK::run(int argct, char** argvt) {
|
|||
FILE* stdin_file;
|
||||
FILE* stderr_file;
|
||||
|
||||
struct rusage ru;
|
||||
getrusage(RUSAGE_CHILDREN, &ru);
|
||||
start_rusage = (float)ru.ru_utime.tv_sec + ((float)ru.ru_utime.tv_usec)/1e+6;
|
||||
|
||||
pid = fork();
|
||||
if (pid == -1) {
|
||||
perror("fork(): ");
|
||||
|
@ -786,10 +794,16 @@ bool TASK::poll(int& status) {
|
|||
int wpid;
|
||||
struct rusage ru;
|
||||
|
||||
wpid = wait4(pid, &status, WNOHANG, &ru);
|
||||
wpid = waitpid(pid, &status, WNOHANG);
|
||||
if (wpid) {
|
||||
getrusage(RUSAGE_CHILDREN, &ru);
|
||||
final_cpu_time = (float)ru.ru_utime.tv_sec + ((float)ru.ru_utime.tv_usec)/1e+6;
|
||||
final_cpu_time -= start_rusage;
|
||||
#ifdef DEBUG
|
||||
printf("process exited; current CPU %f final CPU %f\n",
|
||||
current_cpu_time, final_cpu_time
|
||||
);
|
||||
#endif
|
||||
if (final_cpu_time < current_cpu_time) {
|
||||
final_cpu_time = current_cpu_time;
|
||||
}
|
||||
|
@ -1005,6 +1019,13 @@ int main(int argc, char** argv) {
|
|||
if (counter%10 == 0) {
|
||||
cpu_time = task.cpu_time();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("cpu time %f, checkpoint CPU time %f frac done %f\n",
|
||||
task.starting_cpu + cpu_time,
|
||||
checkpoint_cpu_time,
|
||||
frac_done + delta
|
||||
);
|
||||
#endif
|
||||
boinc_report_app_status(
|
||||
task.starting_cpu + cpu_time,
|
||||
checkpoint_cpu_time,
|
||||
|
@ -1019,6 +1040,18 @@ int main(int argc, char** argv) {
|
|||
counter++;
|
||||
}
|
||||
checkpoint_cpu_time = task.starting_cpu + task.final_cpu_time;
|
||||
#ifdef DEBUG
|
||||
printf("cpu time %f, checkpoint CPU time %f frac done %f\n",
|
||||
task.starting_cpu + task.final_cpu_time,
|
||||
checkpoint_cpu_time,
|
||||
frac_done + task.weight/total_weight
|
||||
);
|
||||
#endif
|
||||
boinc_report_app_status(
|
||||
task.starting_cpu + task.final_cpu_time,
|
||||
checkpoint_cpu_time,
|
||||
frac_done + task.weight/total_weight
|
||||
);
|
||||
write_checkpoint(i+1, checkpoint_cpu_time);
|
||||
weight_completed += task.weight;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue