Print this page
8225 passing invalid global pattern to coreadm wedges it nicely
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/coreadm/coreadm.c
+++ new/usr/src/cmd/coreadm/coreadm.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
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
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 + *
25 + * Copyright 2017 RackTop Systems.
24 26 */
25 27
26 28 #include <stdio.h>
27 29 #include <fcntl.h>
28 30 #include <ctype.h>
29 31 #include <string.h>
30 32 #include <stdlib.h>
31 33 #include <unistd.h>
32 34 #include <errno.h>
33 35 #include <limits.h>
34 36 #include <libintl.h>
35 37 #include <locale.h>
36 38 #include <sys/stat.h>
37 39 #include <sys/corectl.h>
38 40 #include <libproc.h>
39 41 #include <libscf.h>
40 42 #include <libscf_priv.h>
41 43 #include <assert.h>
42 44
43 45 #define E_SUCCESS 0 /* Exit status for success */
44 46 #define E_ERROR 1 /* Exit status for error */
45 47 #define E_USAGE 2 /* Exit status for usage error */
46 48
47 49 static const char PATH_CONFIG[] = "/etc/coreadm.conf";
48 50 static const char PATH_CONFIG_OLD[] = "/etc/coreadm.conf.old";
49 51
50 52 #define COREADM_INST_NAME "system/coreadm:default"
51 53 #define COREADM_INST_FMRI \
52 54 SCF_FMRI_SVC_PREFIX SCF_FMRI_SERVICE_PREFIX COREADM_INST_NAME
53 55
54 56 #define CONFIG_PARAMS "config_params"
55 57 #define GLOBAL_ENABLED "global_enabled"
56 58 #define PROCESS_ENABLED "process_enabled"
57 59 #define GLOBAL_SETID_ENABLED "global_setid_enabled"
58 60 #define PROCESS_SETID_ENABLED "process_setid_enabled"
59 61 #define GLOBAL_LOG_ENABLED "global_log_enabled"
60 62 #define GLOBAL_PATTERN "global_pattern"
61 63 #define GLOBAL_CONTENT "global_content"
62 64 #define INIT_PATTERN "init_pattern"
63 65 #define INIT_CONTENT "init_content"
64 66
65 67 static char *command;
66 68 static uint64_t options;
67 69 static int alloptions;
68 70 static char *glob_pattern;
69 71 static char gpattern[PATH_MAX];
↓ open down ↓ |
36 lines elided |
↑ open up ↑ |
70 72 static core_content_t glob_content = CC_CONTENT_INVALID;
71 73 static char *init_pattern;
72 74 static char ipattern[PATH_MAX];
73 75 static core_content_t init_content = CC_CONTENT_INVALID;
74 76 static char *proc_pattern;
75 77 static size_t proc_size;
76 78 static core_content_t proc_content = CC_CONTENT_INVALID;
77 79
78 80 static int report_settings(void);
79 81 static int do_processes(int, char **);
80 -static int do_modify(boolean_t);
82 +static int do_modify(void);
81 83 static int do_update(void);
82 84 static int do_legacy(void);
83 85
84 86 static scf_propvec_t prop_gpattern = { GLOBAL_PATTERN, NULL, SCF_TYPE_ASTRING };
85 87 static scf_propvec_t prop_gcontent = { GLOBAL_CONTENT, NULL, SCF_TYPE_ASTRING };
86 88 static scf_propvec_t prop_ipattern = { INIT_PATTERN, NULL, SCF_TYPE_ASTRING };
87 89 static scf_propvec_t prop_icontent = { INIT_CONTENT, NULL, SCF_TYPE_ASTRING };
88 90 static scf_propvec_t prop_option[] = {
89 - { GLOBAL_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_PATH },
90 - { PROCESS_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_PATH },
91 - { GLOBAL_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_SETID },
92 - { PROCESS_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_SETID },
93 - { GLOBAL_LOG_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_LOG },
94 - { NULL }
91 + { GLOBAL_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_PATH },
92 + { PROCESS_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_PATH },
93 + { GLOBAL_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_SETID },
94 + { PROCESS_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL,
95 + CC_PROCESS_SETID },
96 + { GLOBAL_LOG_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_LOG },
97 + { NULL }
95 98 };
96 99 #define MAX_PROPS (4 + (sizeof (prop_option) / sizeof (scf_propvec_t)))
97 100
98 101 static void
99 102 usage(void)
100 103 {
101 104 (void) fprintf(stderr, gettext(
102 105 "usage:\n"));
103 106 (void) fprintf(stderr, gettext(
104 107 " %s [ -g pattern ] [ -i pattern ] [ -G content ] [ -I content ]\n"),
105 108 command);
106 109 (void) fprintf(stderr, gettext(
107 110 " [ -e {global | process | global-setid | proc-setid | log} ]\n"));
108 111 (void) fprintf(stderr, gettext(
109 112 " [ -d {global | process | global-setid | proc-setid | log} ]\n"));
110 113 (void) fprintf(stderr, gettext(
111 114 " %s [ -p pattern ] [ -P content ] [ pid ... ]\n"), command);
112 115 exit(E_USAGE);
113 116 }
114 117
115 118 static int
116 119 perm(void)
117 120 {
118 121 (void) fprintf(stderr, gettext("%s: insufficient privileges to "
119 122 "exercise the -[GIgied] options\n"), command);
120 123 return (E_USAGE);
121 124 }
122 125
123 126 static int
124 127 parse_content(char *arg, core_content_t *content)
125 128 {
126 129 if (proc_str2content(arg, content) == 0)
127 130 return (0);
128 131 (void) fprintf(stderr, gettext("%s: invalid content string '%s'\n"),
129 132 command, arg);
130 133 return (1);
131 134 }
132 135
133 136 int
134 137 main(int argc, char **argv)
135 138 {
136 139 int flag;
137 140 int opt;
138 141 int modify;
139 142 int update = 0;
140 143 int legacy_update = 0;
141 144 int error = 0;
142 145 int npids;
143 146 char **pidlist;
144 147
145 148 char curpid[11];
146 149 char *curpid_ptr = &curpid[0];
147 150
148 151 (void) setlocale(LC_ALL, "");
149 152 (void) textdomain(TEXT_DOMAIN);
150 153
151 154 /* command name (e.g., "coreadm") */
152 155 if ((command = strrchr(argv[0], '/')) != NULL)
153 156 command++;
154 157 else
155 158 command = argv[0];
156 159
157 160 while ((opt = getopt(argc, argv, "g:G:i:I:p:P:e:d:uU?")) != EOF) {
158 161 switch (opt) {
159 162 case 'g':
160 163 glob_pattern = optarg;
161 164 break;
162 165 case 'i':
163 166 init_pattern = optarg;
164 167 break;
165 168 case 'p':
166 169 proc_pattern = optarg;
167 170 proc_size = strlen(proc_pattern) + 1;
168 171 break;
169 172 case 'G':
170 173 error |= parse_content(optarg, &glob_content);
171 174 break;
172 175 case 'I':
173 176 error |= parse_content(optarg, &init_content);
174 177 break;
175 178 case 'P':
176 179 error |= parse_content(optarg, &proc_content);
177 180 break;
178 181 case 'e':
179 182 case 'd':
180 183 if (strcmp(optarg, "global") == 0)
181 184 flag = CC_GLOBAL_PATH;
182 185 else if (strcmp(optarg, "process") == 0)
183 186 flag = CC_PROCESS_PATH;
184 187 else if (strcmp(optarg, "global-setid") == 0)
185 188 flag = CC_GLOBAL_SETID;
186 189 else if (strcmp(optarg, "proc-setid") == 0)
187 190 flag = CC_PROCESS_SETID;
188 191 else if (strcmp(optarg, "log") == 0)
189 192 flag = CC_GLOBAL_LOG;
190 193 else {
191 194 flag = 0;
192 195 error = 1;
193 196 }
194 197 if (opt == 'e')
195 198 options |= flag;
196 199 else
197 200 options &= ~flag;
198 201 alloptions |= flag;
199 202 break;
200 203 case 'U':
201 204 update = 1;
202 205 break;
203 206 case 'u':
204 207 legacy_update = 1;
205 208 break;
206 209 case '?':
207 210 default:
208 211 error = 1;
209 212 break;
210 213 }
211 214 }
212 215
213 216 npids = argc - optind;
214 217 pidlist = argv + optind;
215 218
216 219 if (error)
217 220 usage();
218 221
219 222 /*
220 223 * If 'modify' is true, we must modify the system settings
221 224 * and update the configuration file with the new parameters.
222 225 */
223 226 modify = glob_pattern != NULL || glob_content != CC_CONTENT_INVALID ||
224 227 init_pattern != NULL || init_content != CC_CONTENT_INVALID ||
225 228 alloptions != 0;
226 229
227 230 if ((update || legacy_update) && (modify || proc_pattern != NULL ||
228 231 proc_content != CC_CONTENT_INVALID || npids != 0)) {
229 232 (void) fprintf(stderr,
230 233 gettext("%s: the -u option must stand alone\n"), command);
231 234 usage();
232 235 }
233 236 if (modify &&
234 237 (proc_pattern != NULL || proc_content != CC_CONTENT_INVALID)) {
235 238 (void) fprintf(stderr, gettext(
↓ open down ↓ |
131 lines elided |
↑ open up ↑ |
236 239 "%s: -[GIgied] and -[Pp] options are mutually exclusive\n"),
237 240 command);
238 241 usage();
239 242 }
240 243 if (modify && npids != 0) {
241 244 (void) fprintf(stderr, gettext(
242 245 "%s: -[GIgied] options cannot have a process-id list\n"),
243 246 command);
244 247 usage();
245 248 }
249 + if (glob_pattern != NULL && glob_pattern[0] != '/') {
250 + (void) fprintf(stderr, gettext(
251 + "%s: the -g option must specify an absolute path\n"),
252 + command);
253 + usage();
254 + }
246 255 if ((proc_pattern != NULL || proc_content != CC_CONTENT_INVALID) &&
247 256 npids == 0) {
248 257 (void) sprintf(curpid, "%u", (uint_t)getppid());
249 258 npids = 1;
250 259 pidlist = &curpid_ptr;
251 260 }
252 261
253 262 if (legacy_update)
254 263 return (do_legacy());
255 264 if (update)
256 265 return (do_update());
257 266 if (modify)
258 - return (do_modify(B_FALSE));
267 + return (do_modify());
259 268 if (npids != 0)
260 269 return (do_processes(npids, pidlist));
261 270
262 271 return (report_settings());
263 272 }
264 273
265 274 static int
266 275 report_settings(void)
267 276 {
268 277 char content_str[PRCONTENTBUFSZ];
269 278
270 279 if ((options = core_get_options()) == -1) {
271 280 perror("core_get_options()");
272 281 return (E_ERROR);
273 282 }
274 283 if (core_get_global_path(gpattern, sizeof (gpattern)) != 0) {
275 284 perror("core_get_global_path()");
276 285 return (E_ERROR);
277 286 }
278 287 if (core_get_default_path(ipattern, sizeof (ipattern)) != 0) {
279 288 perror("core_get_default_path()");
280 289 return (E_ERROR);
281 290 }
282 291 if (core_get_global_content(&glob_content) != 0) {
283 292 perror("core_get_global_content()");
284 293 return (E_ERROR);
285 294 }
286 295 if (core_get_default_content(&init_content) != 0) {
287 296 perror("core_get_default_content()");
288 297 return (E_ERROR);
289 298 }
290 299
291 300 (void) printf(gettext(" global core file pattern: %s\n"),
292 301 gpattern);
293 302 (void) proc_content2str(glob_content, content_str,
294 303 sizeof (content_str));
295 304 (void) printf(gettext(" global core file content: %s\n"),
296 305 content_str);
297 306 (void) printf(gettext(" init core file pattern: %s\n"),
298 307 ipattern);
299 308 (void) proc_content2str(init_content, content_str,
300 309 sizeof (content_str));
301 310 (void) printf(gettext(" init core file content: %s\n"),
302 311 content_str);
303 312 (void) printf(gettext(" global core dumps: %s\n"),
304 313 (options & CC_GLOBAL_PATH)? "enabled" : "disabled");
305 314 (void) printf(gettext(" per-process core dumps: %s\n"),
306 315 (options & CC_PROCESS_PATH)? "enabled" : "disabled");
307 316 (void) printf(gettext(" global setid core dumps: %s\n"),
308 317 (options & CC_GLOBAL_SETID)? "enabled" : "disabled");
309 318 (void) printf(gettext(" per-process setid core dumps: %s\n"),
310 319 (options & CC_PROCESS_SETID)? "enabled" : "disabled");
311 320 (void) printf(gettext(" global core dump logging: %s\n"),
312 321 (options & CC_GLOBAL_LOG)? "enabled" : "disabled");
313 322 return (E_SUCCESS);
314 323 }
315 324
316 325 static int
317 326 do_processes(int npids, char **pidlist)
318 327 {
319 328 char process_path[PATH_MAX];
320 329 core_content_t content;
321 330 pid_t pid;
322 331 char *next;
323 332 int rc = E_SUCCESS;
324 333 char content_str[PRCONTENTBUFSZ];
325 334
326 335 if (proc_pattern == NULL && proc_content == CC_CONTENT_INVALID) {
327 336 while (npids-- > 0) {
328 337 pid = strtol(*pidlist, &next, 10);
329 338 if (*next != '\0' || !isdigit(**pidlist)) {
330 339 (void) fprintf(stderr,
331 340 gettext("%s: invalid process-id\n"),
332 341 *pidlist);
333 342 rc = E_USAGE;
334 343 } else if (core_get_process_path(process_path,
335 344 sizeof (process_path), pid) != 0 ||
336 345 core_get_process_content(&content, pid) != 0) {
337 346 perror(*pidlist);
338 347 rc = E_USAGE;
339 348 } else {
340 349 (void) proc_content2str(content, content_str,
341 350 sizeof (content_str));
342 351 (void) printf(gettext("%s:\t%s\t%s\n"),
343 352 *pidlist, process_path, content_str);
344 353 }
345 354 pidlist++;
346 355 }
347 356 } else {
348 357 while (npids-- > 0) {
349 358 pid = strtol(*pidlist, &next, 10);
350 359 if (*next != '\0') {
351 360 (void) fprintf(stderr,
352 361 gettext("%s: invalid process-id\n"),
353 362 *pidlist);
354 363 rc = E_USAGE;
355 364 } else {
356 365 if (proc_pattern != NULL &&
357 366 core_set_process_path(proc_pattern,
358 367 proc_size, pid) != 0) {
359 368 perror(*pidlist);
360 369 rc = E_USAGE;
361 370 }
362 371
363 372 if (proc_content != CC_CONTENT_INVALID &&
364 373 core_set_process_content(
365 374 &proc_content, pid) != 0) {
366 375 perror(*pidlist);
367 376 rc = E_USAGE;
368 377 }
369 378 }
370 379 pidlist++;
371 380 }
372 381 }
373 382
374 383 return (rc);
↓ open down ↓ |
106 lines elided |
↑ open up ↑ |
375 384 }
376 385
377 386 static void
378 387 addprop(scf_propvec_t *props, int size, int count, scf_propvec_t *pv, void *ptr)
379 388 {
380 389 assert(count + 1 < size);
381 390 props[count] = *pv;
382 391 props[count].pv_ptr = ptr;
383 392 }
384 393
385 -static boolean_t
386 -is_online(const char *fmri)
394 +static int
395 +make_active(void)
387 396 {
388 - char *state = smf_get_state(fmri);
389 - boolean_t result = state != NULL &&
390 - strcmp(state, SCF_STATE_STRING_ONLINE) == 0;
397 + char *state = smf_get_state(COREADM_INST_FMRI);
391 398
392 - free(state);
393 - return (result);
399 + switch (state == NULL ? -1 : smf_state_from_string(state)) {
400 + case SCF_STATE_ONLINE:
401 + if (smf_refresh_instance_synchronous(COREADM_INST_FMRI) != 0) {
402 + (void) fprintf(stderr,
403 + gettext("%s: Unable to refresh %s: %s\n"),
404 + command, COREADM_INST_FMRI,
405 + scf_strerror(scf_error()));
406 + return (-1);
407 + }
408 + break;
409 + case SCF_STATE_DEGRADED:
410 + case SCF_STATE_MAINT:
411 + if (smf_restore_instance_synchronous(COREADM_INST_FMRI) != 0) {
412 + (void) fprintf(stderr,
413 + gettext("%s: Unable to clear %s: %s\n"),
414 + command, COREADM_INST_FMRI,
415 + scf_strerror(scf_error()));
416 + return (-1);
417 + }
418 + break;
419 + case SCF_STATE_DISABLED:
420 + if (smf_enable_instance_synchronous(COREADM_INST_FMRI,
421 + 0) != 0) {
422 + (void) fprintf(stderr,
423 + gettext("%s: Unable to enable %s: %s\n"),
424 + command, COREADM_INST_FMRI,
425 + scf_strerror(scf_error()));
426 + return (-1);
427 + }
428 + break;
429 + case SCF_STATE_OFFLINE:
430 + default:
431 + (void) fprintf(stderr,
432 + gettext("%s: coreadm service not online\n"), command);
433 + return (-1);
434 + }
435 +
436 + return (0);
394 437 }
395 438
396 439 /*
397 440 * The user has specified the -g, -G, -i, -I, -d, or -e options to
398 441 * modify the given configuration parameter. Perform the modification
399 442 * in the smf repository and then perform a smf_refresh_instance which
400 443 * will cause a coreadm -u to occur which will transfer ALL coreadm
401 444 * configuration information from the repository to the kernel.
402 445 */
403 446 static int
404 -do_modify(boolean_t method)
447 +do_modify(void)
405 448 {
406 449 char gcontentstr[PRCONTENTBUFSZ];
407 450 char icontentstr[PRCONTENTBUFSZ];
408 451 scf_propvec_t *prop;
409 452 scf_propvec_t properties[MAX_PROPS + 1];
410 453 int count = 0;
411 454
412 - if (!method && !is_online(COREADM_INST_FMRI)) {
413 - (void) fprintf(stderr,
414 - gettext("%s: coreadm service not online\n"), command);
415 - return (E_ERROR);
416 - }
417 -
418 455 if (glob_pattern != NULL)
419 456 addprop(properties, MAX_PROPS, count++, &prop_gpattern,
420 457 glob_pattern);
421 458
422 459 if (glob_content != CC_CONTENT_INVALID) {
423 460 (void) proc_content2str(glob_content, gcontentstr,
424 461 sizeof (gcontentstr));
425 462 addprop(properties, MAX_PROPS, count++, &prop_gcontent,
426 463 gcontentstr);
427 464 }
428 465
429 466 if (init_pattern != NULL)
430 467 addprop(properties, MAX_PROPS, count++, &prop_ipattern,
431 468 init_pattern);
432 469
433 470 if (init_content != CC_CONTENT_INVALID) {
434 471 (void) proc_content2str(init_content, icontentstr,
435 472 sizeof (icontentstr));
436 473 addprop(properties, MAX_PROPS, count++, &prop_icontent,
437 474 icontentstr);
438 475 }
439 476
440 477 for (prop = prop_option; prop->pv_prop != NULL; prop++)
441 478 if ((alloptions & prop->pv_aux) != 0)
442 479 addprop(properties, MAX_PROPS, count++, prop, &options);
443 480
444 481 properties[count].pv_prop = NULL;
445 482
446 483 prop = NULL;
447 484 if (scf_write_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, properties,
448 485 &prop) == SCF_FAILED) {
449 486 if (prop != NULL) {
450 487 (void) fprintf(stderr, gettext(
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
451 488 "%s: Unable to write property '%s': %s"), command,
452 489 prop->pv_prop, scf_strerror(scf_error()));
453 490 } else {
454 491 (void) fprintf(stderr, gettext(
455 492 "%s: Unable to write configuration: %s\n"),
456 493 command, scf_strerror(scf_error()));
457 494 }
458 495 return (E_ERROR);
459 496 }
460 497
461 - if (smf_refresh_instance(COREADM_INST_FMRI) != 0) {
462 - (void) fprintf(stderr,
463 - gettext("%s: Unable to refresh %s: %s\n"
464 - "Configuration stored but not made active.\n"),
465 - command, COREADM_INST_FMRI, scf_strerror(scf_error()));
498 + if (make_active() != 0) {
499 + (void) fprintf(stderr, gettext(
500 + "Configuration stored but not made active.\n"));
466 501 return (E_ERROR);
467 502 }
468 503
469 504 return (E_SUCCESS);
470 505 }
471 506
472 507 static const char *
473 508 write_kernel(void)
474 509 {
475 510 if (core_set_global_path(glob_pattern, strlen(glob_pattern) + 1) != 0)
476 511 return ("core_set_global_path()");
477 512
478 513 if (core_set_global_content(&glob_content) != 0)
479 514 return ("core_set_global_content()");
480 515
481 516 if (core_set_default_path(init_pattern, strlen(init_pattern) + 1) != 0)
482 517 return ("core_set_default_path()");
483 518
484 519 if (core_set_default_content(&init_content) != 0)
485 520 return ("core_set_init_content()");
486 521
487 522 if (core_set_options((int)options) != 0)
488 523 return ("core_set_options()");
489 524
490 525 return (NULL);
491 526 }
492 527
493 528 /*
494 529 * BUFSIZE must be large enough to contain the longest path plus some more.
495 530 */
496 531 #define BUFSIZE (PATH_MAX + 80)
497 532
498 533 static int
499 534 yes(char *name, char *value, int line)
500 535 {
501 536 if (strcmp(value, "yes") == 0)
502 537 return (1);
503 538 if (strcmp(value, "no") == 0)
504 539 return (0);
505 540 (void) fprintf(stderr, gettext(
506 541 "\"%s\", line %d: warning: value must be yes or no: %s=%s\n"),
507 542 PATH_CONFIG, line, name, value);
508 543 return (0);
509 544 }
510 545
511 546 static int
512 547 read_legacy(void)
513 548 {
514 549 FILE *fp;
515 550 int line;
516 551 char buf[BUFSIZE];
517 552 char name[BUFSIZE], value[BUFSIZE];
518 553 int n, len;
519 554
520 555 /* defaults */
521 556 alloptions = CC_OPTIONS;
522 557 options = CC_PROCESS_PATH;
523 558 gpattern[0] = '\0';
524 559 (void) strcpy(ipattern, "core");
525 560 glob_content = init_content = CC_CONTENT_DEFAULT;
526 561
527 562 glob_pattern = gpattern;
528 563 init_pattern = ipattern;
529 564
530 565 if ((fp = fopen(PATH_CONFIG, "r")) == NULL)
531 566 return (0);
532 567
533 568 for (line = 1; fgets(buf, sizeof (buf), fp) != NULL; line++) {
534 569 /*
535 570 * Skip comment lines and empty lines.
536 571 */
537 572 if (buf[0] == '#' || buf[0] == '\n')
538 573 continue;
539 574 /*
540 575 * Look for "name=value", with optional whitespace on either
541 576 * side, terminated by a newline, and consuming the whole line.
542 577 */
543 578 /* LINTED - unbounded string specifier */
544 579 n = sscanf(buf, " %[^=]=%s \n%n", name, value, &len);
545 580 if (n >= 1 && name[0] != '\0' &&
546 581 (n == 1 || len == strlen(buf))) {
547 582 if (n == 1)
548 583 value[0] = '\0';
549 584 if (strcmp(name, "COREADM_GLOB_PATTERN") == 0) {
550 585 (void) strcpy(gpattern, value);
551 586 continue;
552 587 }
553 588 if (strcmp(name, "COREADM_GLOB_CONTENT") == 0) {
554 589 (void) proc_str2content(value, &glob_content);
555 590 continue;
556 591 }
557 592 if (strcmp(name, "COREADM_INIT_PATTERN") == 0) {
558 593 (void) strcpy(ipattern, value);
559 594 continue;
560 595 }
561 596 if (strcmp(name, "COREADM_INIT_CONTENT") == 0) {
562 597 (void) proc_str2content(value, &init_content);
563 598 continue;
564 599 }
565 600 if (strcmp(name, "COREADM_GLOB_ENABLED") == 0) {
566 601 if (yes(name, value, line))
567 602 options |= CC_GLOBAL_PATH;
568 603 continue;
569 604 }
570 605 if (strcmp(name, "COREADM_PROC_ENABLED") == 0) {
571 606 if (yes(name, value, line))
572 607 options |= CC_PROCESS_PATH;
573 608 else
574 609 options &= ~CC_PROCESS_PATH;
575 610 continue;
576 611 }
577 612 if (strcmp(name, "COREADM_GLOB_SETID_ENABLED") == 0) {
578 613 if (yes(name, value, line))
579 614 options |= CC_GLOBAL_SETID;
580 615 continue;
581 616 }
582 617 if (strcmp(name, "COREADM_PROC_SETID_ENABLED") == 0) {
583 618 if (yes(name, value, line))
584 619 options |= CC_PROCESS_SETID;
585 620 continue;
586 621 }
587 622 if (strcmp(name, "COREADM_GLOB_LOG_ENABLED") == 0) {
588 623 if (yes(name, value, line))
589 624 options |= CC_GLOBAL_LOG;
590 625 continue;
591 626 }
592 627 (void) fprintf(stderr, gettext(
593 628 "\"%s\", line %d: warning: invalid token: %s\n"),
594 629 PATH_CONFIG, line, name);
595 630 } else {
596 631 (void) fprintf(stderr,
597 632 gettext("\"%s\", line %d: syntax error\n"),
598 633 PATH_CONFIG, line);
599 634 }
600 635 }
601 636 (void) fclose(fp);
602 637
603 638 return (1);
604 639 }
605 640
606 641 /*
607 642 * Loads and applies the coreadm configuration stored in the default
608 643 * coreadm instance. As this option is (only) used from within an SMF
609 644 * service method, this function must return an SMF_EXIT_* exit status
610 645 * to its caller.
611 646 */
612 647 static int
613 648 do_update(void)
614 649 {
↓ open down ↓ |
139 lines elided |
↑ open up ↑ |
615 650 char *gcstr, *icstr;
616 651 scf_propvec_t properties[MAX_PROPS + 1];
617 652 scf_propvec_t *prop;
618 653 int count = 0;
619 654 const char *errstr;
620 655
621 656 if (read_legacy()) {
622 657 if ((errstr = write_kernel()) != NULL)
623 658 goto error;
624 659
625 - if (do_modify(B_TRUE) != 0 ||
660 + if (do_modify() != 0 ||
626 661 rename(PATH_CONFIG, PATH_CONFIG_OLD) != 0) {
627 662 (void) fprintf(stderr, gettext(
628 663 "%s: failed to import legacy configuration.\n"),
629 664 command);
630 665 return (SMF_EXIT_ERR_FATAL);
631 666 }
632 667 return (SMF_EXIT_OK);
633 668 }
634 669
635 670 addprop(properties, MAX_PROPS, count++, &prop_gpattern, &glob_pattern);
636 671 addprop(properties, MAX_PROPS, count++, &prop_gcontent, &gcstr);
637 672 addprop(properties, MAX_PROPS, count++, &prop_ipattern, &init_pattern);
638 673 addprop(properties, MAX_PROPS, count++, &prop_icontent, &icstr);
639 674 for (prop = prop_option; prop->pv_prop != NULL; prop++)
640 675 addprop(properties, MAX_PROPS, count++, prop, &options);
641 676 properties[count].pv_prop = NULL;
642 677
643 678 alloptions = CC_OPTIONS;
644 - if (scf_read_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, B_TRUE,
679 + if (scf_read_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, B_FALSE,
645 680 properties, &prop) == SCF_FAILED) {
646 681 if (prop != NULL) {
647 682 (void) fprintf(stderr, gettext(
648 683 "%s: configuration property '%s' not found.\n"),
649 684 command, prop->pv_prop);
650 685 } else {
651 686 (void) fprintf(stderr, gettext(
652 687 "%s: unable to read configuration: %s\n"),
653 688 command, scf_strerror(scf_error()));
654 689 }
655 690 return (SMF_EXIT_ERR_FATAL);
656 691 }
657 692
658 693 (void) proc_str2content(gcstr, &glob_content);
659 694 (void) proc_str2content(icstr, &init_content);
660 695
661 696 errstr = write_kernel();
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
662 697 scf_clean_propvec(properties);
663 698 if (errstr == NULL)
664 699 return (SMF_EXIT_OK);
665 700
666 701 error:
667 702 if (errno == EPERM) {
668 703 (void) perm();
669 704 return (SMF_EXIT_ERR_PERM);
670 705 }
671 706 perror(errstr);
672 - return (SMF_EXIT_ERR_FATAL);
707 + return (errno == EINVAL ? SMF_EXIT_ERR_CONFIG : SMF_EXIT_ERR_FATAL);
673 708 }
674 709
675 710 static int do_legacy()
676 711 {
677 712 const char *errstr;
678 713
679 714 if (read_legacy() && (errstr = write_kernel()) != NULL) {
680 715 if (errno == EPERM)
681 716 return (perm());
682 717 perror(errstr);
683 718 return (E_ERROR);
684 719 }
685 720
686 721 return (E_SUCCESS);
687 722 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX