mirror of
http://galexander.org/git/simplesshd.git
synced 2025-01-07 13:40:54 +00:00
automatically restart sshd if the system kills it (or it crashes). but
don't restart it if it dies twice within 10 seconds. only access sshd_pid (et al) from a few select spots now, with proper synchronization.
This commit is contained in:
parent
2aeae24aed
commit
73d4406ee1
@ -25,7 +25,6 @@ conf_path_file(const char *fn)
|
|||||||
static JNIEnv *env;
|
static JNIEnv *env;
|
||||||
static jclass cl_string;
|
static jclass cl_string;
|
||||||
static jclass cl_simplesshdservice;
|
static jclass cl_simplesshdservice;
|
||||||
static jfieldID fid_sss_sshd_pid;
|
|
||||||
|
|
||||||
extern int dropbear_main(int argc, char **argv);
|
extern int dropbear_main(int argc, char **argv);
|
||||||
|
|
||||||
@ -49,8 +48,6 @@ jni_init(JNIEnv *env_)
|
|||||||
CLASS(string, "java/lang/String")
|
CLASS(string, "java/lang/String")
|
||||||
CLASS(simplesshdservice, "org/galexander/sshd/SimpleSSHDService")
|
CLASS(simplesshdservice, "org/galexander/sshd/SimpleSSHDService")
|
||||||
|
|
||||||
STFIELD(sss_sshd_pid, simplesshdservice, "sshd_pid", "I")
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +112,7 @@ from_java_string(jobject s)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
Java_org_galexander_sshd_SimpleSSHDService_start_1sshd(JNIEnv *env_,
|
Java_org_galexander_sshd_SimpleSSHDService_start_1sshd(JNIEnv *env_,
|
||||||
jclass cl,
|
jclass cl,
|
||||||
jint port, jobject jpath, jobject jshell, jobject jhome, jobject jextra,
|
jint port, jobject jpath, jobject jshell, jobject jhome, jobject jextra,
|
||||||
@ -167,23 +164,18 @@ Java_org_galexander_sshd_SimpleSSHDService_start_1sshd(JNIEnv *env_,
|
|||||||
(sizeof argv / sizeof *argv) - argc);
|
(sizeof argv / sizeof *argv) - argc);
|
||||||
fprintf(stderr, "starting dropbear\n");
|
fprintf(stderr, "starting dropbear\n");
|
||||||
retval = dropbear_main(argc, argv);
|
retval = dropbear_main(argc, argv);
|
||||||
|
/* NB - probably not reachable */
|
||||||
fprintf(stderr, "dropbear finished (%d)\n", retval);
|
fprintf(stderr, "dropbear finished (%d)\n", retval);
|
||||||
} else {
|
exit(0);
|
||||||
(*env)->SetStaticIntField(env, cl_simplesshdservice,
|
|
||||||
fid_sss_sshd_pid, pid);
|
|
||||||
}
|
}
|
||||||
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_org_galexander_sshd_SimpleSSHDService_stop_1sshd(JNIEnv *env_, jclass cl)
|
Java_org_galexander_sshd_SimpleSSHDService_kill(JNIEnv *env_, jclass cl,
|
||||||
|
jint pid)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
|
||||||
if (!jni_init(env_)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pid = (*env)->GetStaticIntField(env, cl_simplesshdservice, fid_sss_sshd_pid);
|
|
||||||
kill(pid, SIGKILL);
|
kill(pid, SIGKILL);
|
||||||
(*env)->SetStaticIntField(env, cl_simplesshdservice, fid_sss_sshd_pid, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT int JNICALL
|
JNIEXPORT int JNICALL
|
||||||
|
@ -9,7 +9,13 @@ import java.io.File;
|
|||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
|
|
||||||
public class SimpleSSHDService extends Service {
|
public class SimpleSSHDService extends Service {
|
||||||
public static int sshd_pid = 0;
|
/* if restarting twice within 10 seconds, give up */
|
||||||
|
private static final int MIN_DURATION = 10000;
|
||||||
|
|
||||||
|
private static final Object lock = new Object();
|
||||||
|
private static int sshd_pid = 0;
|
||||||
|
private static long sshd_when = 0;
|
||||||
|
private static long sshd_duration = 0;
|
||||||
|
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
@ -17,11 +23,8 @@ public class SimpleSSHDService extends Service {
|
|||||||
Prefs.init(this);
|
Prefs.init(this);
|
||||||
|
|
||||||
read_pidfile();
|
read_pidfile();
|
||||||
if (is_started()) {
|
|
||||||
/* would prefer to restart the daemon process rather
|
stop_sshd(); /* it would be stale anyways */
|
||||||
* than leave the stale one around.. */
|
|
||||||
stop_sshd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
@ -48,9 +51,7 @@ public class SimpleSSHDService extends Service {
|
|||||||
/* unfortunately, android doesn't reliably call this when, i.e.,
|
/* unfortunately, android doesn't reliably call this when, i.e.,
|
||||||
* the package is upgraded... so it's really pretty useless */
|
* the package is upgraded... so it's really pretty useless */
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
if (is_started()) {
|
|
||||||
stop_sshd();
|
stop_sshd();
|
||||||
}
|
|
||||||
stopSelf();
|
stopSelf();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
@ -59,23 +60,55 @@ public class SimpleSSHDService extends Service {
|
|||||||
return (sshd_pid != 0);
|
return (sshd_pid != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void do_start() {
|
private static void stop_sshd() {
|
||||||
if (is_started()) {
|
int pid;
|
||||||
stop_sshd();
|
synchronized (lock) {
|
||||||
|
pid = sshd_pid;
|
||||||
|
sshd_pid = 0;
|
||||||
}
|
}
|
||||||
start_sshd(Prefs.get_port(),
|
if (pid != 0) {
|
||||||
|
kill(pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void maybe_restart(int pid) {
|
||||||
|
boolean do_restart = false;
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
synchronized (lock) {
|
||||||
|
if (sshd_pid == pid) {
|
||||||
|
sshd_pid = 0;
|
||||||
|
do_restart =
|
||||||
|
((sshd_duration == 0) ||
|
||||||
|
(sshd_when == 0) ||
|
||||||
|
(sshd_duration >= MIN_DURATION) ||
|
||||||
|
((now-sshd_when) >= MIN_DURATION));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (do_restart) {
|
||||||
|
do_start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void do_start() {
|
||||||
|
stop_sshd();
|
||||||
|
final int pid = start_sshd(Prefs.get_port(),
|
||||||
Prefs.get_path(), Prefs.get_shell(),
|
Prefs.get_path(), Prefs.get_shell(),
|
||||||
Prefs.get_home(), Prefs.get_extra(),
|
Prefs.get_home(), Prefs.get_extra(),
|
||||||
(Prefs.get_rsyncbuffer() ? 1 : 0));
|
(Prefs.get_rsyncbuffer() ? 1 : 0));
|
||||||
|
|
||||||
if (sshd_pid != 0) {
|
long now = System.currentTimeMillis();
|
||||||
final int pid = sshd_pid;
|
if (pid != 0) {
|
||||||
|
synchronized (lock) {
|
||||||
|
stop_sshd();
|
||||||
|
sshd_pid = pid;
|
||||||
|
sshd_duration = ((sshd_when != 0)
|
||||||
|
? (now - sshd_when) : 0);
|
||||||
|
sshd_when = now;
|
||||||
|
}
|
||||||
(new Thread() {
|
(new Thread() {
|
||||||
public void run() {
|
public void run() {
|
||||||
waitpid(pid);
|
waitpid(pid);
|
||||||
if (sshd_pid == pid) {
|
maybe_restart(pid);
|
||||||
sshd_pid = 0;
|
|
||||||
}
|
|
||||||
SimpleSSHD.update_startstop();
|
SimpleSSHD.update_startstop();
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
@ -86,23 +119,32 @@ public class SimpleSSHDService extends Service {
|
|||||||
private static void read_pidfile() {
|
private static void read_pidfile() {
|
||||||
try {
|
try {
|
||||||
File f = new File(Prefs.get_path(), "dropbear.pid");
|
File f = new File(Prefs.get_path(), "dropbear.pid");
|
||||||
|
int pid = 0;
|
||||||
if (f.exists()) {
|
if (f.exists()) {
|
||||||
BufferedReader r = new BufferedReader(
|
BufferedReader r = new BufferedReader(
|
||||||
new FileReader(f));
|
new FileReader(f));
|
||||||
try {
|
try {
|
||||||
sshd_pid =
|
pid =
|
||||||
Integer.valueOf(r.readLine());
|
Integer.valueOf(r.readLine());
|
||||||
} finally {
|
} finally {
|
||||||
r.close();
|
r.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (pid != 0) {
|
||||||
|
synchronized (lock) {
|
||||||
|
stop_sshd();
|
||||||
|
sshd_pid = pid;
|
||||||
|
sshd_when = System.currentTimeMillis();
|
||||||
|
sshd_duration = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) { /* *shrug* */ }
|
} catch (Exception e) { /* *shrug* */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void start_sshd(int port, String path,
|
private static native int start_sshd(int port, String path,
|
||||||
String shell, String home, String extra,
|
String shell, String home, String extra,
|
||||||
int rsyncbuffer);
|
int rsyncbuffer);
|
||||||
private static native void stop_sshd();
|
private static native void kill(int pid);
|
||||||
private static native int waitpid(int pid);
|
private static native int waitpid(int pid);
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("simplesshd-jni");
|
System.loadLibrary("simplesshd-jni");
|
||||||
|
Loading…
Reference in New Issue
Block a user