LCOV - code coverage report
Current view: top level - kernel - acct.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 132 198 66.7 %
Date: 2014-02-18 Functions: 9 12 75.0 %
Branches: 63 138 45.7 %

           Branch data     Line data    Source code
       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                 :            : 
      70                 :            : int 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                 :            :  */
      78                 :            : static 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                 :            :  */
      86                 :            : struct bsd_acct_struct {
      87                 :            :         int                     active;
      88                 :            :         unsigned long           needcheck;
      89                 :            :         struct file             *file;
      90                 :            :         struct pid_namespace    *ns;
      91                 :            :         struct list_head        list;
      92                 :            : };
      93                 :            : 
      94                 :            : static DEFINE_SPINLOCK(acct_lock);
      95                 :            : static LIST_HEAD(acct_list);
      96                 :            : 
      97                 :            : /*
      98                 :            :  * Check the amount of free space and suspend/resume accordingly.
      99                 :            :  */
     100                 :          0 : static int check_free_space(struct bsd_acct_struct *acct, struct file *file)
     101                 :            : {
     102                 :            :         struct kstatfs sbuf;
     103                 :            :         int res;
     104                 :            :         int act;
     105                 :            :         u64 resume;
     106                 :            :         u64 suspend;
     107                 :            : 
     108                 :            :         spin_lock(&acct_lock);
     109                 :          1 :         res = acct->active;
     110 [ +  - ][ +  - ]:          1 :         if (!file || time_is_before_jiffies(acct->needcheck))
     111                 :            :                 goto out;
     112                 :            :         spin_unlock(&acct_lock);
     113                 :            : 
     114                 :            :         /* May block */
     115         [ +  - ]:          1 :         if (vfs_statfs(&file->f_path, &sbuf))
     116                 :            :                 return res;
     117                 :          1 :         suspend = sbuf.f_blocks * SUSPEND;
     118                 :          1 :         resume = sbuf.f_blocks * RESUME;
     119                 :            : 
     120                 :          1 :         do_div(suspend, 100);
     121                 :          1 :         do_div(resume, 100);
     122                 :            : 
     123         [ +  - ]:          1 :         if (sbuf.f_bavail <= suspend)
     124                 :            :                 act = -1;
     125         [ -  + ]:          1 :         else if (sbuf.f_bavail >= resume)
     126                 :            :                 act = 1;
     127                 :            :         else
     128                 :            :                 act = 0;
     129                 :            : 
     130                 :            :         /*
     131                 :            :          * If some joker switched acct->file under us we'ld better be
     132                 :            :          * silent and _not_ touch anything.
     133                 :            :          */
     134                 :            :         spin_lock(&acct_lock);
     135         [ +  - ]:          2 :         if (file != acct->file) {
     136         [ +  - ]:          1 :                 if (act)
     137                 :          1 :                         res = act>0;
     138                 :            :                 goto out;
     139                 :            :         }
     140                 :            : 
     141         [ #  # ]:          0 :         if (acct->active) {
     142         [ #  # ]:          0 :                 if (act < 0) {
     143                 :          0 :                         acct->active = 0;
     144                 :          0 :                         printk(KERN_INFO "Process accounting paused\n");
     145                 :            :                 }
     146                 :            :         } else {
     147         [ #  # ]:          0 :                 if (act > 0) {
     148                 :          0 :                         acct->active = 1;
     149                 :          0 :                         printk(KERN_INFO "Process accounting resumed\n");
     150                 :            :                 }
     151                 :            :         }
     152                 :            : 
     153                 :          0 :         acct->needcheck = jiffies + ACCT_TIMEOUT*HZ;
     154                 :          0 :         res = acct->active;
     155                 :            : out:
     156                 :            :         spin_unlock(&acct_lock);
     157                 :          1 :         return res;
     158                 :            : }
     159                 :            : 
     160                 :            : /*
     161                 :            :  * Close the old accounting file (if currently open) and then replace
     162                 :            :  * it with file (if non-NULL).
     163                 :            :  *
     164                 :            :  * NOTE: acct_lock MUST be held on entry and exit.
     165                 :            :  */
     166                 :          0 : static void acct_file_reopen(struct bsd_acct_struct *acct, struct file *file,
     167                 :            :                 struct pid_namespace *ns)
     168                 :            : {
     169                 :            :         struct file *old_acct = NULL;
     170                 :            :         struct pid_namespace *old_ns = NULL;
     171                 :            : 
     172         [ +  + ]:          2 :         if (acct->file) {
     173                 :            :                 old_acct = acct->file;
     174                 :            :                 old_ns = acct->ns;
     175                 :          1 :                 acct->active = 0;
     176                 :          1 :                 acct->file = NULL;
     177                 :          1 :                 acct->ns = NULL;
     178                 :            :                 list_del(&acct->list);
     179                 :            :         }
     180         [ +  + ]:          2 :         if (file) {
     181                 :          1 :                 acct->file = file;
     182                 :          1 :                 acct->ns = ns;
     183                 :          1 :                 acct->needcheck = jiffies + ACCT_TIMEOUT*HZ;
     184                 :          1 :                 acct->active = 1;
     185                 :          1 :                 list_add(&acct->list, &acct_list);
     186                 :            :         }
     187         [ #  # ]:          2 :         if (old_acct) {
     188                 :          1 :                 mnt_unpin(old_acct->f_path.mnt);
     189                 :            :                 spin_unlock(&acct_lock);
     190                 :          1 :                 do_acct_process(acct, old_ns, old_acct);
     191                 :          1 :                 filp_close(old_acct, NULL);
     192                 :            :                 spin_lock(&acct_lock);
     193                 :            :         }
     194                 :          0 : }
     195                 :            : 
     196                 :          0 : static int acct_on(struct filename *pathname)
     197                 :            : {
     198                 :          1 :         struct file *file;
     199                 :            :         struct vfsmount *mnt;
     200                 :            :         struct pid_namespace *ns;
     201                 :            :         struct bsd_acct_struct *acct = NULL;
     202                 :            : 
     203                 :            :         /* Difference from BSD - they don't do O_APPEND */
     204                 :          1 :         file = file_open_name(pathname, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
     205         [ -  + ]:          2 :         if (IS_ERR(file))
     206                 :          0 :                 return PTR_ERR(file);
     207                 :            : 
     208         [ -  + ]:          1 :         if (!S_ISREG(file_inode(file)->i_mode)) {
     209                 :          0 :                 filp_close(file, NULL);
     210                 :          0 :                 return -EACCES;
     211                 :            :         }
     212                 :            : 
     213         [ -  + ]:          1 :         if (!file->f_op->write) {
     214                 :          0 :                 filp_close(file, NULL);
     215                 :          0 :                 return -EIO;
     216                 :            :         }
     217                 :            : 
     218                 :          1 :         ns = task_active_pid_ns(current);
     219         [ +  - ]:          1 :         if (ns->bacct == NULL) {
     220                 :            :                 acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL);
     221         [ -  + ]:          1 :                 if (acct == NULL) {
     222                 :          0 :                         filp_close(file, NULL);
     223                 :          0 :                         return -ENOMEM;
     224                 :            :                 }
     225                 :            :         }
     226                 :            : 
     227                 :            :         spin_lock(&acct_lock);
     228         [ +  - ]:          1 :         if (ns->bacct == NULL) {
     229                 :          1 :                 ns->bacct = acct;
     230                 :            :                 acct = NULL;
     231                 :            :         }
     232                 :            : 
     233                 :          1 :         mnt = file->f_path.mnt;
     234                 :          1 :         mnt_pin(mnt);
     235                 :          1 :         acct_file_reopen(ns->bacct, file, ns);
     236                 :            :         spin_unlock(&acct_lock);
     237                 :            : 
     238                 :          1 :         mntput(mnt); /* it's pinned, now give up active reference */
     239                 :          1 :         kfree(acct);
     240                 :            : 
     241                 :          1 :         return 0;
     242                 :            : }
     243                 :            : 
     244                 :            : /**
     245                 :            :  * sys_acct - enable/disable process accounting
     246                 :            :  * @name: file name for accounting records or NULL to shutdown accounting
     247                 :            :  *
     248                 :            :  * Returns 0 for success or negative errno values for failure.
     249                 :            :  *
     250                 :            :  * sys_acct() is the only system call needed to implement process
     251                 :            :  * accounting. It takes the name of the file where accounting records
     252                 :            :  * should be written. If the filename is NULL, accounting will be
     253                 :            :  * shutdown.
     254                 :            :  */
     255                 :          0 : SYSCALL_DEFINE1(acct, const char __user *, name)
     256                 :            : {
     257                 :            :         int error = 0;
     258                 :            : 
     259         [ +  - ]:          3 :         if (!capable(CAP_SYS_PACCT))
     260                 :            :                 return -EPERM;
     261                 :            : 
     262         [ +  + ]:          3 :         if (name) {
     263                 :          1 :                 struct filename *tmp = getname(name);
     264         [ -  + ]:          1 :                 if (IS_ERR(tmp))
     265                 :            :                         return (PTR_ERR(tmp));
     266                 :          1 :                 error = acct_on(tmp);
     267                 :          1 :                 putname(tmp);
     268                 :            :         } else {
     269                 :            :                 struct bsd_acct_struct *acct;
     270                 :            : 
     271                 :          2 :                 acct = task_active_pid_ns(current)->bacct;
     272         [ +  + ]:          2 :                 if (acct == NULL)
     273                 :            :                         return 0;
     274                 :            : 
     275                 :            :                 spin_lock(&acct_lock);
     276                 :          1 :                 acct_file_reopen(acct, NULL, NULL);
     277                 :            :                 spin_unlock(&acct_lock);
     278                 :            :         }
     279                 :            : 
     280                 :            :         return error;
     281                 :            : }
     282                 :            : 
     283                 :            : /**
     284                 :            :  * acct_auto_close - turn off a filesystem's accounting if it is on
     285                 :            :  * @m: vfsmount being shut down
     286                 :            :  *
     287                 :            :  * If the accounting is turned on for a file in the subtree pointed to
     288                 :            :  * to by m, turn accounting off.  Done when m is about to die.
     289                 :            :  */
     290                 :          0 : void acct_auto_close_mnt(struct vfsmount *m)
     291                 :            : {
     292                 :            :         struct bsd_acct_struct *acct;
     293                 :            : 
     294                 :            :         spin_lock(&acct_lock);
     295                 :            : restart:
     296         [ #  # ]:          0 :         list_for_each_entry(acct, &acct_list, list)
     297 [ #  # ][ #  # ]:          0 :                 if (acct->file && acct->file->f_path.mnt == m) {
     298                 :          0 :                         acct_file_reopen(acct, NULL, NULL);
     299                 :          0 :                         goto restart;
     300                 :            :                 }
     301                 :            :         spin_unlock(&acct_lock);
     302                 :          0 : }
     303                 :            : 
     304                 :            : /**
     305                 :            :  * acct_auto_close - turn off a filesystem's accounting if it is on
     306                 :            :  * @sb: super block for the filesystem
     307                 :            :  *
     308                 :            :  * If the accounting is turned on for a file in the filesystem pointed
     309                 :            :  * to by sb, turn accounting off.
     310                 :            :  */
     311                 :          0 : void acct_auto_close(struct super_block *sb)
     312                 :            : {
     313                 :            :         struct bsd_acct_struct *acct;
     314                 :            : 
     315                 :            :         spin_lock(&acct_lock);
     316                 :            : restart:
     317         [ #  # ]:          0 :         list_for_each_entry(acct, &acct_list, list)
     318 [ #  # ][ #  # ]:          0 :                 if (acct->file && acct->file->f_path.dentry->d_sb == sb) {
     319                 :          0 :                         acct_file_reopen(acct, NULL, NULL);
     320                 :          0 :                         goto restart;
     321                 :            :                 }
     322                 :            :         spin_unlock(&acct_lock);
     323                 :          0 : }
     324                 :            : 
     325                 :          0 : void acct_exit_ns(struct pid_namespace *ns)
     326                 :            : {
     327                 :          0 :         struct bsd_acct_struct *acct = ns->bacct;
     328                 :            : 
     329         [ #  # ]:          0 :         if (acct == NULL)
     330                 :          0 :                 return;
     331                 :            : 
     332                 :            :         spin_lock(&acct_lock);
     333         [ #  # ]:          0 :         if (acct->file != NULL)
     334                 :          0 :                 acct_file_reopen(acct, NULL, NULL);
     335                 :            :         spin_unlock(&acct_lock);
     336                 :            : 
     337                 :          0 :         kfree(acct);
     338                 :            : }
     339                 :            : 
     340                 :            : /*
     341                 :            :  *  encode an unsigned long into a comp_t
     342                 :            :  *
     343                 :            :  *  This routine has been adopted from the encode_comp_t() function in
     344                 :            :  *  the kern_acct.c file of the FreeBSD operating system. The encoding
     345                 :            :  *  is a 13-bit fraction with a 3-bit (base 8) exponent.
     346                 :            :  */
     347                 :            : 
     348                 :            : #define MANTSIZE        13                      /* 13 bit mantissa. */
     349                 :            : #define EXPSIZE         3                       /* Base 8 (3 bit) exponent. */
     350                 :            : #define MAXFRACT        ((1 << MANTSIZE) - 1)     /* Maximum fractional value. */
     351                 :            : 
     352                 :            : static comp_t encode_comp_t(unsigned long value)
     353                 :            : {
     354                 :            :         int exp, rnd;
     355                 :            : 
     356                 :            :         exp = rnd = 0;
     357 [ -  + ][ -  + ]:          8 :         while (value > MAXFRACT) {
         [ -  + ][ -  + ]
         [ -  + ][ -  + ]
     358                 :          0 :                 rnd = value & (1 << (EXPSIZE - 1));   /* Round up? */
     359                 :          0 :                 value >>= EXPSIZE;        /* Base 8 exponent == 3 bit shift. */
     360                 :          0 :                 exp++;
     361                 :            :         }
     362                 :            : 
     363                 :            :         /*
     364                 :            :          * If we need to round up, do it (and handle overflow correctly).
     365                 :            :          */
     366 [ -  + ][ #  # ]:          7 :         if (rnd && (++value > MAXFRACT)) {
         [ -  + ][ #  # ]
         [ -  + ][ #  # ]
         [ -  + ][ #  # ]
         [ -  + ][ #  # ]
         [ -  + ][ #  # ]
     367                 :          0 :                 value >>= EXPSIZE;
     368                 :          0 :                 exp++;
     369                 :            :         }
     370                 :            : 
     371                 :            :         /*
     372                 :            :          * Clean it up and polish it off.
     373                 :            :          */
     374                 :          7 :         exp <<= MANTSIZE;         /* Shift the exponent into place */
     375                 :          8 :         exp += value;                   /* and add on the mantissa. */
     376                 :          8 :         return exp;
     377                 :            : }
     378                 :            : 
     379                 :            : #if ACCT_VERSION==1 || ACCT_VERSION==2
     380                 :            : /*
     381                 :            :  * encode an u64 into a comp2_t (24 bits)
     382                 :            :  *
     383                 :            :  * Format: 5 bit base 2 exponent, 20 bits mantissa.
     384                 :            :  * The leading bit of the mantissa is not stored, but implied for
     385                 :            :  * non-zero exponents.
     386                 :            :  * Largest encodable value is 50 bits.
     387                 :            :  */
     388                 :            : 
     389                 :            : #define MANTSIZE2       20                      /* 20 bit mantissa. */
     390                 :            : #define EXPSIZE2        5                       /* 5 bit base 2 exponent. */
     391                 :            : #define MAXFRACT2       ((1ul << MANTSIZE2) - 1) /* Maximum fractional value. */
     392                 :            : #define MAXEXP2         ((1 <<EXPSIZE2) - 1)    /* Maximum exponent. */
     393                 :            : 
     394                 :          0 : static comp2_t encode_comp2_t(u64 value)
     395                 :            : {
     396                 :            :         int exp, rnd;
     397                 :            : 
     398                 :          1 :         exp = (value > (MAXFRACT2>>1));
     399                 :            :         rnd = 0;
     400         [ -  + ]:          1 :         while (value > MAXFRACT2) {
     401                 :          0 :                 rnd = value & 1;
     402                 :          0 :                 value >>= 1;
     403                 :          0 :                 exp++;
     404                 :            :         }
     405                 :            : 
     406                 :            :         /*
     407                 :            :          * If we need to round up, do it (and handle overflow correctly).
     408                 :            :          */
     409 [ -  + ][ #  # ]:          1 :         if (rnd && (++value > MAXFRACT2)) {
     410                 :          0 :                 value >>= 1;
     411                 :          0 :                 exp++;
     412                 :            :         }
     413                 :            : 
     414            [ + ]:          1 :         if (exp > MAXEXP2) {
     415                 :            :                 /* Overflow. Return largest representable number instead. */
     416                 :            :                 return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
     417                 :            :         } else {
     418                 :          1 :                 return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
     419                 :            :         }
     420                 :            : }
     421                 :            : #endif
     422                 :            : 
     423                 :            : #if ACCT_VERSION==3
     424                 :            : /*
     425                 :            :  * encode an u64 into a 32 bit IEEE float
     426                 :            :  */
     427                 :            : static u32 encode_float(u64 value)
     428                 :            : {
     429                 :            :         unsigned exp = 190;
     430                 :            :         unsigned u;
     431                 :            : 
     432                 :            :         if (value==0) return 0;
     433                 :            :         while ((s64)value > 0){
     434                 :            :                 value <<= 1;
     435                 :            :                 exp--;
     436                 :            :         }
     437                 :            :         u = (u32)(value >> 40) & 0x7fffffu;
     438                 :            :         return u | (exp << 23);
     439                 :            : }
     440                 :            : #endif
     441                 :            : 
     442                 :            : /*
     443                 :            :  *  Write an accounting entry for an exiting process
     444                 :            :  *
     445                 :            :  *  The acct_process() call is the workhorse of the process
     446                 :            :  *  accounting system. The struct acct is built here and then written
     447                 :            :  *  into the accounting file. This function should only be called from
     448                 :            :  *  do_exit() or when switching to a different output file.
     449                 :            :  */
     450                 :            : 
     451                 :            : /*
     452                 :            :  *  do_acct_process does all actual work. Caller holds the reference to file.
     453                 :            :  */
     454                 :          0 : static void do_acct_process(struct bsd_acct_struct *acct,
     455                 :            :                 struct pid_namespace *ns, struct file *file)
     456                 :            : {
     457                 :          1 :         struct pacct_struct *pacct = &current->signal->pacct;
     458                 :            :         acct_t ac;
     459                 :            :         mm_segment_t fs;
     460                 :            :         unsigned long flim;
     461                 :            :         u64 elapsed;
     462                 :            :         u64 run_time;
     463                 :            :         struct timespec uptime;
     464                 :            :         struct tty_struct *tty;
     465                 :            :         const struct cred *orig_cred;
     466                 :            : 
     467                 :            :         /* Perform file operations on behalf of whoever enabled accounting */
     468                 :          1 :         orig_cred = override_creds(file->f_cred);
     469                 :            : 
     470                 :            :         /*
     471                 :            :          * First check to see if there is enough free_space to continue
     472                 :            :          * the process accounting system.
     473                 :            :          */
     474         [ +  - ]:          1 :         if (!check_free_space(acct, file))
     475                 :            :                 goto out;
     476                 :            : 
     477                 :            :         /*
     478                 :            :          * Fill the accounting struct with the needed info as recorded
     479                 :            :          * by the different kernel functions.
     480                 :            :          */
     481                 :          1 :         memset(&ac, 0, sizeof(acct_t));
     482                 :            : 
     483                 :          1 :         ac.ac_version = ACCT_VERSION | ACCT_BYTEORDER;
     484                 :          1 :         strlcpy(ac.ac_comm, current->comm, sizeof(ac.ac_comm));
     485                 :            : 
     486                 :            :         /* calculate run_time in nsec*/
     487                 :          1 :         do_posix_clock_monotonic_gettime(&uptime);
     488                 :          1 :         run_time = (u64)uptime.tv_sec*NSEC_PER_SEC + uptime.tv_nsec;
     489                 :          2 :         run_time -= (u64)current->group_leader->start_time.tv_sec * NSEC_PER_SEC
     490                 :          1 :                        + current->group_leader->start_time.tv_nsec;
     491                 :            :         /* convert nsec -> AHZ */
     492                 :            :         elapsed = nsec_to_AHZ(run_time);
     493                 :            : #if ACCT_VERSION==3
     494                 :            :         ac.ac_etime = encode_float(elapsed);
     495                 :            : #else
     496         [ +  - ]:          1 :         ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
     497                 :            :                                (unsigned long) elapsed : (unsigned long) -1l);
     498                 :            : #endif
     499                 :            : #if ACCT_VERSION==1 || ACCT_VERSION==2
     500                 :            :         {
     501                 :            :                 /* new enlarged etime field */
     502                 :          1 :                 comp2_t etime = encode_comp2_t(elapsed);
     503                 :          1 :                 ac.ac_etime_hi = etime >> 16;
     504                 :          1 :                 ac.ac_etime_lo = (u16) etime;
     505                 :            :         }
     506                 :            : #endif
     507                 :          1 :         do_div(elapsed, AHZ);
     508                 :          1 :         ac.ac_btime = get_seconds() - elapsed;
     509                 :            :         /* we really need to bite the bullet and change layout */
     510                 :          2 :         ac.ac_uid = from_kuid_munged(file->f_cred->user_ns, orig_cred->uid);
     511                 :          2 :         ac.ac_gid = from_kgid_munged(file->f_cred->user_ns, orig_cred->gid);
     512                 :            : #if ACCT_VERSION==2
     513                 :          1 :         ac.ac_ahz = AHZ;
     514                 :            : #endif
     515                 :            : #if ACCT_VERSION==1 || ACCT_VERSION==2
     516                 :            :         /* backward-compatible 16 bit fields */
     517                 :          1 :         ac.ac_uid16 = ac.ac_uid;
     518                 :          1 :         ac.ac_gid16 = ac.ac_gid;
     519                 :            : #endif
     520                 :            : #if ACCT_VERSION==3
     521                 :            :         ac.ac_pid = task_tgid_nr_ns(current, ns);
     522                 :            :         rcu_read_lock();
     523                 :            :         ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), ns);
     524                 :            :         rcu_read_unlock();
     525                 :            : #endif
     526                 :            : 
     527                 :          1 :         spin_lock_irq(&current->sighand->siglock);
     528                 :          2 :         tty = current->signal->tty;       /* Safe as we hold the siglock */
     529         [ +  + ]:          2 :         ac.ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0;
     530                 :          2 :         ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
     531                 :          2 :         ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));
     532                 :          1 :         ac.ac_flag = pacct->ac_flag;
     533                 :          1 :         ac.ac_mem = encode_comp_t(pacct->ac_mem);
     534                 :          1 :         ac.ac_minflt = encode_comp_t(pacct->ac_minflt);
     535                 :          1 :         ac.ac_majflt = encode_comp_t(pacct->ac_majflt);
     536                 :          1 :         ac.ac_exitcode = pacct->ac_exitcode;
     537                 :          1 :         spin_unlock_irq(&current->sighand->siglock);
     538                 :          1 :         ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */
     539                 :          1 :         ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
     540                 :          1 :         ac.ac_swaps = encode_comp_t(0);
     541                 :            : 
     542                 :            :         /*
     543                 :            :          * Get freeze protection. If the fs is frozen, just skip the write
     544                 :            :          * as we could deadlock the system otherwise.
     545                 :            :          */
     546         [ +  - ]:          1 :         if (!file_start_write_trylock(file))
     547                 :            :                 goto out;
     548                 :            :         /*
     549                 :            :          * Kernel segment override to datasegment and write it
     550                 :            :          * to the accounting file.
     551                 :            :          */
     552                 :          1 :         fs = get_fs();
     553                 :            :         set_fs(KERNEL_DS);
     554                 :            :         /*
     555                 :            :          * Accounting records are not subject to resource limits.
     556                 :            :          */
     557                 :          1 :         flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
     558                 :          1 :         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
     559                 :          1 :         file->f_op->write(file, (char *)&ac,
     560                 :            :                                sizeof(acct_t), &file->f_pos);
     561                 :          1 :         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
     562                 :            :         set_fs(fs);
     563                 :            :         file_end_write(file);
     564                 :            : out:
     565                 :          1 :         revert_creds(orig_cred);
     566                 :          1 : }
     567                 :            : 
     568                 :            : /**
     569                 :            :  * acct_collect - collect accounting information into pacct_struct
     570                 :            :  * @exitcode: task exit code
     571                 :            :  * @group_dead: not 0, if this thread is the last one in the process.
     572                 :            :  */
     573                 :          0 : void acct_collect(long exitcode, int group_dead)
     574                 :            : {
     575                 :    1151923 :         struct pacct_struct *pacct = &current->signal->pacct;
     576                 :            :         cputime_t utime, stime;
     577                 :            :         unsigned long vsize = 0;
     578                 :            : 
     579 [ +  + ][ +  + ]:    1151923 :         if (group_dead && current->mm) {
     580                 :            :                 struct vm_area_struct *vma;
     581                 :    1149126 :                 down_read(&current->mm->mmap_sem);
     582                 :    1149126 :                 vma = current->mm->mmap;
     583         [ +  + ]:   21636736 :                 while (vma) {
     584                 :   20487610 :                         vsize += vma->vm_end - vma->vm_start;
     585                 :   20487610 :                         vma = vma->vm_next;
     586                 :            :                 }
     587                 :    1149126 :                 up_read(&current->mm->mmap_sem);
     588                 :            :         }
     589                 :            : 
     590                 :    1151923 :         spin_lock_irq(&current->sighand->siglock);
     591         [ +  + ]:    1151923 :         if (group_dead)
     592                 :    1149607 :                 pacct->ac_mem = vsize / 1024;
     593         [ +  + ]:    1151923 :         if (thread_group_leader(current)) {
     594                 :    1149607 :                 pacct->ac_exitcode = exitcode;
     595         [ +  + ]:    1149607 :                 if (current->flags & PF_FORKNOEXEC)
     596                 :    1090933 :                         pacct->ac_flag |= AFORK;
     597                 :            :         }
     598         [ +  + ]:    1151923 :         if (current->flags & PF_SUPERPRIV)
     599                 :      14934 :                 pacct->ac_flag |= ASU;
     600            [ + ]:    1151923 :         if (current->flags & PF_DUMPCORE)
     601                 :         19 :                 pacct->ac_flag |= ACORE;
     602         [ #  # ]:          0 :         if (current->flags & PF_SIGNALED)
     603                 :        341 :                 pacct->ac_flag |= AXSIG;
     604                 :          0 :         task_cputime(current, &utime, &stime);
     605                 :          0 :         pacct->ac_utime += utime;
     606                 :          0 :         pacct->ac_stime += stime;
     607                 :          0 :         pacct->ac_minflt += current->min_flt;
     608                 :          0 :         pacct->ac_majflt += current->maj_flt;
     609                 :          0 :         spin_unlock_irq(&current->sighand->siglock);
     610                 :    1151923 : }
     611                 :            : 
     612                 :          0 : static void acct_process_in_ns(struct pid_namespace *ns)
     613                 :            : {
     614                 :            :         struct file *file = NULL;
     615                 :            :         struct bsd_acct_struct *acct;
     616                 :            : 
     617                 :    1149607 :         acct = ns->bacct;
     618                 :            :         /*
     619                 :            :          * accelerate the common fastpath:
     620                 :            :          */
     621 [ +  + ][ -  + ]:    1149607 :         if (!acct || !acct->file)
     622                 :            :                 return;
     623                 :            : 
     624                 :            :         spin_lock(&acct_lock);
     625                 :          0 :         file = acct->file;
     626         [ #  # ]:          0 :         if (unlikely(!file)) {
     627                 :            :                 spin_unlock(&acct_lock);
     628                 :            :                 return;
     629                 :            :         }
     630                 :            :         get_file(file);
     631                 :            :         spin_unlock(&acct_lock);
     632                 :            : 
     633                 :          0 :         do_acct_process(acct, ns, file);
     634                 :          0 :         fput(file);
     635                 :            : }
     636                 :            : 
     637                 :            : /**
     638                 :            :  * acct_process - now just a wrapper around acct_process_in_ns,
     639                 :            :  * which in turn is a wrapper around do_acct_process.
     640                 :            :  *
     641                 :            :  * handles process accounting for an exiting task
     642                 :            :  */
     643                 :          0 : void acct_process(void)
     644                 :            : {
     645                 :    1149605 :         struct pid_namespace *ns;
     646                 :            : 
     647                 :            :         /*
     648                 :            :          * This loop is safe lockless, since current is still
     649                 :            :          * alive and holds its namespace, which in turn holds
     650                 :            :          * its parent.
     651                 :            :          */
     652         [ +  + ]:    2299214 :         for (ns = task_active_pid_ns(current); ns != NULL; ns = ns->parent)
     653                 :    1149605 :                 acct_process_in_ns(ns);
     654                 :    1149606 : }

Generated by: LCOV version 1.9