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