Print this page
2249 libbrand suppresses libxml2 errors
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Eric Shrock <eric.schrock@delphix.com>
Reviewed by: Milan Jurik <milan.jurik@xylab.cz>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libbrand/common/libbrand.c
+++ new/usr/src/lib/libbrand/common/libbrand.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 /*
23 23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 + * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
24 25 */
25 26
26 27 #include <assert.h>
27 28 #include <dirent.h>
28 29 #include <errno.h>
29 30 #include <fnmatch.h>
30 31 #include <signal.h>
31 32 #include <stdlib.h>
32 33 #include <unistd.h>
33 34 #include <strings.h>
34 35 #include <synch.h>
35 36 #include <sys/brand.h>
36 37 #include <sys/fcntl.h>
37 38 #include <sys/param.h>
38 39 #include <sys/stat.h>
39 40 #include <sys/systeminfo.h>
40 41 #include <sys/types.h>
41 42 #include <thread.h>
42 43 #include <zone.h>
43 44
44 45 #include <libbrand_impl.h>
45 46 #include <libbrand.h>
46 47
47 48 #define DTD_ELEM_ATTACH ((const xmlChar *) "attach")
48 49 #define DTD_ELEM_BOOT ((const xmlChar *) "boot")
49 50 #define DTD_ELEM_BRAND ((const xmlChar *) "brand")
50 51 #define DTD_ELEM_CLONE ((const xmlChar *) "clone")
51 52 #define DTD_ELEM_COMMENT ((const xmlChar *) "comment")
52 53 #define DTD_ELEM_DETACH ((const xmlChar *) "detach")
53 54 #define DTD_ELEM_DEVICE ((const xmlChar *) "device")
54 55 #define DTD_ELEM_GLOBAL_MOUNT ((const xmlChar *) "global_mount")
55 56 #define DTD_ELEM_HALT ((const xmlChar *) "halt")
56 57 #define DTD_ELEM_INITNAME ((const xmlChar *) "initname")
57 58 #define DTD_ELEM_INSTALL ((const xmlChar *) "install")
58 59 #define DTD_ELEM_INSTALLOPTS ((const xmlChar *) "installopts")
59 60 #define DTD_ELEM_LOGIN_CMD ((const xmlChar *) "login_cmd")
60 61 #define DTD_ELEM_FORCELOGIN_CMD ((const xmlChar *) "forcedlogin_cmd")
61 62 #define DTD_ELEM_MODNAME ((const xmlChar *) "modname")
62 63 #define DTD_ELEM_MOUNT ((const xmlChar *) "mount")
63 64 #define DTD_ELEM_POSTATTACH ((const xmlChar *) "postattach")
64 65 #define DTD_ELEM_POSTCLONE ((const xmlChar *) "postclone")
65 66 #define DTD_ELEM_POSTINSTALL ((const xmlChar *) "postinstall")
66 67 #define DTD_ELEM_POSTSNAP ((const xmlChar *) "postsnap")
67 68 #define DTD_ELEM_POSTSTATECHG ((const xmlChar *) "poststatechange")
68 69 #define DTD_ELEM_PREDETACH ((const xmlChar *) "predetach")
69 70 #define DTD_ELEM_PRESNAP ((const xmlChar *) "presnap")
70 71 #define DTD_ELEM_PRESTATECHG ((const xmlChar *) "prestatechange")
71 72 #define DTD_ELEM_PREUNINSTALL ((const xmlChar *) "preuninstall")
72 73 #define DTD_ELEM_PRIVILEGE ((const xmlChar *) "privilege")
73 74 #define DTD_ELEM_QUERY ((const xmlChar *) "query")
74 75 #define DTD_ELEM_SYMLINK ((const xmlChar *) "symlink")
75 76 #define DTD_ELEM_SYSBOOT ((const xmlChar *) "sysboot")
76 77 #define DTD_ELEM_UNINSTALL ((const xmlChar *) "uninstall")
77 78 #define DTD_ELEM_USER_CMD ((const xmlChar *) "user_cmd")
78 79 #define DTD_ELEM_VALIDSNAP ((const xmlChar *) "validatesnap")
79 80 #define DTD_ELEM_VERIFY_CFG ((const xmlChar *) "verify_cfg")
80 81 #define DTD_ELEM_VERIFY_ADM ((const xmlChar *) "verify_adm")
81 82
82 83 #define DTD_ATTR_ALLOWEXCL ((const xmlChar *) "allow-exclusive-ip")
83 84 #define DTD_ATTR_ARCH ((const xmlChar *) "arch")
84 85 #define DTD_ATTR_DIRECTORY ((const xmlChar *) "directory")
85 86 #define DTD_ATTR_IPTYPE ((const xmlChar *) "ip-type")
86 87 #define DTD_ATTR_MATCH ((const xmlChar *) "match")
87 88 #define DTD_ATTR_MODE ((const xmlChar *) "mode")
88 89 #define DTD_ATTR_NAME ((const xmlChar *) "name")
89 90 #define DTD_ATTR_OPT ((const xmlChar *) "opt")
90 91 #define DTD_ATTR_PATH ((const xmlChar *) "path")
91 92 #define DTD_ATTR_SET ((const xmlChar *) "set")
92 93 #define DTD_ATTR_SOURCE ((const xmlChar *) "source")
93 94 #define DTD_ATTR_SPECIAL ((const xmlChar *) "special")
94 95 #define DTD_ATTR_TARGET ((const xmlChar *) "target")
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
95 96 #define DTD_ATTR_TYPE ((const xmlChar *) "type")
96 97
97 98 #define DTD_ENTITY_TRUE "true"
98 99
99 100 static volatile boolean_t libbrand_initialized = B_FALSE;
100 101 static char i_curr_arch[MAXNAMELEN];
101 102 static char i_curr_zone[ZONENAME_MAX];
102 103
103 104 /*ARGSUSED*/
104 105 static void
105 -brand_error_func(void *ctx, const char *msg, ...)
106 +brand_warning_func(void *ctx, const char *msg, ...)
106 107 {
107 108 /*
108 - * Ignore error messages from libxml
109 + * Ignore warning messages from libxml
109 110 */
110 111 }
111 112
113 +/*ARGSUSED*/
114 +static void
115 +brand_error_func(void *ctx, const char *msg, ...)
116 +{
117 + va_list args;
118 +
119 + va_start(args, msg);
120 + (void) vfprintf(stderr, msg, args);
121 + va_end(args);
122 +}
123 +
112 124 static boolean_t
113 125 libbrand_initialize()
114 126 {
115 127 static mutex_t initialize_lock = DEFAULTMUTEX;
116 128
117 129 (void) mutex_lock(&initialize_lock);
118 130
119 131 if (libbrand_initialized) {
120 132 (void) mutex_unlock(&initialize_lock);
121 133 return (B_TRUE);
122 134 }
123 135
124 136 if (sysinfo(SI_ARCHITECTURE, i_curr_arch, sizeof (i_curr_arch)) < 0) {
125 137 (void) mutex_unlock(&initialize_lock);
126 138 return (B_FALSE);
127 139 }
128 140
129 141 if (getzonenamebyid(getzoneid(), i_curr_zone,
130 142 sizeof (i_curr_zone)) < 0) {
131 143 (void) mutex_unlock(&initialize_lock);
132 144 return (B_FALSE);
133 145 }
134 146
135 147 /*
136 148 * Note that here we're initializing per-process libxml2
137 149 * state. By doing so we're implicitly assuming that
138 150 * no other code in this process is also trying to
139 151 * use libxml2. But in most case we know this not to
140 152 * be true since we're almost always used in conjunction
141 153 * with libzonecfg, which also uses libxml2. Lucky for
142 154 * us, libzonecfg initializes libxml2 to essentially
143 155 * the same defaults as we're using below.
144 156 */
145 157 (void) xmlLineNumbersDefault(1);
146 158 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
147 159 xmlDoValidityCheckingDefaultValue = 1;
148 160 (void) xmlKeepBlanksDefault(0);
149 161 xmlGetWarningsDefaultValue = 0;
150 162 xmlSetGenericErrorFunc(NULL, brand_error_func);
151 163
152 164 libbrand_initialized = B_TRUE;
153 165 (void) mutex_unlock(&initialize_lock);
154 166 return (B_TRUE);
155 167 }
156 168
157 169 static const char *
158 170 get_curr_arch(void)
159 171 {
160 172 if (!libbrand_initialize())
161 173 return (NULL);
162 174
163 175 return (i_curr_arch);
164 176 }
165 177
166 178 static const char *
167 179 get_curr_zone(void)
168 180 {
169 181 if (!libbrand_initialize())
170 182 return (NULL);
171 183
172 184 return (i_curr_zone);
173 185 }
174 186
175 187 /*
176 188 * Internal function to open an XML file
177 189 *
178 190 * Returns the XML doc pointer, or NULL on failure. It will validate the
179 191 * document, as well as removing any comments from the document structure.
180 192 */
181 193 static xmlDocPtr
182 194 open_xml_file(const char *file)
183 195 {
184 196 xmlDocPtr doc;
185 197 xmlValidCtxtPtr cvp;
186 198 int valid;
187 199
188 200 if (!libbrand_initialize())
189 201 return (NULL);
190 202
191 203 /*
192 204 * Parse the file
193 205 */
194 206 if ((doc = xmlParseFile(file)) == NULL)
↓ open down ↓ |
73 lines elided |
↑ open up ↑ |
195 207 return (NULL);
196 208
197 209 /*
198 210 * Validate the file
199 211 */
200 212 if ((cvp = xmlNewValidCtxt()) == NULL) {
201 213 xmlFreeDoc(doc);
202 214 return (NULL);
203 215 }
204 216 cvp->error = brand_error_func;
205 - cvp->warning = brand_error_func;
217 + cvp->warning = brand_warning_func;
206 218 valid = xmlValidateDocument(cvp, doc);
207 219 xmlFreeValidCtxt(cvp);
208 220 if (valid == 0) {
209 221 xmlFreeDoc(doc);
210 222 return (NULL);
211 223 }
212 224
213 225 return (doc);
214 226 }
215 227 /*
216 228 * Open a handle to the named brand.
217 229 *
218 230 * Returns a handle to the named brand, which is used for all subsequent brand
219 231 * interaction, or NULL if unable to open or initialize the brand.
220 232 */
221 233 brand_handle_t
222 234 brand_open(const char *name)
223 235 {
224 236 struct brand_handle *bhp;
225 237 char path[MAXPATHLEN];
226 238 xmlNodePtr node;
227 239 xmlChar *property;
228 240 struct stat statbuf;
229 241
230 242 /*
231 243 * Make sure brand name isn't too long
232 244 */
233 245 if (strlen(name) >= MAXNAMELEN)
234 246 return (NULL);
235 247
236 248 /*
237 249 * Check that the brand exists
238 250 */
239 251 (void) snprintf(path, sizeof (path), "%s/%s", BRAND_DIR, name);
240 252
241 253 if (stat(path, &statbuf) != 0)
242 254 return (NULL);
243 255
244 256 /*
245 257 * Allocate brand handle
246 258 */
247 259 if ((bhp = malloc(sizeof (struct brand_handle))) == NULL)
248 260 return (NULL);
249 261 bzero(bhp, sizeof (struct brand_handle));
250 262
251 263 (void) strcpy(bhp->bh_name, name);
252 264
253 265 /*
254 266 * Open the configuration file
255 267 */
256 268 (void) snprintf(path, sizeof (path), "%s/%s/%s", BRAND_DIR, name,
257 269 BRAND_CONFIG);
258 270 if ((bhp->bh_config = open_xml_file(path)) == NULL) {
259 271 brand_close((brand_handle_t)bhp);
260 272 return (NULL);
261 273 }
262 274
263 275 /*
264 276 * Verify that the name of the brand matches the directory in which it
265 277 * is installed.
266 278 */
267 279 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL) {
268 280 brand_close((brand_handle_t)bhp);
269 281 return (NULL);
270 282 }
271 283
272 284 if (xmlStrcmp(node->name, DTD_ELEM_BRAND) != 0) {
273 285 brand_close((brand_handle_t)bhp);
274 286 return (NULL);
275 287 }
276 288
277 289 if ((property = xmlGetProp(node, DTD_ATTR_NAME)) == NULL) {
278 290 brand_close((brand_handle_t)bhp);
279 291 return (NULL);
280 292 }
281 293
282 294 if (strcmp((char *)property, name) != 0) {
283 295 xmlFree(property);
284 296 brand_close((brand_handle_t)bhp);
285 297 return (NULL);
286 298 }
287 299 xmlFree(property);
288 300
289 301 /*
290 302 * Open handle to platform configuration file.
291 303 */
292 304 (void) snprintf(path, sizeof (path), "%s/%s/%s", BRAND_DIR, name,
293 305 BRAND_PLATFORM);
294 306 if ((bhp->bh_platform = open_xml_file(path)) == NULL) {
295 307 brand_close((brand_handle_t)bhp);
296 308 return (NULL);
297 309 }
298 310
299 311 return ((brand_handle_t)bhp);
300 312 }
301 313
302 314 /*
303 315 * Closes the given brand handle
304 316 */
305 317 void
306 318 brand_close(brand_handle_t bh)
307 319 {
308 320 struct brand_handle *bhp = (struct brand_handle *)bh;
309 321 if (bhp->bh_platform != NULL)
310 322 xmlFreeDoc(bhp->bh_platform);
311 323 if (bhp->bh_config != NULL)
312 324 xmlFreeDoc(bhp->bh_config);
313 325 free(bhp);
314 326 }
315 327
316 328 static int
317 329 i_substitute_tokens(const char *sbuf, char *dbuf, int dbuf_size,
318 330 const char *zonename, const char *zonepath, const char *username,
319 331 const char *curr_zone)
320 332 {
321 333 int dst, src;
322 334
323 335 /*
324 336 * Walk through the characters, substituting values as needed.
325 337 */
326 338 dbuf[0] = '\0';
327 339 dst = 0;
328 340 for (src = 0; src < strlen((char *)sbuf) && dst < dbuf_size; src++) {
329 341 if (sbuf[src] != '%') {
330 342 dbuf[dst++] = sbuf[src];
331 343 continue;
332 344 }
333 345
334 346 switch (sbuf[++src]) {
335 347 case '%':
336 348 dst += strlcpy(dbuf + dst, "%", dbuf_size - dst);
337 349 break;
338 350 case 'R':
339 351 if (zonepath == NULL)
340 352 break;
341 353 dst += strlcpy(dbuf + dst, zonepath, dbuf_size - dst);
342 354 break;
343 355 case 'u':
344 356 if (username == NULL)
345 357 break;
346 358 dst += strlcpy(dbuf + dst, username, dbuf_size - dst);
347 359 break;
348 360 case 'Z':
349 361 if (curr_zone == NULL)
350 362 break;
351 363 /* name of the zone we're running in */
352 364 dst += strlcpy(dbuf + dst, curr_zone, dbuf_size - dst);
353 365 break;
354 366 case 'z':
355 367 /* name of the zone we're operating on */
356 368 if (zonename == NULL)
357 369 break;
358 370 dst += strlcpy(dbuf + dst, zonename, dbuf_size - dst);
359 371 break;
360 372 }
361 373 }
362 374
363 375 if (dst >= dbuf_size)
364 376 return (-1);
365 377
366 378 dbuf[dst] = '\0';
367 379 return (0);
368 380 }
369 381
370 382 /*
371 383 * Retrieve the given tag from the brand.
372 384 * Perform the following substitutions as necessary:
373 385 *
374 386 * %% %
375 387 * %u Username
376 388 * %z Name of target zone
377 389 * %Z Name of current zone
378 390 * %R Zonepath of zone
379 391 *
380 392 * Returns 0 on success, -1 on failure.
381 393 */
382 394 static int
383 395 brand_get_value(struct brand_handle *bhp, const char *zonename,
384 396 const char *zonepath, const char *username, const char *curr_zone,
385 397 char *buf, size_t len, const xmlChar *tagname,
386 398 boolean_t substitute, boolean_t optional)
387 399 {
388 400 xmlNodePtr node;
389 401 xmlChar *content;
390 402 int err = 0;
391 403
392 404 /*
393 405 * Retrieve the specified value from the XML doc
394 406 */
395 407 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL)
396 408 return (-1);
397 409
398 410 if (xmlStrcmp(node->name, DTD_ELEM_BRAND) != 0)
399 411 return (-1);
400 412
401 413 for (node = node->xmlChildrenNode; node != NULL;
402 414 node = node->next) {
403 415 if (xmlStrcmp(node->name, tagname) == 0)
404 416 break;
405 417 }
406 418
407 419 if (node == NULL) {
408 420 if (optional) {
409 421 buf[0] = '\0';
410 422 return (0);
411 423 } else {
412 424 return (-1);
413 425 }
414 426 }
415 427
416 428 if ((content = xmlNodeGetContent(node)) == NULL)
417 429 return (-1);
418 430
419 431 if (strlen((char *)content) == 0) {
420 432 /*
421 433 * If the entry in the config file is empty, check to see
422 434 * whether this is an optional field. If so, we return the
423 435 * empty buffer. If not, we return an error.
424 436 */
425 437 if (optional) {
426 438 buf[0] = '\0';
427 439 } else {
428 440 err = -1;
429 441 }
430 442 } else {
431 443 /* Substitute token values as needed. */
432 444 if (substitute) {
433 445 if (i_substitute_tokens((char *)content, buf, len,
434 446 zonename, zonepath, username, curr_zone) != 0)
435 447 err = -1;
436 448 } else {
437 449 if (strlcpy(buf, (char *)content, len) >= len)
438 450 err = -1;
439 451 }
440 452 }
441 453
442 454 xmlFree(content);
443 455
444 456 return (err);
445 457 }
446 458
447 459 int
448 460 brand_get_attach(brand_handle_t bh, const char *zonename,
449 461 const char *zonepath, char *buf, size_t len)
450 462 {
451 463 struct brand_handle *bhp = (struct brand_handle *)bh;
452 464 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
453 465 buf, len, DTD_ELEM_ATTACH, B_TRUE, B_TRUE));
454 466 }
455 467
456 468 int
457 469 brand_get_boot(brand_handle_t bh, const char *zonename,
458 470 const char *zonepath, char *buf, size_t len)
459 471 {
460 472 struct brand_handle *bhp = (struct brand_handle *)bh;
461 473 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
462 474 buf, len, DTD_ELEM_BOOT, B_TRUE, B_TRUE));
463 475 }
464 476
465 477 int
466 478 brand_get_brandname(brand_handle_t bh, char *buf, size_t len)
467 479 {
468 480 struct brand_handle *bhp = (struct brand_handle *)bh;
469 481 if (len <= strlen(bhp->bh_name))
470 482 return (-1);
471 483
472 484 (void) strcpy(buf, bhp->bh_name);
473 485
474 486 return (0);
475 487 }
476 488
477 489 int
478 490 brand_get_clone(brand_handle_t bh, const char *zonename,
479 491 const char *zonepath, char *buf, size_t len)
480 492 {
481 493 struct brand_handle *bhp = (struct brand_handle *)bh;
482 494 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
483 495 buf, len, DTD_ELEM_CLONE, B_TRUE, B_TRUE));
484 496 }
485 497
486 498 int
487 499 brand_get_detach(brand_handle_t bh, const char *zonename,
488 500 const char *zonepath, char *buf, size_t len)
489 501 {
490 502 struct brand_handle *bhp = (struct brand_handle *)bh;
491 503 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
492 504 buf, len, DTD_ELEM_DETACH, B_TRUE, B_TRUE));
493 505 }
494 506
495 507 int
496 508 brand_get_halt(brand_handle_t bh, const char *zonename,
497 509 const char *zonepath, char *buf, size_t len)
498 510 {
499 511 struct brand_handle *bhp = (struct brand_handle *)bh;
500 512 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
501 513 buf, len, DTD_ELEM_HALT, B_TRUE, B_TRUE));
502 514 }
503 515
504 516 int
505 517 brand_get_initname(brand_handle_t bh, char *buf, size_t len)
506 518 {
507 519 struct brand_handle *bhp = (struct brand_handle *)bh;
508 520 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
509 521 buf, len, DTD_ELEM_INITNAME, B_FALSE, B_FALSE));
510 522 }
511 523
512 524 int
513 525 brand_get_login_cmd(brand_handle_t bh, const char *username,
514 526 char *buf, size_t len)
515 527 {
516 528 struct brand_handle *bhp = (struct brand_handle *)bh;
517 529 const char *curr_zone = get_curr_zone();
518 530 return (brand_get_value(bhp, NULL, NULL, username, curr_zone,
519 531 buf, len, DTD_ELEM_LOGIN_CMD, B_TRUE, B_FALSE));
520 532 }
521 533
522 534 int
523 535 brand_get_forcedlogin_cmd(brand_handle_t bh, const char *username,
524 536 char *buf, size_t len)
525 537 {
526 538 struct brand_handle *bhp = (struct brand_handle *)bh;
527 539 const char *curr_zone = get_curr_zone();
528 540 return (brand_get_value(bhp, NULL, NULL, username, curr_zone,
529 541 buf, len, DTD_ELEM_FORCELOGIN_CMD, B_TRUE, B_FALSE));
530 542 }
531 543
532 544 int
533 545 brand_get_user_cmd(brand_handle_t bh, const char *username,
534 546 char *buf, size_t len)
535 547 {
536 548 struct brand_handle *bhp = (struct brand_handle *)bh;
537 549
538 550 return (brand_get_value(bhp, NULL, NULL, username, NULL,
539 551 buf, len, DTD_ELEM_USER_CMD, B_TRUE, B_FALSE));
540 552 }
541 553
542 554 int
543 555 brand_get_install(brand_handle_t bh, const char *zonename,
544 556 const char *zonepath, char *buf, size_t len)
545 557 {
546 558 struct brand_handle *bhp = (struct brand_handle *)bh;
547 559 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
548 560 buf, len, DTD_ELEM_INSTALL, B_TRUE, B_FALSE));
549 561 }
550 562
551 563 int
552 564 brand_get_installopts(brand_handle_t bh, char *buf, size_t len)
553 565 {
554 566 struct brand_handle *bhp = (struct brand_handle *)bh;
555 567 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
556 568 buf, len, DTD_ELEM_INSTALLOPTS, B_FALSE, B_TRUE));
557 569 }
558 570
559 571 int
560 572 brand_get_modname(brand_handle_t bh, char *buf, size_t len)
561 573 {
562 574 struct brand_handle *bhp = (struct brand_handle *)bh;
563 575 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
564 576 buf, len, DTD_ELEM_MODNAME, B_FALSE, B_TRUE));
565 577 }
566 578
567 579 int
568 580 brand_get_postattach(brand_handle_t bh, const char *zonename,
569 581 const char *zonepath, char *buf, size_t len)
570 582 {
571 583 struct brand_handle *bhp = (struct brand_handle *)bh;
572 584 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
573 585 buf, len, DTD_ELEM_POSTATTACH, B_TRUE, B_TRUE));
574 586 }
575 587
576 588 int
577 589 brand_get_postclone(brand_handle_t bh, const char *zonename,
578 590 const char *zonepath, char *buf, size_t len)
579 591 {
580 592 struct brand_handle *bhp = (struct brand_handle *)bh;
581 593 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
582 594 buf, len, DTD_ELEM_POSTCLONE, B_TRUE, B_TRUE));
583 595 }
584 596
585 597 int
586 598 brand_get_postinstall(brand_handle_t bh, const char *zonename,
587 599 const char *zonepath, char *buf, size_t len)
588 600 {
589 601 struct brand_handle *bhp = (struct brand_handle *)bh;
590 602 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
591 603 buf, len, DTD_ELEM_POSTINSTALL, B_TRUE, B_TRUE));
592 604 }
593 605
594 606 int
595 607 brand_get_postsnap(brand_handle_t bh, const char *zonename,
596 608 const char *zonepath, char *buf, size_t len)
597 609 {
598 610 struct brand_handle *bhp = (struct brand_handle *)bh;
599 611 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
600 612 buf, len, DTD_ELEM_POSTSNAP, B_TRUE, B_TRUE));
601 613 }
602 614
603 615 int
604 616 brand_get_poststatechange(brand_handle_t bh, const char *zonename,
605 617 const char *zonepath, char *buf, size_t len)
606 618 {
607 619 struct brand_handle *bhp = (struct brand_handle *)bh;
608 620 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
609 621 buf, len, DTD_ELEM_POSTSTATECHG, B_TRUE, B_TRUE));
610 622 }
611 623
612 624 int
613 625 brand_get_predetach(brand_handle_t bh, const char *zonename,
614 626 const char *zonepath, char *buf, size_t len)
615 627 {
616 628 struct brand_handle *bhp = (struct brand_handle *)bh;
617 629 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
618 630 buf, len, DTD_ELEM_PREDETACH, B_TRUE, B_TRUE));
619 631 }
620 632
621 633 int
622 634 brand_get_presnap(brand_handle_t bh, const char *zonename,
623 635 const char *zonepath, char *buf, size_t len)
624 636 {
625 637 struct brand_handle *bhp = (struct brand_handle *)bh;
626 638 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
627 639 buf, len, DTD_ELEM_PRESNAP, B_TRUE, B_TRUE));
628 640 }
629 641
630 642 int
631 643 brand_get_prestatechange(brand_handle_t bh, const char *zonename,
632 644 const char *zonepath, char *buf, size_t len)
633 645 {
634 646 struct brand_handle *bhp = (struct brand_handle *)bh;
635 647 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
636 648 buf, len, DTD_ELEM_PRESTATECHG, B_TRUE, B_TRUE));
637 649 }
638 650
639 651 int
640 652 brand_get_preuninstall(brand_handle_t bh, const char *zonename,
641 653 const char *zonepath, char *buf, size_t len)
642 654 {
643 655 struct brand_handle *bhp = (struct brand_handle *)bh;
644 656 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
645 657 buf, len, DTD_ELEM_PREUNINSTALL, B_TRUE, B_TRUE));
646 658 }
647 659
648 660 int
649 661 brand_get_query(brand_handle_t bh, const char *zonename,
650 662 const char *zonepath, char *buf, size_t len)
651 663 {
652 664 struct brand_handle *bhp = (struct brand_handle *)bh;
653 665 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
654 666 buf, len, DTD_ELEM_QUERY, B_TRUE, B_TRUE));
655 667 }
656 668
657 669 int
658 670 brand_get_uninstall(brand_handle_t bh, const char *zonename,
659 671 const char *zonepath, char *buf, size_t len)
660 672 {
661 673 struct brand_handle *bhp = (struct brand_handle *)bh;
662 674 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
663 675 buf, len, DTD_ELEM_UNINSTALL, B_TRUE, B_TRUE));
664 676 }
665 677
666 678 int
667 679 brand_get_validatesnap(brand_handle_t bh, const char *zonename,
668 680 const char *zonepath, char *buf, size_t len)
669 681 {
670 682 struct brand_handle *bhp = (struct brand_handle *)bh;
671 683 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
672 684 buf, len, DTD_ELEM_VALIDSNAP, B_TRUE, B_TRUE));
673 685 }
674 686
675 687 int
676 688 brand_get_verify_cfg(brand_handle_t bh, char *buf, size_t len)
677 689 {
678 690 struct brand_handle *bhp = (struct brand_handle *)bh;
679 691 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
680 692 buf, len, DTD_ELEM_VERIFY_CFG, B_FALSE, B_TRUE));
681 693 }
682 694
683 695 int
684 696 brand_get_verify_adm(brand_handle_t bh, const char *zonename,
685 697 const char *zonepath, char *buf, size_t len)
686 698 {
687 699 struct brand_handle *bhp = (struct brand_handle *)bh;
688 700 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
689 701 buf, len, DTD_ELEM_VERIFY_ADM, B_TRUE, B_TRUE));
690 702 }
691 703
692 704 int
693 705 brand_get_sysboot(brand_handle_t bh, const char *zonename,
694 706 const char *zonepath, char *buf, size_t len)
695 707 {
696 708 struct brand_handle *bhp = (struct brand_handle *)bh;
697 709 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
698 710 buf, len, DTD_ELEM_SYSBOOT, B_TRUE, B_TRUE));
699 711 }
700 712
701 713 boolean_t
702 714 brand_allow_exclusive_ip(brand_handle_t bh)
703 715 {
704 716 struct brand_handle *bhp = (struct brand_handle *)bh;
705 717 xmlNodePtr node;
706 718 xmlChar *allow_excl;
707 719 boolean_t ret;
708 720
709 721 assert(bhp != NULL);
710 722
711 723 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
712 724 return (B_FALSE);
713 725
714 726 allow_excl = xmlGetProp(node, DTD_ATTR_ALLOWEXCL);
715 727 if (allow_excl == NULL)
716 728 return (B_FALSE);
717 729
718 730 /* Note: only return B_TRUE if it's "true" */
719 731 if (strcmp((char *)allow_excl, DTD_ENTITY_TRUE) == 0)
720 732 ret = B_TRUE;
721 733 else
722 734 ret = B_FALSE;
723 735
724 736 xmlFree(allow_excl);
725 737
726 738 return (ret);
727 739 }
728 740
729 741 /*
730 742 * Iterate over brand privileges
731 743 *
732 744 * Walks the brand config, searching for <privilege> elements, calling the
733 745 * specified callback for each. Returns 0 on success, or -1 on failure.
734 746 */
735 747 int
736 748 brand_config_iter_privilege(brand_handle_t bh,
737 749 int (*func)(void *, priv_iter_t *), void *data)
738 750 {
739 751 struct brand_handle *bhp = (struct brand_handle *)bh;
740 752 xmlNodePtr node;
741 753 xmlChar *name, *set, *iptype;
742 754 priv_iter_t priv_iter;
743 755 int ret;
744 756
745 757 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL)
746 758 return (-1);
747 759
748 760 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
749 761
750 762 if (xmlStrcmp(node->name, DTD_ELEM_PRIVILEGE) != 0)
751 763 continue;
752 764
753 765 name = xmlGetProp(node, DTD_ATTR_NAME);
754 766 set = xmlGetProp(node, DTD_ATTR_SET);
755 767 iptype = xmlGetProp(node, DTD_ATTR_IPTYPE);
756 768
757 769 if (name == NULL || set == NULL || iptype == NULL) {
758 770 if (name != NULL)
759 771 xmlFree(name);
760 772 if (set != NULL)
761 773 xmlFree(set);
762 774 if (iptype != NULL)
763 775 xmlFree(iptype);
764 776 return (-1);
765 777 }
766 778
767 779 priv_iter.pi_name = (char *)name;
768 780 priv_iter.pi_set = (char *)set;
769 781 priv_iter.pi_iptype = (char *)iptype;
770 782
771 783 ret = func(data, &priv_iter);
772 784
773 785 xmlFree(name);
774 786 xmlFree(set);
775 787 xmlFree(iptype);
776 788
777 789 if (ret != 0)
778 790 return (-1);
779 791 }
780 792
781 793 return (0);
782 794 }
783 795
784 796 static int
785 797 i_brand_platform_iter_mounts(struct brand_handle *bhp, const char *zonepath,
786 798 int (*func)(void *, const char *, const char *, const char *,
787 799 const char *), void *data, const xmlChar *mount_type)
788 800 {
789 801 xmlNodePtr node;
790 802 xmlChar *special, *dir, *type, *opt;
791 803 char special_exp[MAXPATHLEN];
792 804 char opt_exp[MAXPATHLEN];
793 805 int ret;
794 806
795 807 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
796 808 return (-1);
797 809
798 810 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
799 811
800 812 if (xmlStrcmp(node->name, mount_type) != 0)
801 813 continue;
802 814
803 815 special = xmlGetProp(node, DTD_ATTR_SPECIAL);
804 816 dir = xmlGetProp(node, DTD_ATTR_DIRECTORY);
805 817 type = xmlGetProp(node, DTD_ATTR_TYPE);
806 818 opt = xmlGetProp(node, DTD_ATTR_OPT);
807 819 if ((special == NULL) || (dir == NULL) || (type == NULL) ||
808 820 (opt == NULL)) {
809 821 ret = -1;
810 822 goto next;
811 823 }
812 824
813 825 /* Substitute token values as needed. */
814 826 if ((ret = i_substitute_tokens((char *)special,
815 827 special_exp, sizeof (special_exp),
816 828 NULL, zonepath, NULL, NULL)) != 0)
817 829 goto next;
818 830
819 831 /* opt might not be defined */
820 832 if (strlen((const char *)opt) == 0) {
821 833 xmlFree(opt);
822 834 opt = NULL;
823 835 } else {
824 836 if ((ret = i_substitute_tokens((char *)opt,
825 837 opt_exp, sizeof (opt_exp),
826 838 NULL, zonepath, NULL, NULL)) != 0)
827 839 goto next;
828 840 }
829 841
830 842 ret = func(data, (char *)special_exp, (char *)dir,
831 843 (char *)type, ((opt != NULL) ? opt_exp : NULL));
832 844
833 845 next:
834 846 if (special != NULL)
835 847 xmlFree(special);
836 848 if (dir != NULL)
837 849 xmlFree(dir);
838 850 if (type != NULL)
839 851 xmlFree(type);
840 852 if (opt != NULL)
841 853 xmlFree(opt);
842 854 if (ret != 0)
843 855 return (-1);
844 856 }
845 857 return (0);
846 858 }
847 859
848 860
849 861 /*
850 862 * Iterate over global platform filesystems
851 863 *
852 864 * Walks the platform, searching for <global_mount> elements, calling the
853 865 * specified callback for each. Returns 0 on success, or -1 on failure.
854 866 *
855 867 * Perform the following substitutions as necessary:
856 868 *
857 869 * %R Zonepath of zone
858 870 */
859 871 int
860 872 brand_platform_iter_gmounts(brand_handle_t bh, const char *zonepath,
861 873 int (*func)(void *, const char *, const char *, const char *,
862 874 const char *), void *data)
863 875 {
864 876 struct brand_handle *bhp = (struct brand_handle *)bh;
865 877 return (i_brand_platform_iter_mounts(bhp, zonepath, func, data,
866 878 DTD_ELEM_GLOBAL_MOUNT));
867 879 }
868 880
869 881 /*
870 882 * Iterate over non-global zone platform filesystems
871 883 *
872 884 * Walks the platform, searching for <mount> elements, calling the
873 885 * specified callback for each. Returns 0 on success, or -1 on failure.
874 886 */
875 887 int
876 888 brand_platform_iter_mounts(brand_handle_t bh, int (*func)(void *,
877 889 const char *, const char *, const char *, const char *), void *data)
878 890 {
879 891 struct brand_handle *bhp = (struct brand_handle *)bh;
880 892 return (i_brand_platform_iter_mounts(bhp, NULL, func, data,
881 893 DTD_ELEM_MOUNT));
882 894 }
883 895
884 896 /*
885 897 * Iterate over platform symlinks
886 898 *
887 899 * Walks the platform, searching for <symlink> elements, calling the
888 900 * specified callback for each. Returns 0 on success, or -1 on failure.
889 901 */
890 902 int
891 903 brand_platform_iter_link(brand_handle_t bh,
892 904 int (*func)(void *, const char *, const char *), void *data)
893 905 {
894 906 struct brand_handle *bhp = (struct brand_handle *)bh;
895 907 xmlNodePtr node;
896 908 xmlChar *source, *target;
897 909 int ret;
898 910
899 911 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
900 912 return (-1);
901 913
902 914 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
903 915
904 916 if (xmlStrcmp(node->name, DTD_ELEM_SYMLINK) != 0)
905 917 continue;
906 918
907 919 source = xmlGetProp(node, DTD_ATTR_SOURCE);
908 920 target = xmlGetProp(node, DTD_ATTR_TARGET);
909 921
910 922 if (source == NULL || target == NULL) {
911 923 if (source != NULL)
912 924 xmlFree(source);
913 925 if (target != NULL)
914 926 xmlFree(target);
915 927 return (-1);
916 928 }
917 929
918 930 ret = func(data, (char *)source, (char *)target);
919 931
920 932 xmlFree(source);
921 933 xmlFree(target);
922 934
923 935 if (ret != 0)
924 936 return (-1);
925 937 }
926 938
927 939 return (0);
928 940 }
929 941
930 942 /*
931 943 * Iterate over platform devices
932 944 *
933 945 * Walks the platform, searching for <device> elements, calling the
934 946 * specified callback for each. Returns 0 on success, or -1 on failure.
935 947 */
936 948 int
937 949 brand_platform_iter_devices(brand_handle_t bh, const char *zonename,
938 950 int (*func)(void *, const char *, const char *), void *data,
939 951 const char *curr_iptype)
940 952 {
941 953 struct brand_handle *bhp = (struct brand_handle *)bh;
942 954 const char *curr_arch = get_curr_arch();
943 955 xmlNodePtr node;
944 956 xmlChar *match, *name, *arch, *iptype;
945 957 char match_exp[MAXPATHLEN];
946 958 boolean_t err = B_FALSE;
947 959 int ret = 0;
948 960
949 961
950 962 assert(bhp != NULL);
951 963 assert(zonename != NULL);
952 964 assert(func != NULL);
953 965 assert(curr_iptype != NULL);
954 966
955 967 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
956 968 return (-1);
957 969
958 970 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
959 971
960 972 if (xmlStrcmp(node->name, DTD_ELEM_DEVICE) != 0)
961 973 continue;
962 974
963 975 match = xmlGetProp(node, DTD_ATTR_MATCH);
964 976 name = xmlGetProp(node, DTD_ATTR_NAME);
965 977 arch = xmlGetProp(node, DTD_ATTR_ARCH);
966 978 iptype = xmlGetProp(node, DTD_ATTR_IPTYPE);
967 979 if ((match == NULL) || (name == NULL) || (arch == NULL) ||
968 980 (iptype == NULL)) {
969 981 err = B_TRUE;
970 982 goto next;
971 983 }
972 984
973 985 /* check if the arch matches */
974 986 if ((strcmp((char *)arch, "all") != 0) &&
975 987 (strcmp((char *)arch, curr_arch) != 0))
976 988 goto next;
977 989
978 990 /* check if the iptype matches */
979 991 if ((strcmp((char *)iptype, "all") != 0) &&
980 992 (strcmp((char *)iptype, curr_iptype) != 0))
981 993 goto next;
982 994
983 995 /* Substitute token values as needed. */
984 996 if ((ret = i_substitute_tokens((char *)match,
985 997 match_exp, sizeof (match_exp),
986 998 zonename, NULL, NULL, NULL)) != 0) {
987 999 err = B_TRUE;
988 1000 goto next;
989 1001 }
990 1002
991 1003 /* name might not be defined */
992 1004 if (strlen((const char *)name) == 0) {
993 1005 xmlFree(name);
994 1006 name = NULL;
995 1007 }
996 1008
997 1009 /* invoke the callback */
998 1010 ret = func(data, (const char *)match_exp, (const char *)name);
999 1011
1000 1012 next:
1001 1013 if (match != NULL)
1002 1014 xmlFree(match);
1003 1015 if (name != NULL)
1004 1016 xmlFree(name);
1005 1017 if (arch != NULL)
1006 1018 xmlFree(arch);
1007 1019 if (iptype != NULL)
1008 1020 xmlFree(iptype);
1009 1021 if (err)
1010 1022 return (-1);
1011 1023 if (ret != 0)
1012 1024 return (-1);
1013 1025 }
1014 1026
1015 1027 return (0);
1016 1028 }
↓ open down ↓ |
801 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX