2014-02-24 14:50:57

by Hannes Reinecke

[permalink] [raw]
Subject: [PATCHv3] tty: Set correct tty name in 'active' sysfs attribute

The 'active' sysfs attribute should refer to the currently
active tty devices the console is running on, not the currently
active console.
The console structure doesn't refer to any device in sysfs,
only the tty the console is running on has.
So we need to print out the tty names in 'active', not
the console names.
But we need to take care for the virtual console to always display
'tty0' so as not to break existing programs.

Cc: Lennart Poettering <[email protected]>
Cc: Kay Sievers <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Jiri Slaby <[email protected]>
Signed-off-by: Werner Fink <[email protected]>
Signed-off-by: Hannes Reinecke <[email protected]>
---
drivers/tty/tty_io.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index c74a00a..96eb462 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -1271,12 +1271,13 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p)
*
* Locking: None
*/
-static void tty_line_name(struct tty_driver *driver, int index, char *p)
+static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)
{
if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE)
- strcpy(p, driver->name);
+ return sprintf(p, "%s", driver->name);
else
- sprintf(p, "%s%d", driver->name, index + driver->name_base);
+ return sprintf(p, "%s%d", driver->name,
+ index + driver->name_base);
}

/**
@@ -3545,9 +3546,20 @@ static ssize_t show_cons_active(struct device *dev,
if (i >= ARRAY_SIZE(cs))
break;
}
- while (i--)
- count += sprintf(buf + count, "%s%d%c",
- cs[i]->name, cs[i]->index, i ? ' ':'\n');
+ while (i--) {
+ struct tty_driver *driver;
+ const char *name = cs[i]->name;
+ int index = cs[i]->index;
+
+ driver = cs[i]->device(cs[i], &index);
+ /* Some programs rely on 'tty0' for console */
+ if (driver && (index > 0 || driver->major != TTY_MAJOR)) {
+ count += tty_line_name(driver, index, buf + count);
+ count += sprintf(buf + count, "%c", i ? ' ':'\n');
+ } else
+ count += sprintf(buf + count, "%s%d%c",
+ name, cs[i]->index, i ? ' ':'\n');
+ }
console_unlock();

return count;
--
1.7.12.4


2014-02-24 14:58:12

by David Herrmann

[permalink] [raw]
Subject: Re: [PATCHv3] tty: Set correct tty name in 'active' sysfs attribute

Hi

On Mon, Feb 24, 2014 at 3:50 PM, Hannes Reinecke <[email protected]> wrote:
> The 'active' sysfs attribute should refer to the currently
> active tty devices the console is running on, not the currently
> active console.
> The console structure doesn't refer to any device in sysfs,
> only the tty the console is running on has.
> So we need to print out the tty names in 'active', not
> the console names.
> But we need to take care for the virtual console to always display
> 'tty0' so as not to break existing programs.
>
> Cc: Lennart Poettering <[email protected]>
> Cc: Kay Sievers <[email protected]>
> Cc: Greg Kroah-Hartman <[email protected]>
> Cc: Jiri Slaby <[email protected]>
> Signed-off-by: Werner Fink <[email protected]>
> Signed-off-by: Hannes Reinecke <[email protected]>
> ---
> drivers/tty/tty_io.c | 24 ++++++++++++++++++------
> 1 file changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
> index c74a00a..96eb462 100644
> --- a/drivers/tty/tty_io.c
> +++ b/drivers/tty/tty_io.c
> @@ -1271,12 +1271,13 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p)
> *
> * Locking: None
> */
> -static void tty_line_name(struct tty_driver *driver, int index, char *p)
> +static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)
> {
> if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE)
> - strcpy(p, driver->name);
> + return sprintf(p, "%s", driver->name);
> else
> - sprintf(p, "%s%d", driver->name, index + driver->name_base);
> + return sprintf(p, "%s%d", driver->name,
> + index + driver->name_base);
> }
>
> /**
> @@ -3545,9 +3546,20 @@ static ssize_t show_cons_active(struct device *dev,
> if (i >= ARRAY_SIZE(cs))
> break;
> }
> - while (i--)
> - count += sprintf(buf + count, "%s%d%c",
> - cs[i]->name, cs[i]->index, i ? ' ':'\n');
> + while (i--) {
> + struct tty_driver *driver;
> + const char *name = cs[i]->name;
> + int index = cs[i]->index;
> +
> + driver = cs[i]->device(cs[i], &index);
> + /* Some programs rely on 'tty0' for console */
> + if (driver && (index > 0 || driver->major != TTY_MAJOR)) {

As Ray mentioned in the previous discussion, this has to be
cs[i]->index instead of "index" as ->device() changes the parameter.
See drivers/tty/vt/vt.c vt_console_device().

Thanks
David

> + count += tty_line_name(driver, index, buf + count);
> + count += sprintf(buf + count, "%c", i ? ' ':'\n');
> + } else
> + count += sprintf(buf + count, "%s%d%c",
> + name, cs[i]->index, i ? ' ':'\n');
> + }
> console_unlock();
>
> return count;
> --
> 1.7.12.4
>

2014-02-25 07:51:06

by Hannes Reinecke

[permalink] [raw]
Subject: Re: [PATCHv3] tty: Set correct tty name in 'active' sysfs attribute

On 02/24/2014 03:58 PM, David Herrmann wrote:
> Hi
>
> On Mon, Feb 24, 2014 at 3:50 PM, Hannes Reinecke <[email protected]> wrote:
>> The 'active' sysfs attribute should refer to the currently
>> active tty devices the console is running on, not the currently
>> active console.
>> The console structure doesn't refer to any device in sysfs,
>> only the tty the console is running on has.
>> So we need to print out the tty names in 'active', not
>> the console names.
>> But we need to take care for the virtual console to always display
>> 'tty0' so as not to break existing programs.
>>
>> Cc: Lennart Poettering <[email protected]>
>> Cc: Kay Sievers <[email protected]>
>> Cc: Greg Kroah-Hartman <[email protected]>
>> Cc: Jiri Slaby <[email protected]>
>> Signed-off-by: Werner Fink <[email protected]>
>> Signed-off-by: Hannes Reinecke <[email protected]>
>> ---
>> drivers/tty/tty_io.c | 24 ++++++++++++++++++------
>> 1 file changed, 18 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
>> index c74a00a..96eb462 100644
>> --- a/drivers/tty/tty_io.c
>> +++ b/drivers/tty/tty_io.c
>> @@ -1271,12 +1271,13 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p)
>> *
>> * Locking: None
>> */
>> -static void tty_line_name(struct tty_driver *driver, int index, char *p)
>> +static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)
>> {
>> if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE)
>> - strcpy(p, driver->name);
>> + return sprintf(p, "%s", driver->name);
>> else
>> - sprintf(p, "%s%d", driver->name, index + driver->name_base);
>> + return sprintf(p, "%s%d", driver->name,
>> + index + driver->name_base);
>> }
>>
>> /**
>> @@ -3545,9 +3546,20 @@ static ssize_t show_cons_active(struct device *dev,
>> if (i >= ARRAY_SIZE(cs))
>> break;
>> }
>> - while (i--)
>> - count += sprintf(buf + count, "%s%d%c",
>> - cs[i]->name, cs[i]->index, i ? ' ':'\n');
>> + while (i--) {
>> + struct tty_driver *driver;
>> + const char *name = cs[i]->name;
>> + int index = cs[i]->index;
>> +
>> + driver = cs[i]->device(cs[i], &index);
>> + /* Some programs rely on 'tty0' for console */
>> + if (driver && (index > 0 || driver->major != TTY_MAJOR)) {
>
> As Ray mentioned in the previous discussion, this has to be
> cs[i]->index instead of "index" as ->device() changes the parameter.
> See drivers/tty/vt/vt.c vt_console_device().
>
Positive?
I thought this was precisely the problem, ->device() changing the
index '0' into something non-zero.
The reports we had were that the line 'tty0' changed into 'tty1'.
Hence ->device() converted cs[i]->index (which is '0') into index
(which is '1').
Hence the check would be correct, wouldn't it?

Cheers,

Hannes
--
Dr. Hannes Reinecke zSeries & Storage
[email protected] +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: J. Hawn, J. Guild, F. Imend?rffer, HRB 16746 (AG N?rnberg)

2014-02-25 09:38:13

by David Herrmann

[permalink] [raw]
Subject: Re: [PATCHv3] tty: Set correct tty name in 'active' sysfs attribute

Hi

On Tue, Feb 25, 2014 at 8:51 AM, Hannes Reinecke <[email protected]> wrote:
> On 02/24/2014 03:58 PM, David Herrmann wrote:
>> Hi
>>
>> On Mon, Feb 24, 2014 at 3:50 PM, Hannes Reinecke <[email protected]> wrote:
>>> The 'active' sysfs attribute should refer to the currently
>>> active tty devices the console is running on, not the currently
>>> active console.
>>> The console structure doesn't refer to any device in sysfs,
>>> only the tty the console is running on has.
>>> So we need to print out the tty names in 'active', not
>>> the console names.
>>> But we need to take care for the virtual console to always display
>>> 'tty0' so as not to break existing programs.
>>>
>>> Cc: Lennart Poettering <[email protected]>
>>> Cc: Kay Sievers <[email protected]>
>>> Cc: Greg Kroah-Hartman <[email protected]>
>>> Cc: Jiri Slaby <[email protected]>
>>> Signed-off-by: Werner Fink <[email protected]>
>>> Signed-off-by: Hannes Reinecke <[email protected]>
>>> ---
>>> drivers/tty/tty_io.c | 24 ++++++++++++++++++------
>>> 1 file changed, 18 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
>>> index c74a00a..96eb462 100644
>>> --- a/drivers/tty/tty_io.c
>>> +++ b/drivers/tty/tty_io.c
>>> @@ -1271,12 +1271,13 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p)
>>> *
>>> * Locking: None
>>> */
>>> -static void tty_line_name(struct tty_driver *driver, int index, char *p)
>>> +static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)
>>> {
>>> if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE)
>>> - strcpy(p, driver->name);
>>> + return sprintf(p, "%s", driver->name);
>>> else
>>> - sprintf(p, "%s%d", driver->name, index + driver->name_base);
>>> + return sprintf(p, "%s%d", driver->name,
>>> + index + driver->name_base);
>>> }
>>>
>>> /**
>>> @@ -3545,9 +3546,20 @@ static ssize_t show_cons_active(struct device *dev,
>>> if (i >= ARRAY_SIZE(cs))
>>> break;
>>> }
>>> - while (i--)
>>> - count += sprintf(buf + count, "%s%d%c",
>>> - cs[i]->name, cs[i]->index, i ? ' ':'\n');
>>> + while (i--) {
>>> + struct tty_driver *driver;
>>> + const char *name = cs[i]->name;
>>> + int index = cs[i]->index;
>>> +
>>> + driver = cs[i]->device(cs[i], &index);
>>> + /* Some programs rely on 'tty0' for console */
>>> + if (driver && (index > 0 || driver->major != TTY_MAJOR)) {
>>
>> As Ray mentioned in the previous discussion, this has to be
>> cs[i]->index instead of "index" as ->device() changes the parameter.
>> See drivers/tty/vt/vt.c vt_console_device().
>>
> Positive?
> I thought this was precisely the problem, ->device() changing the
> index '0' into something non-zero.
> The reports we had were that the line 'tty0' changed into 'tty1'.
> Hence ->device() converted cs[i]->index (which is '0') into index
> (which is '1').
> Hence the check would be correct, wouldn't it?

If "cs[i]" points to tty0, then cs[i]->index is 0. If you call
->device(), it will store 1 (or !=0) in "index". Thus, "(driver &&
(index > 0))" will be true and you will write tty1 into the file
instead of tty0. So you don't want to check whether the new value is
non-zero, but whether the *previous* value was 0, turning this into:

if (driver && (cs[i]->index > 0 || driver->major != TTY_MAJOR))

So loosely speaking, we use the new code only for devices which either
are not a VT or have an idx > 0. Otherwise, we use our fallback.

Thanks
David

2014-02-27 11:17:00

by Kay Sievers

[permalink] [raw]
Subject: Re: [PATCHv3] tty: Set correct tty name in 'active' sysfs attribute

On Tue, Feb 25, 2014 at 10:38 AM, David Herrmann <[email protected]> wrote:
> On Tue, Feb 25, 2014 at 8:51 AM, Hannes Reinecke <[email protected]> wrote:

>> Positive?
>> I thought this was precisely the problem, ->device() changing the
>> index '0' into something non-zero.
>> The reports we had were that the line 'tty0' changed into 'tty1'.
>> Hence ->device() converted cs[i]->index (which is '0') into index
>> (which is '1').
>> Hence the check would be correct, wouldn't it?
>
> If "cs[i]" points to tty0, then cs[i]->index is 0. If you call
> ->device(), it will store 1 (or !=0) in "index". Thus, "(driver &&
> (index > 0))" will be true and you will write tty1 into the file
> instead of tty0. So you don't want to check whether the new value is
> non-zero, but whether the *previous* value was 0, turning this into:
>
> if (driver && (cs[i]->index > 0 || driver->major != TTY_MAJOR))
>
> So loosely speaking, we use the new code only for devices which either
> are not a VT or have an idx > 0. Otherwise, we use our fallback.

Hannes, David, care to update the patch to do that? It all sounds fine
to me. And we should get this merged again.

Kay

2014-02-27 11:33:03

by David Herrmann

[permalink] [raw]
Subject: Re: [PATCHv3] tty: Set correct tty name in 'active' sysfs attribute

Hi

On Thu, Feb 27, 2014 at 12:16 PM, Kay Sievers <[email protected]> wrote:
> On Tue, Feb 25, 2014 at 10:38 AM, David Herrmann <[email protected]> wrote:
>> On Tue, Feb 25, 2014 at 8:51 AM, Hannes Reinecke <[email protected]> wrote:
>
>>> Positive?
>>> I thought this was precisely the problem, ->device() changing the
>>> index '0' into something non-zero.
>>> The reports we had were that the line 'tty0' changed into 'tty1'.
>>> Hence ->device() converted cs[i]->index (which is '0') into index
>>> (which is '1').
>>> Hence the check would be correct, wouldn't it?
>>
>> If "cs[i]" points to tty0, then cs[i]->index is 0. If you call
>> ->device(), it will store 1 (or !=0) in "index". Thus, "(driver &&
>> (index > 0))" will be true and you will write tty1 into the file
>> instead of tty0. So you don't want to check whether the new value is
>> non-zero, but whether the *previous* value was 0, turning this into:
>>
>> if (driver && (cs[i]->index > 0 || driver->major != TTY_MAJOR))
>>
>> So loosely speaking, we use the new code only for devices which either
>> are not a VT or have an idx > 0. Otherwise, we use our fallback.
>
> Hannes, David, care to update the patch to do that? It all sounds fine
> to me. And we should get this merged again.

I have picked it up and resent a fixed patch. I screwed up the version
field, so it's called v3 again.. sorry.

Thanks
David