linux/kernel/acct.c
<<
>>
Prefs
   1/*
   2 *  linux/kernel/acct.c
   3 *
   4 *  BSD Process Accounting for Linux
   5 *
   6 *  Author: Marco van Wieringen <mvw@planets.elm.net>
   7 *
   8 *  Some code based on ideas and code from:
   9 *  Thomas K. Dyas <tdyas@eden.rutgers.edu>
  10 *
  11 *  This file implements BSD-style process accounting. Whenever any
  12 *  process exits, an accounting record of type "struct acct" is
  13 *  written to the file specified with the acct() system call. It is
  14 *  up to user-level programs to do useful things with the accounting
  15 *  log. The kernel just provides the raw accounting information.
  16 *
  17 * (C) Copyright 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.
  18 *
  19 *  Plugged two leaks. 1) It didn't return acct_file into the free_filps if
  20 *  the file happened to be read-only. 2) If the accounting was suspended
  21 *  due to the lack of space it happily allowed to reopen it and completely
  22 *  lost the old acct_file. 3/10/98, Al Viro.
  23 *
  24 *  Now we silently close acct_file on attempt to reopen. Cleaned sys_acct().
  25 *  XTerms and EMACS are manifestations of pure evil. 21/10/98, AV.
  26 *
  27 *  Fixed a nasty interaction with with sys_umount(). If the accointing
  28 *  was suspeneded we failed to stop it on umount(). Messy.
  29 *  Another one: remount to readonly didn't stop accounting.
  30 *      Question: what should we do if we have CAP_SYS_ADMIN but not
  31 *  CAP_SYS_PACCT? Current code does the following: umount returns -EBUSY
  32 *  unless we are messing with the root. In that case we are getting a
  33 *  real mess with do_remount_sb(). 9/11/98, AV.
  34 *
  35 *  Fixed a bunch of races (and pair of leaks). Probably not the best way,
  36 *  but this one obviously doesn't introduce deadlocks. Later. BTW, found
  37 *  one race (and leak) in BSD implementation.
  38 *  OK, that's better. ANOTHER race and leak in BSD variant. There always
  39 *  is one more bug... 10/11/98, AV.
  40 *
  41 *      Oh, fsck... Oopsable SMP race in do_process_acct() - we must hold
  42 * ->mmap_sem to walk the vma list of current->mm. Nasty, since it leaks
  43 * a struct file opened for write. Fixed. 2/6/2000, AV.
  44 */
  45
  46#include <linux/mm.h>
  47#include <linux/slab.h>
  48#include <linux/acct.h>
  49#include <linux/capability.h>
  50#include <linux/file.h>
  51#include <linux/tty.h>
  52#include <linux/security.h>
  53#include <linux/vfs.h>
  54#include <linux/jiffies.h>
  55#include <linux/times.h>
  56#include <linux/syscalls.h>
  57#include <linux/mount.h>
  58#include <asm/uaccess.h>
  59#include <asm/div64.h>
  60#include <linux/blkdev.h> /* sector_div */
  61#include <linux/pid_namespace.h>
  62
  63/*
  64 * These constants control the amount of freespace that suspend and
  65 * resume the process accounting system, and the time delay between
  66 * each check.
  67 * Turned into sysctl-controllable parameters. AV, 12/11/98
  68 */
  69
  70int acct_parm[3] = {4, 2, 30};
  71#define RESUME          (acct_parm[0])  /* >foo% free space - resume */
  72#define SUSPEND         (acct_parm[1])  /* <foo% free space - suspend */
  73#define ACCT_TIMEOUT    (acct_parm[2])  /* foo second timeout between checks */
  74
  75/*
  76 * External references and all of the globals.
  77 */
  78static void do_acct_process(struct bsd_acct_struct *acct,
  79                struct pid_namespace *ns, struct file *);
  80
  81/*
  82 * This structure is used so that all the data protected by lock
  83 * can be placed in the same cache line as the lock.  This primes
  84 * the cache line to have the data after getting the lock.
  85 */
  86struct bsd_acct_struct {
  87        volatile int            active;
  88        volatile int            needcheck;
  89        struct file             *file;
  90        struct pid_namespace    *ns;
  91        struct timer_list       timer;
  92        struct list_head        list;
  93};
  94
  95static DEFINE_SPINLOCK(acct_lock);
  96static LIST_HEAD(acct_list);
  97
  98/*
  99 * Called whenever the timer says to check the free space.
 100 */
 101static void acct_timeout(unsigned long x)
 102{
 103        struct bsd_acct_struct *acct = (struct bsd_acct_struct *)x;
 104        acct->needcheck = 1;
 105}
 106
 107/*
 108 * Check the amount of free space and suspend/resume accordingly.
 109 */
 110static int check_free_space(struct bsd_acct_struct *acct, struct file *file)
 111{
 112        struct kstatfs sbuf;
 113        int res;
 114        int act;
 115        sector_t resume;
 116        sector_t suspend;
 117
 118        spin_lock(&acct_lock);
 119        res = acct->active;
 120        if (!file || !acct->needcheck)
 121                goto out;
 122        spin_unlock(&acct_lock);
 123
 124        /* May block */
 125        if (vfs_statfs(file->f_path.dentry, &sbuf))
 126                return res;
 127        suspend = sbuf.f_blocks * SUSPEND;
 128        resume = sbuf.f_blocks * RESUME;
 129
 130        sector_div(suspend, 100);
 131        sector_div(resume, 100);
 132
 133        if (sbuf.f_bavail <= suspend)
 134                act = -1;
 135        else if (sbuf.f_bavail >= resume)
 136                act = 1;
 137        else
 138                act = 0;
 139
 140        /*
 141         * If some joker switched acct->file under us we'ld better be
 142         * silent and _not_ touch anything.
 143         */
 144        spin_lock(&acct_lock);
 145        if (file != acct->file) {
 146                if (act)
 147                        res = act>0;
 148                goto out;
 149        }
 150
 151        if (acct->active) {
 152                if (act < 0) {
 153                        acct->active = 0;
 154                        printk(KERN_INFO "Process accounting paused\n");
 155                }
 156        } else {
 157                if (act > 0) {
 158                        acct->active = 1;
 159                        printk(KERN_INFO "Process accounting resumed\n");
 160                }
 161        }
 162
 163        del_timer(&acct->timer);
 164        acct->needcheck = 0;
 165        acct->timer.expires = jiffies + ACCT_TIMEOUT*HZ;
 166        add_timer(&acct->timer);
 167        res = acct->active;
 168out:
 169        spin_unlock(&acct_lock);
 170        return res;
 171}
 172
 173/*
 174 * Close the old accounting file (if currently open) and then replace
 175 * it with file (if non-NULL).
 176 *
 177 * NOTE: acct_lock MUST be held on entry and exit.
 178 */
 179static void acct_file_reopen(struct bsd_acct_struct *acct, struct file *file,
 180                struct pid_namespace *ns)
 181{
 182        struct file *old_acct = NULL;
 183        struct pid_namespace *old_ns = NULL;
 184
 185        if (acct->file) {
 186                old_acct = acct->file;
 187                old_ns = acct->ns;
 188                del_timer(&acct->timer);
 189                acct->active = 0;
 190                acct->needcheck = 0;
 191                acct->file = NULL;
 192                acct->ns = NULL;
 193                list_del(&acct->list);
 194        }
 195        if (file) {
 196                acct->file = file;
 197                acct->ns = ns;
 198                acct->needcheck = 0;
 199                acct->active = 1;
 200                list_add(&acct->list, &acct_list);
 201                /* It's been deleted if it was used before so this is safe */
 202                setup_timer(&acct->timer, acct_timeout, (unsigned long)acct);
 203                acct->timer.expires = jiffies + ACCT_TIMEOUT*HZ;
 204                add_timer(&acct->timer);
 205        }
 206        if (old_acct) {
 207                mnt_unpin(old_acct->f_path.mnt);
 208                spin_unlock(&acct_lock);
 209                do_acct_process(acct, old_ns, old_acct);
 210                filp_close(old_acct, NULL);
 211                spin_lock(&acct_lock);
 212        }
 213}
 214
 215static int acct_on(char *name)
 216{
 217        struct file *file;
 218        struct vfsmount *mnt;
 219        int error;
 220        struct pid_namespace *ns;
 221        struct bsd_acct_struct *acct = NULL;
 222
 223        /* Difference from BSD - they don't do O_APPEND */
 224        file = filp_open(name, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
 225        if (IS_ERR(file))
 226                return PTR_ERR(file);
 227
 228        if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) {
 229                filp_close(file, NULL);
 230                return -EACCES;
 231        }
 232
 233        if (!file->f_op->write) {
 234                filp_close(file, NULL);
 235                return -EIO;
 236        }
 237
 238        ns = task_active_pid_ns(current);
 239        if (ns->bacct == NULL) {
 240                acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL);
 241                if (acct == NULL) {
 242                        filp_close(file, NULL);
 243                        return -ENOMEM;
 244                }
 245        }
 246
 247        error = security_acct(file);
 248        if (error) {
 249                kfree(acct);
 250                filp_close(file, NULL);
 251                return error;
 252        }
 253
 254        spin_lock(&acct_lock);
 255        if (ns->bacct == NULL) {
 256                ns->bacct = acct;
 257                acct = NULL;
 258        }
 259
 260        mnt = file->f_path.mnt;
 261        mnt_pin(mnt);
 262        acct_file_reopen(ns->bacct, file, ns);
 263        spin_unlock(&acct_lock);
 264
 265        mntput(mnt); /* it's pinned, now give up active reference */
 266        kfree(acct);
 267
 268        return 0;
 269}
 270
 271/**
 272 * sys_acct - enable/disable process accounting
 273 * @name: file name for accounting records or NULL to shutdown accounting
 274 *
 275 * Returns 0 for success or negative errno values for failure.
 276 *
 277 * sys_acct() is the only system call needed to implement process
 278 * accounting. It takes the name of the file where accounting records
 279 * should be written. If the filename is NULL, accounting will be
 280 * shutdown.
 281 */
 282SYSCALL_DEFINE1(acct, const char __user *, name)
 283{
 284        int error;
 285
 286        if (!capable(CAP_SYS_PACCT))
 287                return -EPERM;
 288
 289        if (name) {
 290                char *tmp = getname(name);
 291                if (IS_ERR(tmp))
 292                        return (PTR_ERR(tmp));
 293                error = acct_on(tmp);
 294                putname(tmp);
 295        } else {
 296                struct bsd_acct_struct *acct;
 297
 298                acct = task_active_pid_ns(current)->bacct;
 299                if (acct == NULL)
 300                        return 0;
 301
 302                error = security_acct(NULL);
 303                if (!error) {
 304                        spin_lock(&acct_lock);
 305                        acct_file_reopen(acct, NULL, NULL);
 306                        spin_unlock(&acct_lock);
 307                }
 308        }
 309        return error;
 310}
 311
 312/**
 313 * acct_auto_close - turn off a filesystem's accounting if it is on
 314 * @m: vfsmount being shut down
 315 *
 316 * If the accounting is turned on for a file in the subtree pointed to
 317 * to by m, turn accounting off.  Done when m is about to die.
 318 */
 319void acct_auto_close_mnt(struct vfsmount *m)
 320{
 321        struct bsd_acct_struct *acct;
 322
 323        spin_lock(&acct_lock);
 324restart:
 325        list_for_each_entry(acct, &acct_list, list)
 326                if (acct->file && acct->file->f_path.mnt == m) {
 327                        acct_file_reopen(acct, NULL, NULL);
 328                        goto restart;
 329                }
 330        spin_unlock(&acct_lock);
 331}
 332
 333/**
 334 * acct_auto_close - turn off a filesystem's accounting if it is on
 335 * @sb: super block for the filesystem
 336 *
 337 * If the accounting is turned on for a file in the filesystem pointed
 338 * to by sb, turn accounting off.
 339 */
 340void acct_auto_close(struct super_block *sb)
 341{
 342        struct bsd_acct_struct *acct;
 343
 344        spin_lock(&acct_lock);
 345restart:
 346        list_for_each_entry(acct, &acct_list, list)
 347                if (acct->file && acct->file->f_path.mnt->mnt_sb == sb) {
 348                        acct_file_reopen(acct, NULL, NULL);
 349                        goto restart;
 350                }
 351        spin_unlock(&acct_lock);
 352}
 353
 354void acct_exit_ns(struct pid_namespace *ns)
 355{
 356        struct bsd_acct_struct *acct;
 357
 358        spin_lock(&acct_lock);
 359        acct = ns->bacct;
 360        if (acct != NULL) {
 361                if (acct->file != NULL)
 362                        acct_file_reopen(acct, NULL, NULL);
 363
 364                kfree(acct);
 365        }
 366        spin_unlock(&acct_lock);
 367}
 368
 369/*
 370 *  encode an unsigned long into a comp_t
 371 *
 372 *  This routine has been adopted from the encode_comp_t() function in
 373 *  the kern_acct.c file of the FreeBSD operating system. The encoding
 374 *  is a 13-bit fraction with a 3-bit (base 8) exponent.
 375 */
 376
 377#define MANTSIZE        13                      /* 13 bit mantissa. */
 378#define EXPSIZE         3                       /* Base 8 (3 bit) exponent. */
 379#define MAXFRACT        ((1 << MANTSIZE) - 1)   /* Maximum fractional value. */
 380
 381static comp_t encode_comp_t(unsigned long value)
 382{
 383        int exp, rnd;
 384
 385        exp = rnd = 0;
 386        while (value > MAXFRACT) {
 387                rnd = value & (1 << (EXPSIZE - 1));     /* Round up? */
 388                value >>= EXPSIZE;      /* Base 8 exponent == 3 bit shift. */
 389                exp++;
 390        }
 391
 392        /*
 393         * If we need to round up, do it (and handle overflow correctly).
 394         */
 395        if (rnd && (++value > MAXFRACT)) {
 396                value >>= EXPSIZE;
 397                exp++;
 398        }
 399
 400        /*
 401         * Clean it up and polish it off.
 402         */
 403        exp <<= MANTSIZE;               /* Shift the exponent into place */
 404        exp += value;                   /* and add on the mantissa. */
 405        return exp;
 406}
 407
 408#if ACCT_VERSION==1 || ACCT_VERSION==2
 409/*
 410 * encode an u64 into a comp2_t (24 bits)
 411 *
 412 * Format: 5 bit base 2 exponent, 20 bits mantissa.
 413 * The leading bit of the mantissa is not stored, but implied for
 414 * non-zero exponents.
 415 * Largest encodable value is 50 bits.
 416 */
 417
 418#define MANTSIZE2       20                      /* 20 bit mantissa. */
 419#define EXPSIZE2        5                       /* 5 bit base 2 exponent. */
 420#define MAXFRACT2       ((1ul << MANTSIZE2) - 1) /* Maximum fractional value. */
 421#define MAXEXP2         ((1 <<EXPSIZE2) - 1)    /* Maximum exponent. */
 422
 423static comp2_t encode_comp2_t(u64 value)
 424{
 425        int exp, rnd;
 426
 427        exp = (value > (MAXFRACT2>>1));
 428        rnd = 0;
 429        while (value > MAXFRACT2) {
 430                rnd = value & 1;
 431                value >>= 1;
 432                exp++;
 433        }
 434
 435        /*
 436         * If we need to round up, do it (and handle overflow correctly).
 437         */
 438        if (rnd && (++value > MAXFRACT2)) {
 439                value >>= 1;
 440                exp++;
 441        }
 442
 443        if (exp > MAXEXP2) {
 444                /* Overflow. Return largest representable number instead. */
 445                return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
 446        } else {
 447                return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
 448        }
 449}
 450#endif
 451
 452#if ACCT_VERSION==3
 453/*
 454 * encode an u64 into a 32 bit IEEE float
 455 */
 456static u32 encode_float(u64 value)
 457{
 458        unsigned exp = 190;
 459        unsigned u;
 460
 461        if (value==0) return 0;
 462        while ((s64)value > 0){
 463                value <<= 1;
 464                exp--;
 465        }
 466        u = (u32)(value >> 40) & 0x7fffffu;
 467        return u | (exp << 23);
 468}
 469#endif
 470
 471/*
 472 *  Write an accounting entry for an exiting process
 473 *
 474 *  The acct_process() call is the workhorse of the process
 475 *  accounting system. The struct acct is built here and then written
 476 *  into the accounting file. This function should only be called from
 477 *  do_exit() or when switching to a different output file.
 478 */
 479
 480/*
 481 *  do_acct_process does all actual work. Caller holds the reference to file.
 482 */
 483static void do_acct_process(struct bsd_acct_struct *acct,
 484                struct pid_namespace *ns, struct file *file)
 485{
 486        struct pacct_struct *pacct = &current->signal->pacct;
 487        acct_t ac;
 488        mm_segment_t fs;
 489        unsigned long flim;
 490        u64 elapsed;
 491        u64 run_time;
 492        struct timespec uptime;
 493        struct tty_struct *tty;
 494
 495        /*
 496         * First check to see if there is enough free_space to continue
 497         * the process accounting system.
 498         */
 499        if (!check_free_space(acct, file))
 500                return;
 501
 502        /*
 503         * Fill the accounting struct with the needed info as recorded
 504         * by the different kernel functions.
 505         */
 506        memset((caddr_t)&ac, 0, sizeof(acct_t));
 507
 508        ac.ac_version = ACCT_VERSION | ACCT_BYTEORDER;
 509        strlcpy(ac.ac_comm, current->comm, sizeof(ac.ac_comm));
 510
 511        /* calculate run_time in nsec*/
 512        do_posix_clock_monotonic_gettime(&uptime);
 513        run_time = (u64)uptime.tv_sec*NSEC_PER_SEC + uptime.tv_nsec;
 514        run_time -= (u64)current->group_leader->start_time.tv_sec * NSEC_PER_SEC
 515                       + current->group_leader->start_time.tv_nsec;
 516        /* convert nsec -> AHZ */
 517        elapsed = nsec_to_AHZ(run_time);
 518#if ACCT_VERSION==3
 519        ac.ac_etime = encode_float(elapsed);
 520#else
 521        ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
 522                               (unsigned long) elapsed : (unsigned long) -1l);
 523#endif
 524#if ACCT_VERSION==1 || ACCT_VERSION==2
 525        {
 526                /* new enlarged etime field */
 527                comp2_t etime = encode_comp2_t(elapsed);
 528                ac.ac_etime_hi = etime >> 16;
 529                ac.ac_etime_lo = (u16) etime;
 530        }
 531#endif
 532        do_div(elapsed, AHZ);
 533        ac.ac_btime = get_seconds() - elapsed;
 534        /* we really need to bite the bullet and change layout */
 535        ac.ac_uid = current->uid;
 536        ac.ac_gid = current->gid;
 537#if ACCT_VERSION==2
 538        ac.ac_ahz = AHZ;
 539#endif
 540#if ACCT_VERSION==1 || ACCT_VERSION==2
 541        /* backward-compatible 16 bit fields */
 542        ac.ac_uid16 = current->uid;
 543        ac.ac_gid16 = current->gid;
 544#endif
 545#if ACCT_VERSION==3
 546        ac.ac_pid = task_tgid_nr_ns(current, ns);
 547        rcu_read_lock();
 548        ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), ns);
 549        rcu_read_unlock();
 550#endif
 551
 552        spin_lock_irq(&current->sighand->siglock);
 553        tty = current->signal->tty;
 554        ac.ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0;
 555        ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
 556        ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));
 557        ac.ac_flag = pacct->ac_flag;
 558        ac.ac_mem = encode_comp_t(pacct->ac_mem);
 559        ac.ac_minflt = encode_comp_t(pacct->ac_minflt);
 560        ac.ac_majflt = encode_comp_t(pacct->ac_majflt);
 561        ac.ac_exitcode = pacct->ac_exitcode;
 562        spin_unlock_irq(&current->sighand->siglock);
 563        ac.ac_io = encode_comp_t(0 /* current->io_usage */);    /* %% */
 564        ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
 565        ac.ac_swaps = encode_comp_t(0);
 566
 567        /*
 568         * Kernel segment override to datasegment and write it
 569         * to the accounting file.
 570         */
 571        fs = get_fs();
 572        set_fs(KERNEL_DS);
 573        /*
 574         * Accounting records are not subject to resource limits.
 575         */
 576        flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
 577        current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
 578        file->f_op->write(file, (char *)&ac,
 579                               sizeof(acct_t), &file->f_pos);
 580        current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
 581        set_fs(fs);
 582}
 583
 584/**
 585 * acct_init_pacct - initialize a new pacct_struct
 586 * @pacct: per-process accounting info struct to initialize
 587 */
 588void acct_init_pacct(struct pacct_struct *pacct)
 589{
 590        memset(pacct, 0, sizeof(struct pacct_struct));
 591        pacct->ac_utime = pacct->ac_stime = cputime_zero;
 592}
 593
 594/**
 595 * acct_collect - collect accounting information into pacct_struct
 596 * @exitcode: task exit code
 597 * @group_dead: not 0, if this thread is the last one in the process.
 598 */
 599void acct_collect(long exitcode, int group_dead)
 600{
 601        struct pacct_struct *pacct = &current->signal->pacct;
 602        unsigned long vsize = 0;
 603
 604        if (group_dead && current->mm) {
 605                struct vm_area_struct *vma;
 606                down_read(&current->mm->mmap_sem);
 607                vma = current->mm->mmap;
 608                while (vma) {
 609                        vsize += vma->vm_end - vma->vm_start;
 610                        vma = vma->vm_next;
 611                }
 612                up_read(&current->mm->mmap_sem);
 613        }
 614
 615        spin_lock_irq(&current->sighand->siglock);
 616        if (group_dead)
 617                pacct->ac_mem = vsize / 1024;
 618        if (thread_group_leader(current)) {
 619                pacct->ac_exitcode = exitcode;
 620                if (current->flags & PF_FORKNOEXEC)
 621                        pacct->ac_flag |= AFORK;
 622        }
 623        if (current->flags & PF_SUPERPRIV)
 624                pacct->ac_flag |= ASU;
 625        if (current->flags & PF_DUMPCORE)
 626                pacct->ac_flag |= ACORE;
 627        if (current->flags & PF_SIGNALED)
 628                pacct->ac_flag |= AXSIG;
 629        pacct->ac_utime = cputime_add(pacct->ac_utime, current->utime);
 630        pacct->ac_stime = cputime_add(pacct->ac_stime, current->stime);
 631        pacct->ac_minflt += current->min_flt;
 632        pacct->ac_majflt += current->maj_flt;
 633        spin_unlock_irq(&current->sighand->siglock);
 634}
 635
 636static void acct_process_in_ns(struct pid_namespace *ns)
 637{
 638        struct file *file = NULL;
 639        struct bsd_acct_struct *acct;
 640
 641        acct = ns->bacct;
 642        /*
 643         * accelerate the common fastpath:
 644         */
 645        if (!acct || !acct->file)
 646                return;
 647
 648        spin_lock(&acct_lock);
 649        file = acct->file;
 650        if (unlikely(!file)) {
 651                spin_unlock(&acct_lock);
 652                return;
 653        }
 654        get_file(file);
 655        spin_unlock(&acct_lock);
 656
 657        do_acct_process(acct, ns, file);
 658        fput(file);
 659}
 660
 661/**
 662 * acct_process - now just a wrapper around acct_process_in_ns,
 663 * which in turn is a wrapper around do_acct_process.
 664 *
 665 * handles process accounting for an exiting task
 666 */
 667void acct_process(void)
 668{
 669        struct pid_namespace *ns;
 670
 671        /*
 672         * This loop is safe lockless, since current is still
 673         * alive and holds its namespace, which in turn holds
 674         * its parent.
 675         */
 676        for (ns = task_active_pid_ns(current); ns != NULL; ns = ns->parent)
 677                acct_process_in_ns(ns);
 678}
 679