Print this page
11690 ::ps -s could show service FMRIs
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Jason King <jason.king@joyent.com>


  44 #include <sys/stack.h>
  45 #include <sys/cpuvar.h>
  46 #include <sys/vnode.h>
  47 #include <sys/vfs.h>
  48 #include <sys/flock_impl.h>
  49 #include <sys/kmem_impl.h>
  50 #include <sys/vmem_impl.h>
  51 #include <sys/kstat.h>
  52 #include <sys/dditypes.h>
  53 #include <sys/ddi_impldefs.h>
  54 #include <sys/sysmacros.h>
  55 #include <sys/sysconf.h>
  56 #include <sys/task.h>
  57 #include <sys/project.h>
  58 #include <sys/errorq_impl.h>
  59 #include <sys/cred_impl.h>
  60 #include <sys/zone.h>
  61 #include <sys/panic.h>
  62 #include <regex.h>
  63 #include <sys/port_impl.h>

  64 
  65 #include "avl.h"
  66 #include "bio.h"
  67 #include "bitset.h"
  68 #include "combined.h"
  69 #include "contract.h"
  70 #include "cpupart_mdb.h"
  71 #include "cred.h"
  72 #include "ctxop.h"
  73 #include "cyclic.h"
  74 #include "damap.h"
  75 #include "ddi_periodic.h"
  76 #include "devinfo.h"
  77 #include "dnlc.h"
  78 #include "findstack.h"
  79 #include "fm.h"
  80 #include "gcore.h"
  81 #include "group.h"
  82 #include "irm.h"
  83 #include "kgrep.h"


 127 pstat2ch(uchar_t state)
 128 {
 129         switch (state) {
 130                 case SSLEEP: return ('S');
 131                 case SRUN: return ('R');
 132                 case SZOMB: return ('Z');
 133                 case SIDL: return ('I');
 134                 case SONPROC: return ('O');
 135                 case SSTOP: return ('T');
 136                 case SWAIT: return ('W');
 137                 default: return ('?');
 138         }
 139 }
 140 
 141 #define PS_PRTTHREADS   0x1
 142 #define PS_PRTLWPS      0x2
 143 #define PS_PSARGS       0x4
 144 #define PS_TASKS        0x8
 145 #define PS_PROJECTS     0x10
 146 #define PS_ZONES        0x20

 147 
 148 static int
 149 ps_threadprint(uintptr_t addr, const void *data, void *private)
 150 {
 151         const kthread_t *t = (const kthread_t *)data;
 152         uint_t prt_flags = *((uint_t *)private);
 153 
 154         static const mdb_bitmask_t t_state_bits[] = {
 155                 { "TS_FREE",    UINT_MAX,       TS_FREE         },
 156                 { "TS_SLEEP",   TS_SLEEP,       TS_SLEEP        },
 157                 { "TS_RUN",     TS_RUN,         TS_RUN          },
 158                 { "TS_ONPROC",  TS_ONPROC,      TS_ONPROC       },
 159                 { "TS_ZOMB",    TS_ZOMB,        TS_ZOMB         },
 160                 { "TS_STOPPED", TS_STOPPED,     TS_STOPPED      },
 161                 { "TS_WAIT",    TS_WAIT,        TS_WAIT         },
 162                 { NULL,         0,              0               }
 163         };
 164 
 165         if (prt_flags & PS_PRTTHREADS)
 166                 mdb_printf("\tT  %?a <%b>\n", addr, t->t_state, t_state_bits);


 256 
 257         mdb_printf("%p [pid %d]:\n", addr, pid.pid_id);
 258         mdb_printf("\tp_flag:      %08x <%b>\n", pr.p_flag, pr.p_flag,
 259             p_flag_bits);
 260         mdb_printf("\tp_pidflag:   %08x <%b>\n", pr.p_pidflag, pr.p_pidflag,
 261             p_pidflag_bits);
 262         mdb_printf("\tp_proc_flag: %08x <%b>\n", pr.p_proc_flag, pr.p_proc_flag,
 263             p_proc_flag_bits);
 264 
 265         return (DCMD_OK);
 266 }
 267 
 268 typedef struct mdb_ps_proc {
 269         char            p_stat;
 270         struct pid      *p_pidp;
 271         struct pid      *p_pgidp;
 272         struct cred     *p_cred;
 273         struct sess     *p_sessp;
 274         struct task     *p_task;
 275         struct zone     *p_zone;

 276         pid_t           p_ppid;
 277         uint_t          p_flag;
 278         struct {
 279                 char            u_comm[MAXCOMLEN + 1];
 280                 char            u_psargs[PSARGSZ];
 281         } p_user;
 282 } mdb_ps_proc_t;
 283 






 284 int
 285 ps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 286 {
 287         uint_t prt_flags = 0;
 288         mdb_ps_proc_t pr;
 289         struct pid pid, pgid, sid;
 290         sess_t session;
 291         cred_t cred;
 292         task_t tk;
 293         kproject_t pj;
 294         zone_t zn;


 295 
 296         if (!(flags & DCMD_ADDRSPEC)) {
 297                 if (mdb_walk_dcmd("proc", "ps", argc, argv) == -1) {
 298                         mdb_warn("can't walk 'proc'");
 299                         return (DCMD_ERR);
 300                 }
 301                 return (DCMD_OK);
 302         }
 303 
 304         if (mdb_getopts(argc, argv,
 305             'f', MDB_OPT_SETBITS, PS_PSARGS, &prt_flags,
 306             'l', MDB_OPT_SETBITS, PS_PRTLWPS, &prt_flags,

 307             'T', MDB_OPT_SETBITS, PS_TASKS, &prt_flags,
 308             'P', MDB_OPT_SETBITS, PS_PROJECTS, &prt_flags,
 309             'z', MDB_OPT_SETBITS, PS_ZONES, &prt_flags,
 310             't', MDB_OPT_SETBITS, PS_PRTTHREADS, &prt_flags, NULL) != argc)
 311                 return (DCMD_USAGE);
 312 
 313         if (DCMD_HDRSPEC(flags)) {
 314                 mdb_printf("%<u>%1s %6s %6s %6s %6s ",
 315                     "S", "PID", "PPID", "PGID", "SID");
 316                 if (prt_flags & PS_TASKS)
 317                         mdb_printf("%5s ", "TASK");
 318                 if (prt_flags & PS_PROJECTS)
 319                         mdb_printf("%5s ", "PROJ");
 320                 if (prt_flags & PS_ZONES)
 321                         mdb_printf("%5s ", "ZONE");
 322                 mdb_printf("%6s %10s %?s %s%</u>\n",


 323                     "UID", "FLAGS", "ADDR", "NAME");
 324         }
 325 
 326         if (mdb_ctf_vread(&pr, "proc_t", "mdb_ps_proc_t", addr, 0) == -1)
 327                 return (DCMD_ERR);
 328 
 329         mdb_vread(&pid, sizeof (pid), (uintptr_t)pr.p_pidp);
 330         mdb_vread(&pgid, sizeof (pgid), (uintptr_t)pr.p_pgidp);
 331         mdb_vread(&cred, sizeof (cred), (uintptr_t)pr.p_cred);
 332         mdb_vread(&session, sizeof (session), (uintptr_t)pr.p_sessp);
 333         mdb_vread(&sid, sizeof (sid), (uintptr_t)session.s_sidp);
 334         if (prt_flags & (PS_TASKS | PS_PROJECTS))
 335                 mdb_vread(&tk, sizeof (tk), (uintptr_t)pr.p_task);
 336         if (prt_flags & PS_PROJECTS)
 337                 mdb_vread(&pj, sizeof (pj), (uintptr_t)tk.tk_proj);
 338         if (prt_flags & PS_ZONES)
 339                 mdb_vread(&zn, sizeof (zn), (uintptr_t)pr.p_zone);


 340 
 341         mdb_printf("%c %6d %6d %6d %6d ",


















 342             pstat2ch(pr.p_stat), pid.pid_id, pr.p_ppid, pgid.pid_id,
 343             sid.pid_id);
 344         if (prt_flags & PS_TASKS)
 345                 mdb_printf("%5d ", tk.tk_tkid);
 346         if (prt_flags & PS_PROJECTS)
 347                 mdb_printf("%5d ", pj.kpj_id);
 348         if (prt_flags & PS_ZONES)
 349                 mdb_printf("%5d ", zn.zone_id);
 350         mdb_printf("%6d 0x%08x %0?p %s\n",


 351             cred.cr_uid, pr.p_flag, addr,
 352             (prt_flags & PS_PSARGS) ? pr.p_user.u_psargs : pr.p_user.u_comm);
 353 
 354         if (prt_flags & ~PS_PSARGS)
 355                 (void) mdb_pwalk("thread", ps_threadprint, &prt_flags, addr);
 356 
 357         return (DCMD_OK);
 358 }
 359 
 360 static void
 361 ps_help(void)
 362 {
 363         mdb_printf("Display processes.\n\n"
 364             "Options:\n"
 365             "    -f\tDisplay command arguments\n"
 366             "    -l\tDisplay LWPs\n"
 367             "    -T\tDisplay tasks\n"
 368             "    -P\tDisplay projects\n"

 369             "    -z\tDisplay zones\n"
 370             "    -t\tDisplay threads\n\n");
 371 
 372         mdb_printf("The resulting output is a table of the processes on the "
 373             "system.  The\n"
 374             "columns in the output consist of a combination of the "
 375             "following fields:\n\n");
 376         mdb_printf("S\tProcess state.  Possible states are:\n"
 377             "\tS\tSleeping (SSLEEP)\n"
 378             "\tR\tRunnable (SRUN)\n"
 379             "\tZ\tZombie (SZOMB)\n"
 380             "\tI\tIdle (SIDL)\n"
 381             "\tO\tOn Cpu (SONPROC)\n"
 382             "\tT\tStopped (SSTOP)\n"
 383             "\tW\tWaiting (SWAIT)\n");
 384 
 385         mdb_printf("PID\tProcess id.\n");
 386         mdb_printf("PPID\tParent process id.\n");
 387         mdb_printf("PGID\tProcess group id.\n");
 388         mdb_printf("SID\tProcess id of the session leader.\n");
 389         mdb_printf("TASK\tThe task id of the process.\n");
 390         mdb_printf("PROJ\tThe project id of the process.\n");
 391         mdb_printf("ZONE\tThe zone id of the process.\n");

 392         mdb_printf("UID\tThe user id of the process.\n");
 393         mdb_printf("FLAGS\tThe process flags (see ::pflags).\n");
 394         mdb_printf("ADDR\tThe kernel address of the proc_t structure of the "
 395             "process\n");
 396         mdb_printf("NAME\tThe name (p_user.u_comm field) of the process.  If "
 397             "the -f flag\n"
 398             "\tis specified, the arguments of the process are displayed.\n");
 399 }
 400 
 401 #define PG_NEWEST       0x0001
 402 #define PG_OLDEST       0x0002
 403 #define PG_PIPE_OUT     0x0004
 404 #define PG_EXACT_MATCH  0x0008
 405 
 406 typedef struct pgrep_data {
 407         uint_t pg_flags;
 408         uint_t pg_psflags;
 409         uintptr_t pg_xaddr;
 410         hrtime_t pg_xstart;
 411         const char *pg_pat;




  44 #include <sys/stack.h>
  45 #include <sys/cpuvar.h>
  46 #include <sys/vnode.h>
  47 #include <sys/vfs.h>
  48 #include <sys/flock_impl.h>
  49 #include <sys/kmem_impl.h>
  50 #include <sys/vmem_impl.h>
  51 #include <sys/kstat.h>
  52 #include <sys/dditypes.h>
  53 #include <sys/ddi_impldefs.h>
  54 #include <sys/sysmacros.h>
  55 #include <sys/sysconf.h>
  56 #include <sys/task.h>
  57 #include <sys/project.h>
  58 #include <sys/errorq_impl.h>
  59 #include <sys/cred_impl.h>
  60 #include <sys/zone.h>
  61 #include <sys/panic.h>
  62 #include <regex.h>
  63 #include <sys/port_impl.h>
  64 #include <sys/contract/process_impl.h>
  65 
  66 #include "avl.h"
  67 #include "bio.h"
  68 #include "bitset.h"
  69 #include "combined.h"
  70 #include "contract.h"
  71 #include "cpupart_mdb.h"
  72 #include "cred.h"
  73 #include "ctxop.h"
  74 #include "cyclic.h"
  75 #include "damap.h"
  76 #include "ddi_periodic.h"
  77 #include "devinfo.h"
  78 #include "dnlc.h"
  79 #include "findstack.h"
  80 #include "fm.h"
  81 #include "gcore.h"
  82 #include "group.h"
  83 #include "irm.h"
  84 #include "kgrep.h"


 128 pstat2ch(uchar_t state)
 129 {
 130         switch (state) {
 131                 case SSLEEP: return ('S');
 132                 case SRUN: return ('R');
 133                 case SZOMB: return ('Z');
 134                 case SIDL: return ('I');
 135                 case SONPROC: return ('O');
 136                 case SSTOP: return ('T');
 137                 case SWAIT: return ('W');
 138                 default: return ('?');
 139         }
 140 }
 141 
 142 #define PS_PRTTHREADS   0x1
 143 #define PS_PRTLWPS      0x2
 144 #define PS_PSARGS       0x4
 145 #define PS_TASKS        0x8
 146 #define PS_PROJECTS     0x10
 147 #define PS_ZONES        0x20
 148 #define PS_SERVICES     0x40
 149 
 150 static int
 151 ps_threadprint(uintptr_t addr, const void *data, void *private)
 152 {
 153         const kthread_t *t = (const kthread_t *)data;
 154         uint_t prt_flags = *((uint_t *)private);
 155 
 156         static const mdb_bitmask_t t_state_bits[] = {
 157                 { "TS_FREE",    UINT_MAX,       TS_FREE         },
 158                 { "TS_SLEEP",   TS_SLEEP,       TS_SLEEP        },
 159                 { "TS_RUN",     TS_RUN,         TS_RUN          },
 160                 { "TS_ONPROC",  TS_ONPROC,      TS_ONPROC       },
 161                 { "TS_ZOMB",    TS_ZOMB,        TS_ZOMB         },
 162                 { "TS_STOPPED", TS_STOPPED,     TS_STOPPED      },
 163                 { "TS_WAIT",    TS_WAIT,        TS_WAIT         },
 164                 { NULL,         0,              0               }
 165         };
 166 
 167         if (prt_flags & PS_PRTTHREADS)
 168                 mdb_printf("\tT  %?a <%b>\n", addr, t->t_state, t_state_bits);


 258 
 259         mdb_printf("%p [pid %d]:\n", addr, pid.pid_id);
 260         mdb_printf("\tp_flag:      %08x <%b>\n", pr.p_flag, pr.p_flag,
 261             p_flag_bits);
 262         mdb_printf("\tp_pidflag:   %08x <%b>\n", pr.p_pidflag, pr.p_pidflag,
 263             p_pidflag_bits);
 264         mdb_printf("\tp_proc_flag: %08x <%b>\n", pr.p_proc_flag, pr.p_proc_flag,
 265             p_proc_flag_bits);
 266 
 267         return (DCMD_OK);
 268 }
 269 
 270 typedef struct mdb_ps_proc {
 271         char            p_stat;
 272         struct pid      *p_pidp;
 273         struct pid      *p_pgidp;
 274         struct cred     *p_cred;
 275         struct sess     *p_sessp;
 276         struct task     *p_task;
 277         struct zone     *p_zone;
 278         struct cont_process *p_ct_process;
 279         pid_t           p_ppid;
 280         uint_t          p_flag;
 281         struct {
 282                 char            u_comm[MAXCOMLEN + 1];
 283                 char            u_psargs[PSARGSZ];
 284         } p_user;
 285 } mdb_ps_proc_t;
 286 
 287 /*
 288  * A reasonable enough limit. Note that we purposefully let this column over-run
 289  * if needed.
 290  */
 291 #define FMRI_LEN (128)
 292 
 293 int
 294 ps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 295 {
 296         uint_t prt_flags = 0;
 297         mdb_ps_proc_t pr;
 298         struct pid pid, pgid, sid;
 299         sess_t session;
 300         cred_t cred;
 301         task_t tk;
 302         kproject_t pj;
 303         zone_t zn;
 304         struct cont_process cp;
 305         char fmri[FMRI_LEN] = "";
 306 
 307         if (!(flags & DCMD_ADDRSPEC)) {
 308                 if (mdb_walk_dcmd("proc", "ps", argc, argv) == -1) {
 309                         mdb_warn("can't walk 'proc'");
 310                         return (DCMD_ERR);
 311                 }
 312                 return (DCMD_OK);
 313         }
 314 
 315         if (mdb_getopts(argc, argv,
 316             'f', MDB_OPT_SETBITS, PS_PSARGS, &prt_flags,
 317             'l', MDB_OPT_SETBITS, PS_PRTLWPS, &prt_flags,
 318             's', MDB_OPT_SETBITS, PS_SERVICES, &prt_flags,
 319             'T', MDB_OPT_SETBITS, PS_TASKS, &prt_flags,
 320             'P', MDB_OPT_SETBITS, PS_PROJECTS, &prt_flags,
 321             'z', MDB_OPT_SETBITS, PS_ZONES, &prt_flags,
 322             't', MDB_OPT_SETBITS, PS_PRTTHREADS, &prt_flags, NULL) != argc)
 323                 return (DCMD_USAGE);
 324 
 325         if (DCMD_HDRSPEC(flags)) {
 326                 mdb_printf("%<u>%-1s %-6s %-6s %-6s %-6s ",
 327                     "S", "PID", "PPID", "PGID", "SID");
 328                 if (prt_flags & PS_TASKS)
 329                         mdb_printf("%-5s ", "TASK");
 330                 if (prt_flags & PS_PROJECTS)
 331                         mdb_printf("%-5s ", "PROJ");
 332                 if (prt_flags & PS_ZONES)
 333                         mdb_printf("%-5s ", "ZONE");
 334                 if (prt_flags & PS_SERVICES)
 335                         mdb_printf("%-40s ", "SERVICE");
 336                 mdb_printf("%-6s %-10s %-?s %-s%</u>\n",
 337                     "UID", "FLAGS", "ADDR", "NAME");
 338         }
 339 
 340         if (mdb_ctf_vread(&pr, "proc_t", "mdb_ps_proc_t", addr, 0) == -1)
 341                 return (DCMD_ERR);
 342 
 343         mdb_vread(&pid, sizeof (pid), (uintptr_t)pr.p_pidp);
 344         mdb_vread(&pgid, sizeof (pgid), (uintptr_t)pr.p_pgidp);
 345         mdb_vread(&cred, sizeof (cred), (uintptr_t)pr.p_cred);
 346         mdb_vread(&session, sizeof (session), (uintptr_t)pr.p_sessp);
 347         mdb_vread(&sid, sizeof (sid), (uintptr_t)session.s_sidp);
 348         if (prt_flags & (PS_TASKS | PS_PROJECTS))
 349                 mdb_vread(&tk, sizeof (tk), (uintptr_t)pr.p_task);
 350         if (prt_flags & PS_PROJECTS)
 351                 mdb_vread(&pj, sizeof (pj), (uintptr_t)tk.tk_proj);
 352         if (prt_flags & PS_ZONES)
 353                 mdb_vread(&zn, sizeof (zn), (uintptr_t)pr.p_zone);
 354         if ((prt_flags & PS_SERVICES) && pr.p_ct_process != NULL) {
 355                 mdb_vread(&cp, sizeof (cp), (uintptr_t)pr.p_ct_process);
 356 
 357                 if (mdb_read_refstr((uintptr_t)cp.conp_svc_fmri, fmri,
 358                     sizeof (fmri)) <= 0)
 359                         (void) strlcpy(fmri, "?", sizeof (fmri));
 360 
 361                 /* Strip any standard prefix and suffix. */
 362                 if (strncmp(fmri, "svc:/", sizeof ("svc:/") - 1) == 0) {
 363                         char *i = fmri;
 364                         char *j = fmri + sizeof ("svc:/") - 1;
 365                         for (; *j != '\0'; i++, j++) {
 366                                 if (strcmp(j, ":default") == 0)
 367                                         break;
 368                                 *i = *j;
 369                         }
 370 
 371                         *i = '\0';
 372                 }
 373         }
 374 
 375         mdb_printf("%-c %-6d %-6d %-6d %-6d ",
 376             pstat2ch(pr.p_stat), pid.pid_id, pr.p_ppid, pgid.pid_id,
 377             sid.pid_id);
 378         if (prt_flags & PS_TASKS)
 379                 mdb_printf("%-5d ", tk.tk_tkid);
 380         if (prt_flags & PS_PROJECTS)
 381                 mdb_printf("%-5d ", pj.kpj_id);
 382         if (prt_flags & PS_ZONES)
 383                 mdb_printf("%-5d ", zn.zone_id);
 384         if (prt_flags & PS_SERVICES)
 385                 mdb_printf("%-40s ", fmri);
 386         mdb_printf("%-6d 0x%08x %0?p %-s\n",
 387             cred.cr_uid, pr.p_flag, addr,
 388             (prt_flags & PS_PSARGS) ? pr.p_user.u_psargs : pr.p_user.u_comm);
 389 
 390         if (prt_flags & ~PS_PSARGS)
 391                 (void) mdb_pwalk("thread", ps_threadprint, &prt_flags, addr);
 392 
 393         return (DCMD_OK);
 394 }
 395 
 396 static void
 397 ps_help(void)
 398 {
 399         mdb_printf("Display processes.\n\n"
 400             "Options:\n"
 401             "    -f\tDisplay command arguments\n"
 402             "    -l\tDisplay LWPs\n"
 403             "    -T\tDisplay tasks\n"
 404             "    -P\tDisplay projects\n"
 405             "    -s\tDisplay SMF FMRI\n"
 406             "    -z\tDisplay zones\n"
 407             "    -t\tDisplay threads\n\n");
 408 
 409         mdb_printf("The resulting output is a table of the processes on the "
 410             "system.  The\n"
 411             "columns in the output consist of a combination of the "
 412             "following fields:\n\n");
 413         mdb_printf("S\tProcess state.  Possible states are:\n"
 414             "\tS\tSleeping (SSLEEP)\n"
 415             "\tR\tRunnable (SRUN)\n"
 416             "\tZ\tZombie (SZOMB)\n"
 417             "\tI\tIdle (SIDL)\n"
 418             "\tO\tOn Cpu (SONPROC)\n"
 419             "\tT\tStopped (SSTOP)\n"
 420             "\tW\tWaiting (SWAIT)\n");
 421 
 422         mdb_printf("PID\tProcess id.\n");
 423         mdb_printf("PPID\tParent process id.\n");
 424         mdb_printf("PGID\tProcess group id.\n");
 425         mdb_printf("SID\tProcess id of the session leader.\n");
 426         mdb_printf("TASK\tThe task id of the process.\n");
 427         mdb_printf("PROJ\tThe project id of the process.\n");
 428         mdb_printf("ZONE\tThe zone id of the process.\n");
 429         mdb_printf("SERVICE The SMF service FMRI of the process.\n");
 430         mdb_printf("UID\tThe user id of the process.\n");
 431         mdb_printf("FLAGS\tThe process flags (see ::pflags).\n");
 432         mdb_printf("ADDR\tThe kernel address of the proc_t structure of the "
 433             "process\n");
 434         mdb_printf("NAME\tThe name (p_user.u_comm field) of the process.  If "
 435             "the -f flag\n"
 436             "\tis specified, the arguments of the process are displayed.\n");
 437 }
 438 
 439 #define PG_NEWEST       0x0001
 440 #define PG_OLDEST       0x0002
 441 #define PG_PIPE_OUT     0x0004
 442 #define PG_EXACT_MATCH  0x0008
 443 
 444 typedef struct pgrep_data {
 445         uint_t pg_flags;
 446         uint_t pg_psflags;
 447         uintptr_t pg_xaddr;
 448         hrtime_t pg_xstart;
 449         const char *pg_pat;