Print this page
    
OS-3280 need a way to specify the root of a native system in the lx brand
OS-3279 lx brand should allow delegated datasets
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/ptools/ptime/ptime.c
          +++ new/usr/src/cmd/ptools/ptime/ptime.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   *
  25   25   * Portions Copyright 2008 Chad Mynhier
  26   26   */
  27   27  /*
  28   28   * Copyright 2016 Joyent, Inc.
  29   29   */
  30   30  
  31   31  #include <stdio.h>
  32   32  #include <stdlib.h>
  33   33  #include <unistd.h>
  
    | 
      ↓ open down ↓ | 
    33 lines elided | 
    
      ↑ open up ↑ | 
  
  34   34  #include <fcntl.h>
  35   35  #include <string.h>
  36   36  #include <errno.h>
  37   37  #include <math.h>
  38   38  #include <wait.h>
  39   39  #include <signal.h>
  40   40  #include <sys/types.h>
  41   41  #include <sys/time.h>
  42   42  #include <signal.h>
  43   43  #include <libproc.h>
       44 +#include <limits.h>
       45 +#include "ptools_common.h"
  44   46  
  45   47  static  int     look(pid_t);
  46   48  static  void    hr_min_sec(char *, long);
  47   49  static  void    prtime(char *, timestruc_t *);
  48   50  static  int     perr(const char *);
  49   51  
  50   52  static  void    tsadd(timestruc_t *result, timestruc_t *a, timestruc_t *b);
  51   53  static  void    tssub(timestruc_t *result, timestruc_t *a, timestruc_t *b);
  52   54  static  void    hrt2ts(hrtime_t hrt, timestruc_t *tsp);
  53   55  
  54   56  static  char    *command;
  55   57  static  char    *pidarg;
  56   58  static  char    procname[64];
  57   59  
  58   60  static  int     Fflag;
  59   61  static  int     mflag;
  60   62  static  int     errflg;
  61   63  static  int     pflag;
  62   64  static  int     pfirst;
  63   65  
  64   66  static int
  65   67  ptime_pid(const char *pidstr)
  66   68  {
  67   69          struct ps_prochandle *Pr;
  68   70          pid_t pid;
  69   71          int gret;
  70   72  
  71   73          if ((Pr = proc_arg_grab(pidstr, PR_ARG_PIDS,
  72   74              Fflag | PGRAB_RDONLY, &gret)) == NULL) {
  73   75                  (void) fprintf(stderr, "%s: cannot examine %s: %s\n",
  74   76                      command, pidstr, Pgrab_error(gret));
  75   77                  return (1);
  76   78          }
  77   79  
  78   80          pid = Pstatus(Pr)->pr_pid;
  79   81          (void) sprintf(procname, "%d", (int)pid);       /* for perr() */
  80   82          (void) look(pid);
  81   83          Prelease(Pr, 0);
  82   84          return (0);
  83   85  }
  84   86  
  85   87  int
  86   88  main(int argc, char **argv)
  87   89  {
  88   90          int opt, exit;
  89   91          pid_t pid;
  90   92          struct siginfo info;
  91   93          int status;
  92   94          int gret;
  93   95          struct ps_prochandle *Pr;
  94   96  
  95   97          if ((command = strrchr(argv[0], '/')) != NULL)
  96   98                  command++;
  97   99          else
  98  100                  command = argv[0];
  99  101  
 100  102          while ((opt = getopt(argc, argv, "Fhmp:")) != EOF) {
 101  103                  switch (opt) {
 102  104                  case 'F':               /* force grabbing (no O_EXCL) */
 103  105                          Fflag = PGRAB_FORCE;
 104  106                          break;
 105  107                  case 'm':               /* microstate accounting */
 106  108                          mflag = 1;
 107  109                          break;
 108  110                  case 'p':
 109  111                          pflag = 1;
 110  112                          pidarg = optarg;
 111  113                          break;
 112  114                  default:
 113  115                          errflg = 1;
 114  116                          break;
 115  117                  }
 116  118          }
 117  119  
 118  120          argc -= optind;
 119  121          argv += optind;
 120  122  
 121  123          if (((pidarg != NULL) ^ (argc < 1)) || errflg) {
 122  124                  (void) fprintf(stderr,
 123  125                      "usage:\t%s [-mh] [-p pidlist | command [ args ... ]]\n",
 124  126                      command);
 125  127                  (void) fprintf(stderr,
 126  128                      "  (time a command using microstate accounting)\n");
 127  129                  return (1);
 128  130          }
 129  131  
 130  132          if (pflag) {
 131  133                  char *pp;
 132  134  
 133  135                  exit = 0;
 134  136                  (void) signal(SIGINT, SIG_IGN);
 135  137                  (void) signal(SIGQUIT, SIG_IGN);
 136  138  
 137  139                  pp = strtok(pidarg, ", ");
 138  140                  if (pp == NULL) {
 139  141                          (void) fprintf(stderr, "%s: invalid argument for -p\n",
 140  142                              command);
 141  143                          return (1);
 142  144                  }
 143  145                  exit = ptime_pid(pp);
 144  146                  while ((pp = strtok(NULL, ", ")) != NULL) {
 145  147                          exit |= ptime_pid(pp);
 146  148                  }
 147  149                  return (exit);
 148  150          }
 149  151  
 150  152  
 151  153          if ((Pr = Pcreate(argv[0], &argv[0], &gret, NULL, 0)) == NULL) {
 152  154                  (void) fprintf(stderr, "%s: failed to exec %s: %s\n",
 153  155                      command, argv[0], Pcreate_error(gret));
 154  156                  return (1);
 155  157          }
 156  158          if (Psetrun(Pr, 0, 0) == -1) {
 157  159                  (void) fprintf(stderr, "%s: failed to set running %s: "
 158  160                      "%s\n", command, argv[0], strerror(errno));
 159  161                  return (1);
 160  162          }
 161  163  
 162  164          pid = Pstatus(Pr)->pr_pid;
 163  165  
 164  166          (void) sprintf(procname, "%d", (int)pid);       /* for perr() */
 165  167          (void) signal(SIGINT, SIG_IGN);
 166  168          (void) signal(SIGQUIT, SIG_IGN);
 167  169  
 168  170          (void) waitid(P_PID, pid, &info, WEXITED | WNOWAIT);
 169  171  
 170  172          (void) look(pid);
 171  173  
 172  174          (void) waitpid(pid, &status, 0);
 173  175  
 174  176          if (WIFEXITED(status))
 175  177                  return (WEXITSTATUS(status));
 176  178  
 177  179          if (WIFSIGNALED(status)) {
 178  180                  int sig = WTERMSIG(status);
 179  181                  char name[SIG2STR_MAX];
 180  182  
 181  183                  (void) fprintf(stderr, "%s: command terminated "
  
    | 
      ↓ open down ↓ | 
    128 lines elided | 
    
      ↑ open up ↑ | 
  
 182  184                      "abnormally by %s\n", command,
 183  185                      proc_signame(sig, name, sizeof (name)));
 184  186          }
 185  187  
 186  188          return (status | WCOREFLG); /* see time(1) */
 187  189  }
 188  190  
 189  191  static int
 190  192  look(pid_t pid)
 191  193  {
 192      -        char pathname[100];
      194 +        char pathname[PATH_MAX];
 193  195          int rval = 0;
 194  196          int fd;
 195  197          psinfo_t psinfo;
 196  198          prusage_t prusage;
 197  199          timestruc_t real, user, sys;
 198  200          hrtime_t hrtime;
 199  201          prusage_t *pup = &prusage;
 200  202  
 201  203          pfirst++;
 202  204  
 203  205          if (proc_get_psinfo(pid, &psinfo) < 0)
 204  206                  return (perr("read psinfo"));
 205  207  
 206      -        (void) sprintf(pathname, "/proc/%d/usage", (int)pid);
      208 +        (void) proc_snprintf(pathname, sizeof (pathname), "/proc/%d/usage",
      209 +            (int)pid);
 207  210          if ((fd = open(pathname, O_RDONLY)) < 0)
 208  211                  return (perr("open usage"));
 209  212  
 210  213          if (read(fd, &prusage, sizeof (prusage)) != sizeof (prusage))
 211  214                  rval = perr("read usage");
 212  215          else {
 213  216                  if (pidarg) {
 214  217                          hrtime = gethrtime();
 215  218                          hrt2ts(hrtime, &real);
 216  219                  } else {
 217  220                          real = pup->pr_term;
 218  221                  }
 219  222                  tssub(&real, &real, &pup->pr_create);
 220  223                  user = pup->pr_utime;
 221  224                  sys = pup->pr_stime;
 222  225                  if (!mflag)
 223  226                          tsadd(&sys, &sys, &pup->pr_ttime);
 224  227  
 225  228                  if (!pflag || pfirst > 1)
 226  229                          (void) fprintf(stderr, "\n");
 227  230                  if (pflag)
 228  231                          (void) fprintf(stderr, "%d:\t%.70s\n",
 229  232                              (int)psinfo.pr_pid, psinfo.pr_psargs);
 230  233                  prtime("real", &real);
 231  234                  prtime("user", &user);
 232  235                  prtime("sys", &sys);
 233  236  
 234  237                  if (mflag) {
 235  238                          prtime("trap", &pup->pr_ttime);
 236  239                          prtime("tflt", &pup->pr_tftime);
 237  240                          prtime("dflt", &pup->pr_dftime);
 238  241                          prtime("kflt", &pup->pr_kftime);
 239  242                          prtime("lock", &pup->pr_ltime);
 240  243                          prtime("slp", &pup->pr_slptime);
 241  244                          prtime("lat", &pup->pr_wtime);
 242  245                          prtime("stop", &pup->pr_stoptime);
 243  246                  }
 244  247          }
 245  248  
 246  249          (void) close(fd);
 247  250          return (rval);
 248  251  }
 249  252  
 250  253  static void
 251  254  hr_min_sec(char *buf, long sec)
 252  255  {
 253  256          if (sec >= 3600)
 254  257                  (void) sprintf(buf, "%ld:%.2ld:%.2ld",
 255  258                      sec / 3600, (sec % 3600) / 60, sec % 60);
 256  259          else if (sec >= 60)
 257  260                  (void) sprintf(buf, "%ld:%.2ld",
 258  261                      sec / 60, sec % 60);
 259  262          else
 260  263                  (void) sprintf(buf, "%ld", sec);
 261  264  }
 262  265  
 263  266  static void
 264  267  prtime(char *name, timestruc_t *ts)
 265  268  {
 266  269          char buf[32];
 267  270  
 268  271          hr_min_sec(buf, ts->tv_sec);
 269  272  
 270  273          (void) fprintf(stderr, "%-4s %8s.%.9u\n",
 271  274              name, buf, (uint_t)ts->tv_nsec);
 272  275  }
 273  276  
 274  277  static int
 275  278  perr(const char *s)
 276  279  {
 277  280          if (s)
 278  281                  (void) fprintf(stderr, "%s: ", procname);
 279  282          else
 280  283                  s = procname;
 281  284          perror(s);
 282  285          return (1);
 283  286  }
 284  287  
 285  288  static  void
 286  289  tsadd(timestruc_t *result, timestruc_t *a, timestruc_t *b)
 287  290  {
 288  291          result->tv_sec = a->tv_sec + b->tv_sec;
 289  292          if ((result->tv_nsec = a->tv_nsec + b->tv_nsec) >= 1000000000) {
 290  293                  result->tv_nsec -= 1000000000;
 291  294                  result->tv_sec += 1;
 292  295          }
 293  296  }
 294  297  
 295  298  static  void
 296  299  tssub(timestruc_t *result, timestruc_t *a, timestruc_t *b)
 297  300  {
 298  301          result->tv_sec = a->tv_sec - b->tv_sec;
 299  302          if ((result->tv_nsec = a->tv_nsec - b->tv_nsec) < 0) {
 300  303                  result->tv_nsec += 1000000000;
 301  304                  result->tv_sec -= 1;
 302  305          }
 303  306  }
 304  307  
 305  308  static void
 306  309  hrt2ts(hrtime_t hrt, timestruc_t *tsp)
 307  310  {
 308  311          tsp->tv_sec = hrt / NANOSEC;
 309  312          tsp->tv_nsec = hrt % NANOSEC;
 310  313  }
  
    | 
      ↓ open down ↓ | 
    94 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX