compat: utmp not cleared on tty logout

Bug #183729 reported by Pete Savage on 2008-01-17
52
This bug affects 5 people
Affects Status Importance Assigned to Milestone
upstart
Low
Petr Lautrbach
kdebase-workspace (Ubuntu)
Undecided
Unassigned
upstart (Fedora)
Fix Released
Low
upstart (Ubuntu)
Undecided
Unassigned

Bug Description

Log into tty1, then tty2 and then log out of both. Now run a w command and you should see something similar to the following;

mac@tootoo:~/source/procps-3.2.7/proc$ w
 10:39:09 up 33 days, 23:11, 4 users, load average: 1.31, 0.62, 0.39
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
mac tty7 :0 11Jan08 4:34m 7:24m 36.02s x-session-manager
mac pts/1 :0.0 08:54 0.00s 0.19s 0.00s w

It shows that 4 users are logged in. Obviously this is wrong. I wrote a small C utility to hack out what w and uptime get as information from utmp.

#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <unistd.h>
#include <utmp.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
  struct utmp *utmpstruct;
  struct utmp entry;

  //system("echo before adding entry:;who");

  setutent();
  //pututline(&entry);
  while ((utmpstruct = getutent())){
        if ((utmpstruct->ut_type == USER_PROCESS) && (utmpstruct->ut_name[0] != '\0'))
        printf(utmpstruct->ut_line);
        printf("\t");
        printf("%d",utmpstruct->ut_pid);
        printf("\n");
  }
  endutent();
  return 0;
}

You'll get an output like this

mac@tootoo:~$ ./a.out
        0
        50
        4305
        4306
tty2 14989
        4312
tty1 4313
        4314
tty7 30255
        0
pts/1 9712
        0
        0
        0
        0
        0
        20929
        14914
        15034

However, running the following , to try to find the pid for the tty1 process, gives;

mac@tootoo:~/source/procps-3.2.7/proc$ ps aux | grep 4313
mac 15524 0.0 0.0 2988 768 pts/1 R+ 10:42 0:00 grep 4313
mac@tootoo:~/source/procps-3.2.7/proc$

This is obviously wrong, utmp still has the old process id's associated as being logged in.

Running the following gives the new tty pid

mac@tootoo:~/source/procps-3.2.7/proc$ ps aux | grep tty1
root 14914 0.0 0.0 1692 516 tty1 Ss+ 10:33 0:00 /sbin/getty 38400 tty1
mac 15605 0.0 0.0 2988 764 pts/1 R+ 10:44 0:00 grep tty1
mac@tootoo:~/source/procps-3.2.7/proc$

There is now a new pid for tty1

Koen Beek (koen-beek) wrote :

behaviour confirmed on gutsy amd64

2.6.22-14-generic #1 SMP Tue Dec 18 05:28:27 UTC 2007 x86_64 GNU/Linux

RobC (rccase) wrote :

I also have this problem on edgy-server i386
2.6.17-12-server #2 SMP Tue Dec 18 02:13:45 UTC 2007 i686 GNU/Linux

Well known bug in Upstart, simply due to its utter lack of utmp handling -- we've known that it behaves like this since edgy, but figured nobody would probably notice in practice.

It's on the TODO list to fix, but pretty low priority.

Changed in procps:
importance: Undecided → Low

Moving bug upstream (I wish Launchpad could do this properly)

Changed in upstart:
importance: Undecided → Low
status: New → Confirmed
status: Confirmed → Invalid
status: Confirmed → Triaged
Pete Savage (petesavage) wrote :

Scott,

It caused me a fair amount of worry, when I thought my machine had hacked binaries ;)

Pete

Changed in upstart:
milestone: none → 0.5
arboc (dcobra) wrote :

I'm using kubuntu 8.04 / KDE-4 Remix. Here's my scenario:

During an X session, on occasion I need to use a virtual console for whatever reason. So I switch to tty1 (Ctrl-Alt-F1) , log in, do some stuff, then log out, go back to X (Alt-F7) and continue working. When I leave for the day, I select Shutdown, confirm, and go away, thinking the system will shutdown as usual.

The next time I use the computer (which may be several days later), I find out it never shut down at all, because kdm stopped at a dialog asking me if I want to abort an active session on vt1.

I think this bug deserves a higher priority. Even if I had seen the dialog, it is still annoying to have to click an extra button to confirm aborting an active session which no longer exists. I imagine these ghost sessions showing up in "finger", "last", etc. can probably cause other significant problems as well.

It would really help if the developers of upstart can suggest a workaround to clear the entry left over in utmp, until this bug is fixed in a future release (perhaps some command in the .logout file, or a change in /etc/event.d/tty?)

arboc (dcobra) wrote :

Here's the workaround I found myself, in case somebody is interested. Install the runit package, which seems to handle utmp better than upstart does, copy the /etc/sv/getty-5 directory that comes with it to /etc/sv/getty-1 through getty-4 and getty-6, modify the run and finish scripts and the supervise link in these directories, changing the tty numbers accordingly. Finally, stop upstart from running getty by moving /etc/event.d/tty? elsewhere and tell runit to take charge of running them by making soft links from /etc/service/getty-? to /etc/sv/getty-?. That's it, no more stale utmp entries.

I'm still interested if anybody cares to comment on whether there is a better workaround than this one.

As a side note, pardon my ignorance, but I thought moving a bug upstream meant that it is actually caused by some other bug in an underlying package, but I couldn't find the continuation of this bug anywhere in launchpad. So is it abandoned or where was it taken up?

Changed in upstart:
milestone: 0.5 → none
Changed in upstart:
status: Invalid → Triaged

Description of problem:
If user switches to terminal (Ctrl+Alt+Fx) use it and then exits, this terminal stays listed in sessions to switch to

Version-Release number of selected component (if applicable):

How reproducible:
always

Steps to Reproduce:
1.switch to terminal (Ctrl+Alt+F2)
2.enter username and password
3.logout
4.kde->switch user

Actual results:
"user: TTY login (vt2)" is listed even if session has been already terminated

Expected results:
only active sessions are listed

Additional info:
if you repeat above steps, you can achieve "user: TTY login (vt2)" to be listed twice (three times, four...)

Confirmed.

Interesting, I wonder by what method kde uses to determine users logged into tty's... either that's broken or console logins are.

"last" gives interesting results for me:
rdieter1 tty2 ... Wed nov 5 08:52 gone - no logout

except, I *did* logout.

OK, looks like tty logins never finish logging out. For me, ALT-F2 goto console, login... do stuff... logout... stuck, no login: prompt

Now, who to blame for this? :)

bouncing over to util-linux-ng (owner of login), in hopes of some insight.

Interesting, I can't reproduce anymore, how about you?

This bug appears to have been reported against 'rawhide' during the Fedora 10 development cycle.
Changing version to '10'.

More information and reason for this action is here:
http://fedoraproject.org/wiki/BugZappers/HouseKeeping

I'm in work now, where I have kde 4.1.3 packages from updates-testing and it doesn't work for me. Still the "same" problem.

I think there is (maybe) one difference: If I try to switch user via "start"->Switch user and select tty console, it starts new session with kdm as if I select "start new session". If I try to switch via screen saver lock or via kdm, it "works" as usual. I don't know if this is new change or if it was working this way already.

I can test also on system updated without updates-testing today later if you want.

Changed in upstart:
milestone: none → 0.5-later

I take back comment #4, console logins are still not registerring logout, 'last' still reports only 'gone - no logout'

It seems that /sbin/init from upstart does not care about utmp at all.

(Note that mingetty(8) and login(1) can create a new utmp entry on systems
where init(8) is broken, but init(8) has to set the entry to DEAD_PROCESS
state when user logout and login process has exited).

See utmp man page:

  The first entries ever created result from init(8) processing inittab(5).
  Before an entry is processed, though, init(8) cleans up utmp by setting
  ut_type to DEAD_PROCESS, clearing ut_user, ut_host, and ut_time with null
  bytes for each record which ut_type is not DEAD_PROCESS or RUN_LVL and where
  no process with PID ut_pid exists. If no empty record with the needed ut_id
  can be found, init(8) creates a new one. It sets ut_id from the inittab,
  ut_pid and ut_time to the current values, and ut_type to INIT_PROCESS.

  mingetty(8) (or agetty(8)) locates the entry by the PID, changes ut_type to
  LOGIN_PRO- CESS, changes ut_time, sets ut_line, and waits for connection to be
  established. login(1), after a user has been authenticated, changes ut_type
  to USER_PROCESS, changes ut_time, and sets ut_host and ut_addr. Depending on
  mingetty(8) (or agetty(8)) and login(1), records may be located by ut_line
  instead of the preferable ut_pid.

  When init(8) finds that a process has exited, it locates its utmp entry by
  ut_pid, sets ut_type to DEAD_PROCESS, and clears ut_user, ut_host and ut_time
  with null bytes.

Reassignig to upstart.

Created attachment 344797
utmp patch

It fixes problem with tty logins which stays in sessions list.

It adds new stanza - utmp - and writes utmp entries and wtmp log
as described in utmp(5).

Needs to add "utmp <id>" to /etc/event.d/tty<id>

Tested againts F10 and devel branch

I would greatly prefer to not change the job syntax if at all possible.

Historically /sbin/init in upstart hasn't directly altered utmp. The upstart runlevel command does the utmp editing by itself.

Following that pattern, the right way is to create a helper.

Petr Lautrbach (plautrba) wrote :

Hi

This patch is againts lp:upstart/0.3 branch.

It adds "utmp <id>" stanza and writes utmp entries and wtmp log
as described in utmp(5).

How it works:

When child is forked and job->utmp is set, child inserts to first line with same id (utmp.ut_id)
new values with his own pid, id, actual time and type set to INIT_PROCESS and logs in wtmp.

When jobs die and utmp is set, init sets type DEAD_PROCESS and clears values for entry
with dead process pid. Entry is also logged to wtmp log.

*** Bug 502362 has been marked as a duplicate of this bug. ***

it folows upstart 0.5 roadmap https://lists.ubuntu.com/archives/upstart-devel/2007-October/000468.html:

Finally init will maintain INIT_PROCESS and DEAD_PROCESS entries in utmp
for jobs that require it, through a "utmp id" stanza. The general user
of this will the getty job, where such utmp entries are necessary for
correct behaviour.

> Following that pattern, the right way is to create a helper.

I can't imagine how this helper should work. Do you have any idea about that?

Anyway it has to be somehow handled by init. There should be set line with INIT_PROCESS and right pid (of new process) before running new getty (or another tty process).

> I would greatly prefer to not change the job syntax if at all possible.

It's a way how to tell init what id (representing terminal name suffix) use when writes to utmp line with INIT_PROCESS before exec to getty as long as we don't use inittab for that.

what do you think about this:

create something called utmp-helper (compat/sysv/utmp-helper.c) with usage:

utmp-helper --id <terminal suffix> -- <command for what we need utmp handling>

utmp-helper will do fork(), in child it will save pid of new process, id and INIT_PROCESS to utmp table, call setsid() for controlling tty and execv() to <command for what we need utmp handling>, in parrent it will wait() until child terminates, then set DEAD_PROCESS into utmp table and log to wtmp log.

and then exec line in /etc/event.d/tty* will be changed to:
exec utmp-helper --id 1 -- /sbin/mingetty tty1

Petr: that's pretty much how I was thinking it should be solved. Would you be willing to assign copyright for that to Canonical so I can apply it to the source?

summary: - utmp not cleared on tty logout
+ compat: utmp not cleared on tty logout
Changed in upstart:
milestone: 0.5-later → none
Petr Lautrbach (plautrba) wrote :

I've just sent copyright assignment in accordance with ContributingCode

looks like upstream will accept patch from Comment #9

Changed in upstart (Fedora):
status: Unknown → In Progress

Hi Petr,

I received the assignment, thanks very much! Sorry, I haven't dropped this; here's a quick review of the code, and thoughts on merging it with 0.6

0.6.x have a util/utmp.c already for reading and writing runlevel and reboot records, it feels like these process records should go in there as well - but then that'd mean having utmp.c shared between init/ and util/ and there's no directory for that yet (it's not appropriate to go into libnih)

Why the __GLIBC__ check? Unless I'm mistaken, the gettimeofday() and assign would work in either case. In general I've tried to avoid #ifdef in the Upstart code. Should use the utmpx.h functions rather than utmp.h?

Thoughts on the utmp stanza, firstly we should check the length of this at parse time rather than silently truncating. Also given instance jobs we probably want to expand environment variables here so you can do:

    utmp $ID

For things like a single getty job, that wouldn't be sufficient since you'd want the ids to match the getty ids. That'd mean supporting shell-style replacements in expansion (which we don't do yet)

    utmp ${TTY#tty}

Should init not always set DEAD_PROCESS for any pid it's supervised, whether or not it created the utmp entry in the first place? Problem there of course is that we don't know the ut_id of them I guess, so we'd have to iterate the entire utmp file every time?

paths.h defines a WTMP macro, this shouldn't be necessary since _PATH_WTMP is already defined in utmp.h

(Arguably a few of those things in paths.h should go away and be replaced by things from <paths.h> like _PATH_CONSOLE, _PATH_DEVNULL, _PATH_BSHELL, etc.)

Missing tests, should check for a utmp record being written, failing to write, etc. (possible by calling utmpname() in the test) - it should be ok for wtmp to fail at any time, so the test is safe. Should check for the entries being cleared too.

One thing that the manpage isn't quite clear about is what happens when you create an INIT_PROCESS entry but search for a USER_PROCESS entry to delete, as you've done there - I think this will still find it, but a test would help us be sure.

A. D. Nieman (adnieman) wrote :

I can appreciate that this is tasked to be fixed, but I feel that it is important enough that the issue should have been addressed a year ago. Do not take this as reproach. I understand that most of the software in the open source community is privately developed by the individuals in the community. I just would like it fixed.

Has this patch made it into F10/F11/Rawhide?

--
Steven M. Parrish - KDE Triage Master
                  - PackageKit Triager
Fedora Bugzappers volunteer triage team
https://fedoraproject.org/wiki/BugZappers

Afaict, the patch has not been integrated, but I'd love to be wrong.

Unfortunately it seems you're not wrong, the problem persists with upstart-0.3.11-1.fc11.x86_64 on F-11, and looks like later versions don't have it either.

(In reply to comment #19)
> and looks like later versions don't have it either.

...where with "it" I mean a fix.

Upstream is not doing any more releases for 0.3.x. Since it doesn't look like we're advancing to the next version any time soon this should probably be rolled in by us.

confirmed issue remains in f12, rebasing.

*** Bug 542138 has been marked as a duplicate of this bug. ***

Created attachment 376109
add utmp_clean_id and call it from post-stop stanza

another helper suggestion:

call umtp_clean_id in post-stop stanza, eg for /etc/event.d/tty2:

post-stop exec /sbin/utmp_clean_id 2

utmp_clean_id is simple utility which cleans (sets type to DEAD_PROCESS and nulls other rows) lines with given id and type LOGIN_PROCESS or USER_PROCESS.

these patch is related to initscripts that provides /etc/event.d/tty*

Created attachment 398797
set DEAD_PROCESS for died proccess with pid in utmp table

(with this patch) init tries to find utmp entry for each tracked process which died. If entry is found, it sets type to DEAD_PROCESS and logs to wtmp log.

mingetty takes care about setting INIT_PROCESS/LOGIN_PROCESS itself.

There is no need to change anything else like it was in previous patches.

koji scratch build is here http://koji.fedoraproject.org/koji/taskinfo?taskID=2041266

upstart-0.3.11-4.fc12 has been submitted as an update for Fedora 12.
http://admin.fedoraproject.org/updates/upstart-0.3.11-4.fc12

upstart-0.3.11-4.fc12 has been pushed to the Fedora 12 testing repository. If problems still persist, please make note of it in this bug report.
 If you want to test the update, you can install it with
 su -c 'yum --enablerepo=updates-testing update upstart'. You can provide feedback for this update here: http://admin.fedoraproject.org/updates/upstart-0.3.11-4.fc12

Changed in kdebase-workspace (Ubuntu):
status: New → Invalid

upstart-0.3.11-4.fc12 has been pushed to the Fedora 12 stable repository. If problems still persist, please make note of it in this bug report.

For sanity's sake, I'm closing the Ubuntu tasks for upstream Upstart bugs. I've experimented with having both, but it is just making bugs hard to find now. Will use the policy whereby bugs on the Ubuntu package exist in the Ubuntu packaging or patches only, any bugs in the Upstart code are Upstream bugs.

Changed in upstart (Ubuntu):
status: Triaged → Invalid
Petr Lautrbach (plautrba) wrote :

If we assume that *getty takes care about setting INIT_PROCESS/LOGIN_PROCESS itself, we need just set DEAD_PROCESS for dead processes with pid in utmp table and log it into wtmp.

Init goes through the utmp table, tries to find entry with dead process pid and sets it to DEAD_PROCESS. There is no need to create/set up "utmp" stanza.

Test covers utmp table with 2 entries and with 2 situation - process is in LOGIN_PROCESS or USER_PROCESS.

Marc - A. Dahlhaus (mad-wol) wrote :

Petr's patch in comment #15 fixes the problem for me. agetty displays logged on users as expected in issue outputs.

Marc - A. Dahlhaus (mad-wol) wrote :

With Petr's patch in comment #15:
On boot issue still displays one user logged in. This is cleared by the first users logout.
Could be a leftover from the previous shutdown/reboot that got not cleared up the right way, but i am only guessing here...

I would love to see proper utmp and wtmp record handling in upstart would get some love in upstart soon.

Marc - A. Dahlhaus (mad-wol) wrote :

Found the cause of the stray login that was shown on startup, it was unrelated to Petr's patch or upstart itself in any way.
So please ignore the first part of comment #17.

Changed in upstart:
status: Triaged → Fix Committed
assignee: nobody → Petr Lautrbach (plautrba)
milestone: none → 0.6.8
Changed in upstart:
milestone: none → 1.0
Changed in upstart:
status: Fix Committed → Fix Released
Changed in upstart (Ubuntu):
status: Invalid → New
importance: Low → Undecided
tags: added: patch
Evan Peck (colors) wrote :

Since this both has patch(es) and instructions to replicate the error/problem,
I will mark this as Confirmed in upstart(Ubuntu).

Thank you!

Changed in upstart (Ubuntu):
status: New → Confirmed
Steve Langasek (vorlon) on 2012-02-04
Changed in upstart (Ubuntu):
status: Confirmed → Fix Released
Dirley (cpd-dirley) wrote :

This fix will be ported to 0.6 series? On my company, we have more then 50 servers using Ubuntu 10.04 LTS that are affect by this bug.

Steve Langasek (vorlon) wrote :

> This fix will be ported to 0.6 series?

No, sorry. If this is a blocking bug for you, I recommend upgrading to 12.04 LTS.

Bruno Nova (brunonova) wrote :

Are you sure this is fixed?
I'm seeing this exact bug in Trusty. Logging out of a TTY doesn't lower the number of users in uptime, w, etc.

Now, Vivid switched to systemd, so if the bug is really in upstart, it may not be worth wasting time here.
But, Trusty is an LTS... so, I don't know.

Changed in upstart (Fedora):
importance: Unknown → Low
status: In Progress → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.