solaris~on-src

view usr/src/cmd/gcore/gcore.c @ 13149:b23a4dab3d50

6973228 Cannot download firmware 2.103.x.x on Emulex FCoE HBAs 6960289 fiber side of emulex cna does not connect to the storage 6950462 Emulex HBA permanently DESTROYED, if the firmware upgrade is interrupted 6964513 COMSTAR - Emulex LP9002 fail to return a SCSI Inquiry correctly to a VMware 4 Initiator
author Sukumar Swaminathan <Sukumar.Swaminathan@Sun.COM>
date Wed, 18 Aug 2010 15:52:48 -0600
parents 68f95e015346
children
line source
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <stdio_ext.h>
31 #include <limits.h>
32 #include <libproc.h>
33 #include <sys/corectl.h>
34 #include <sys/sysmacros.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <string.h>
38 #include <strings.h>
39 #include <errno.h>
40 #include <zone.h>
42 static char *pname;
44 static void
45 convert_path(const char *path, char *fname, size_t size,
46 struct ps_prochandle *P)
47 {
48 char *p, *s;
49 ssize_t len;
50 const psinfo_t *pip = Ppsinfo(P);
51 int got_uts = 0;
52 struct utsname uts;
53 char exec[PATH_MAX];
55 fname[size - 1] = '\0';
56 size--;
58 while ((p = strchr(path, '%')) != NULL && size != 0) {
59 len = MIN(size, p - path);
60 bcopy(path, fname, len);
62 fname += len;
63 if ((size -= len) == 0)
64 break;
66 p++;
67 switch (*p) {
68 case 'p':
69 len = snprintf(fname, size, "%d", (int)pip->pr_pid);
70 break;
71 case 'u':
72 len = snprintf(fname, size, "%d", (int)pip->pr_uid);
73 break;
74 case 'g':
75 len = snprintf(fname, size, "%d", (int)pip->pr_gid);
76 break;
77 case 'f':
78 len = snprintf(fname, size, "%s", pip->pr_fname);
79 break;
80 case 'd':
81 len = 0;
82 if (Pexecname(P, exec, sizeof (exec)) == NULL ||
83 exec[0] != '/' || (s = strrchr(exec, '/')) == NULL)
84 break;
86 *s = '\0';
87 len = snprintf(fname, size, "%s", &exec[1]);
88 break;
89 case 'n':
90 if (got_uts++ == 0)
91 (void) uname(&uts);
92 len = snprintf(fname, size, "%s", uts.nodename);
93 break;
94 case 'm':
95 if (got_uts++ == 0)
96 (void) uname(&uts);
97 len = snprintf(fname, size, "%s", uts.machine);
98 break;
99 case 't':
100 len = snprintf(fname, size, "%ld", (long)time(NULL));
101 break;
102 case 'z':
103 /*
104 * getzonenamebyid() returns the size including the
105 * terminating null byte so we need to adjust len.
106 */
107 if ((len = getzonenamebyid(pip->pr_zoneid, fname,
108 size)) < 0)
109 len = snprintf(fname, size, "%d",
110 (int)pip->pr_zoneid);
111 else
112 len--;
113 break;
114 case '%':
115 *fname = '%';
116 len = 1;
117 break;
118 default:
119 len = snprintf(fname, size, "%%%c", *p);
120 }
122 if (len >= size)
123 return;
125 fname += len;
126 size -= len;
128 path = p + 1;
129 }
131 (void) strncpy(fname, path, size);
132 }
134 static void
135 gcore(struct ps_prochandle *P, const char *fname, core_content_t content,
136 int *errp)
137 {
138 if (Pgcore(P, fname, content) == 0) {
139 (void) printf("%s: %s dumped\n", pname, fname);
140 } else {
141 (void) fprintf(stderr, "%s: %s dump failed: %s\n", pname,
142 fname, strerror(errno));
143 (*errp)++;
144 }
145 }
147 int
148 main(int argc, char **argv)
149 {
150 struct ps_prochandle *P;
151 int gerr;
152 char *prefix = NULL;
153 int opt;
154 int opt_p = 0, opt_g = 0, opt_c = 0;
155 int oflags = 0;
156 int i;
157 char fname[MAXPATHLEN];
158 char path[MAXPATHLEN];
159 int err = 0;
160 core_content_t content = CC_CONTENT_DEFAULT;
161 struct rlimit rlim;
163 if ((pname = strrchr(argv[0], '/')) == NULL)
164 pname = argv[0];
165 else
166 argv[0] = ++pname; /* for getopt() */
168 while ((opt = getopt(argc, argv, "o:Fgpc:")) != EOF) {
169 switch (opt) {
170 case 'o':
171 prefix = optarg;
172 break;
173 case 'c':
174 if (proc_str2content(optarg, &content) != 0) {
175 (void) fprintf(stderr, "%s: invalid "
176 "content string '%s'\n", pname, optarg);
177 goto usage;
178 }
179 opt_c = 1;
180 break;
181 case 'F':
182 oflags |= PGRAB_FORCE;
183 break;
184 case 'p':
185 opt_p = 1;
186 break;
187 case 'g':
188 opt_g = 1;
189 break;
190 default:
191 goto usage;
192 }
193 }
195 if ((opt_p | opt_g) == 0) {
196 if (prefix == NULL)
197 prefix = "core";
198 } else {
199 int options;
201 if ((options = core_get_options()) == -1) {
202 perror("core_get_options()");
203 return (1);
204 }
206 if (opt_p && !(options & CC_PROCESS_PATH)) {
207 (void) fprintf(stderr, "%s: per-process core dumps "
208 "are disabled (ignoring -p)\n", pname);
209 opt_p = 0;
210 }
212 if (opt_g && !(options & CC_GLOBAL_PATH)) {
213 (void) fprintf(stderr, "%s: global core dumps "
214 "are disabled (ignoring -g)\n", pname);
215 opt_g = 0;
216 }
218 if ((opt_p | opt_g) == 0 && prefix == NULL)
219 return (1);
220 }
222 argc -= optind;
223 argv += optind;
225 if (argc == 0)
226 goto usage;
228 /*
229 * Make sure we'll have enough file descriptors to handle a target
230 * that has many many mappings.
231 */
232 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
233 rlim.rlim_cur = rlim.rlim_max;
234 (void) setrlimit(RLIMIT_NOFILE, &rlim);
235 (void) enable_extended_FILE_stdio(-1, -1);
236 }
238 for (i = 0; i < argc; i++) {
239 P = proc_arg_grab(argv[i], PR_ARG_PIDS, oflags, &gerr);
240 if (P == NULL) {
241 (void) fprintf(stderr, "%s: cannot grab %s: %s\n",
242 pname, argv[i], Pgrab_error(gerr));
243 err++;
244 continue;
245 }
247 if (prefix != NULL) {
248 (void) snprintf(path, sizeof (path), "%s.%%p", prefix);
249 convert_path(path, fname, sizeof (fname), P);
251 gcore(P, fname, content, &err);
252 }
254 if (opt_p) {
255 pid_t pid = Pstatus(P)->pr_pid;
256 (void) core_get_process_path(path, sizeof (path), pid);
257 convert_path(path, fname, sizeof (fname), P);
258 if (!opt_c)
259 (void) core_get_process_content(&content, pid);
261 gcore(P, fname, content, &err);
262 }
264 if (opt_g) {
265 /*
266 * Global core files are always just readable and
267 * writable by their owner so we temporarily change
268 * the umask.
269 */
270 mode_t oldmode = umask(S_IXUSR | S_IRWXG | S_IRWXO);
272 (void) core_get_global_path(path, sizeof (path));
273 convert_path(path, fname, sizeof (fname), P);
274 if (!opt_c)
275 (void) core_get_global_content(&content);
277 gcore(P, fname, content, &err);
279 (void) umask(oldmode);
280 }
282 Prelease(P, 0);
283 }
285 return (err != 0);
287 usage:
288 (void) fprintf(stderr, "usage: %s "
289 "[ -pgF ] [ -o filename ] [ -c content ] pid ...\n", pname);
290 return (2);
291 }