zoneadmd.c (ffbafc5382b8d46def826aec8c419ad31dff8ebd) | zoneadmd.c (3f2f09c1efd66f6d2995998ea72c5df8c70c9a97) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 226 unchanged lines hidden (view full) --- 235 236 buflen = snprintf(zlogp->log, zlogp->loglen, "%s\n", buf); 237 copylen = MIN(buflen, zlogp->loglen); 238 zlogp->log += copylen; 239 zlogp->loglen -= copylen; 240 } 241} 242 | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 226 unchanged lines hidden (view full) --- 235 236 buflen = snprintf(zlogp->log, zlogp->loglen, "%s\n", buf); 237 copylen = MIN(buflen, zlogp->loglen); 238 zlogp->log += copylen; 239 zlogp->loglen -= copylen; 240 } 241} 242 |
243/* 244 * Emit a warning for any boot arguments which are unrecognized. Since 245 * Solaris boot arguments are getopt(3c) compatible (see kernel(1m)), we 246 * put the arguments into an argv style array, use getopt to process them, 247 * and put the resultant argument string back into outargs. 248 * 249 * During the filtering, we pull out any arguments which are truly "boot" 250 * arguments, leaving only those which are to be passed intact to the 251 * progenitor process. The one we support at the moment is -i, which 252 * indicates to the kernel which program should be launched as 'init'. 253 * 254 * A return of Z_INVAL indicates specifically that the arguments are 255 * not valid; this is a non-fatal error. Except for Z_OK, all other return 256 * values are treated as fatal. 257 */ |
|
243static int | 258static int |
259filter_bootargs(zlog_t *zlogp, const char *inargs, char *outargs, 260 char *init_file, char *badarg) 261{ 262 int argc = 0, argc_save; 263 int i; 264 int err; 265 char *arg, *lasts, **argv = NULL, **argv_save; 266 char zonecfg_args[BOOTARGS_MAX]; 267 char scratchargs[BOOTARGS_MAX], *sargs; 268 char c; 269 270 bzero(outargs, BOOTARGS_MAX); 271 bzero(badarg, BOOTARGS_MAX); 272 273 (void) strlcpy(init_file, PATH_TO_INIT, MAXPATHLEN); 274 275 /* 276 * If the user didn't specify transient boot arguments, check 277 * to see if there were any specified in the zone configuration, 278 * and use them if applicable. 279 */ 280 if (inargs == NULL || inargs[0] == '\0') { 281 zone_dochandle_t handle; 282 if ((handle = zonecfg_init_handle()) == NULL) { 283 zerror(zlogp, B_TRUE, 284 "getting zone configuration handle"); 285 return (Z_BAD_HANDLE); 286 } 287 err = zonecfg_get_snapshot_handle(zone_name, handle); 288 if (err != Z_OK) { 289 zerror(zlogp, B_FALSE, 290 "invalid configuration snapshot"); 291 zonecfg_fini_handle(handle); 292 return (Z_BAD_HANDLE); 293 } 294 295 bzero(zonecfg_args, sizeof (zonecfg_args)); 296 (void) zonecfg_get_bootargs(handle, zonecfg_args, 297 sizeof (zonecfg_args)); 298 inargs = zonecfg_args; 299 zonecfg_fini_handle(handle); 300 } 301 302 if (strlen(inargs) >= BOOTARGS_MAX) { 303 zerror(zlogp, B_FALSE, "boot argument string too long"); 304 return (Z_INVAL); 305 } 306 307 (void) strlcpy(scratchargs, inargs, sizeof (scratchargs)); 308 sargs = scratchargs; 309 while ((arg = strtok_r(sargs, " \t", &lasts)) != NULL) { 310 sargs = NULL; 311 argc++; 312 } 313 314 if ((argv = calloc(argc + 1, sizeof (char *))) == NULL) { 315 zerror(zlogp, B_FALSE, "memory allocation failed"); 316 return (Z_NOMEM); 317 } 318 319 argv_save = argv; 320 argc_save = argc; 321 322 (void) strlcpy(scratchargs, inargs, sizeof (scratchargs)); 323 sargs = scratchargs; 324 i = 0; 325 while ((arg = strtok_r(sargs, " \t", &lasts)) != NULL) { 326 sargs = NULL; 327 if ((argv[i] = strdup(arg)) == NULL) { 328 err = Z_NOMEM; 329 zerror(zlogp, B_FALSE, "memory allocation failed"); 330 goto done; 331 } 332 i++; 333 } 334 335 /* 336 * We preserve compatibility with the Solaris system boot behavior, 337 * which allows: 338 * 339 * # reboot kernel/unix -s -m verbose 340 * 341 * In this example, kernel/unix tells the booter what file to 342 * boot. We don't want reboot in a zone to be gratuitously different, 343 * so we silently ignore the boot file, if necessary. 344 */ 345 if (argv[0] == NULL) 346 goto done; 347 348 assert(argv[0][0] != ' '); 349 assert(argv[0][0] != '\t'); 350 351 if (argv[0][0] != '-' && argv[0][0] != '\0') { 352 argv = &argv[1]; 353 argc--; 354 } 355 356 optind = 0; 357 opterr = 0; 358 err = Z_OK; 359 while ((c = getopt(argc, argv, "i:m:s")) != -1) { 360 switch (c) { 361 case 'i': 362 /* 363 * -i is handled by the runtime and is not passed 364 * along to userland 365 */ 366 (void) strlcpy(init_file, optarg, MAXPATHLEN); 367 break; 368 case 'm': 369 case 's': 370 /* These pass through unmolested */ 371 (void) snprintf(outargs, BOOTARGS_MAX, 372 "%s -%c %s ", outargs, c, optarg ? optarg : ""); 373 break; 374 case '?': 375 /* 376 * We warn about unknown arguments but pass them 377 * along anyway-- if someone wants to develop their 378 * own init replacement, they can pass it whatever 379 * args they want. 380 */ 381 err = Z_INVAL; 382 (void) snprintf(outargs, BOOTARGS_MAX, 383 "%s -%c", outargs, optopt); 384 (void) snprintf(badarg, BOOTARGS_MAX, 385 "%s -%c", badarg, optopt); 386 break; 387 } 388 } 389 390 /* 391 * For Solaris Zones we warn about and discard non-option arguments. 392 * Hence 'boot foo bar baz gub' --> 'boot'. However, to be similar 393 * to the kernel, we concat up all the other remaining boot args. 394 * and warn on them as a group. 395 */ 396 if (optind < argc) { 397 err = Z_INVAL; 398 while (optind < argc) { 399 (void) snprintf(badarg, BOOTARGS_MAX, "%s%s%s", 400 badarg, strlen(badarg) > 0 ? " " : "", 401 argv[optind]); 402 optind++; 403 } 404 zerror(zlogp, B_FALSE, "WARNING: Unused or invalid boot " 405 "arguments `%s'.", badarg); 406 } 407 408done: 409 for (i = 0; i < argc_save; i++) { 410 if (argv_save[i] != NULL) 411 free(argv_save[i]); 412 } 413 free(argv_save); 414 return (err); 415} 416 417 418static int |
|
244mkzonedir(zlog_t *zlogp) 245{ 246 struct stat st; 247 /* 248 * We must create and lock everyone but root out of ZONES_TMPDIR 249 * since anyone can open any UNIX domain socket, regardless of 250 * its file system permissions. Sigh... 251 */ --- 146 unchanged lines hidden (view full) --- 398 return (0); 399} 400 401static int 402zone_bootup(zlog_t *zlogp, const char *bootargs) 403{ 404 zoneid_t zoneid; 405 struct stat st; | 419mkzonedir(zlog_t *zlogp) 420{ 421 struct stat st; 422 /* 423 * We must create and lock everyone but root out of ZONES_TMPDIR 424 * since anyone can open any UNIX domain socket, regardless of 425 * its file system permissions. Sigh... 426 */ --- 146 unchanged lines hidden (view full) --- 573 return (0); 574} 575 576static int 577zone_bootup(zlog_t *zlogp, const char *bootargs) 578{ 579 zoneid_t zoneid; 580 struct stat st; |
406 char zroot[MAXPATHLEN], initpath[MAXPATHLEN]; | 581 char zroot[MAXPATHLEN], initpath[MAXPATHLEN], init_file[MAXPATHLEN]; 582 char nbootargs[BOOTARGS_MAX]; 583 int err; |
407 408 if (init_console_slave(zlogp) != 0) 409 return (-1); 410 reset_slave_terminal(zlogp); 411 412 if ((zoneid = getzoneidbyname(zone_name)) == -1) { 413 zerror(zlogp, B_TRUE, "unable to get zoneid"); 414 return (-1); 415 } 416 417 if (zone_mount_early(zlogp, zoneid) != 0) 418 return (-1); 419 | 584 585 if (init_console_slave(zlogp) != 0) 586 return (-1); 587 reset_slave_terminal(zlogp); 588 589 if ((zoneid = getzoneidbyname(zone_name)) == -1) { 590 zerror(zlogp, B_TRUE, "unable to get zoneid"); 591 return (-1); 592 } 593 594 if (zone_mount_early(zlogp, zoneid) != 0) 595 return (-1); 596 |
597 err = filter_bootargs(zlogp, bootargs, nbootargs, init_file, 598 bad_boot_arg); 599 if (err == Z_INVAL) 600 eventstream_write(Z_EVT_ZONE_BADARGS); 601 else if (err != Z_OK) 602 return (-1); 603 604 assert(init_file[0] != '\0'); 605 |
|
420 /* | 606 /* |
421 * Try to anticipate possible problems: Make sure init is executable. | 607 * Try to anticipate possible problems: Make sure whatever binary 608 * is supposed to be init is executable. |
422 */ 423 if (zone_get_rootpath(zone_name, zroot, sizeof (zroot)) != Z_OK) { 424 zerror(zlogp, B_FALSE, "unable to determine zone root"); 425 return (-1); 426 } | 609 */ 610 if (zone_get_rootpath(zone_name, zroot, sizeof (zroot)) != Z_OK) { 611 zerror(zlogp, B_FALSE, "unable to determine zone root"); 612 return (-1); 613 } |
427 (void) snprintf(initpath, sizeof (initpath), "%s%s", zroot, 428 PATH_TO_INIT); | 614 (void) snprintf(initpath, sizeof (initpath), "%s%s", zroot, init_file); |
429 430 if (stat(initpath, &st) == -1) { 431 zerror(zlogp, B_TRUE, "could not stat %s", initpath); 432 return (-1); 433 } 434 435 if ((st.st_mode & S_IXUSR) == 0) { 436 zerror(zlogp, B_FALSE, "%s is not executable", initpath); 437 return (-1); 438 } 439 | 615 616 if (stat(initpath, &st) == -1) { 617 zerror(zlogp, B_TRUE, "could not stat %s", initpath); 618 return (-1); 619 } 620 621 if ((st.st_mode & S_IXUSR) == 0) { 622 zerror(zlogp, B_FALSE, "%s is not executable", initpath); 623 return (-1); 624 } 625 |
440 if (zone_boot(zoneid, bootargs) == -1) { | 626 if (zone_setattr(zoneid, ZONE_ATTR_INITNAME, init_file, 0) == -1) { 627 zerror(zlogp, B_TRUE, "could not set zone boot file"); 628 return (-1); 629 } 630 631 if (zone_setattr(zoneid, ZONE_ATTR_BOOTARGS, nbootargs, 0) == -1) { 632 zerror(zlogp, B_TRUE, "could not set zone boot arguments"); 633 return (-1); 634 } 635 636 if (zone_boot(zoneid) == -1) { |
441 zerror(zlogp, B_TRUE, "unable to boot zone"); 442 return (-1); 443 } 444 445 return (0); 446} 447 448static int --- 114 unchanged lines hidden (view full) --- 563 zlog.log = zlog.buf; 564 /* defer initialization of zlog.locale until after credential check */ 565 zlogp = &zlog; 566 567 if (alen != sizeof (zone_cmd_arg_t)) { 568 /* 569 * This really shouldn't be happening. 570 */ | 637 zerror(zlogp, B_TRUE, "unable to boot zone"); 638 return (-1); 639 } 640 641 return (0); 642} 643 644static int --- 114 unchanged lines hidden (view full) --- 759 zlog.log = zlog.buf; 760 /* defer initialization of zlog.locale until after credential check */ 761 zlogp = &zlog; 762 763 if (alen != sizeof (zone_cmd_arg_t)) { 764 /* 765 * This really shouldn't be happening. 766 */ |
571 zerror(&logsys, B_FALSE, "invalid argument"); | 767 zerror(&logsys, B_FALSE, "argument size (%d bytes) " 768 "unexpected (expected %d bytes)", alen, 769 sizeof (zone_cmd_arg_t)); |
572 goto out; 573 } 574 cmd = zargp->cmd; 575 576 if (door_ucred(&uc) != 0) { 577 zerror(&logsys, B_TRUE, "door_ucred"); 578 goto out; 579 } --- 169 unchanged lines hidden (view full) --- 749 * zone; the second client loses, but his request 750 * doesn't fail, since the zone is now in the desired 751 * state. 752 */ 753 zerror(zlogp, B_FALSE, "zone is already ready"); 754 rval = 0; 755 break; 756 case Z_BOOT: | 770 goto out; 771 } 772 cmd = zargp->cmd; 773 774 if (door_ucred(&uc) != 0) { 775 zerror(&logsys, B_TRUE, "door_ucred"); 776 goto out; 777 } --- 169 unchanged lines hidden (view full) --- 947 * zone; the second client loses, but his request 948 * doesn't fail, since the zone is now in the desired 949 * state. 950 */ 951 zerror(zlogp, B_FALSE, "zone is already ready"); 952 rval = 0; 953 break; 954 case Z_BOOT: |
955 (void) strlcpy(boot_args, zargp->bootbuf, 956 sizeof (boot_args)); |
|
757 eventstream_write(Z_EVT_ZONE_BOOTING); 758 rval = zone_bootup(zlogp, zargp->bootbuf); 759 audit_put_record(zlogp, uc, rval, "boot"); 760 if (rval != 0) { 761 bringup_failure_recovery = B_TRUE; 762 (void) zone_halt(zlogp, B_FALSE); 763 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 764 } | 957 eventstream_write(Z_EVT_ZONE_BOOTING); 958 rval = zone_bootup(zlogp, zargp->bootbuf); 959 audit_put_record(zlogp, uc, rval, "boot"); 960 if (rval != 0) { 961 bringup_failure_recovery = B_TRUE; 962 (void) zone_halt(zlogp, B_FALSE); 963 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 964 } |
965 boot_args[0] = '\0'; |
|
765 break; 766 case Z_HALT: 767 if (kernelcall) /* Invalid; can't happen */ 768 abort(); 769 if ((rval = zone_halt(zlogp, B_FALSE)) != 0) 770 break; 771 eventstream_write(Z_EVT_ZONE_HALTED); 772 break; --- 56 unchanged lines hidden (view full) --- 829 rval = 0; 830 break; 831 case Z_HALT: 832 if ((rval = zone_halt(zlogp, B_FALSE)) != 0) 833 break; 834 eventstream_write(Z_EVT_ZONE_HALTED); 835 break; 836 case Z_REBOOT: | 966 break; 967 case Z_HALT: 968 if (kernelcall) /* Invalid; can't happen */ 969 abort(); 970 if ((rval = zone_halt(zlogp, B_FALSE)) != 0) 971 break; 972 eventstream_write(Z_EVT_ZONE_HALTED); 973 break; --- 56 unchanged lines hidden (view full) --- 1030 rval = 0; 1031 break; 1032 case Z_HALT: 1033 if ((rval = zone_halt(zlogp, B_FALSE)) != 0) 1034 break; 1035 eventstream_write(Z_EVT_ZONE_HALTED); 1036 break; 1037 case Z_REBOOT: |
1038 (void) strlcpy(boot_args, zargp->bootbuf, 1039 sizeof (boot_args)); |
|
837 eventstream_write(Z_EVT_ZONE_REBOOTING); 838 if ((rval = zone_halt(zlogp, B_FALSE)) != 0) { 839 eventstream_write(Z_EVT_ZONE_BOOTFAILED); | 1040 eventstream_write(Z_EVT_ZONE_REBOOTING); 1041 if ((rval = zone_halt(zlogp, B_FALSE)) != 0) { 1042 eventstream_write(Z_EVT_ZONE_BOOTFAILED); |
1043 boot_args[0] = '\0'; |
|
840 break; 841 } 842 if ((rval = zone_ready(zlogp, B_FALSE)) != 0) { 843 eventstream_write(Z_EVT_ZONE_BOOTFAILED); | 1044 break; 1045 } 1046 if ((rval = zone_ready(zlogp, B_FALSE)) != 0) { 1047 eventstream_write(Z_EVT_ZONE_BOOTFAILED); |
1048 boot_args[0] = '\0'; |
|
844 break; 845 } | 1049 break; 1050 } |
846 rval = zone_bootup(zlogp, ""); | 1051 rval = zone_bootup(zlogp, zargp->bootbuf); |
847 audit_put_record(zlogp, uc, rval, "reboot"); 848 if (rval != 0) { 849 (void) zone_halt(zlogp, B_FALSE); 850 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 851 } | 1052 audit_put_record(zlogp, uc, rval, "reboot"); 1053 if (rval != 0) { 1054 (void) zone_halt(zlogp, B_FALSE); 1055 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1056 } |
1057 boot_args[0] = '\0'; |
|
852 break; 853 case Z_NOTE_UNINSTALLING: 854 case Z_MOUNT: 855 case Z_UNMOUNT: 856 zerror(zlogp, B_FALSE, "%s operation is invalid " 857 "for zones in state '%s'", z_cmd_name(cmd), 858 zone_state_str(zstate)); 859 rval = -1; --- 79 unchanged lines hidden (view full) --- 939 int doorfd = -1; 940 int err, ret = -1; 941 struct stat st; 942 struct flock flock; 943 zone_state_t zstate; 944 945top: 946 if ((err = zone_get_state(zone_name, &zstate)) != Z_OK) { | 1058 break; 1059 case Z_NOTE_UNINSTALLING: 1060 case Z_MOUNT: 1061 case Z_UNMOUNT: 1062 zerror(zlogp, B_FALSE, "%s operation is invalid " 1063 "for zones in state '%s'", z_cmd_name(cmd), 1064 zone_state_str(zstate)); 1065 rval = -1; --- 79 unchanged lines hidden (view full) --- 1145 int doorfd = -1; 1146 int err, ret = -1; 1147 struct stat st; 1148 struct flock flock; 1149 zone_state_t zstate; 1150 1151top: 1152 if ((err = zone_get_state(zone_name, &zstate)) != Z_OK) { |
947 zerror(zlogp, B_FALSE, "failed to get zone state: %s\n", | 1153 zerror(zlogp, B_FALSE, "failed to get zone state: %s", |
948 zonecfg_strerror(err)); 949 goto out; 950 } 951 if ((doorfd = open(zone_door_path, O_CREAT|O_RDWR, 952 S_IREAD|S_IWRITE)) < 0) { 953 zerror(zlogp, B_TRUE, "failed to open %s", zone_door_path); 954 goto out; 955 } --- 164 unchanged lines hidden (view full) --- 1120 */ 1121 if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) { 1122 zerror(zlogp, B_FALSE, "cannot manage the %s zone", 1123 GLOBAL_ZONENAME); 1124 return (1); 1125 } 1126 1127 if (zone_get_id(zone_name, &zid) != 0) { | 1154 zonecfg_strerror(err)); 1155 goto out; 1156 } 1157 if ((doorfd = open(zone_door_path, O_CREAT|O_RDWR, 1158 S_IREAD|S_IWRITE)) < 0) { 1159 zerror(zlogp, B_TRUE, "failed to open %s", zone_door_path); 1160 goto out; 1161 } --- 164 unchanged lines hidden (view full) --- 1326 */ 1327 if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) { 1328 zerror(zlogp, B_FALSE, "cannot manage the %s zone", 1329 GLOBAL_ZONENAME); 1330 return (1); 1331 } 1332 1333 if (zone_get_id(zone_name, &zid) != 0) { |
1128 zerror(zlogp, B_FALSE, "could not manage %s: %s\n", zone_name, | 1334 zerror(zlogp, B_FALSE, "could not manage %s: %s", zone_name, |
1129 zonecfg_strerror(Z_NO_ZONE)); 1130 return (1); 1131 } 1132 1133 if ((err = zone_get_state(zone_name, &zstate)) != Z_OK) { | 1335 zonecfg_strerror(Z_NO_ZONE)); 1336 return (1); 1337 } 1338 1339 if ((err = zone_get_state(zone_name, &zstate)) != Z_OK) { |
1134 zerror(zlogp, B_FALSE, "failed to get zone state: %s\n", | 1340 zerror(zlogp, B_FALSE, "failed to get zone state: %s", |
1135 zonecfg_strerror(err)); 1136 return (1); 1137 } 1138 if (zstate < ZONE_STATE_INSTALLED) { 1139 zerror(zlogp, B_FALSE, 1140 "cannot manage a zone which is in state '%s'", 1141 zone_state_str(zstate)); 1142 return (1); --- 11 unchanged lines hidden (view full) --- 1154 if (getppriv(PRIV_EFFECTIVE, privset) != 0) { 1155 zerror(zlogp, B_TRUE, "%s failed", "getppriv"); 1156 priv_freeset(privset); 1157 return (1); 1158 } 1159 1160 if (priv_isfullset(privset) == B_FALSE) { 1161 zerror(zlogp, B_FALSE, "You lack sufficient privilege to " | 1341 zonecfg_strerror(err)); 1342 return (1); 1343 } 1344 if (zstate < ZONE_STATE_INSTALLED) { 1345 zerror(zlogp, B_FALSE, 1346 "cannot manage a zone which is in state '%s'", 1347 zone_state_str(zstate)); 1348 return (1); --- 11 unchanged lines hidden (view full) --- 1360 if (getppriv(PRIV_EFFECTIVE, privset) != 0) { 1361 zerror(zlogp, B_TRUE, "%s failed", "getppriv"); 1362 priv_freeset(privset); 1363 return (1); 1364 } 1365 1366 if (priv_isfullset(privset) == B_FALSE) { 1367 zerror(zlogp, B_FALSE, "You lack sufficient privilege to " |
1162 "run this command (all privs required)\n"); | 1368 "run this command (all privs required)"); |
1163 priv_freeset(privset); 1164 return (1); 1165 } 1166 priv_freeset(privset); 1167 1168 if (mkzonedir(zlogp) != 0) 1169 return (1); 1170 --- 244 unchanged lines hidden --- | 1369 priv_freeset(privset); 1370 return (1); 1371 } 1372 priv_freeset(privset); 1373 1374 if (mkzonedir(zlogp) != 0) 1375 return (1); 1376 --- 244 unchanged lines hidden --- |