Re: [PATCH v2 3/3] vstatus: Display an informational message when the VSTATUS character is pressed or TIOCSTAT ioctl is called.

2022-02-06 Thread Jiri Slaby

On 06. 02. 22, 16:48, Walt Drummond wrote:

When triggered by pressing the VSTATUS key or calling the TIOCSTAT
ioctl, the n_tty line discipline will display a message on the user's
tty that provides basic information about the system and an
'interesting' process in the current foreground process group, eg:

   load: 0.58  cmd: sleep 744474 [sleeping] 0.36r 0.00u 0.00s 0% 772k

The status message provides:
  - System load average
  - Command name and process id (from the perspective of the session)
  - Scheduler state
  - Total wall-clock run time
  - User space run time
  - System space run time
  - Percentage of on-cpu time
  - Resident set size

The message is only displayed when the tty has the VSTATUS character
set, the local flags ICANON and IEXTEN are enabled and NOKERNINFO is
disabled; it is always displayed when TIOCSTAT is called regardless of
tty settings.

Signed-off-by: Walt Drummond 
---


It looks like my comments were addressed. However you did not document 
the chances since v1 here. IOW, [v2] tag missing here.


And please add the CCs I added last time, so that relevant people still 
can comment.


thanks,
--
js
suse labs


Re: [PATCH v2 3/3] vstatus: Display an informational message when the VSTATUS character is pressed or TIOCSTAT ioctl is called.

2022-02-06 Thread Greg KH
On Sun, Feb 06, 2022 at 07:48:54AM -0800, Walt Drummond wrote:
> When triggered by pressing the VSTATUS key or calling the TIOCSTAT
> ioctl, the n_tty line discipline will display a message on the user's
> tty that provides basic information about the system and an
> 'interesting' process in the current foreground process group, eg:
> 
>   load: 0.58  cmd: sleep 744474 [sleeping] 0.36r 0.00u 0.00s 0% 772k
> 
> The status message provides:
>  - System load average
>  - Command name and process id (from the perspective of the session)
>  - Scheduler state
>  - Total wall-clock run time
>  - User space run time
>  - System space run time
>  - Percentage of on-cpu time
>  - Resident set size

This should be documented somewhere, and not buried in a changelog text
like this.  Can you also add this information somewhere in the
Documentation/ directory so that people have a hint as to what is going
on here?

> The message is only displayed when the tty has the VSTATUS character
> set, the local flags ICANON and IEXTEN are enabled and NOKERNINFO is
> disabled; it is always displayed when TIOCSTAT is called regardless of
> tty settings.
> 
> Signed-off-by: Walt Drummond 
> ---
>  drivers/tty/Makefile   |   2 +-
>  drivers/tty/n_tty.c|  34 +++
>  drivers/tty/n_tty_status.c | 181 +
>  drivers/tty/tty_io.c   |   2 +-
>  include/linux/tty.h|   5 +
>  5 files changed, 222 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/tty/n_tty_status.c

Also, any chance for a test to be added so that we can ensure that this
doesn't change over time in ways that confuse/break people?

Is this now a new user/kernel api format that we must preserve for
forever?  Can we add/remove items over time that make sense or are
programs (not just people), going to parse this?

> 
> diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile
> index a2bd75fbaaa4..3539d7ab77e5 100644
> --- a/drivers/tty/Makefile
> +++ b/drivers/tty/Makefile
> @@ -2,7 +2,7 @@
>  obj-$(CONFIG_TTY)+= tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
>  tty_buffer.o tty_port.o tty_mutex.o \
>  tty_ldsem.o tty_baudrate.o tty_jobctrl.o \
> -n_null.o
> +n_null.o n_tty_status.o
>  obj-$(CONFIG_LEGACY_PTYS)+= pty.o
>  obj-$(CONFIG_UNIX98_PTYS)+= pty.o
>  obj-$(CONFIG_AUDIT)  += tty_audit.o
> diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
> index 64a058a4c63b..fd70efc333d7 100644
> --- a/drivers/tty/n_tty.c
> +++ b/drivers/tty/n_tty.c
> @@ -80,6 +80,7 @@
>  #define ECHO_BLOCK   256
>  #define ECHO_DISCARD_WATERMARK   N_TTY_BUF_SIZE - (ECHO_BLOCK + 32)
>  
> +#define STATUS_LINE_LEN 160   /* tty status line will truncate at this 
> length */

Tabs please.


>  
>  #undef N_TTY_TRACE
>  #ifdef N_TTY_TRACE
> @@ -127,6 +128,8 @@ struct n_tty_data {
>   struct mutex output_lock;
>  };
>  
> +static void n_tty_status(struct tty_struct *tty);
> +
>  #define MASK(x) ((x) & (N_TTY_BUF_SIZE - 1))
>  
>  static inline size_t read_cnt(struct n_tty_data *ldata)
> @@ -1334,6 +1337,11 @@ static void n_tty_receive_char_special(struct 
> tty_struct *tty, unsigned char c)
>   commit_echoes(tty);
>   return;
>   }
> + if (c == STATUS_CHAR(tty) && L_IEXTEN(tty)) {
> + if (!L_NOKERNINFO(tty))
> + n_tty_status(tty);
> + return;
> + }
>   if (c == '\n') {
>   if (L_ECHO(tty) || L_ECHONL(tty)) {
>   echo_char_raw('\n', ldata);
> @@ -1763,6 +1771,7 @@ static void n_tty_set_termios(struct tty_struct *tty, 
> struct ktermios *old)
>   set_bit(EOF_CHAR(tty), ldata->char_map);
>   set_bit('\n', ldata->char_map);
>   set_bit(EOL_CHAR(tty), ldata->char_map);
> + set_bit(STATUS_CHAR(tty), ldata->char_map);
>   if (L_IEXTEN(tty)) {
>   set_bit(WERASE_CHAR(tty), ldata->char_map);
>   set_bit(LNEXT_CHAR(tty), ldata->char_map);
> @@ -2413,6 +2422,26 @@ static unsigned long inq_canon(struct n_tty_data 
> *ldata)
>   return nr;
>  }
>  
> +static void n_tty_status(struct tty_struct *tty)
> +{
> + struct n_tty_data *ldata = tty->disc_data;
> + char *msg;
> + size_t len;
> +
> + msg = kzalloc(STATUS_LINE_LEN, GFP_KERNEL);

Please check for memory failures.

> +
> + if (ldata->column != 0) {
> + *msg = '\n';
> + len = n_tty_get_status(tty, msg + 1, STATUS_LINE_LEN - 1);
> + } else {
> + len = n_tty_get_status(tty, msg, STATUS_LINE_LEN);
> + }
> +
> + do_n_tty_write(tty, NULL, msg, len);
> +
> + kfree(msg);
> +}
> +
>  static int n_tty_ioctl(struct

[PATCH v2 3/3] vstatus: Display an informational message when the VSTATUS character is pressed or TIOCSTAT ioctl is called.

2022-02-06 Thread Walt Drummond
When triggered by pressing the VSTATUS key or calling the TIOCSTAT
ioctl, the n_tty line discipline will display a message on the user's
tty that provides basic information about the system and an
'interesting' process in the current foreground process group, eg:

  load: 0.58  cmd: sleep 744474 [sleeping] 0.36r 0.00u 0.00s 0% 772k

The status message provides:
 - System load average
 - Command name and process id (from the perspective of the session)
 - Scheduler state
 - Total wall-clock run time
 - User space run time
 - System space run time
 - Percentage of on-cpu time
 - Resident set size

The message is only displayed when the tty has the VSTATUS character
set, the local flags ICANON and IEXTEN are enabled and NOKERNINFO is
disabled; it is always displayed when TIOCSTAT is called regardless of
tty settings.

Signed-off-by: Walt Drummond 
---
 drivers/tty/Makefile   |   2 +-
 drivers/tty/n_tty.c|  34 +++
 drivers/tty/n_tty_status.c | 181 +
 drivers/tty/tty_io.c   |   2 +-
 include/linux/tty.h|   5 +
 5 files changed, 222 insertions(+), 2 deletions(-)
 create mode 100644 drivers/tty/n_tty_status.c

diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile
index a2bd75fbaaa4..3539d7ab77e5 100644
--- a/drivers/tty/Makefile
+++ b/drivers/tty/Makefile
@@ -2,7 +2,7 @@
 obj-$(CONFIG_TTY)  += tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o \
   tty_buffer.o tty_port.o tty_mutex.o \
   tty_ldsem.o tty_baudrate.o tty_jobctrl.o \
-  n_null.o
+  n_null.o n_tty_status.o
 obj-$(CONFIG_LEGACY_PTYS)  += pty.o
 obj-$(CONFIG_UNIX98_PTYS)  += pty.o
 obj-$(CONFIG_AUDIT)+= tty_audit.o
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 64a058a4c63b..fd70efc333d7 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -80,6 +80,7 @@
 #define ECHO_BLOCK 256
 #define ECHO_DISCARD_WATERMARK N_TTY_BUF_SIZE - (ECHO_BLOCK + 32)
 
+#define STATUS_LINE_LEN 160   /* tty status line will truncate at this length 
*/
 
 #undef N_TTY_TRACE
 #ifdef N_TTY_TRACE
@@ -127,6 +128,8 @@ struct n_tty_data {
struct mutex output_lock;
 };
 
+static void n_tty_status(struct tty_struct *tty);
+
 #define MASK(x) ((x) & (N_TTY_BUF_SIZE - 1))
 
 static inline size_t read_cnt(struct n_tty_data *ldata)
@@ -1334,6 +1337,11 @@ static void n_tty_receive_char_special(struct tty_struct 
*tty, unsigned char c)
commit_echoes(tty);
return;
}
+   if (c == STATUS_CHAR(tty) && L_IEXTEN(tty)) {
+   if (!L_NOKERNINFO(tty))
+   n_tty_status(tty);
+   return;
+   }
if (c == '\n') {
if (L_ECHO(tty) || L_ECHONL(tty)) {
echo_char_raw('\n', ldata);
@@ -1763,6 +1771,7 @@ static void n_tty_set_termios(struct tty_struct *tty, 
struct ktermios *old)
set_bit(EOF_CHAR(tty), ldata->char_map);
set_bit('\n', ldata->char_map);
set_bit(EOL_CHAR(tty), ldata->char_map);
+   set_bit(STATUS_CHAR(tty), ldata->char_map);
if (L_IEXTEN(tty)) {
set_bit(WERASE_CHAR(tty), ldata->char_map);
set_bit(LNEXT_CHAR(tty), ldata->char_map);
@@ -2413,6 +2422,26 @@ static unsigned long inq_canon(struct n_tty_data *ldata)
return nr;
 }
 
+static void n_tty_status(struct tty_struct *tty)
+{
+   struct n_tty_data *ldata = tty->disc_data;
+   char *msg;
+   size_t len;
+
+   msg = kzalloc(STATUS_LINE_LEN, GFP_KERNEL);
+
+   if (ldata->column != 0) {
+   *msg = '\n';
+   len = n_tty_get_status(tty, msg + 1, STATUS_LINE_LEN - 1);
+   } else {
+   len = n_tty_get_status(tty, msg, STATUS_LINE_LEN);
+   }
+
+   do_n_tty_write(tty, NULL, msg, len);
+
+   kfree(msg);
+}
+
 static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
   unsigned int cmd, unsigned long arg)
 {
@@ -2430,6 +2459,11 @@ static int n_tty_ioctl(struct tty_struct *tty, struct 
file *file,
retval = read_cnt(ldata);
up_write(&tty->termios_rwsem);
return put_user(retval, (unsigned int __user *) arg);
+   case TIOCSTAT:
+   down_read(&tty->termios_rwsem);
+   n_tty_status(tty);
+   up_read(&tty->termios_rwsem);
+   return 0;
default:
return n_tty_ioctl_helper(tty, file, cmd, arg);
}
diff --git a/drivers/tty/n_tty_status.c b/drivers/tty/n_tty_status.c
new file mode 100644
index ..f0e053651368
--- /dev/null
+++ b/drivers/tty/n_tty_status.c
@@ -0,0