'ControlMaster persist'
David Woodhouse
dwmw2 at infradead.org
Mon Jun 13 00:16:47 EST 2005
On Sun, 2005-06-12 at 14:18 +0100, David Woodhouse wrote:
> I'll do that in the next patch, which will add 'persist' and
> 'autopersist' to the available options.
... which start a master and leave it running even after the ssh command
which triggers its creation has gone. Looks like the simplest way to
achieve this is to fork a new ssh client process to become the master,
then wait for it to complete and use it in slave mode.
Should I make 'ask' and 'auto' into separate flags rather than
variations of the 'ControlMaster' option?
--- openssh-4.1p1/readconf.c~ 2005-06-12 11:18:05.000000000 +0100
+++ openssh-4.1p1/readconf.c 2005-06-12 14:34:26.000000000 +0100
@@ -799,15 +799,19 @@
filename, linenum);
value = 0; /* To avoid compiler warning... */
if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
- value = 1;
+ value = CONTROL_MASTER;
else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
- value = 0;
+ value = CONTROL_SLAVE;
else if (strcmp(arg, "ask") == 0)
- value = 2;
+ value = CONTROL_ASK;
+ else if (strcmp(arg, "persist") == 0)
+ value = CONTROL_PERSIST;
else if (strcmp(arg, "auto") == 0)
- value = 3;
+ value = CONTROL_AUTO;
else if (strcmp(arg, "autoask") == 0)
- value = 4;
+ value = CONTROL_AUTOASK;
+ else if (strcmp(arg, "autopersist") == 0)
+ value = CONTROL_AUTOPERSIST;
else
fatal("%.200s line %d: Bad ControlMaster argument.", filename, linenum);
if (*activep && *intptr == -1)
--- openssh-4.1p1/readconf.h~ 2005-03-01 10:47:37.000000000 +0000
+++ openssh-4.1p1/readconf.h 2005-06-12 14:34:15.000000000 +0100
@@ -116,6 +116,13 @@
int hash_known_hosts;
} Options;
+#define CONTROL_SLAVE 0
+#define CONTROL_MASTER 1
+#define CONTROL_ASK 2
+#define CONTROL_PERSIST 3
+#define CONTROL_AUTO 4
+#define CONTROL_AUTOASK 5
+#define CONTROL_AUTOPERSIST 6
void initialize_options(Options *);
void fill_default_options(Options *);
--- openssh-4.1p1/ssh.c~ 2005-06-12 13:55:32.000000000 +0100
+++ openssh-4.1p1/ssh.c 2005-06-12 15:02:09.000000000 +0100
@@ -659,12 +659,52 @@
options.control_path = xstrdup(buffer_ptr(&path));
}
}
+ startpersist:
+ if (options.control_master == CONTROL_PERSIST) {
+ pid_t masterpid = fork();
+
+ if (masterpid < 0)
+ fatal("fork: %s", strerror(errno));
+
+ if (masterpid) {
+ /* We are the parent. Wait for the child to
+ set itself up as master, then use its
+ control socket */
+ int status;
+ if (waitpid(masterpid, &status, 0) < 0)
+ fatal("waitpid: %s", strerror(errno));
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status))
+ fatal("Master connection failed, returned %d", WEXITSTATUS(status));
+ } else if (WIFSIGNALED(status)) {
+ fatal("Master connection failed, died with signal %d", WTERMSIG(status));
+ } else {
+ fatal("Master connection failed. status %d\n", status);
+ }
+ /* The master exited with zero status, so the socket
+ should be ready for us now */
+ options.control_master = CONTROL_SLAVE;
+ } else {
+ /* We are the child. Set ourselves up as master */
+ no_shell_flag = 1;
+ no_tty_flag = 1;
+ tty_flag = 0;
+ fork_after_authentication_flag = 1;
+ stdin_null_flag = 1;
+ options.control_master = CONTROL_MASTER;
+ }
+ }
+
if (options.control_path != NULL &&
- (options.control_master == 0 || options.control_master == 3 ||
- options.control_master == 4)) {
+ (options.control_master == CONTROL_SLAVE ||
+ options.control_master >= CONTROL_AUTO)) {
/* This only returns in the 'ask' cases, if we should
become a master */
control_client(options.control_path);
+
+ if (options.control_master == CONTROL_PERSIST)
+ goto startpersist;
}
/* Open a connection to the remote host. */
@@ -1355,10 +1395,10 @@
fatal("%s socket(): %s", __func__, strerror(errno));
if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) {
- if (options.control_master >= 2) {
+ if (options.control_master >= CONTROL_AUTO) {
debug("Couldn't connect to %s: %s", path, strerror(errno));
/* Automatic mode; return and become a master */
- options.control_master -= 2;
+ options.control_master -= CONTROL_AUTO-1;
close(sock);
return;
}
--
dwmw2
More information about the openssh-unix-dev
mailing list