Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@parallels.com>2015-02-13 15:09:52 +0300
committerPavel Emelyanov <xemul@parallels.com>2015-02-13 15:11:38 +0300
commit7d482de1ca9bb8c873e47ea5fe48b27399fc4187 (patch)
treeff0eca59d81316ca48ce8e38808d7a1404f76a2d
parent26ef7867708d16b38c9ebc1e85c54755cea14091 (diff)
tty: Restore locked termios with usernsd call
Locked termios require global CAP_SYS_ADMIN. But let's restore everything for tty in one call since regular termios depend on locked and it's not nice to do sync usernsd call for locked only. Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Acked-by: Andrew Vagin <avagin@parallels.com>
-rw-r--r--tty.c78
1 files changed, 60 insertions, 18 deletions
diff --git a/tty.c b/tty.c
index c4b8765d1..01d8c3ea8 100644
--- a/tty.c
+++ b/tty.c
@@ -28,6 +28,7 @@
#include "proc_parse.h"
#include "file-ids.h"
#include "files-reg.h"
+#include "namespaces.h"
#include "protobuf.h"
#include "protobuf/tty.pb-c.h"
@@ -606,10 +607,54 @@ static void tty_show_pty_info(char *prefix, struct tty_info *info)
tty_is_master(info), info->tie->sid, info->tie->pgrp, info->inherit);
}
+struct tty_parms {
+ int tty_id;
+ unsigned has;
+#define HAS_TERMIOS_L 0x1
+#define HAS_TERMIOS 0x2
+#define HAS_WINS 0x4
+ struct termios tl;
+ struct termios t;
+ struct winsize w;
+};
+
+static int do_restore_tty_parms(void *arg, int fd)
+{
+ struct tty_parms *p = arg;
+
+ /*
+ * Only locked termios need CAP_SYS_ADMIN, but we
+ * restore them all here, since the regular tremios
+ * restore is affected by locked and thus we would
+ * have to do synchronous usernsd call which is not
+ * nice.
+ *
+ * Window size is restored here as it might depend
+ * on termios too. Just to be on the safe side.
+ */
+
+ if ((p->has & HAS_TERMIOS_L) &&
+ ioctl(fd, TIOCSLCKTRMIOS, &p->tl) < 0)
+ goto err;
+
+ if ((p->has & HAS_TERMIOS) &&
+ ioctl(fd, TCSETS, &p->t) < 0)
+ goto err;
+
+ if ((p->has & HAS_WINS) &&
+ ioctl(fd, TIOCSWINSZ, &p->w) < 0)
+ goto err;
+
+ return 0;
+
+err:
+ pr_perror("Can't set tty params on %d", p->tty_id);
+ return -1;
+}
+
static int restore_tty_params(int fd, struct tty_info *info)
{
- struct winsize w;
- struct termios t;
+ struct tty_parms p;
/*
* It's important to zeroify termios
@@ -620,31 +665,28 @@ static int restore_tty_params(int fd, struct tty_info *info)
* never be extended.
*/
+ p.has = 0;
+ p.tty_id = info->tfe->id;
+
if (info->tie->termios_locked) {
- memzero(&t, sizeof(t));
- termios_copy(&t, info->tie->termios_locked);
- if (ioctl(fd, TIOCSLCKTRMIOS, &t) < 0)
- goto err;
+ memzero(&p.tl, sizeof(p.tl));
+ p.has |= HAS_TERMIOS_L;
+ termios_copy(&p.tl, info->tie->termios_locked);
}
if (info->tie->termios) {
- memzero(&t, sizeof(t));
- termios_copy(&t, info->tie->termios);
- if (ioctl(fd, TCSETS, &t) < 0)
- goto err;
+ memzero(&p.t, sizeof(p.t));
+ p.has |= HAS_TERMIOS;
+ termios_copy(&p.t, info->tie->termios);
}
if (info->tie->winsize) {
- memzero(&w, sizeof(w));
- winsize_copy(&w, info->tie->winsize);
- if (ioctl(fd, TIOCSWINSZ, &w) < 0)
- goto err;
+ memzero(&p.w, sizeof(p.w));
+ p.has |= HAS_WINS;
+ winsize_copy(&p.w, info->tie->winsize);
}
- return 0;
-err:
- pr_perror("Can't set tty params on %d", info->tfe->id);
- return -1;
+ return userns_call(do_restore_tty_parms, UNS_ASYNC, &p, sizeof(p), fd);
}
static int pty_open_slaves(struct tty_info *info)