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