diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h index 67840fcc6..d05d2c9ac 100644 --- a/include/parasite-syscall.h +++ b/include/parasite-syscall.h @@ -106,7 +106,7 @@ extern struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_list); extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size); -extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd); +extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd, int type); extern int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *item); extern int parasite_fini_threads_seized(struct parasite_ctl *ctl); diff --git a/include/parasite.h b/include/parasite.h index 774eba0c6..44be00c30 100644 --- a/include/parasite.h +++ b/include/parasite.h @@ -209,6 +209,7 @@ static inline int drain_fds_size(struct parasite_drain_fd *dfds) struct parasite_tty_args { int fd; + int type; int sid; int pgrp; diff --git a/parasite-syscall.c b/parasite-syscall.c index 7cc1a84e0..9699a2ab4 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -715,12 +715,13 @@ int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_mis return 0; } -struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd) +struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd, int type) { struct parasite_tty_args *p; p = parasite_args(ctl, struct parasite_tty_args); p->fd = fd; + p->type = type; if (parasite_execute_daemon(PARASITE_CMD_DUMP_TTY, ctl) < 0) return NULL; diff --git a/pie/parasite.c b/pie/parasite.c index bab67f8db..7f1b80acc 100644 --- a/pie/parasite.c +++ b/pie/parasite.c @@ -15,6 +15,7 @@ #include "lock.h" #include "vdso.h" #include "log.h" +#include "tty.h" #include @@ -329,44 +330,47 @@ static int parasite_dump_tty(struct parasite_tty_args *args) # define TIOCGEXCL _IOR('T', 0x40, int) #endif - ret = tty_ioctl(args->fd, TIOCGSID, &args->sid); - if (ret < 0) - goto err; - - ret = tty_ioctl(args->fd, TIOCGPGRP, &args->pgrp); - if (ret < 0) - goto err; - - ret = tty_ioctl(args->fd, TIOCGPKT, &args->st_pckt); - if (ret < 0) - goto err; - - ret = tty_ioctl(args->fd, TIOCGPTLCK, &args->st_lock); - if (ret < 0) - goto err; - - ret = tty_ioctl(args->fd, TIOCGEXCL, &args->st_excl); - if (ret < 0) - goto err; - - args->hangup = false; - return 0; - -err: - if (ret != -EIO) { - pr_err("TTY: Can't get sid/pgrp: %d\n", ret); - return -1; - } - - /* kernel reports EIO for get ioctls on pair-less ptys */ args->sid = 0; args->pgrp = 0; args->st_pckt = 0; args->st_lock = 0; args->st_excl = 0; - args->hangup = true; +#define __tty_ioctl(cmd, arg) \ + do { \ + ret = tty_ioctl(args->fd, cmd, &arg); \ + if (ret < 0) { \ + if (ret == -ENOTTY) \ + arg = 0; \ + else if (ret == -EIO) \ + goto err_io; \ + else \ + goto err; \ + } \ + } while (0) + + __tty_ioctl(TIOCGSID, args->sid); + __tty_ioctl(TIOCGPGRP, args->pgrp); + __tty_ioctl(TIOCGEXCL, args->st_excl); + + if (args->type == TTY_TYPE_PTM || + args->type == TTY_TYPE_PTS) { + __tty_ioctl(TIOCGPKT, args->st_pckt); + __tty_ioctl(TIOCGPTLCK, args->st_lock); + } + + args->hangup = false; return 0; + +err: + pr_err("tty: Can't fetch params: err = %d\n", ret); + return -1; +err_io: + + /* kernel reports EIO for get ioctls on pair-less ptys */ + args->hangup = true; + return 0; +#undef __tty_ioctl } #ifdef CONFIG_VDSO diff --git a/tty.c b/tty.c index 6f6200737..07978fcd9 100644 --- a/tty.c +++ b/tty.c @@ -1080,7 +1080,7 @@ static int dump_pty_info(int lfd, u32 id, const struct fd_parms *p, int type, in BUILD_BUG_ON(sizeof(termios.c_cc) != sizeof(void *)); BUILD_BUG_ON((sizeof(termios.c_cc) * TERMIOS_NCC) < sizeof(t.c_cc)); - pti = parasite_dump_tty(p->ctl, p->fd); + pti = parasite_dump_tty(p->ctl, p->fd, type); if (!pti) return -1;