Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/zoneadmd/zoneadmd.c
          +++ new/usr/src/cmd/zoneadmd/zoneadmd.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
  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) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
  25   25   * Copyright 2016 Joyent, Inc.
  26   26   */
  27   27  
  28   28  /*
  29   29   * zoneadmd manages zones; one zoneadmd process is launched for each
  30   30   * non-global zone on the system.  This daemon juggles four jobs:
  31   31   *
  32   32   * - Implement setup and teardown of the zone "virtual platform": mount and
  33   33   *   unmount filesystems; create and destroy network interfaces; communicate
  34   34   *   with devfsadmd to lay out devices for the zone; instantiate the zone
  35   35   *   console device; configure process runtime attributes such as resource
  36   36   *   controls, pool bindings, fine-grained privileges.
  37   37   *
  38   38   * - Launch the zone's init(1M) process.
  39   39   *
  40   40   * - Implement a door server; clients (like zoneadm) connect to the door
  41   41   *   server and request zone state changes.  The kernel is also a client of
  42   42   *   this door server.  A request to halt or reboot the zone which originates
  43   43   *   *inside* the zone results in a door upcall from the kernel into zoneadmd.
  44   44   *
  45   45   *   One minor problem is that messages emitted by zoneadmd need to be passed
  46   46   *   back to the zoneadm process making the request.  These messages need to
  47   47   *   be rendered in the client's locale; so, this is passed in as part of the
  48   48   *   request.  The exception is the kernel upcall to zoneadmd, in which case
  49   49   *   messages are syslog'd.
  50   50   *
  51   51   *   To make all of this work, the Makefile adds -a to xgettext to extract *all*
  52   52   *   strings, and an exclusion file (zoneadmd.xcl) is used to exclude those
  53   53   *   strings which do not need to be translated.
  54   54   *
  55   55   * - Act as a console server for zlogin -C processes; see comments in zcons.c
  56   56   *   for more information about the zone console architecture.
  57   57   *
  58   58   * DESIGN NOTES
  59   59   *
  60   60   * Restart:
  61   61   *   A chief design constraint of zoneadmd is that it should be restartable in
  62   62   *   the case that the administrator kills it off, or it suffers a fatal error,
  63   63   *   without the running zone being impacted; this is akin to being able to
  64   64   *   reboot the service processor of a server without affecting the OS instance.
  65   65   */
  66   66  
  67   67  #include <sys/param.h>
  68   68  #include <sys/mman.h>
  69   69  #include <sys/types.h>
  70   70  #include <sys/stat.h>
  71   71  #include <sys/sysmacros.h>
  72   72  #include <sys/time.h>
  73   73  
  74   74  #include <bsm/adt.h>
  75   75  #include <bsm/adt_event.h>
  76   76  
  77   77  #include <alloca.h>
  78   78  #include <assert.h>
  79   79  #include <errno.h>
  80   80  #include <door.h>
  81   81  #include <fcntl.h>
  82   82  #include <locale.h>
  83   83  #include <signal.h>
  84   84  #include <stdarg.h>
  85   85  #include <stdio.h>
  86   86  #include <stdlib.h>
  87   87  #include <string.h>
  88   88  #include <strings.h>
  89   89  #include <synch.h>
  90   90  #include <syslog.h>
  91   91  #include <thread.h>
  92   92  #include <unistd.h>
  93   93  #include <wait.h>
  94   94  #include <limits.h>
  95   95  #include <zone.h>
  96   96  #include <libbrand.h>
  97   97  #include <sys/brand.h>
  98   98  #include <libcontract.h>
  99   99  #include <libcontract_priv.h>
 100  100  #include <sys/brand.h>
 101  101  #include <sys/contract/process.h>
 102  102  #include <sys/ctfs.h>
 103  103  #include <libdladm.h>
 104  104  #include <sys/dls_mgmt.h>
 105  105  #include <libscf.h>
 106  106  
 107  107  #include <libzonecfg.h>
 108  108  #include <zonestat_impl.h>
 109  109  #include "zoneadmd.h"
 110  110  
 111  111  static char *progname;
 112  112  char *zone_name;        /* zone which we are managing */
  
    | 
      ↓ open down ↓ | 
    112 lines elided | 
    
      ↑ open up ↑ | 
  
 113  113  zone_dochandle_t snap_hndl;     /* handle for snapshot created when ready */
 114  114  char zonepath[MAXNAMELEN];
 115  115  char pool_name[MAXNAMELEN];
 116  116  char default_brand[MAXNAMELEN];
 117  117  char brand_name[MAXNAMELEN];
 118  118  boolean_t zone_isnative;
 119  119  boolean_t zone_iscluster;
 120  120  boolean_t zone_islabeled;
 121  121  boolean_t shutdown_in_progress;
 122  122  static zoneid_t zone_id;
 123      -static zoneid_t zone_did = 0;
 124  123  dladm_handle_t dld_handle = NULL;
 125  124  
 126      -char pre_statechg_hook[2 * MAXPATHLEN];
 127      -char post_statechg_hook[2 * MAXPATHLEN];
      125 +static char pre_statechg_hook[2 * MAXPATHLEN];
      126 +static char post_statechg_hook[2 * MAXPATHLEN];
 128  127  char query_hook[2 * MAXPATHLEN];
 129  128  
 130  129  zlog_t logsys;
 131  130  
 132  131  mutex_t lock = DEFAULTMUTEX;    /* to serialize stuff */
 133  132  mutex_t msglock = DEFAULTMUTEX; /* for calling setlocale() */
 134  133  
 135  134  static sema_t scratch_sem;      /* for scratch zones */
 136  135  
 137  136  static char     zone_door_path[MAXPATHLEN];
 138  137  static int      zone_door = -1;
 139  138  
 140  139  boolean_t in_death_throes = B_FALSE;    /* daemon is dying */
 141  140  boolean_t bringup_failure_recovery = B_FALSE; /* ignore certain failures */
 142  141  
 143  142  #if !defined(TEXT_DOMAIN)               /* should be defined by cc -D */
 144  143  #define TEXT_DOMAIN     "SYS_TEST"      /* Use this only if it wasn't */
 145  144  #endif
 146  145  
 147  146  #define DEFAULT_LOCALE  "C"
 148  147  
 149  148  #define RSRC_NET        "net"
 150  149  #define RSRC_DEV        "device"
 151  150  
 152  151  static const char *
 153  152  z_cmd_name(zone_cmd_t zcmd)
 154  153  {
 155  154          /* This list needs to match the enum in sys/zone.h */
 156  155          static const char *zcmdstr[] = {
 157  156                  "ready", "boot", "forceboot", "reboot", "halt",
 158  157                  "note_uninstalling", "mount", "forcemount", "unmount",
 159  158                  "shutdown"
 160  159          };
 161  160  
 162  161          if (zcmd >= sizeof (zcmdstr) / sizeof (*zcmdstr))
 163  162                  return ("unknown");
 164  163          else
 165  164                  return (zcmdstr[(int)zcmd]);
 166  165  }
 167  166  
 168  167  static char *
 169  168  get_execbasename(char *execfullname)
 170  169  {
 171  170          char *last_slash, *execbasename;
 172  171  
 173  172          /* guard against '/' at end of command invocation */
 174  173          for (;;) {
 175  174                  last_slash = strrchr(execfullname, '/');
 176  175                  if (last_slash == NULL) {
 177  176                          execbasename = execfullname;
 178  177                          break;
 179  178                  } else {
 180  179                          execbasename = last_slash + 1;
 181  180                          if (*execbasename == '\0') {
 182  181                                  *last_slash = '\0';
 183  182                                  continue;
 184  183                          }
 185  184                          break;
 186  185                  }
 187  186          }
 188  187          return (execbasename);
 189  188  }
 190  189  
 191  190  static void
 192  191  usage(void)
 193  192  {
 194  193          (void) fprintf(stderr, gettext("Usage: %s -z zonename\n"), progname);
 195  194          (void) fprintf(stderr,
 196  195              gettext("\tNote: %s should not be run directly.\n"), progname);
 197  196          exit(2);
 198  197  }
 199  198  
 200  199  /* ARGSUSED */
 201  200  static void
 202  201  sigchld(int sig)
 203  202  {
 204  203  }
 205  204  
 206  205  char *
 207  206  localize_msg(char *locale, const char *msg)
 208  207  {
 209  208          char *out;
 210  209  
 211  210          (void) mutex_lock(&msglock);
 212  211          (void) setlocale(LC_MESSAGES, locale);
 213  212          out = gettext(msg);
 214  213          (void) setlocale(LC_MESSAGES, DEFAULT_LOCALE);
 215  214          (void) mutex_unlock(&msglock);
 216  215          return (out);
 217  216  }
 218  217  
 219  218  /* PRINTFLIKE3 */
 220  219  void
 221  220  zerror(zlog_t *zlogp, boolean_t use_strerror, const char *fmt, ...)
 222  221  {
 223  222          va_list alist;
 224  223          char buf[MAXPATHLEN * 2]; /* enough space for err msg with a path */
 225  224          char *bp;
 226  225          int saved_errno = errno;
 227  226  
 228  227          if (zlogp == NULL)
 229  228                  return;
 230  229          if (zlogp == &logsys)
 231  230                  (void) snprintf(buf, sizeof (buf), "[zone '%s'] ",
 232  231                      zone_name);
 233  232          else
 234  233                  buf[0] = '\0';
 235  234          bp = &(buf[strlen(buf)]);
 236  235  
 237  236          /*
 238  237           * In theory, the locale pointer should be set to either "C" or a
 239  238           * char array, so it should never be NULL
 240  239           */
 241  240          assert(zlogp->locale != NULL);
 242  241          /* Locale is per process, but we are multi-threaded... */
 243  242          fmt = localize_msg(zlogp->locale, fmt);
 244  243  
 245  244          va_start(alist, fmt);
 246  245          (void) vsnprintf(bp, sizeof (buf) - (bp - buf), fmt, alist);
 247  246          va_end(alist);
 248  247          bp = &(buf[strlen(buf)]);
 249  248          if (use_strerror)
 250  249                  (void) snprintf(bp, sizeof (buf) - (bp - buf), ": %s",
 251  250                      strerror(saved_errno));
 252  251          if (zlogp == &logsys) {
 253  252                  (void) syslog(LOG_ERR, "%s", buf);
 254  253          } else if (zlogp->logfile != NULL) {
 255  254                  (void) fprintf(zlogp->logfile, "%s\n", buf);
 256  255          } else {
 257  256                  size_t buflen;
 258  257                  size_t copylen;
 259  258  
 260  259                  buflen = snprintf(zlogp->log, zlogp->loglen, "%s\n", buf);
 261  260                  copylen = MIN(buflen, zlogp->loglen);
 262  261                  zlogp->log += copylen;
 263  262                  zlogp->loglen -= copylen;
 264  263          }
 265  264  }
 266  265  
 267  266  /*
 268  267   * Append src to dest, modifying dest in the process. Prefix src with
 269  268   * a space character if dest is a non-empty string.
 270  269   */
 271  270  static void
 272  271  strnappend(char *dest, size_t n, const char *src)
 273  272  {
 274  273          (void) snprintf(dest, n, "%s%s%s", dest,
 275  274              dest[0] == '\0' ? "" : " ", src);
 276  275  }
 277  276  
 278  277  /*
 279  278   * Since illumos boot arguments are getopt(3c) compatible (see kernel(1m)), we
 280  279   * put the arguments into an argv style array, use getopt to process them,
 281  280   * and put the resultant argument string back into outargs. Non-native brands
 282  281   * may support alternate forms of boot arguments so we must handle that as well.
 283  282   *
 284  283   * During the filtering, we pull out any arguments which are truly "boot"
 285  284   * arguments, leaving only those which are to be passed intact to the
 286  285   * progenitor process.  The one we support at the moment is -i, which
  
    | 
      ↓ open down ↓ | 
    149 lines elided | 
    
      ↑ open up ↑ | 
  
 287  286   * indicates to the kernel which program should be launched as 'init'.
 288  287   *
 289  288   * Except for Z_OK, all other return values are treated as fatal.
 290  289   */
 291  290  static int
 292  291  filter_bootargs(zlog_t *zlogp, const char *inargs, char *outargs,
 293  292      char *init_file)
 294  293  {
 295  294          int argc = 0, argc_save;
 296  295          int i;
 297      -        int err = Z_OK;
      296 +        int err;
 298  297          char *arg, *lasts, **argv = NULL, **argv_save;
 299  298          char zonecfg_args[BOOTARGS_MAX];
 300  299          char scratchargs[BOOTARGS_MAX], *sargs;
 301  300          char scratchopt[3];
 302  301          char c;
 303  302  
 304  303          bzero(outargs, BOOTARGS_MAX);
 305  304  
 306  305          /*
 307  306           * If the user didn't specify transient boot arguments, check
 308  307           * to see if there were any specified in the zone configuration,
 309  308           * and use them if applicable.
 310  309           */
 311  310          if (inargs == NULL || inargs[0] == '\0')  {
      311 +                zone_dochandle_t handle;
      312 +                if ((handle = zonecfg_init_handle()) == NULL) {
      313 +                        zerror(zlogp, B_TRUE,
      314 +                            "getting zone configuration handle");
      315 +                        return (Z_BAD_HANDLE);
      316 +                }
      317 +                err = zonecfg_get_snapshot_handle(zone_name, handle);
      318 +                if (err != Z_OK) {
      319 +                        zerror(zlogp, B_FALSE,
      320 +                            "invalid configuration snapshot");
      321 +                        zonecfg_fini_handle(handle);
      322 +                        return (Z_BAD_HANDLE);
      323 +                }
      324 +
 312  325                  bzero(zonecfg_args, sizeof (zonecfg_args));
 313      -                (void) zonecfg_get_bootargs(snap_hndl, zonecfg_args,
      326 +                (void) zonecfg_get_bootargs(handle, zonecfg_args,
 314  327                      sizeof (zonecfg_args));
 315  328                  inargs = zonecfg_args;
      329 +                zonecfg_fini_handle(handle);
 316  330          }
 317  331  
 318  332          if (strlen(inargs) >= BOOTARGS_MAX) {
 319  333                  zerror(zlogp, B_FALSE, "boot argument string too long");
 320  334                  return (Z_INVAL);
 321  335          }
 322  336  
 323  337          (void) strlcpy(scratchargs, inargs, sizeof (scratchargs));
 324  338          sargs = scratchargs;
 325  339          while ((arg = strtok_r(sargs, " \t", &lasts)) != NULL) {
 326  340                  sargs = NULL;
 327  341                  argc++;
 328  342          }
 329  343  
 330  344          if ((argv = calloc(argc + 1, sizeof (char *))) == NULL) {
 331  345                  zerror(zlogp, B_FALSE, "memory allocation failed");
 332  346                  return (Z_NOMEM);
 333  347          }
 334  348  
 335  349          argv_save = argv;
 336  350          argc_save = argc;
 337  351  
 338  352          (void) strlcpy(scratchargs, inargs, sizeof (scratchargs));
 339  353          sargs = scratchargs;
 340  354          i = 0;
 341  355          while ((arg = strtok_r(sargs, " \t", &lasts)) != NULL) {
 342  356                  sargs = NULL;
 343  357                  if ((argv[i] = strdup(arg)) == NULL) {
 344  358                          err = Z_NOMEM;
 345  359                          zerror(zlogp, B_FALSE, "memory allocation failed");
 346  360                          goto done;
 347  361                  }
 348  362                  i++;
 349  363          }
 350  364  
 351  365          /*
 352  366           * We preserve compatibility with the illumos system boot behavior,
 353  367           * which allows:
 354  368           *
 355  369           *      # reboot kernel/unix -s -m verbose
 356  370           *
 357  371           * In this example, kernel/unix tells the booter what file to boot. The
 358  372           * original intent of this was that we didn't want reboot in a zone to
 359  373           * be gratuitously different, so we would silently ignore the boot
 360  374           * file, if necessary. However, this usage is archaic and has never
 361  375           * been common, since it is impossible to boot a zone onto a different
 362  376           * kernel. Ignoring the first argument breaks for non-native brands
 363  377           * which pass boot arguments in a different style. e.g.
 364  378           *      systemd.log_level=debug
 365  379           * Thus, for backward compatibility we only ignore the first argument
 366  380           * if it appears to be in the illumos form and attempting to specify a
 367  381           * kernel.
 368  382           */
 369  383          if (argv[0] == NULL)
 370  384                  goto done;
 371  385  
 372  386          assert(argv[0][0] != ' ');
 373  387          assert(argv[0][0] != '\t');
 374  388  
 375  389          if (strncmp(argv[0], "kernel/", 7) == 0) {
 376  390                  argv = &argv[1];
 377  391                  argc--;
 378  392          }
 379  393  
 380  394          optind = 0;
 381  395          opterr = 0;
 382  396          err = Z_OK;
 383  397          while ((c = getopt(argc, argv, "fi:m:s")) != -1) {
 384  398                  switch (c) {
 385  399                  case 'i':
 386  400                          /*
 387  401                           * -i is handled by the runtime and is not passed
 388  402                           * along to userland
 389  403                           */
 390  404                          (void) strlcpy(init_file, optarg, MAXPATHLEN);
 391  405                          break;
 392  406                  case 'f':
 393  407                          /* This has already been processed by zoneadm */
 394  408                          break;
 395  409                  case 'm':
 396  410                  case 's':
 397  411                          /* These pass through unmolested */
 398  412                          (void) snprintf(scratchopt, sizeof (scratchopt),
 399  413                              "-%c", c);
 400  414                          strnappend(outargs, BOOTARGS_MAX, scratchopt);
 401  415                          if (optarg != NULL)
 402  416                                  strnappend(outargs, BOOTARGS_MAX, optarg);
 403  417                          break;
 404  418                  case '?':
 405  419                          /*
 406  420                           * If a brand has its own init, we need to pass along
 407  421                           * whatever the user provides. We use the entire
 408  422                           * unknown string here so that we correctly handle
 409  423                           * unknown long options (e.g. --debug).
 410  424                           */
 411  425                          strnappend(outargs, BOOTARGS_MAX, argv[optind - 1]);
 412  426                          break;
 413  427                  }
 414  428          }
 415  429  
 416  430          /*
 417  431           * We need to pass along everything else since we don't know what
 418  432           * the brand's init is expecting. For example, an argument list like:
 419  433           *   --confdir /foo --debug
 420  434           * will cause the getopt parsing to stop at '/foo' but we need to pass
 421  435           * that on, along with the '--debug'. This does mean that we require
 422  436           * any of our known options (-ifms) to preceed the brand-specific ones.
 423  437           */
 424  438          while (optind < argc) {
 425  439                  strnappend(outargs, BOOTARGS_MAX, argv[optind]);
 426  440                  optind++;
 427  441          }
 428  442  
 429  443  done:
 430  444          for (i = 0; i < argc_save; i++) {
 431  445                  if (argv_save[i] != NULL)
 432  446                          free(argv_save[i]);
 433  447          }
 434  448          free(argv_save);
 435  449          return (err);
 436  450  }
 437  451  
 438  452  
 439  453  static int
 440  454  mkzonedir(zlog_t *zlogp)
 441  455  {
 442  456          struct stat st;
 443  457          /*
 444  458           * We must create and lock everyone but root out of ZONES_TMPDIR
 445  459           * since anyone can open any UNIX domain socket, regardless of
 446  460           * its file system permissions.  Sigh...
 447  461           */
 448  462          if (mkdir(ZONES_TMPDIR, S_IRWXU) < 0 && errno != EEXIST) {
 449  463                  zerror(zlogp, B_TRUE, "could not mkdir '%s'", ZONES_TMPDIR);
 450  464                  return (-1);
 451  465          }
 452  466          /* paranoia */
 453  467          if ((stat(ZONES_TMPDIR, &st) < 0) || !S_ISDIR(st.st_mode)) {
 454  468                  zerror(zlogp, B_TRUE, "'%s' is not a directory", ZONES_TMPDIR);
  
    | 
      ↓ open down ↓ | 
    129 lines elided | 
    
      ↑ open up ↑ | 
  
 455  469                  return (-1);
 456  470          }
 457  471          (void) chmod(ZONES_TMPDIR, S_IRWXU);
 458  472          return (0);
 459  473  }
 460  474  
 461  475  /*
 462  476   * Run the brand's pre-state change callback, if it exists.
 463  477   */
 464  478  static int
 465      -brand_prestatechg(zlog_t *zlogp, int state, int cmd, boolean_t debug)
      479 +brand_prestatechg(zlog_t *zlogp, int state, int cmd)
 466  480  {
 467  481          char cmdbuf[2 * MAXPATHLEN];
 468  482          const char *altroot;
 469  483  
 470  484          if (pre_statechg_hook[0] == '\0')
 471  485                  return (0);
 472  486  
 473  487          altroot = zonecfg_get_root();
 474  488          if (snprintf(cmdbuf, sizeof (cmdbuf), "%s %d %d %s", pre_statechg_hook,
 475  489              state, cmd, altroot) > sizeof (cmdbuf))
 476  490                  return (-1);
 477  491  
 478      -        if (do_subproc(zlogp, cmdbuf, NULL, debug) != 0)
      492 +        if (do_subproc(zlogp, cmdbuf, NULL) != 0)
 479  493                  return (-1);
 480  494  
 481  495          return (0);
 482  496  }
 483  497  
 484  498  /*
 485  499   * Run the brand's post-state change callback, if it exists.
 486  500   */
 487  501  static int
 488      -brand_poststatechg(zlog_t *zlogp, int state, int cmd, boolean_t debug)
      502 +brand_poststatechg(zlog_t *zlogp, int state, int cmd)
 489  503  {
 490  504          char cmdbuf[2 * MAXPATHLEN];
 491  505          const char *altroot;
 492  506  
 493  507          if (post_statechg_hook[0] == '\0')
 494  508                  return (0);
 495  509  
 496  510          altroot = zonecfg_get_root();
 497  511          if (snprintf(cmdbuf, sizeof (cmdbuf), "%s %d %d %s", post_statechg_hook,
 498  512              state, cmd, altroot) > sizeof (cmdbuf))
 499  513                  return (-1);
 500  514  
 501      -        if (do_subproc(zlogp, cmdbuf, NULL, debug) != 0)
      515 +        if (do_subproc(zlogp, cmdbuf, NULL) != 0)
 502  516                  return (-1);
 503  517  
 504  518          return (0);
 505  519  }
 506  520  
 507  521  /*
 508  522   * Notify zonestatd of the new zone.  If zonestatd is not running, this
 509  523   * will do nothing.
 510  524   */
 511  525  static void
 512  526  notify_zonestatd(zoneid_t zoneid)
 513  527  {
 514  528          int cmd[2];
 515  529          int fd;
 516  530          door_arg_t params;
 517  531  
 518  532          fd = open(ZS_DOOR_PATH, O_RDONLY);
 519  533          if (fd < 0)
 520  534                  return;
 521  535  
 522  536          cmd[0] = ZSD_CMD_NEW_ZONE;
 523  537          cmd[1] = zoneid;
 524  538          params.data_ptr = (char *)&cmd;
 525  539          params.data_size = sizeof (cmd);
 526  540          params.desc_ptr = NULL;
 527  541          params.desc_num = 0;
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
 528  542          params.rbuf = NULL;
 529  543          params.rsize = NULL;
 530  544          (void) door_call(fd, ¶ms);
 531  545          (void) close(fd);
 532  546  }
 533  547  
 534  548  /*
 535  549   * Bring a zone up to the pre-boot "ready" stage.  The mount_cmd argument is
 536  550   * 'true' if this is being invoked as part of the processing for the "mount"
 537  551   * subcommand.
 538      - *
 539      - * If a scratch zone mount (ALT_MOUNT) is being performed then do not
 540      - * call the state change hooks.
 541  552   */
 542  553  static int
 543      -zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate, boolean_t debug)
      554 +zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate)
 544  555  {
 545  556          int err;
 546      -        boolean_t snapped = B_FALSE;
 547  557  
 548      -        if ((snap_hndl = zonecfg_init_handle()) == NULL) {
 549      -                zerror(zlogp, B_TRUE, "getting zone configuration handle");
 550      -                goto bad;
 551      -        }
      558 +        if (!ALT_MOUNT(mount_cmd) &&
      559 +            brand_prestatechg(zlogp, zstate, Z_READY) != 0)
      560 +                return (-1);
      561 +
 552  562          if ((err = zonecfg_create_snapshot(zone_name)) != Z_OK) {
 553  563                  zerror(zlogp, B_FALSE, "unable to create snapshot: %s",
 554  564                      zonecfg_strerror(err));
 555  565                  goto bad;
 556  566          }
 557      -        snapped = B_TRUE;
 558  567  
 559      -        if (zonecfg_get_snapshot_handle(zone_name, snap_hndl) != Z_OK) {
 560      -                zerror(zlogp, B_FALSE, "invalid configuration snapshot");
      568 +        if ((zone_id = vplat_create(zlogp, mount_cmd)) == -1) {
      569 +                if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
      570 +                        zerror(zlogp, B_FALSE, "destroying snapshot: %s",
      571 +                            zonecfg_strerror(err));
 561  572                  goto bad;
 562  573          }
 563      -
 564      -        if (zone_did == 0)
 565      -                zone_did = zone_get_did(zone_name);
 566      -
 567      -        if (!ALT_MOUNT(mount_cmd) &&
 568      -            brand_prestatechg(zlogp, zstate, Z_READY, debug) != 0)
 569      -                goto bad;
 570      -
 571      -        if ((zone_id = vplat_create(zlogp, mount_cmd, zone_did)) == -1)
 572      -                goto bad;
 573      -
 574  574          if (vplat_bringup(zlogp, mount_cmd, zone_id) != 0) {
 575  575                  bringup_failure_recovery = B_TRUE;
 576      -                (void) vplat_teardown(NULL, (mount_cmd != Z_MNT_BOOT), B_FALSE,
 577      -                    debug);
      576 +                (void) vplat_teardown(NULL, (mount_cmd != Z_MNT_BOOT), B_FALSE);
      577 +                if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
      578 +                        zerror(zlogp, B_FALSE, "destroying snapshot: %s",
      579 +                            zonecfg_strerror(err));
 578  580                  goto bad;
 579  581          }
 580  582  
 581  583          if (!ALT_MOUNT(mount_cmd) &&
 582      -            brand_poststatechg(zlogp, zstate, Z_READY, debug) != 0)
      584 +            brand_poststatechg(zlogp, zstate, Z_READY) != 0)
 583  585                  goto bad;
 584  586  
 585  587          return (0);
 586  588  
 587  589  bad:
 588  590          /*
 589  591           * If something goes wrong, we up the zones's state to the target
 590  592           * state, READY, and then invoke the hook as if we're halting.
 591  593           */
 592  594          if (!ALT_MOUNT(mount_cmd))
 593      -                (void) brand_poststatechg(zlogp, ZONE_STATE_READY, Z_HALT,
 594      -                    debug);
 595      -
 596      -        if (snapped)
 597      -                if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
 598      -                        zerror(zlogp, B_FALSE, "destroying snapshot: %s",
 599      -                            zonecfg_strerror(err));
 600      -        zonecfg_fini_handle(snap_hndl);
 601      -        snap_hndl = NULL;
      595 +                (void) brand_poststatechg(zlogp, ZONE_STATE_READY, Z_HALT);
 602  596          return (-1);
 603  597  }
 604  598  
 605  599  int
 606  600  init_template(void)
 607  601  {
 608  602          int fd;
 609  603          int err = 0;
 610  604  
 611  605          fd = open64(CTFS_ROOT "/process/template", O_RDWR);
 612  606          if (fd == -1)
 613  607                  return (-1);
 614  608  
 615  609          /*
 616  610           * For now, zoneadmd doesn't do anything with the contract.
 617  611           * Deliver no events, don't inherit, and allow it to be orphaned.
 618  612           */
 619  613          err |= ct_tmpl_set_critical(fd, 0);
 620  614          err |= ct_tmpl_set_informative(fd, 0);
 621  615          err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR);
 622  616          err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT);
 623  617          if (err || ct_tmpl_activate(fd)) {
 624  618                  (void) close(fd);
 625  619                  return (-1);
 626  620          }
 627  621  
 628  622          return (fd);
 629  623  }
 630  624  
 631  625  typedef struct fs_callback {
 632  626          zlog_t          *zlogp;
 633  627          zoneid_t        zoneid;
 634  628          boolean_t       mount_cmd;
 635  629  } fs_callback_t;
 636  630  
 637  631  static int
 638  632  mount_early_fs(void *data, const char *spec, const char *dir,
 639  633      const char *fstype, const char *opt)
 640  634  {
 641  635          zlog_t *zlogp = ((fs_callback_t *)data)->zlogp;
 642  636          zoneid_t zoneid = ((fs_callback_t *)data)->zoneid;
 643  637          boolean_t mount_cmd = ((fs_callback_t *)data)->mount_cmd;
 644  638          char rootpath[MAXPATHLEN];
 645  639          pid_t child;
 646  640          int child_status;
 647  641          int tmpl_fd;
 648  642          int rv;
 649  643          ctid_t ct;
 650  644  
 651  645          /* determine the zone rootpath */
 652  646          if (mount_cmd) {
 653  647                  char luroot[MAXPATHLEN];
 654  648  
 655  649                  (void) snprintf(luroot, sizeof (luroot), "%s/lu", zonepath);
 656  650                  resolve_lofs(zlogp, luroot, sizeof (luroot));
 657  651                  (void) strlcpy(rootpath, luroot, sizeof (rootpath));
 658  652          } else {
 659  653                  if (zone_get_rootpath(zone_name,
 660  654                      rootpath, sizeof (rootpath)) != Z_OK) {
 661  655                          zerror(zlogp, B_FALSE, "unable to determine zone root");
 662  656                          return (-1);
 663  657                  }
 664  658          }
 665  659  
 666  660          if ((rv = valid_mount_path(zlogp, rootpath, spec, dir, fstype)) < 0) {
 667  661                  zerror(zlogp, B_FALSE, "%s%s is not a valid mount point",
 668  662                      rootpath, dir);
 669  663                  return (-1);
 670  664          } else if (rv > 0) {
 671  665                  /* The mount point path doesn't exist, create it now. */
 672  666                  if (make_one_dir(zlogp, rootpath, dir,
 673  667                      DEFAULT_DIR_MODE, DEFAULT_DIR_USER,
 674  668                      DEFAULT_DIR_GROUP) != 0) {
 675  669                          zerror(zlogp, B_FALSE, "failed to create mount point");
 676  670                          return (-1);
 677  671                  }
 678  672  
 679  673                  /*
 680  674                   * Now this might seem weird, but we need to invoke
 681  675                   * valid_mount_path() again.  Why?  Because it checks
 682  676                   * to make sure that the mount point path is canonical,
 683  677                   * which it can only do if the path exists, so now that
 684  678                   * we've created the path we have to verify it again.
 685  679                   */
 686  680                  if ((rv = valid_mount_path(zlogp, rootpath, spec, dir,
 687  681                      fstype)) < 0) {
 688  682                          zerror(zlogp, B_FALSE,
 689  683                              "%s%s is not a valid mount point", rootpath, dir);
 690  684                          return (-1);
 691  685                  }
 692  686          }
 693  687  
 694  688          if ((tmpl_fd = init_template()) == -1) {
 695  689                  zerror(zlogp, B_TRUE, "failed to create contract");
 696  690                  return (-1);
 697  691          }
 698  692  
 699  693          if ((child = fork()) == -1) {
 700  694                  (void) ct_tmpl_clear(tmpl_fd);
 701  695                  (void) close(tmpl_fd);
 702  696                  zerror(zlogp, B_TRUE, "failed to fork");
 703  697                  return (-1);
 704  698  
 705  699          } else if (child == 0) {        /* child */
 706  700                  char opt_buf[MAX_MNTOPT_STR];
 707  701                  int optlen = 0;
 708  702                  int mflag = MS_DATA;
 709  703                  int i;
 710  704                  int ret;
 711  705  
 712  706                  (void) ct_tmpl_clear(tmpl_fd);
 713  707                  /*
 714  708                   * Even though there are no procs running in the zone, we
 715  709                   * do this for paranoia's sake.
 716  710                   */
 717  711                  (void) closefrom(0);
 718  712  
 719  713                  if (zone_enter(zoneid) == -1) {
 720  714                          _exit(errno);
 721  715                  }
 722  716                  if (opt != NULL) {
 723  717                          /*
 724  718                           * The mount() system call is incredibly annoying.
 725  719                           * If options are specified, we need to copy them
 726  720                           * into a temporary buffer since the mount() system
 727  721                           * call will overwrite the options string.  It will
 728  722                           * also fail if the new option string it wants to
 729  723                           * write is bigger than the one we passed in, so
 730  724                           * you must pass in a buffer of the maximum possible
 731  725                           * option string length.  sigh.
 732  726                           */
 733  727                          (void) strlcpy(opt_buf, opt, sizeof (opt_buf));
 734  728                          opt = opt_buf;
 735  729                          optlen = MAX_MNTOPT_STR;
 736  730                          mflag = MS_OPTIONSTR;
 737  731                  }
 738  732  
 739  733                  /*
 740  734                   * There is an obscure race condition which can cause mount
 741  735                   * to return EBUSY. This happens for example on the mount
 742  736                   * of the zone's /etc/svc/volatile file system if there is
 743  737                   * a GZ process running svcs -Z, which will touch the
 744  738                   * mountpoint, just as we're trying to do the mount. To cope
 745  739                   * with this, we retry up to 3 times to let this transient
 746  740                   * process get out of the way.
 747  741                   */
 748  742                  for (i = 0; i < 3; i++) {
 749  743                          ret = 0;
 750  744                          if (mount(spec, dir, mflag, fstype, NULL, 0, opt,
 751  745                              optlen) != 0)
 752  746                                  ret = errno;
 753  747                          if (ret != EBUSY)
 754  748                                  break;
 755  749                          (void) sleep(1);
 756  750                  }
 757  751                  _exit(ret);
 758  752          }
 759  753  
 760  754          /* parent */
 761  755          if (contract_latest(&ct) == -1)
 762  756                  ct = -1;
 763  757          (void) ct_tmpl_clear(tmpl_fd);
 764  758          (void) close(tmpl_fd);
 765  759          if (waitpid(child, &child_status, 0) != child) {
 766  760                  /* unexpected: we must have been signalled */
 767  761                  (void) contract_abandon_id(ct);
 768  762                  return (-1);
 769  763          }
 770  764          (void) contract_abandon_id(ct);
 771  765          if (WEXITSTATUS(child_status) != 0) {
  
    | 
      ↓ open down ↓ | 
    160 lines elided | 
    
      ↑ open up ↑ | 
  
 772  766                  errno = WEXITSTATUS(child_status);
 773  767                  zerror(zlogp, B_TRUE, "mount of %s failed", dir);
 774  768                  return (-1);
 775  769          }
 776  770  
 777  771          return (0);
 778  772  }
 779  773  
 780  774  /*
 781  775   * env variable name format
 782      - *      _ZONECFG_{resource name}_{identifying attr. name}_{property name}
 783      - * Any dashes (-) in the property names are replaced with underscore (_).
      776 + *      _ZONECFG;{resource name};{identifying attr. name};{property name}
 784  777   */
 785  778  static void
 786  779  set_zonecfg_env(char *rsrc, char *attr, char *name, char *val)
 787  780  {
 788  781          char *p;
 789  782          /* Enough for maximal name, rsrc + attr, & slop for ZONECFG & _'s */
 790  783          char nm[2 * MAXNAMELEN + 32];
 791  784  
 792  785          if (attr == NULL)
 793  786                  (void) snprintf(nm, sizeof (nm), "_ZONECFG_%s_%s", rsrc,
 794  787                      name);
 795  788          else
 796  789                  (void) snprintf(nm, sizeof (nm), "_ZONECFG_%s_%s_%s", rsrc,
 797  790                      attr, name);
 798  791  
 799  792          p = nm;
 800  793          while ((p = strchr(p, '-')) != NULL)
 801  794                  *p++ = '_';
 802  795  
 803  796          (void) setenv(nm, val, 1);
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
 804  797  }
 805  798  
 806  799  /*
 807  800   * Export zonecfg network and device properties into environment for the boot
 808  801   * and state change hooks.
 809  802   * If debug is true, export the brand hook debug env. variable as well.
 810  803   *
 811  804   * We could export more of the config in the future, as necessary.
 812  805   */
 813  806  static int
 814      -setup_subproc_env(boolean_t debug)
      807 +setup_subproc_env()
 815  808  {
 816  809          int res;
      810 +        zone_dochandle_t handle;
 817  811          struct zone_nwiftab ntab;
 818  812          struct zone_devtab dtab;
 819      -        struct zone_attrtab atab;
 820  813          char net_resources[MAXNAMELEN * 2];
 821  814          char dev_resources[MAXNAMELEN * 2];
 822  815  
 823      -        /* snap_hndl is null when called through the set_brand_env code path */
 824      -        if (snap_hndl == NULL)
 825      -                return (Z_OK);
      816 +        if ((handle = zonecfg_init_handle()) == NULL)
      817 +                exit(Z_NOMEM);
 826  818  
 827      -        net_resources[0] = '\0';
 828      -        if ((res = zonecfg_setnwifent(snap_hndl)) != Z_OK)
      819 +        if ((res = zonecfg_get_handle(zone_name, handle)) != Z_OK)
 829  820                  goto done;
 830  821  
 831      -        while (zonecfg_getnwifent(snap_hndl, &ntab) == Z_OK) {
      822 +        if ((res = zonecfg_setnwifent(handle)) != Z_OK)
      823 +                goto done;
      824 +
      825 +        while (zonecfg_getnwifent(handle, &ntab) == Z_OK) {
 832  826                  struct zone_res_attrtab *rap;
 833  827                  char *phys;
 834  828  
 835  829                  phys = ntab.zone_nwif_physical;
 836  830  
 837  831                  (void) strlcat(net_resources, phys, sizeof (net_resources));
 838  832                  (void) strlcat(net_resources, " ", sizeof (net_resources));
 839  833  
 840  834                  set_zonecfg_env(RSRC_NET, phys, "physical", phys);
 841  835  
 842  836                  set_zonecfg_env(RSRC_NET, phys, "address",
 843  837                      ntab.zone_nwif_address);
 844  838                  set_zonecfg_env(RSRC_NET, phys, "allowed-address",
 845  839                      ntab.zone_nwif_allowed_address);
 846  840                  set_zonecfg_env(RSRC_NET, phys, "defrouter",
 847  841                      ntab.zone_nwif_defrouter);
  
    | 
      ↓ open down ↓ | 
    6 lines elided | 
    
      ↑ open up ↑ | 
  
 848  842                  set_zonecfg_env(RSRC_NET, phys, "global-nic",
 849  843                      ntab.zone_nwif_gnic);
 850  844                  set_zonecfg_env(RSRC_NET, phys, "mac-addr", ntab.zone_nwif_mac);
 851  845                  set_zonecfg_env(RSRC_NET, phys, "vlan-id",
 852  846                      ntab.zone_nwif_vlan_id);
 853  847  
 854  848                  for (rap = ntab.zone_nwif_attrp; rap != NULL;
 855  849                      rap = rap->zone_res_attr_next)
 856  850                          set_zonecfg_env(RSRC_NET, phys, rap->zone_res_attr_name,
 857  851                              rap->zone_res_attr_value);
 858      -                nwifent_free_attrs(&ntab);
 859  852          }
 860  853  
 861      -        (void) setenv("_ZONECFG_net_resources", net_resources, 1);
      854 +        (void) zonecfg_endnwifent(handle);
 862  855  
 863      -        (void) zonecfg_endnwifent(snap_hndl);
 864      -
 865      -        if ((res = zonecfg_setdevent(snap_hndl)) != Z_OK)
      856 +        if ((res = zonecfg_setdevent(handle)) != Z_OK)
 866  857                  goto done;
 867  858  
 868      -        while (zonecfg_getdevent(snap_hndl, &dtab) == Z_OK) {
      859 +        while (zonecfg_getdevent(handle, &dtab) == Z_OK) {
 869  860                  struct zone_res_attrtab *rap;
 870  861                  char *match;
 871  862  
 872  863                  match = dtab.zone_dev_match;
 873  864  
 874  865                  (void) strlcat(dev_resources, match, sizeof (dev_resources));
 875  866                  (void) strlcat(dev_resources, " ", sizeof (dev_resources));
 876  867  
 877  868                  for (rap = dtab.zone_dev_attrp; rap != NULL;
 878  869                      rap = rap->zone_res_attr_next)
 879  870                          set_zonecfg_env(RSRC_DEV, match,
 880  871                              rap->zone_res_attr_name, rap->zone_res_attr_value);
 881  872          }
 882  873  
 883      -        (void) zonecfg_enddevent(snap_hndl);
      874 +        (void) zonecfg_enddevent(handle);
 884  875  
 885      -        if ((res = zonecfg_setattrent(snap_hndl)) != Z_OK)
 886      -                goto done;
 887      -
 888      -        while (zonecfg_getattrent(snap_hndl, &atab) == Z_OK) {
 889      -                set_zonecfg_env("attr", NULL, atab.zone_attr_name,
 890      -                    atab.zone_attr_value);
 891      -        }
 892      -
 893      -        (void) zonecfg_endattrent(snap_hndl);
 894      -
 895      -        if (debug)
 896      -                (void) setenv("_ZONEADMD_brand_debug", "1", 1);
 897      -        else
 898      -                (void) setenv("_ZONEADMD_brand_debug", "", 1);
 899      -
 900  876          res = Z_OK;
 901  877  
 902  878  done:
      879 +        zonecfg_fini_handle(handle);
 903  880          return (res);
 904  881  }
 905  882  
 906      -void
 907      -nwifent_free_attrs(struct zone_nwiftab *np)
 908      -{
 909      -        struct zone_res_attrtab *rap;
 910      -
 911      -        for (rap = np->zone_nwif_attrp; rap != NULL; ) {
 912      -                struct zone_res_attrtab *tp = rap;
 913      -
 914      -                rap = rap->zone_res_attr_next;
 915      -                free(tp);
 916      -        }
 917      -}
 918      -
 919  883  /*
 920  884   * If retstr is not NULL, the output of the subproc is returned in the str,
 921  885   * otherwise it is output using zerror().  Any memory allocated for retstr
 922  886   * should be freed by the caller.
 923  887   */
 924  888  int
 925      -do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr, boolean_t debug)
      889 +do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr)
 926  890  {
 927  891          char buf[1024];         /* arbitrary large amount */
 928  892          char *inbuf;
 929  893          FILE *file;
 930  894          int status;
 931  895          int rd_cnt;
 932  896  
 933  897          if (retstr != NULL) {
 934  898                  if ((*retstr = malloc(1024)) == NULL) {
 935  899                          zerror(zlogp, B_FALSE, "out of memory");
 936  900                          return (-1);
 937  901                  }
 938  902                  inbuf = *retstr;
 939  903                  rd_cnt = 0;
 940  904          } else {
 941  905                  inbuf = buf;
 942  906          }
 943  907  
 944      -        if (setup_subproc_env(debug) != Z_OK) {
      908 +        if (setup_subproc_env() != Z_OK) {
 945  909                  zerror(zlogp, B_FALSE, "failed to setup environment");
 946  910                  return (-1);
 947  911          }
 948  912  
 949  913          file = popen(cmdbuf, "r");
 950  914          if (file == NULL) {
 951  915                  zerror(zlogp, B_TRUE, "could not launch: %s", cmdbuf);
 952  916                  return (-1);
 953  917          }
 954  918  
 955  919          while (fgets(inbuf, 1024, file) != NULL) {
 956  920                  if (retstr == NULL) {
 957      -                        if (zlogp != &logsys) {
 958      -                                int last = strlen(inbuf) - 1;
 959      -
 960      -                                if (inbuf[last] == '\n')
 961      -                                        inbuf[last] = '\0';
      921 +                        if (zlogp != &logsys)
 962  922                                  zerror(zlogp, B_FALSE, "%s", inbuf);
 963      -                        }
 964  923                  } else {
 965  924                          char *p;
 966  925  
 967  926                          rd_cnt += 1024 - 1;
 968  927                          if ((p = realloc(*retstr, rd_cnt + 1024)) == NULL) {
 969  928                                  zerror(zlogp, B_FALSE, "out of memory");
 970  929                                  (void) pclose(file);
 971  930                                  return (-1);
 972  931                          }
 973  932  
 974  933                          *retstr = p;
 975  934                          inbuf = *retstr + rd_cnt;
 976  935                  }
 977  936          }
 978  937          status = pclose(file);
 979  938  
 980  939          if (WIFSIGNALED(status)) {
 981  940                  zerror(zlogp, B_FALSE, "%s unexpectedly terminated due to "
 982  941                      "signal %d", cmdbuf, WTERMSIG(status));
 983  942                  return (-1);
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
 984  943          }
 985  944          assert(WIFEXITED(status));
 986  945          if (WEXITSTATUS(status) == ZEXIT_EXEC) {
 987  946                  zerror(zlogp, B_FALSE, "failed to exec %s", cmdbuf);
 988  947                  return (-1);
 989  948          }
 990  949          return (WEXITSTATUS(status));
 991  950  }
 992  951  
 993  952  /*
 994      - * Get the path for this zone's init(1M) (or equivalent) process. First look
 995      - * for a zone-specific init-name attr, then get it from the brand.
 996      - */
 997      -static int
 998      -get_initname(brand_handle_t bh, char *initname, int len)
 999      -{
1000      -        struct zone_attrtab a;
1001      -
1002      -        bzero(&a, sizeof (a));
1003      -        (void) strlcpy(a.zone_attr_name, "init-name",
1004      -            sizeof (a.zone_attr_name));
1005      -
1006      -        if (zonecfg_lookup_attr(snap_hndl, &a) == Z_OK) {
1007      -                (void) strlcpy(initname, a.zone_attr_value, len);
1008      -                return (0);
1009      -        }
1010      -
1011      -        return (brand_get_initname(bh, initname, len));
1012      -}
1013      -
1014      -/*
1015      - * Get the restart-init flag for this zone's init(1M) (or equivalent) process.
1016      - * First look for a zone-specific restart-init attr, then get it from the brand.
1017      - */
1018      -static boolean_t
1019      -restartinit(brand_handle_t bh)
1020      -{
1021      -        struct zone_attrtab a;
1022      -
1023      -        bzero(&a, sizeof (a));
1024      -        (void) strlcpy(a.zone_attr_name, "restart-init",
1025      -            sizeof (a.zone_attr_name));
1026      -
1027      -        if (zonecfg_lookup_attr(snap_hndl, &a) == Z_OK) {
1028      -                if (strcmp(a.zone_attr_value, "false") == 0)
1029      -                        return (B_FALSE);
1030      -                return (B_TRUE);
1031      -        }
1032      -
1033      -        return (brand_restartinit(bh));
1034      -}
1035      -
1036      -/*
1037  953   * Get the app-svc-dependent flag for this zone's init process. This is a
1038  954   * zone-specific attr which controls the type of contract we create for the
1039  955   * zone's init. When true, the contract will include CT_PR_EV_EXIT in the fatal
1040  956   * set, so that when any service which is in the same contract exits, the init
1041  957   * application will be terminated.
      958 + *
      959 + * We use the global "snap_hndl", so no parameters get passed here.
1042  960   */
1043  961  static boolean_t
1044      -is_app_svc_dep(brand_handle_t bh)
      962 +is_app_svc_dep(void)
1045  963  {
1046  964          struct zone_attrtab a;
1047  965  
1048  966          bzero(&a, sizeof (a));
1049  967          (void) strlcpy(a.zone_attr_name, "app-svc-dependent",
1050  968              sizeof (a.zone_attr_name));
1051  969  
1052  970          if (zonecfg_lookup_attr(snap_hndl, &a) == Z_OK &&
1053  971              strcmp(a.zone_attr_value, "true") == 0) {
1054  972                  return (B_TRUE);
1055  973          }
1056  974  
1057  975          return (B_FALSE);
1058  976  }
1059  977  
1060  978  static int
1061      -zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate, boolean_t debug)
      979 +zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate)
1062  980  {
1063  981          zoneid_t zoneid;
1064  982          struct stat st;
1065  983          char rpath[MAXPATHLEN], initpath[MAXPATHLEN], init_file[MAXPATHLEN];
1066  984          char nbootargs[BOOTARGS_MAX];
1067  985          char cmdbuf[MAXPATHLEN];
1068  986          fs_callback_t cb;
1069  987          brand_handle_t bh;
1070  988          zone_iptype_t iptype;
1071  989          dladm_status_t status;
1072  990          char errmsg[DLADM_STRSIZE];
1073  991          int err;
1074  992          boolean_t restart_init;
1075  993          boolean_t app_svc_dep;
1076  994  
1077      -        if (brand_prestatechg(zlogp, zstate, Z_BOOT, debug) != 0)
      995 +        if (brand_prestatechg(zlogp, zstate, Z_BOOT) != 0)
1078  996                  return (-1);
1079  997  
1080  998          if ((zoneid = getzoneidbyname(zone_name)) == -1) {
1081  999                  zerror(zlogp, B_TRUE, "unable to get zoneid");
1082 1000                  goto bad;
1083 1001          }
1084 1002  
1085 1003          cb.zlogp = zlogp;
1086 1004          cb.zoneid = zoneid;
1087 1005          cb.mount_cmd = B_FALSE;
1088 1006  
1089 1007          /* Get a handle to the brand info for this zone */
1090 1008          if ((bh = brand_open(brand_name)) == NULL) {
1091 1009                  zerror(zlogp, B_FALSE, "unable to determine zone brand");
1092 1010                  goto bad;
1093 1011          }
1094 1012  
1095 1013          /*
1096 1014           * Get the list of filesystems to mount from the brand
1097 1015           * configuration.  These mounts are done via a thread that will
1098 1016           * enter the zone, so they are done from within the context of the
1099 1017           * zone.
1100 1018           */
1101 1019          if (brand_platform_iter_mounts(bh, mount_early_fs, &cb) != 0) {
1102 1020                  zerror(zlogp, B_FALSE, "unable to mount filesystems");
1103 1021                  brand_close(bh);
1104 1022                  goto bad;
1105 1023          }
1106 1024  
1107 1025          /*
1108 1026           * Get the brand's boot callback if it exists.
1109 1027           */
  
    | 
      ↓ open down ↓ | 
    22 lines elided | 
    
      ↑ open up ↑ | 
  
1110 1028          (void) strcpy(cmdbuf, EXEC_PREFIX);
1111 1029          if (brand_get_boot(bh, zone_name, zonepath, cmdbuf + EXEC_LEN,
1112 1030              sizeof (cmdbuf) - EXEC_LEN) != 0) {
1113 1031                  zerror(zlogp, B_FALSE,
1114 1032                      "unable to determine branded zone's boot callback");
1115 1033                  brand_close(bh);
1116 1034                  goto bad;
1117 1035          }
1118 1036  
1119 1037          /* Get the path for this zone's init(1M) (or equivalent) process.  */
1120      -        if (get_initname(bh, init_file, MAXPATHLEN) != 0) {
     1038 +        if (brand_get_initname(bh, init_file, MAXPATHLEN) != 0) {
1121 1039                  zerror(zlogp, B_FALSE,
1122 1040                      "unable to determine zone's init(1M) location");
1123 1041                  brand_close(bh);
1124 1042                  goto bad;
1125 1043          }
1126 1044  
1127      -        /* See if we should restart init if it dies. */
1128      -        restart_init = restartinit(bh);
     1045 +        /* See if this zone's brand should restart init if it dies. */
     1046 +        restart_init = brand_restartinit(bh);
1129 1047  
1130 1048          /*
1131 1049           * See if we need to setup contract dependencies between the zone's
1132 1050           * primary application and any of its services.
1133 1051           */
1134      -        app_svc_dep = is_app_svc_dep(bh);
     1052 +        app_svc_dep = is_app_svc_dep();
1135 1053  
1136 1054          brand_close(bh);
1137 1055  
1138 1056          err = filter_bootargs(zlogp, bootargs, nbootargs, init_file);
1139 1057          if (err != Z_OK)
1140 1058                  goto bad;
1141 1059  
1142 1060          assert(init_file[0] != '\0');
1143 1061  
1144 1062          /*
1145 1063           * Try to anticipate possible problems: If possible, make sure init is
1146 1064           * executable.
1147 1065           */
1148 1066          if (zone_get_rootpath(zone_name, rpath, sizeof (rpath)) != Z_OK) {
1149 1067                  zerror(zlogp, B_FALSE, "unable to determine zone root");
  
    | 
      ↓ open down ↓ | 
    5 lines elided | 
    
      ↑ open up ↑ | 
  
1150 1068                  goto bad;
1151 1069          }
1152 1070  
1153 1071          (void) snprintf(initpath, sizeof (initpath), "%s%s", rpath, init_file);
1154 1072  
1155 1073          if (lstat(initpath, &st) == -1) {
1156 1074                  zerror(zlogp, B_TRUE, "could not stat %s", initpath);
1157 1075                  goto bad;
1158 1076          }
1159 1077  
1160      -        if ((st.st_mode & S_IFMT) == S_IFLNK) {
1161      -                /* symlink, we'll have to wait and resolve when we boot */
1162      -        } else if ((st.st_mode & S_IXUSR) == 0) {
     1078 +        /*
     1079 +         * If a symlink, we'll have to wait and resolve when we boot,
     1080 +         * otherwise check the executable bits now.
     1081 +         */
     1082 +        if ((st.st_mode & S_IFMT) != S_IFLNK && (st.st_mode & S_IXUSR) == 0) {
1163 1083                  zerror(zlogp, B_FALSE, "%s is not executable", initpath);
1164 1084                  goto bad;
1165 1085          }
1166 1086  
1167 1087          /*
1168 1088           * Exclusive stack zones interact with the dlmgmtd running in the
1169 1089           * global zone.  dladm_zone_boot() tells dlmgmtd that this zone is
1170 1090           * booting, and loads its datalinks from the zone's datalink
1171 1091           * configuration file.
1172 1092           */
1173 1093          if (vplat_get_iptype(zlogp, &iptype) == 0 && iptype == ZS_EXCLUSIVE) {
1174 1094                  status = dladm_zone_boot(dld_handle, zoneid);
1175 1095                  if (status != DLADM_STATUS_OK) {
1176 1096                          zerror(zlogp, B_FALSE, "unable to load zone datalinks: "
1177 1097                              " %s", dladm_status2str(status, errmsg));
  
    | 
      ↓ open down ↓ | 
    5 lines elided | 
    
      ↑ open up ↑ | 
  
1178 1098                          goto bad;
1179 1099                  }
1180 1100          }
1181 1101  
1182 1102          /*
1183 1103           * If there is a brand 'boot' callback, execute it now to give the
1184 1104           * brand one last chance to do any additional setup before the zone
1185 1105           * is booted.
1186 1106           */
1187 1107          if ((strlen(cmdbuf) > EXEC_LEN) &&
1188      -            (do_subproc(zlogp, cmdbuf, NULL, debug) != Z_OK)) {
     1108 +            (do_subproc(zlogp, cmdbuf, NULL) != Z_OK)) {
1189 1109                  zerror(zlogp, B_FALSE, "%s failed", cmdbuf);
1190 1110                  goto bad;
1191 1111          }
1192 1112  
1193 1113          if (zone_setattr(zoneid, ZONE_ATTR_INITNAME, init_file, 0) == -1) {
1194 1114                  zerror(zlogp, B_TRUE, "could not set zone boot file");
1195 1115                  goto bad;
1196 1116          }
1197 1117  
1198 1118          if (zone_setattr(zoneid, ZONE_ATTR_BOOTARGS, nbootargs, 0) == -1) {
1199 1119                  zerror(zlogp, B_TRUE, "could not set zone boot arguments");
1200 1120                  goto bad;
1201 1121          }
1202 1122  
1203 1123          if (!restart_init && zone_setattr(zoneid, ZONE_ATTR_INITNORESTART,
1204 1124              NULL, 0) == -1) {
1205 1125                  zerror(zlogp, B_TRUE, "could not set zone init-no-restart");
1206 1126                  goto bad;
1207 1127          }
1208 1128  
1209 1129          if (app_svc_dep && zone_setattr(zoneid, ZONE_ATTR_APP_SVC_CT,
1210 1130              (void *)B_TRUE, sizeof (boolean_t)) == -1) {
1211 1131                  zerror(zlogp, B_TRUE, "could not set zone app-die");
1212 1132                  goto bad;
1213 1133          }
1214 1134  
1215 1135          /*
  
    | 
      ↓ open down ↓ | 
    17 lines elided | 
    
      ↑ open up ↑ | 
  
1216 1136           * Inform zonestatd of a new zone so that it can install a door for
1217 1137           * the zone to contact it.
1218 1138           */
1219 1139          notify_zonestatd(zone_id);
1220 1140  
1221 1141          if (zone_boot(zoneid) == -1) {
1222 1142                  zerror(zlogp, B_TRUE, "unable to boot zone");
1223 1143                  goto bad;
1224 1144          }
1225 1145  
1226      -        if (brand_poststatechg(zlogp, zstate, Z_BOOT, debug) != 0)
     1146 +        if (brand_poststatechg(zlogp, zstate, Z_BOOT) != 0)
1227 1147                  goto bad;
1228 1148  
1229 1149          /* Startup a thread to perform zfd logging/tty svc for the zone. */
1230 1150          create_log_thread(zlogp, zone_id);
1231 1151  
1232 1152          /* Startup a thread to perform memory capping for the zone. */
1233 1153          create_mcap_thread(zlogp, zone_id);
1234 1154  
1235 1155          return (0);
1236 1156  
1237 1157  bad:
1238 1158          /*
1239 1159           * If something goes wrong, we up the zones's state to the target
1240 1160           * state, RUNNING, and then invoke the hook as if we're halting.
1241 1161           */
1242      -        (void) brand_poststatechg(zlogp, ZONE_STATE_RUNNING, Z_HALT, debug);
     1162 +        (void) brand_poststatechg(zlogp, ZONE_STATE_RUNNING, Z_HALT);
1243 1163  
1244 1164          return (-1);
1245 1165  }
1246 1166  
1247 1167  static int
1248      -zone_halt(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting, int zstate,
1249      -    boolean_t debug)
     1168 +zone_halt(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting, int zstate)
1250 1169  {
1251 1170          int err;
1252 1171  
1253      -        /*
1254      -         * If performing a scratch zone unmount then do not call the
1255      -         * state change hooks.
1256      -         */
1257 1172          if (unmount_cmd == B_FALSE &&
1258      -            brand_prestatechg(zlogp, zstate, Z_HALT, debug) != 0)
     1173 +            brand_prestatechg(zlogp, zstate, Z_HALT) != 0)
1259 1174                  return (-1);
1260 1175  
1261 1176          /* Shutting down, stop the memcap thread */
1262 1177          destroy_mcap_thread();
1263 1178  
1264      -        if (vplat_teardown(zlogp, unmount_cmd, rebooting, debug) != 0) {
     1179 +        if (vplat_teardown(zlogp, unmount_cmd, rebooting) != 0) {
1265 1180                  if (!bringup_failure_recovery)
1266 1181                          zerror(zlogp, B_FALSE, "unable to destroy zone");
1267 1182                  destroy_log_thread();
1268 1183                  return (-1);
1269 1184          }
1270 1185  
1271 1186          /* Shut down is done, stop the log thread */
1272 1187          destroy_log_thread();
1273 1188  
1274 1189          if (unmount_cmd == B_FALSE &&
1275      -            brand_poststatechg(zlogp, zstate, Z_HALT, debug) != 0)
     1190 +            brand_poststatechg(zlogp, zstate, Z_HALT) != 0)
1276 1191                  return (-1);
1277 1192  
1278 1193          if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK)
1279 1194                  zerror(zlogp, B_FALSE, "destroying snapshot: %s",
1280 1195                      zonecfg_strerror(err));
1281 1196  
1282      -        zonecfg_fini_handle(snap_hndl);
1283      -        snap_hndl = NULL;
1284      -
1285 1197          return (0);
1286 1198  }
1287 1199  
1288 1200  static int
1289 1201  zone_graceful_shutdown(zlog_t *zlogp)
1290 1202  {
1291 1203          zoneid_t zoneid;
1292 1204          pid_t child;
1293 1205          char cmdbuf[MAXPATHLEN];
1294 1206          brand_handle_t bh = NULL;
1295 1207          ctid_t ct;
1296 1208          int tmpl_fd;
1297 1209          int child_status;
1298 1210  
1299 1211          if (shutdown_in_progress) {
1300 1212                  zerror(zlogp, B_FALSE, "shutdown already in progress");
1301 1213                  return (-1);
1302 1214          }
1303 1215  
1304 1216          if ((zoneid = getzoneidbyname(zone_name)) == -1) {
1305 1217                  zerror(zlogp, B_TRUE, "unable to get zoneid");
1306 1218                  return (-1);
1307 1219          }
1308 1220  
1309 1221          /* Get a handle to the brand info for this zone */
1310 1222          if ((bh = brand_open(brand_name)) == NULL) {
1311 1223                  zerror(zlogp, B_FALSE, "unable to determine zone brand");
1312 1224                  return (-1);
1313 1225          }
1314 1226  
1315 1227          /*
1316 1228           * If there is a brand 'shutdown' callback, execute it now to give the
1317 1229           * brand a chance to cleanup any custom configuration.
1318 1230           */
1319 1231          (void) strcpy(cmdbuf, EXEC_PREFIX);
1320 1232          if (brand_get_shutdown(bh, zone_name, zonepath, cmdbuf + EXEC_LEN,
1321 1233              sizeof (cmdbuf) - EXEC_LEN) != 0 || strlen(cmdbuf) <= EXEC_LEN) {
1322 1234                  (void) strcat(cmdbuf, SHUTDOWN_DEFAULT);
1323 1235          }
1324 1236          brand_close(bh);
1325 1237  
1326 1238          if ((tmpl_fd = init_template()) == -1) {
1327 1239                  zerror(zlogp, B_TRUE, "failed to create contract");
1328 1240                  return (-1);
1329 1241          }
1330 1242  
1331 1243          if ((child = fork()) == -1) {
1332 1244                  (void) ct_tmpl_clear(tmpl_fd);
1333 1245                  (void) close(tmpl_fd);
1334 1246                  zerror(zlogp, B_TRUE, "failed to fork");
1335 1247                  return (-1);
1336 1248          } else if (child == 0) {
1337 1249                  (void) ct_tmpl_clear(tmpl_fd);
1338 1250                  if (zone_enter(zoneid) == -1) {
1339 1251                          _exit(errno);
1340 1252                  }
1341 1253                  _exit(execl("/bin/sh", "sh", "-c", cmdbuf, (char *)NULL));
1342 1254          }
1343 1255  
1344 1256          if (contract_latest(&ct) == -1)
1345 1257                  ct = -1;
1346 1258          (void) ct_tmpl_clear(tmpl_fd);
1347 1259          (void) close(tmpl_fd);
1348 1260  
1349 1261          if (waitpid(child, &child_status, 0) != child) {
1350 1262                  /* unexpected: we must have been signalled */
1351 1263                  (void) contract_abandon_id(ct);
1352 1264                  return (-1);
1353 1265          }
1354 1266  
1355 1267          (void) contract_abandon_id(ct);
1356 1268          if (WEXITSTATUS(child_status) != 0) {
1357 1269                  errno = WEXITSTATUS(child_status);
1358 1270                  zerror(zlogp, B_FALSE, "unable to shutdown zone");
1359 1271                  return (-1);
1360 1272          }
1361 1273  
1362 1274          shutdown_in_progress = B_TRUE;
1363 1275  
1364 1276          return (0);
1365 1277  }
1366 1278  
1367 1279  static int
1368 1280  zone_wait_shutdown(zlog_t *zlogp)
1369 1281  {
1370 1282          zone_state_t zstate;
1371 1283          uint64_t *tm = NULL;
1372 1284          scf_simple_prop_t *prop = NULL;
1373 1285          int timeout;
1374 1286          int tries;
1375 1287          int rc = -1;
1376 1288  
1377 1289          /* Get default stop timeout from SMF framework */
1378 1290          timeout = SHUTDOWN_WAIT;
1379 1291          if ((prop = scf_simple_prop_get(NULL, SHUTDOWN_FMRI, "stop",
1380 1292              SCF_PROPERTY_TIMEOUT)) != NULL) {
1381 1293                  if ((tm = scf_simple_prop_next_count(prop)) != NULL) {
1382 1294                          if (tm != 0)
1383 1295                                  timeout = *tm;
1384 1296                  }
1385 1297                  scf_simple_prop_free(prop);
1386 1298          }
1387 1299  
1388 1300          /* allow time for zone to shutdown cleanly */
1389 1301          for (tries = 0; tries < timeout; tries ++) {
1390 1302                  (void) sleep(1);
1391 1303                  if (zone_get_state(zone_name, &zstate) == Z_OK &&
1392 1304                      zstate == ZONE_STATE_INSTALLED) {
1393 1305                          rc = 0;
1394 1306                          break;
1395 1307                  }
1396 1308          }
1397 1309  
1398 1310          if (rc != 0)
1399 1311                  zerror(zlogp, B_FALSE, "unable to shutdown zone");
1400 1312  
1401 1313          shutdown_in_progress = B_FALSE;
1402 1314  
1403 1315          return (rc);
1404 1316  }
1405 1317  
1406 1318  
1407 1319  
1408 1320  /*
1409 1321   * Generate AUE_zone_state for a command that boots a zone.
1410 1322   */
1411 1323  static void
1412 1324  audit_put_record(zlog_t *zlogp, ucred_t *uc, int return_val,
1413 1325      char *new_state)
1414 1326  {
1415 1327          adt_session_data_t      *ah;
1416 1328          adt_event_data_t        *event;
1417 1329          int                     pass_fail, fail_reason;
1418 1330  
1419 1331          if (!adt_audit_enabled())
1420 1332                  return;
1421 1333  
1422 1334          if (return_val == 0) {
1423 1335                  pass_fail = ADT_SUCCESS;
1424 1336                  fail_reason = ADT_SUCCESS;
1425 1337          } else {
1426 1338                  pass_fail = ADT_FAILURE;
1427 1339                  fail_reason = ADT_FAIL_VALUE_PROGRAM;
1428 1340          }
1429 1341  
1430 1342          if (adt_start_session(&ah, NULL, 0)) {
1431 1343                  zerror(zlogp, B_TRUE, gettext("audit failure."));
1432 1344                  return;
1433 1345          }
1434 1346          if (adt_set_from_ucred(ah, uc, ADT_NEW)) {
1435 1347                  zerror(zlogp, B_TRUE, gettext("audit failure."));
1436 1348                  (void) adt_end_session(ah);
1437 1349                  return;
1438 1350          }
1439 1351  
1440 1352          event = adt_alloc_event(ah, ADT_zone_state);
1441 1353          if (event == NULL) {
1442 1354                  zerror(zlogp, B_TRUE, gettext("audit failure."));
1443 1355                  (void) adt_end_session(ah);
1444 1356                  return;
1445 1357          }
1446 1358          event->adt_zone_state.zonename = zone_name;
1447 1359          event->adt_zone_state.new_state = new_state;
1448 1360  
1449 1361          if (adt_put_event(event, pass_fail, fail_reason))
1450 1362                  zerror(zlogp, B_TRUE, gettext("audit failure."));
1451 1363  
1452 1364          adt_free_event(event);
1453 1365  
1454 1366          (void) adt_end_session(ah);
1455 1367  }
1456 1368  
1457 1369  /*
1458 1370   * Log the exit time and status of the zone's init process into
1459 1371   * {zonepath}/lastexited. If the zone shutdown normally, the exit status will
1460 1372   * be -1, otherwise it will be the exit status as described in wait.3c.
1461 1373   * If the zone is configured to restart init, then nothing will be logged if
1462 1374   * init exits unexpectedly (the kernel will never upcall in this case).
1463 1375   */
1464 1376  static void
1465 1377  log_init_exit(int status)
1466 1378  {
1467 1379          char p[MAXPATHLEN];
1468 1380          char buf[128];
1469 1381          struct timeval t;
1470 1382          int fd;
1471 1383  
1472 1384          if (snprintf(p, sizeof (p), "%s/lastexited", zonepath) > sizeof (p))
1473 1385                  return;
1474 1386          if (gettimeofday(&t, NULL) != 0)
1475 1387                  return;
1476 1388          if (snprintf(buf, sizeof (buf), "%ld.%ld %d\n", t.tv_sec, t.tv_usec,
1477 1389              status) > sizeof (buf))
1478 1390                  return;
1479 1391          if ((fd = open(p, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0)
1480 1392                  return;
1481 1393  
1482 1394          (void) write(fd, buf, strlen(buf));
1483 1395  
1484 1396          (void) close(fd);
1485 1397  }
1486 1398  
1487 1399  /*
1488 1400   * The main routine for the door server that deals with zone state transitions.
1489 1401   */
  
    | 
      ↓ open down ↓ | 
    195 lines elided | 
    
      ↑ open up ↑ | 
  
1490 1402  /* ARGSUSED */
1491 1403  static void
1492 1404  server(void *cookie, char *args, size_t alen, door_desc_t *dp,
1493 1405      uint_t n_desc)
1494 1406  {
1495 1407          ucred_t *uc = NULL;
1496 1408          const priv_set_t *eset;
1497 1409  
1498 1410          zone_state_t zstate;
1499 1411          zone_cmd_t cmd;
1500      -        boolean_t debug;
1501 1412          int init_status;
1502 1413          zone_cmd_arg_t *zargp;
1503 1414  
1504      -        boolean_t kernelcall = B_TRUE;
     1415 +        boolean_t kernelcall;
1505 1416  
1506 1417          int rval = -1;
1507 1418          uint64_t uniqid;
1508 1419          zoneid_t zoneid = -1;
1509 1420          zlog_t zlog;
1510 1421          zlog_t *zlogp;
1511 1422          zone_cmd_rval_t *rvalp;
1512 1423          size_t rlen = getpagesize(); /* conservative */
1513 1424          fs_callback_t cb;
1514 1425          brand_handle_t bh;
1515 1426          boolean_t wait_shut = B_FALSE;
1516 1427  
1517 1428          /* LINTED E_BAD_PTR_CAST_ALIGN */
1518 1429          zargp = (zone_cmd_arg_t *)args;
1519 1430  
1520 1431          /*
1521 1432           * When we get the door unref message, we've fdetach'd the door, and
1522 1433           * it is time for us to shut down zoneadmd.
1523 1434           */
1524 1435          if (zargp == DOOR_UNREF_DATA) {
1525 1436                  /*
1526 1437                   * See comment at end of main() for info on the last rites.
1527 1438                   */
1528 1439                  exit(0);
1529 1440          }
1530 1441  
1531 1442          if (zargp == NULL) {
1532 1443                  (void) door_return(NULL, 0, 0, 0);
1533 1444          }
1534 1445  
1535 1446          rvalp = alloca(rlen);
1536 1447          bzero(rvalp, rlen);
1537 1448          zlog.logfile = NULL;
1538 1449          zlog.buflen = zlog.loglen = rlen - sizeof (zone_cmd_rval_t) + 1;
1539 1450          zlog.buf = rvalp->errbuf;
1540 1451          zlog.log = zlog.buf;
1541 1452          /* defer initialization of zlog.locale until after credential check */
1542 1453          zlogp = &zlog;
1543 1454  
  
    | 
      ↓ open down ↓ | 
    29 lines elided | 
    
      ↑ open up ↑ | 
  
1544 1455          if (alen != sizeof (zone_cmd_arg_t)) {
1545 1456                  /*
1546 1457                   * This really shouldn't be happening.
1547 1458                   */
1548 1459                  zerror(&logsys, B_FALSE, "argument size (%d bytes) "
1549 1460                      "unexpected (expected %d bytes)", alen,
1550 1461                      sizeof (zone_cmd_arg_t));
1551 1462                  goto out;
1552 1463          }
1553 1464          cmd = zargp->cmd;
1554      -        debug = zargp->debug;
1555 1465          init_status = zargp->status;
1556 1466  
1557 1467          if (door_ucred(&uc) != 0) {
1558 1468                  zerror(&logsys, B_TRUE, "door_ucred");
1559 1469                  goto out;
1560 1470          }
1561 1471          eset = ucred_getprivset(uc, PRIV_EFFECTIVE);
1562 1472          if (ucred_getzoneid(uc) != GLOBAL_ZONEID ||
1563 1473              (eset != NULL ? !priv_ismember(eset, PRIV_SYS_CONFIG) :
1564 1474              ucred_geteuid(uc) != 0)) {
1565 1475                  zerror(&logsys, B_FALSE, "insufficient privileges");
1566 1476                  goto out;
1567 1477          }
1568 1478  
1569 1479          kernelcall = ucred_getpid(uc) == 0;
1570 1480  
1571 1481          /*
1572 1482           * This is safe because we only use a zlog_t throughout the
1573 1483           * duration of a door call; i.e., by the time the pointer
1574 1484           * might become invalid, the door call would be over.
1575 1485           */
1576 1486          zlog.locale = kernelcall ? DEFAULT_LOCALE : zargp->locale;
1577 1487  
1578 1488          (void) mutex_lock(&lock);
1579 1489  
1580 1490          /*
1581 1491           * Once we start to really die off, we don't want more connections.
1582 1492           */
1583 1493          if (in_death_throes) {
1584 1494                  (void) mutex_unlock(&lock);
1585 1495                  ucred_free(uc);
1586 1496                  (void) door_return(NULL, 0, 0, 0);
1587 1497                  thr_exit(NULL);
1588 1498          }
1589 1499  
1590 1500          /*
1591 1501           * Check for validity of command.
1592 1502           */
1593 1503          if (cmd != Z_READY && cmd != Z_BOOT && cmd != Z_FORCEBOOT &&
1594 1504              cmd != Z_REBOOT && cmd != Z_SHUTDOWN && cmd != Z_HALT &&
1595 1505              cmd != Z_NOTE_UNINSTALLING && cmd != Z_MOUNT &&
1596 1506              cmd != Z_FORCEMOUNT && cmd != Z_UNMOUNT) {
1597 1507                  zerror(&logsys, B_FALSE, "invalid command %d", (int)cmd);
1598 1508                  goto out;
1599 1509          }
1600 1510  
1601 1511          if (kernelcall && (cmd != Z_HALT && cmd != Z_REBOOT)) {
1602 1512                  /*
1603 1513                   * Can't happen
1604 1514                   */
1605 1515                  zerror(&logsys, B_FALSE, "received unexpected kernel upcall %d",
1606 1516                      cmd);
1607 1517                  goto out;
1608 1518          }
1609 1519          /*
1610 1520           * We ignore the possibility of someone calling zone_create(2)
1611 1521           * explicitly; all requests must come through zoneadmd.
1612 1522           */
1613 1523          if (zone_get_state(zone_name, &zstate) != Z_OK) {
1614 1524                  /*
1615 1525                   * Something terribly wrong happened
1616 1526                   */
1617 1527                  zerror(&logsys, B_FALSE, "unable to determine state of zone");
1618 1528                  goto out;
1619 1529          }
1620 1530  
1621 1531          if (kernelcall) {
1622 1532                  /*
1623 1533                   * Kernel-initiated requests may lose their validity if the
1624 1534                   * zone_t the kernel was referring to has gone away.
1625 1535                   */
1626 1536                  if ((zoneid = getzoneidbyname(zone_name)) == -1 ||
1627 1537                      zone_getattr(zoneid, ZONE_ATTR_UNIQID, &uniqid,
1628 1538                      sizeof (uniqid)) == -1 || uniqid != zargp->uniqid) {
1629 1539                          /*
1630 1540                           * We're not talking about the same zone. The request
1631 1541                           * must have arrived too late.  Return error.
1632 1542                           */
1633 1543                          rval = -1;
1634 1544                          goto out;
1635 1545                  }
1636 1546                  zlogp = &logsys;        /* Log errors to syslog */
1637 1547          }
1638 1548  
1639 1549          /*
1640 1550           * If we are being asked to forcibly mount or boot a zone, we
1641 1551           * pretend that an INCOMPLETE zone is actually INSTALLED.
1642 1552           */
1643 1553          if (zstate == ZONE_STATE_INCOMPLETE &&
1644 1554              (cmd == Z_FORCEBOOT || cmd == Z_FORCEMOUNT))
1645 1555                  zstate = ZONE_STATE_INSTALLED;
1646 1556  
1647 1557          switch (zstate) {
1648 1558          case ZONE_STATE_CONFIGURED:
1649 1559          case ZONE_STATE_INCOMPLETE:
1650 1560                  /*
1651 1561                   * Not our area of expertise; we just print a nice message
  
    | 
      ↓ open down ↓ | 
    87 lines elided | 
    
      ↑ open up ↑ | 
  
1652 1562                   * and die off.
1653 1563                   */
1654 1564                  zerror(zlogp, B_FALSE,
1655 1565                      "%s operation is invalid for zones in state '%s'",
1656 1566                      z_cmd_name(cmd), zone_state_str(zstate));
1657 1567                  break;
1658 1568  
1659 1569          case ZONE_STATE_INSTALLED:
1660 1570                  switch (cmd) {
1661 1571                  case Z_READY:
1662      -                        rval = zone_ready(zlogp, Z_MNT_BOOT, zstate, debug);
     1572 +                        rval = zone_ready(zlogp, Z_MNT_BOOT, zstate);
1663 1573                          if (rval == 0)
1664 1574                                  eventstream_write(Z_EVT_ZONE_READIED);
1665 1575                          zcons_statechanged();
1666 1576                          break;
1667 1577                  case Z_BOOT:
1668 1578                  case Z_FORCEBOOT:
1669 1579                          eventstream_write(Z_EVT_ZONE_BOOTING);
1670      -                        if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate,
1671      -                            debug)) == 0) {
     1580 +                        if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate))
     1581 +                            == 0) {
1672 1582                                  rval = zone_bootup(zlogp, zargp->bootbuf,
1673      -                                    zstate, debug);
     1583 +                                    zstate);
1674 1584                          }
1675 1585                          audit_put_record(zlogp, uc, rval, "boot");
1676 1586                          zcons_statechanged();
1677 1587                          if (rval != 0) {
1678 1588                                  bringup_failure_recovery = B_TRUE;
1679 1589                                  (void) zone_halt(zlogp, B_FALSE, B_FALSE,
1680      -                                    zstate, debug);
     1590 +                                    zstate);
1681 1591                                  eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1682 1592                          }
1683 1593                          break;
1684 1594                  case Z_SHUTDOWN:
1685 1595                  case Z_HALT:
1686 1596                          if (kernelcall) /* Invalid; can't happen */
1687 1597                                  abort();
1688 1598                          /*
1689 1599                           * We could have two clients racing to halt this
1690 1600                           * zone; the second client loses, but his request
1691 1601                           * doesn't fail, since the zone is now in the desired
1692 1602                           * state.
1693 1603                           */
1694 1604                          zerror(zlogp, B_FALSE, "zone is already halted");
1695 1605                          rval = 0;
1696 1606                          break;
1697 1607                  case Z_REBOOT:
1698 1608                          if (kernelcall) /* Invalid; can't happen */
1699 1609                                  abort();
1700 1610                          zerror(zlogp, B_FALSE, "%s operation is invalid "
1701 1611                              "for zones in state '%s'", z_cmd_name(cmd),
1702 1612                              zone_state_str(zstate));
1703 1613                          rval = -1;
1704 1614                          break;
1705 1615                  case Z_NOTE_UNINSTALLING:
1706 1616                          if (kernelcall) /* Invalid; can't happen */
1707 1617                                  abort();
1708 1618                          /*
1709 1619                           * Tell the console to print out a message about this.
1710 1620                           * Once it does, we will be in_death_throes.
1711 1621                           */
1712 1622                          eventstream_write(Z_EVT_ZONE_UNINSTALLING);
1713 1623                          break;
1714 1624                  case Z_MOUNT:
1715 1625                  case Z_FORCEMOUNT:
1716 1626                          if (kernelcall) /* Invalid; can't happen */
1717 1627                                  abort();
1718 1628                          if (!zone_isnative && !zone_iscluster &&
1719 1629                              !zone_islabeled) {
1720 1630                                  /*
1721 1631                                   * -U mounts the zone without lofs mounting
  
    | 
      ↓ open down ↓ | 
    31 lines elided | 
    
      ↑ open up ↑ | 
  
1722 1632                                   * zone file systems back into the scratch
1723 1633                                   * zone.  This is required when mounting
1724 1634                                   * non-native branded zones.
1725 1635                                   */
1726 1636                                  (void) strlcpy(zargp->bootbuf, "-U",
1727 1637                                      BOOTARGS_MAX);
1728 1638                          }
1729 1639  
1730 1640                          rval = zone_ready(zlogp,
1731 1641                              strcmp(zargp->bootbuf, "-U") == 0 ?
1732      -                            Z_MNT_UPDATE : Z_MNT_SCRATCH, zstate, debug);
     1642 +                            Z_MNT_UPDATE : Z_MNT_SCRATCH, zstate);
1733 1643                          if (rval != 0)
1734 1644                                  break;
1735 1645  
1736 1646                          eventstream_write(Z_EVT_ZONE_READIED);
1737 1647  
1738 1648                          /*
1739 1649                           * Get a handle to the default brand info.
1740 1650                           * We must always use the default brand file system
1741 1651                           * list when mounting the zone.
1742 1652                           */
1743 1653                          if ((bh = brand_open(default_brand)) == NULL) {
1744 1654                                  rval = -1;
1745 1655                                  break;
1746 1656                          }
1747 1657  
1748 1658                          /*
1749 1659                           * Get the list of filesystems to mount from
1750 1660                           * the brand configuration.  These mounts are done
1751 1661                           * via a thread that will enter the zone, so they
1752 1662                           * are done from within the context of the zone.
1753 1663                           */
1754 1664                          cb.zlogp = zlogp;
1755 1665                          cb.zoneid = zone_id;
1756 1666                          cb.mount_cmd = B_TRUE;
1757 1667                          rval = brand_platform_iter_mounts(bh,
1758 1668                              mount_early_fs, &cb);
1759 1669  
1760 1670                          brand_close(bh);
1761 1671  
1762 1672                          /*
1763 1673                           * Ordinarily, /dev/fd would be mounted inside the zone
1764 1674                           * by svc:/system/filesystem/usr:default, but since
1765 1675                           * we're not booting the zone, we need to do this
1766 1676                           * manually.
1767 1677                           */
1768 1678                          if (rval == 0)
1769 1679                                  rval = mount_early_fs(&cb,
1770 1680                                      "fd", "/dev/fd", "fd", NULL);
1771 1681                          break;
1772 1682                  case Z_UNMOUNT:
1773 1683                          if (kernelcall) /* Invalid; can't happen */
1774 1684                                  abort();
1775 1685                          zerror(zlogp, B_FALSE, "zone is already unmounted");
1776 1686                          rval = 0;
1777 1687                          break;
1778 1688                  }
1779 1689                  break;
1780 1690  
1781 1691          case ZONE_STATE_READY:
1782 1692                  switch (cmd) {
1783 1693                  case Z_READY:
  
    | 
      ↓ open down ↓ | 
    41 lines elided | 
    
      ↑ open up ↑ | 
  
1784 1694                          /*
1785 1695                           * We could have two clients racing to ready this
1786 1696                           * zone; the second client loses, but his request
1787 1697                           * doesn't fail, since the zone is now in the desired
1788 1698                           * state.
1789 1699                           */
1790 1700                          zerror(zlogp, B_FALSE, "zone is already ready");
1791 1701                          rval = 0;
1792 1702                          break;
1793 1703                  case Z_BOOT:
1794      -                case Z_FORCEBOOT:
1795 1704                          (void) strlcpy(boot_args, zargp->bootbuf,
1796 1705                              sizeof (boot_args));
1797 1706                          eventstream_write(Z_EVT_ZONE_BOOTING);
1798      -                        rval = zone_bootup(zlogp, zargp->bootbuf, zstate,
1799      -                            debug);
     1707 +                        rval = zone_bootup(zlogp, zargp->bootbuf, zstate);
1800 1708                          audit_put_record(zlogp, uc, rval, "boot");
1801 1709                          zcons_statechanged();
1802 1710                          if (rval != 0) {
1803 1711                                  bringup_failure_recovery = B_TRUE;
1804 1712                                  (void) zone_halt(zlogp, B_FALSE, B_TRUE,
1805      -                                    zstate, debug);
     1713 +                                    zstate);
1806 1714                                  eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1807 1715                          }
1808 1716                          boot_args[0] = '\0';
1809 1717                          break;
1810 1718                  case Z_HALT:
1811 1719                          if (kernelcall) /* Invalid; can't happen */
1812 1720                                  abort();
1813      -                        if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate,
1814      -                            debug)) != 0)
     1721 +                        if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate))
     1722 +                            != 0)
1815 1723                                  break;
1816 1724                          zcons_statechanged();
1817 1725                          eventstream_write(Z_EVT_ZONE_HALTED);
1818 1726                          break;
1819 1727                  case Z_SHUTDOWN:
1820 1728                  case Z_REBOOT:
1821 1729                  case Z_NOTE_UNINSTALLING:
1822 1730                  case Z_MOUNT:
1823      -                case Z_FORCEMOUNT:
1824 1731                  case Z_UNMOUNT:
1825 1732                          if (kernelcall) /* Invalid; can't happen */
1826 1733                                  abort();
1827 1734                          zerror(zlogp, B_FALSE, "%s operation is invalid "
1828 1735                              "for zones in state '%s'", z_cmd_name(cmd),
1829 1736                              zone_state_str(zstate));
1830 1737                          rval = -1;
1831 1738                          break;
1832 1739                  }
1833 1740                  break;
1834 1741  
1835 1742          case ZONE_STATE_MOUNTED:
1836 1743                  switch (cmd) {
1837 1744                  case Z_UNMOUNT:
1838 1745                          if (kernelcall) /* Invalid; can't happen */
1839 1746                                  abort();
1840      -                        rval = zone_halt(zlogp, B_TRUE, B_FALSE, zstate, debug);
     1747 +                        rval = zone_halt(zlogp, B_TRUE, B_FALSE, zstate);
1841 1748                          if (rval == 0) {
1842 1749                                  eventstream_write(Z_EVT_ZONE_HALTED);
1843 1750                                  (void) sema_post(&scratch_sem);
1844 1751                          }
1845 1752                          break;
1846 1753                  default:
1847 1754                          if (kernelcall) /* Invalid; can't happen */
1848 1755                                  abort();
1849 1756                          zerror(zlogp, B_FALSE, "%s operation is invalid "
1850 1757                              "for zones in state '%s'", z_cmd_name(cmd),
1851 1758                              zone_state_str(zstate));
  
    | 
      ↓ open down ↓ | 
    1 lines elided | 
    
      ↑ open up ↑ | 
  
1852 1759                          rval = -1;
1853 1760                          break;
1854 1761                  }
1855 1762                  break;
1856 1763  
1857 1764          case ZONE_STATE_RUNNING:
1858 1765          case ZONE_STATE_SHUTTING_DOWN:
1859 1766          case ZONE_STATE_DOWN:
1860 1767                  switch (cmd) {
1861 1768                  case Z_READY:
1862      -                        if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate,
1863      -                            debug)) != 0)
     1769 +                        if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
     1770 +                            != 0)
1864 1771                                  break;
1865 1772                          zcons_statechanged();
1866      -                        if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate,
1867      -                            debug)) == 0)
     1773 +                        if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) == 0)
1868 1774                                  eventstream_write(Z_EVT_ZONE_READIED);
1869 1775                          else
1870 1776                                  eventstream_write(Z_EVT_ZONE_HALTED);
1871 1777                          break;
1872 1778                  case Z_BOOT:
1873      -                case Z_FORCEBOOT:
1874 1779                          /*
1875 1780                           * We could have two clients racing to boot this
1876 1781                           * zone; the second client loses, but his request
1877 1782                           * doesn't fail, since the zone is now in the desired
1878 1783                           * state.
1879 1784                           */
1880 1785                          zerror(zlogp, B_FALSE, "zone is already booted");
1881 1786                          rval = 0;
1882 1787                          break;
1883 1788                  case Z_HALT:
1884 1789                          if (kernelcall) {
1885 1790                                  log_init_exit(init_status);
1886 1791                          } else {
1887 1792                                  log_init_exit(-1);
1888 1793                          }
1889      -                        if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate,
1890      -                            debug)) != 0)
     1794 +                        if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate))
     1795 +                            != 0)
1891 1796                                  break;
1892 1797                          eventstream_write(Z_EVT_ZONE_HALTED);
1893 1798                          zcons_statechanged();
1894 1799                          break;
1895 1800                  case Z_REBOOT:
1896 1801                          (void) strlcpy(boot_args, zargp->bootbuf,
1897 1802                              sizeof (boot_args));
1898 1803                          eventstream_write(Z_EVT_ZONE_REBOOTING);
1899      -                        if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate,
1900      -                            debug)) != 0) {
     1804 +                        if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate))
     1805 +                            != 0) {
1901 1806                                  eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1902 1807                                  boot_args[0] = '\0';
1903 1808                                  break;
1904 1809                          }
1905 1810                          zcons_statechanged();
1906      -                        if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate,
1907      -                            debug)) != 0) {
     1811 +                        if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) !=
     1812 +                            0) {
1908 1813                                  eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1909 1814                                  boot_args[0] = '\0';
1910 1815                                  break;
1911 1816                          }
1912      -                        rval = zone_bootup(zlogp, zargp->bootbuf, zstate,
1913      -                            debug);
     1817 +                        rval = zone_bootup(zlogp, zargp->bootbuf, zstate);
1914 1818                          audit_put_record(zlogp, uc, rval, "reboot");
1915 1819                          if (rval != 0) {
1916 1820                                  (void) zone_halt(zlogp, B_FALSE, B_TRUE,
1917      -                                    zstate, debug);
     1821 +                                    zstate);
1918 1822                                  eventstream_write(Z_EVT_ZONE_BOOTFAILED);
1919 1823                          }
1920 1824                          boot_args[0] = '\0';
1921 1825                          break;
1922 1826                  case Z_SHUTDOWN:
1923 1827                          if ((rval = zone_graceful_shutdown(zlogp)) == 0) {
1924 1828                                  wait_shut = B_TRUE;
1925 1829                          }
1926 1830                          break;
1927 1831                  case Z_NOTE_UNINSTALLING:
1928 1832                  case Z_MOUNT:
1929      -                case Z_FORCEMOUNT:
1930 1833                  case Z_UNMOUNT:
1931 1834                          zerror(zlogp, B_FALSE, "%s operation is invalid "
1932 1835                              "for zones in state '%s'", z_cmd_name(cmd),
1933 1836                              zone_state_str(zstate));
1934 1837                          rval = -1;
1935 1838                          break;
1936 1839                  }
1937 1840                  break;
1938 1841          default:
1939 1842                  abort();
1940 1843          }
1941 1844  
1942 1845          /*
1943 1846           * Because the state of the zone may have changed, we make sure
1944 1847           * to wake the console poller, which is in charge of initiating
1945 1848           * the shutdown procedure as necessary.
1946 1849           */
1947 1850          eventstream_write(Z_EVT_NULL);
1948 1851  
1949 1852  out:
1950 1853          (void) mutex_unlock(&lock);
1951 1854  
1952 1855          /* Wait for the Z_SHUTDOWN commands to complete */
1953 1856          if (wait_shut)
1954 1857                  rval = zone_wait_shutdown(zlogp);
1955 1858  
1956 1859          if (kernelcall) {
1957 1860                  rvalp = NULL;
1958 1861                  rlen = 0;
1959 1862          } else {
1960 1863                  rvalp->rval = rval;
1961 1864          }
1962 1865          if (uc != NULL)
1963 1866                  ucred_free(uc);
1964 1867          (void) door_return((char *)rvalp, rlen, NULL, 0);
1965 1868          thr_exit(NULL);
1966 1869  }
1967 1870  
1968 1871  static int
1969 1872  setup_door(zlog_t *zlogp)
1970 1873  {
1971 1874          if ((zone_door = door_create(server, NULL,
1972 1875              DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) < 0) {
1973 1876                  zerror(zlogp, B_TRUE, "%s failed", "door_create");
1974 1877                  return (-1);
1975 1878          }
1976 1879          (void) fdetach(zone_door_path);
1977 1880  
1978 1881          if (fattach(zone_door, zone_door_path) != 0) {
1979 1882                  zerror(zlogp, B_TRUE, "fattach to %s failed", zone_door_path);
1980 1883                  (void) door_revoke(zone_door);
1981 1884                  (void) fdetach(zone_door_path);
1982 1885                  zone_door = -1;
1983 1886                  return (-1);
1984 1887          }
1985 1888          return (0);
1986 1889  }
1987 1890  
1988 1891  /*
1989 1892   * zoneadm(1m) will start zoneadmd if it thinks it isn't running; this
1990 1893   * is where zoneadmd itself will check to see that another instance of
1991 1894   * zoneadmd isn't already controlling this zone.
1992 1895   *
1993 1896   * The idea here is that we want to open the path to which we will
1994 1897   * attach our door, lock it, and then make sure that no-one has beat us
1995 1898   * to fattach(3c)ing onto it.
1996 1899   *
1997 1900   * fattach(3c) is really a mount, so there are actually two possible
1998 1901   * vnodes we could be dealing with.  Our strategy is as follows:
1999 1902   *
2000 1903   * - If the file we opened is a regular file (common case):
2001 1904   *      There is no fattach(3c)ed door, so we have a chance of becoming
2002 1905   *      the managing zoneadmd. We attempt to lock the file: if it is
2003 1906   *      already locked, that means someone else raced us here, so we
2004 1907   *      lose and give up.  zoneadm(1m) will try to contact the zoneadmd
2005 1908   *      that beat us to it.
2006 1909   *
2007 1910   * - If the file we opened is a namefs file:
2008 1911   *      This means there is already an established door fattach(3c)'ed
2009 1912   *      to the rendezvous path.  We've lost the race, so we give up.
2010 1913   *      Note that in this case we also try to grab the file lock, and
2011 1914   *      will succeed in acquiring it since the vnode locked by the
2012 1915   *      "winning" zoneadmd was a regular one, and the one we locked was
2013 1916   *      the fattach(3c)'ed door node.  At any rate, no harm is done, and
2014 1917   *      we just return to zoneadm(1m) which knows to retry.
2015 1918   */
2016 1919  static int
2017 1920  make_daemon_exclusive(zlog_t *zlogp)
2018 1921  {
2019 1922          int doorfd = -1;
2020 1923          int err, ret = -1;
2021 1924          struct stat st;
2022 1925          struct flock flock;
2023 1926          zone_state_t zstate;
2024 1927  
2025 1928  top:
2026 1929          if ((err = zone_get_state(zone_name, &zstate)) != Z_OK) {
2027 1930                  zerror(zlogp, B_FALSE, "failed to get zone state: %s",
2028 1931                      zonecfg_strerror(err));
2029 1932                  goto out;
2030 1933          }
2031 1934          if ((doorfd = open(zone_door_path, O_CREAT|O_RDWR,
2032 1935              S_IREAD|S_IWRITE)) < 0) {
2033 1936                  zerror(zlogp, B_TRUE, "failed to open %s", zone_door_path);
2034 1937                  goto out;
2035 1938          }
2036 1939          if (fstat(doorfd, &st) < 0) {
2037 1940                  zerror(zlogp, B_TRUE, "failed to stat %s", zone_door_path);
2038 1941                  goto out;
2039 1942          }
2040 1943          /*
2041 1944           * Lock the file to synchronize with other zoneadmd
2042 1945           */
2043 1946          flock.l_type = F_WRLCK;
2044 1947          flock.l_whence = SEEK_SET;
2045 1948          flock.l_start = (off_t)0;
2046 1949          flock.l_len = (off_t)0;
2047 1950          if (fcntl(doorfd, F_SETLK, &flock) < 0) {
2048 1951                  /*
2049 1952                   * Someone else raced us here and grabbed the lock file
2050 1953                   * first.  A warning here is inappropriate since nothing
2051 1954                   * went wrong.
2052 1955                   */
2053 1956                  goto out;
2054 1957          }
2055 1958  
2056 1959          if (strcmp(st.st_fstype, "namefs") == 0) {
2057 1960                  struct door_info info;
2058 1961  
2059 1962                  /*
2060 1963                   * There is already something fattach()'ed to this file.
2061 1964                   * Lets see what the door is up to.
2062 1965                   */
2063 1966                  if (door_info(doorfd, &info) == 0 && info.di_target != -1) {
2064 1967                          /*
2065 1968                           * Another zoneadmd process seems to be in
2066 1969                           * control of the situation and we don't need to
2067 1970                           * be here.  A warning here is inappropriate
2068 1971                           * since nothing went wrong.
2069 1972                           *
2070 1973                           * If the door has been revoked, the zoneadmd
2071 1974                           * process currently managing the zone is going
2072 1975                           * away.  We'll return control to zoneadm(1m)
2073 1976                           * which will try again (by which time zoneadmd
2074 1977                           * will hopefully have exited).
2075 1978                           */
2076 1979                          goto out;
2077 1980                  }
2078 1981  
2079 1982                  /*
2080 1983                   * If we got this far, there's a fattach(3c)'ed door
2081 1984                   * that belongs to a process that has exited, which can
2082 1985                   * happen if the previous zoneadmd died unexpectedly.
2083 1986                   *
2084 1987                   * Let user know that something is amiss, but that we can
2085 1988                   * recover; if the zone is in the installed state, then don't
2086 1989                   * message, since having a running zoneadmd isn't really
2087 1990                   * expected/needed.  We want to keep occurences of this message
2088 1991                   * limited to times when zoneadmd is picking back up from a
2089 1992                   * zoneadmd that died while the zone was in some non-trivial
2090 1993                   * state.
2091 1994                   */
2092 1995                  if (zstate > ZONE_STATE_INSTALLED) {
2093 1996                          static zoneid_t zid;
2094 1997  
2095 1998                          zerror(zlogp, B_FALSE,
2096 1999                              "zone '%s': WARNING: zone is in state '%s', but "
2097 2000                              "zoneadmd does not appear to be available; "
2098 2001                              "restarted zoneadmd to recover.",
2099 2002                              zone_name, zone_state_str(zstate));
2100 2003  
2101 2004                          /*
2102 2005                           * Startup a thread to perform the zfd logging/tty svc
2103 2006                           * and a thread to perform memory capping for the
2104 2007                           * zone. zlogp won't be valid for much longer so use
2105 2008                           * logsys.
2106 2009                           */
2107 2010                          if ((zid = getzoneidbyname(zone_name)) != -1) {
2108 2011                                  create_log_thread(&logsys, zid);
2109 2012                                  create_mcap_thread(&logsys, zid);
2110 2013                          }
2111 2014  
2112 2015                          /* recover the global configuration snapshot */
2113 2016                          if (snap_hndl == NULL) {
2114 2017                                  if ((snap_hndl = zonecfg_init_handle())
2115 2018                                      == NULL ||
2116 2019                                      zonecfg_create_snapshot(zone_name)
2117 2020                                      != Z_OK ||
2118 2021                                      zonecfg_get_snapshot_handle(zone_name,
2119 2022                                      snap_hndl) != Z_OK) {
2120 2023                                          zerror(zlogp, B_FALSE, "recovering "
2121 2024                                              "zone configuration handle");
2122 2025                                          goto out;
2123 2026                                  }
2124 2027                          }
2125 2028                  }
2126 2029  
2127 2030                  (void) fdetach(zone_door_path);
  
    | 
      ↓ open down ↓ | 
    188 lines elided | 
    
      ↑ open up ↑ | 
  
2128 2031                  (void) close(doorfd);
2129 2032                  goto top;
2130 2033          }
2131 2034          ret = 0;
2132 2035  out:
2133 2036          (void) close(doorfd);
2134 2037          return (ret);
2135 2038  }
2136 2039  
2137 2040  /*
2138      - * Run the query hook with the 'env' parameter.  It should return a
2139      - * string of tab-delimited key-value pairs, each of which should be set
2140      - * in the environment.
2141      - *
2142      - * Because the env_vars string values become part of the environment, the
2143      - * string is static and we don't free it.
2144      - *
2145      - * This function is always called before zoneadmd forks and makes itself
2146      - * exclusive, so it is possible there could more than one instance of zoneadmd
2147      - * running in parallel at this point. Thus, we have no zonecfg snapshot and
2148      - * shouldn't take one yet (i.e. snap_hndl is NULL). Thats ok, since we don't
2149      - * need any zonecfg info to query for a brand-specific env value.
2150      - */
2151      -static int
2152      -set_brand_env(zlog_t *zlogp)
2153      -{
2154      -        int ret = 0;
2155      -        static char *env_vars = NULL;
2156      -        char buf[2 * MAXPATHLEN];
2157      -
2158      -        if (query_hook[0] == '\0' || env_vars != NULL)
2159      -                return (0);
2160      -
2161      -        if (snprintf(buf, sizeof (buf), "%s env", query_hook) > sizeof (buf))
2162      -                return (-1);
2163      -
2164      -        if (do_subproc(zlogp, buf, &env_vars, B_FALSE) != 0)
2165      -                return (-1);
2166      -
2167      -        if (env_vars != NULL) {
2168      -                char *sp;
2169      -
2170      -                sp = strtok(env_vars, "\t");
2171      -                while (sp != NULL) {
2172      -                        if (putenv(sp) != 0) {
2173      -                                ret = -1;
2174      -                                break;
2175      -                        }
2176      -                        sp = strtok(NULL, "\t");
2177      -                }
2178      -        }
2179      -
2180      -        return (ret);
2181      -}
2182      -
2183      -/*
2184 2041   * Setup the brand's pre and post state change callbacks, as well as the
2185 2042   * query callback, if any of these exist.
2186 2043   */
2187 2044  static int
2188 2045  brand_callback_init(brand_handle_t bh, char *zone_name)
2189 2046  {
2190 2047          (void) strlcpy(pre_statechg_hook, EXEC_PREFIX,
2191 2048              sizeof (pre_statechg_hook));
2192 2049  
2193 2050          if (brand_get_prestatechange(bh, zone_name, zonepath,
2194 2051              pre_statechg_hook + EXEC_LEN,
2195 2052              sizeof (pre_statechg_hook) - EXEC_LEN) != 0)
2196 2053                  return (-1);
2197 2054  
2198 2055          if (strlen(pre_statechg_hook) <= EXEC_LEN)
2199 2056                  pre_statechg_hook[0] = '\0';
2200 2057  
2201 2058          (void) strlcpy(post_statechg_hook, EXEC_PREFIX,
2202 2059              sizeof (post_statechg_hook));
2203 2060  
2204 2061          if (brand_get_poststatechange(bh, zone_name, zonepath,
2205 2062              post_statechg_hook + EXEC_LEN,
2206 2063              sizeof (post_statechg_hook) - EXEC_LEN) != 0)
2207 2064                  return (-1);
2208 2065  
2209 2066          if (strlen(post_statechg_hook) <= EXEC_LEN)
2210 2067                  post_statechg_hook[0] = '\0';
2211 2068  
2212 2069          (void) strlcpy(query_hook, EXEC_PREFIX,
2213 2070              sizeof (query_hook));
2214 2071  
2215 2072          if (brand_get_query(bh, zone_name, zonepath, query_hook + EXEC_LEN,
2216 2073              sizeof (query_hook) - EXEC_LEN) != 0)
2217 2074                  return (-1);
2218 2075  
2219 2076          if (strlen(query_hook) <= EXEC_LEN)
2220 2077                  query_hook[0] = '\0';
2221 2078  
2222 2079          return (0);
2223 2080  }
2224 2081  
2225 2082  int
2226 2083  main(int argc, char *argv[])
2227 2084  {
2228 2085          int opt;
2229 2086          zoneid_t zid;
2230 2087          priv_set_t *privset;
2231 2088          zone_state_t zstate;
2232 2089          char parents_locale[MAXPATHLEN];
2233 2090          brand_handle_t bh;
2234 2091          int err;
2235 2092  
2236 2093          pid_t pid;
2237 2094          sigset_t blockset;
2238 2095          sigset_t block_cld;
2239 2096  
2240 2097          struct {
2241 2098                  sema_t sem;
2242 2099                  int status;
2243 2100                  zlog_t log;
2244 2101          } *shstate;
2245 2102          size_t shstatelen = getpagesize();
2246 2103  
2247 2104          zlog_t errlog;
2248 2105          zlog_t *zlogp;
2249 2106  
2250 2107          int ctfd;
2251 2108  
2252 2109          progname = get_execbasename(argv[0]);
2253 2110  
2254 2111          /*
2255 2112           * Make sure stderr is unbuffered
2256 2113           */
2257 2114          (void) setbuffer(stderr, NULL, 0);
2258 2115  
2259 2116          /*
2260 2117           * Get out of the way of mounted filesystems, since we will daemonize
2261 2118           * soon.
2262 2119           */
2263 2120          (void) chdir("/");
2264 2121  
2265 2122          /*
2266 2123           * Use the default system umask per PSARC 1998/110 rather than
2267 2124           * anything that may have been set by the caller.
2268 2125           */
2269 2126          (void) umask(CMASK);
2270 2127  
2271 2128          /*
2272 2129           * Initially we want to use our parent's locale.
2273 2130           */
2274 2131          (void) setlocale(LC_ALL, "");
2275 2132          (void) textdomain(TEXT_DOMAIN);
2276 2133          (void) strlcpy(parents_locale, setlocale(LC_MESSAGES, NULL),
2277 2134              sizeof (parents_locale));
2278 2135  
2279 2136          /*
2280 2137           * This zlog_t is used for writing to stderr
2281 2138           */
2282 2139          errlog.logfile = stderr;
2283 2140          errlog.buflen = errlog.loglen = 0;
2284 2141          errlog.buf = errlog.log = NULL;
2285 2142          errlog.locale = parents_locale;
2286 2143  
2287 2144          /*
2288 2145           * We start off writing to stderr until we're ready to daemonize.
2289 2146           */
2290 2147          zlogp = &errlog;
2291 2148  
2292 2149          /*
2293 2150           * Process options.
2294 2151           */
2295 2152          while ((opt = getopt(argc, argv, "R:z:")) != EOF) {
2296 2153                  switch (opt) {
2297 2154                  case 'R':
2298 2155                          zonecfg_set_root(optarg);
2299 2156                          break;
2300 2157                  case 'z':
2301 2158                          zone_name = optarg;
2302 2159                          break;
2303 2160                  default:
2304 2161                          usage();
2305 2162                  }
2306 2163          }
2307 2164  
2308 2165          if (zone_name == NULL)
2309 2166                  usage();
2310 2167  
2311 2168          /*
2312 2169           * Because usage() prints directly to stderr, it has gettext()
2313 2170           * wrapping, which depends on the locale.  But since zerror() calls
2314 2171           * localize() which tweaks the locale, it is not safe to call zerror()
2315 2172           * until after the last call to usage().  Fortunately, the last call
2316 2173           * to usage() is just above and the first call to zerror() is just
2317 2174           * below.  Don't mess this up.
2318 2175           */
2319 2176          if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) {
2320 2177                  zerror(zlogp, B_FALSE, "cannot manage the %s zone",
2321 2178                      GLOBAL_ZONENAME);
2322 2179                  return (1);
2323 2180          }
2324 2181  
2325 2182          if (zone_get_id(zone_name, &zid) != 0) {
2326 2183                  zerror(zlogp, B_FALSE, "could not manage %s: %s", zone_name,
2327 2184                      zonecfg_strerror(Z_NO_ZONE));
2328 2185                  return (1);
2329 2186          }
2330 2187  
2331 2188          if ((err = zone_get_state(zone_name, &zstate)) != Z_OK) {
2332 2189                  zerror(zlogp, B_FALSE, "failed to get zone state: %s",
2333 2190                      zonecfg_strerror(err));
2334 2191                  return (1);
2335 2192          }
2336 2193          if (zstate < ZONE_STATE_INCOMPLETE) {
2337 2194                  zerror(zlogp, B_FALSE,
2338 2195                      "cannot manage a zone which is in state '%s'",
2339 2196                      zone_state_str(zstate));
2340 2197                  return (1);
2341 2198          }
2342 2199  
2343 2200          if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) {
2344 2201                  zerror(zlogp, B_FALSE, "unable to determine zone path");
2345 2202                  return (-1);
2346 2203          }
2347 2204  
2348 2205          if (zonecfg_default_brand(default_brand,
2349 2206              sizeof (default_brand)) != Z_OK) {
2350 2207                  zerror(zlogp, B_FALSE, "unable to determine default brand");
2351 2208                  return (1);
2352 2209          }
2353 2210  
2354 2211          /* Get a handle to the brand info for this zone */
2355 2212          if (zone_get_brand(zone_name, brand_name, sizeof (brand_name))
2356 2213              != Z_OK) {
2357 2214                  zerror(zlogp, B_FALSE, "unable to determine zone brand");
2358 2215                  return (1);
2359 2216          }
2360 2217          zone_isnative = (strcmp(brand_name, NATIVE_BRAND_NAME) == 0);
2361 2218          zone_islabeled = (strcmp(brand_name, LABELED_BRAND_NAME) == 0);
2362 2219  
2363 2220          /*
2364 2221           * In the alternate root environment, the only supported
2365 2222           * operations are mount and unmount.  In this case, just treat
2366 2223           * the zone as native if it is cluster.  Cluster zones can be
2367 2224           * native for the purpose of LU or upgrade, and the cluster
2368 2225           * brand may not exist in the miniroot (such as in net install
2369 2226           * upgrade).
2370 2227           */
2371 2228          if (strcmp(brand_name, CLUSTER_BRAND_NAME) == 0) {
2372 2229                  zone_iscluster = B_TRUE;
2373 2230                  if (zonecfg_in_alt_root()) {
2374 2231                          (void) strlcpy(brand_name, default_brand,
2375 2232                              sizeof (brand_name));
2376 2233                  }
2377 2234          } else {
2378 2235                  zone_iscluster = B_FALSE;
2379 2236          }
2380 2237  
2381 2238          if ((bh = brand_open(brand_name)) == NULL) {
2382 2239                  zerror(zlogp, B_FALSE, "unable to open zone brand");
2383 2240                  return (1);
2384 2241          }
2385 2242  
2386 2243          /* Get state change brand hooks. */
2387 2244          if (brand_callback_init(bh, zone_name) == -1) {
2388 2245                  zerror(zlogp, B_TRUE,
2389 2246                      "failed to initialize brand state change hooks");
2390 2247                  brand_close(bh);
2391 2248                  return (1);
2392 2249          }
2393 2250  
2394 2251          brand_close(bh);
2395 2252  
2396 2253          /*
2397 2254           * Check that we have all privileges.  It would be nice to pare
2398 2255           * this down, but this is at least a first cut.
2399 2256           */
2400 2257          if ((privset = priv_allocset()) == NULL) {
2401 2258                  zerror(zlogp, B_TRUE, "%s failed", "priv_allocset");
2402 2259                  return (1);
2403 2260          }
2404 2261  
2405 2262          if (getppriv(PRIV_EFFECTIVE, privset) != 0) {
2406 2263                  zerror(zlogp, B_TRUE, "%s failed", "getppriv");
2407 2264                  priv_freeset(privset);
2408 2265                  return (1);
  
    | 
      ↓ open down ↓ | 
    215 lines elided | 
    
      ↑ open up ↑ | 
  
2409 2266          }
2410 2267  
2411 2268          if (priv_isfullset(privset) == B_FALSE) {
2412 2269                  zerror(zlogp, B_FALSE, "You lack sufficient privilege to "
2413 2270                      "run this command (all privs required)");
2414 2271                  priv_freeset(privset);
2415 2272                  return (1);
2416 2273          }
2417 2274          priv_freeset(privset);
2418 2275  
2419      -        if (set_brand_env(zlogp) != 0) {
2420      -                zerror(zlogp, B_FALSE, "Unable to setup brand's environment");
2421      -                return (1);
2422      -        }
2423      -
2424 2276          if (mkzonedir(zlogp) != 0)
2425 2277                  return (1);
2426 2278  
2427 2279          /*
2428 2280           * Pre-fork: setup shared state
2429 2281           */
2430 2282          if ((shstate = (void *)mmap(NULL, shstatelen,
2431 2283              PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, (off_t)0)) ==
2432 2284              MAP_FAILED) {
2433 2285                  zerror(zlogp, B_TRUE, "%s failed", "mmap");
2434 2286                  return (1);
2435 2287          }
2436 2288          if (sema_init(&shstate->sem, 0, USYNC_PROCESS, NULL) != 0) {
2437 2289                  zerror(zlogp, B_TRUE, "%s failed", "sema_init()");
2438 2290                  (void) munmap((char *)shstate, shstatelen);
2439 2291                  return (1);
2440 2292          }
2441 2293          shstate->log.logfile = NULL;
2442 2294          shstate->log.buflen = shstatelen - sizeof (*shstate);
2443 2295          shstate->log.loglen = shstate->log.buflen;
2444 2296          shstate->log.buf = (char *)shstate + sizeof (*shstate);
2445 2297          shstate->log.log = shstate->log.buf;
2446 2298          shstate->log.locale = parents_locale;
2447 2299          shstate->status = -1;
2448 2300  
2449 2301          /*
2450 2302           * We need a SIGCHLD handler so the sema_wait() below will wake
2451 2303           * up if the child dies without doing a sema_post().
2452 2304           */
2453 2305          (void) sigset(SIGCHLD, sigchld);
2454 2306          /*
2455 2307           * We must mask SIGCHLD until after we've coped with the fork
2456 2308           * sufficiently to deal with it; otherwise we can race and
2457 2309           * receive the signal before pid has been initialized
2458 2310           * (yes, this really happens).
2459 2311           */
2460 2312          (void) sigemptyset(&block_cld);
2461 2313          (void) sigaddset(&block_cld, SIGCHLD);
2462 2314          (void) sigprocmask(SIG_BLOCK, &block_cld, NULL);
2463 2315  
2464 2316          /*
2465 2317           * The parent only needs stderr after the fork, so close other fd's
2466 2318           * that we inherited from zoneadm so that the parent doesn't have those
2467 2319           * open while waiting. The child will close the rest after the fork.
2468 2320           */
2469 2321          closefrom(3);
2470 2322  
2471 2323          if ((ctfd = init_template()) == -1) {
2472 2324                  zerror(zlogp, B_TRUE, "failed to create contract");
2473 2325                  return (1);
2474 2326          }
2475 2327  
2476 2328          /*
2477 2329           * Do not let another thread localize a message while we are forking.
2478 2330           */
2479 2331          (void) mutex_lock(&msglock);
2480 2332          pid = fork();
2481 2333          (void) mutex_unlock(&msglock);
2482 2334  
2483 2335          /*
2484 2336           * In all cases (parent, child, and in the event of an error) we
2485 2337           * don't want to cause creation of contracts on subsequent fork()s.
2486 2338           */
2487 2339          (void) ct_tmpl_clear(ctfd);
2488 2340          (void) close(ctfd);
2489 2341  
2490 2342          if (pid == -1) {
2491 2343                  zerror(zlogp, B_TRUE, "could not fork");
2492 2344                  return (1);
2493 2345  
2494 2346          } else if (pid > 0) { /* parent */
2495 2347                  (void) sigprocmask(SIG_UNBLOCK, &block_cld, NULL);
2496 2348                  /*
2497 2349                   * This marks a window of vulnerability in which we receive
2498 2350                   * the SIGCLD before falling into sema_wait (normally we would
2499 2351                   * get woken up from sema_wait with EINTR upon receipt of
2500 2352                   * SIGCLD).  So we may need to use some other scheme like
2501 2353                   * sema_posting in the sigcld handler.
2502 2354                   * blech
2503 2355                   */
2504 2356                  (void) sema_wait(&shstate->sem);
2505 2357                  (void) sema_destroy(&shstate->sem);
2506 2358                  if (shstate->status != 0)
2507 2359                          (void) waitpid(pid, NULL, WNOHANG);
2508 2360                  /*
2509 2361                   * It's ok if we die with SIGPIPE.  It's not like we could have
2510 2362                   * done anything about it.
2511 2363                   */
2512 2364                  (void) fprintf(stderr, "%s", shstate->log.buf);
2513 2365                  _exit(shstate->status == 0 ? 0 : 1);
2514 2366          }
2515 2367  
2516 2368          /*
2517 2369           * The child charges on.
2518 2370           */
2519 2371          (void) sigset(SIGCHLD, SIG_DFL);
2520 2372          (void) sigprocmask(SIG_UNBLOCK, &block_cld, NULL);
2521 2373  
2522 2374          /*
2523 2375           * SIGPIPE can be delivered if we write to a socket for which the
2524 2376           * peer endpoint is gone.  That can lead to too-early termination
2525 2377           * of zoneadmd, and that's not good eats.
2526 2378           */
2527 2379          (void) sigset(SIGPIPE, SIG_IGN);
2528 2380          /*
2529 2381           * Stop using stderr
2530 2382           */
2531 2383          zlogp = &shstate->log;
2532 2384  
2533 2385          /*
2534 2386           * We don't need stdout/stderr from now on.
2535 2387           */
2536 2388          closefrom(0);
2537 2389  
2538 2390          /*
2539 2391           * Initialize the syslog zlog_t.  This needs to be done after
2540 2392           * the call to closefrom().
2541 2393           */
2542 2394          logsys.buf = logsys.log = NULL;
2543 2395          logsys.buflen = logsys.loglen = 0;
2544 2396          logsys.logfile = NULL;
2545 2397          logsys.locale = DEFAULT_LOCALE;
2546 2398  
2547 2399          openlog("zoneadmd", LOG_PID, LOG_DAEMON);
2548 2400  
2549 2401          /*
2550 2402           * The eventstream is used to publish state changes in the zone
2551 2403           * from the door threads to the console I/O poller.
2552 2404           */
2553 2405          if (eventstream_init() == -1) {
2554 2406                  zerror(zlogp, B_TRUE, "unable to create eventstream");
2555 2407                  goto child_out;
2556 2408          }
2557 2409  
2558 2410          (void) snprintf(zone_door_path, sizeof (zone_door_path),
2559 2411              "%s" ZONE_DOOR_PATH, zonecfg_get_root(), zone_name);
2560 2412  
2561 2413          /*
2562 2414           * See if another zoneadmd is running for this zone.  If not, then we
2563 2415           * can now modify system state.
2564 2416           */
2565 2417          if (make_daemon_exclusive(zlogp) == -1)
2566 2418                  goto child_out;
2567 2419  
2568 2420  
2569 2421          /*
2570 2422           * Create/join a new session; we need to be careful of what we do with
2571 2423           * the console from now on so we don't end up being the session leader
2572 2424           * for the terminal we're going to be handing out.
2573 2425           */
2574 2426          (void) setsid();
2575 2427  
2576 2428          /*
2577 2429           * This thread shouldn't be receiving any signals; in particular,
2578 2430           * SIGCHLD should be received by the thread doing the fork().
2579 2431           */
2580 2432          (void) sigfillset(&blockset);
2581 2433          (void) thr_sigsetmask(SIG_BLOCK, &blockset, NULL);
2582 2434  
2583 2435          /*
2584 2436           * Setup the console device and get ready to serve the console;
2585 2437           * once this has completed, we're ready to let console clients
2586 2438           * make an attempt to connect (they will block until
2587 2439           * serve_console_sock() below gets called, and any pending
2588 2440           * connection is accept()ed).
2589 2441           */
2590 2442          if (!zonecfg_in_alt_root() && init_console(zlogp) < 0)
2591 2443                  goto child_out;
2592 2444  
2593 2445          /*
2594 2446           * Take the lock now, so that when the door server gets going, we
2595 2447           * are guaranteed that it won't take a request until we are sure
2596 2448           * that everything is completely set up.  See the child_out: label
2597 2449           * below to see why this matters.
2598 2450           */
2599 2451          (void) mutex_lock(&lock);
2600 2452  
2601 2453          /* Init semaphore for scratch zones. */
2602 2454          if (sema_init(&scratch_sem, 0, USYNC_THREAD, NULL) == -1) {
2603 2455                  zerror(zlogp, B_TRUE,
2604 2456                      "failed to initialize semaphore for scratch zone");
2605 2457                  goto child_out;
2606 2458          }
2607 2459  
2608 2460          /* open the dladm handle */
2609 2461          if (dladm_open(&dld_handle) != DLADM_STATUS_OK) {
2610 2462                  zerror(zlogp, B_FALSE, "failed to open dladm handle");
2611 2463                  goto child_out;
2612 2464          }
2613 2465  
2614 2466          /*
2615 2467           * Note: door setup must occur *after* the console is setup.
2616 2468           * This is so that as zlogin tests the door to see if zoneadmd
2617 2469           * is ready yet, we know that the console will get serviced
2618 2470           * once door_info() indicates that the door is "up".
2619 2471           */
2620 2472          if (setup_door(zlogp) == -1)
2621 2473                  goto child_out;
2622 2474  
2623 2475          /*
2624 2476           * Things seem OK so far; tell the parent process that we're done
2625 2477           * with setup tasks.  This will cause the parent to exit, signalling
2626 2478           * to zoneadm, zlogin, or whatever forked it that we are ready to
2627 2479           * service requests.
2628 2480           */
2629 2481          shstate->status = 0;
2630 2482          (void) sema_post(&shstate->sem);
2631 2483          (void) munmap((char *)shstate, shstatelen);
2632 2484          shstate = NULL;
2633 2485  
2634 2486          (void) mutex_unlock(&lock);
2635 2487  
2636 2488          /*
2637 2489           * zlogp is now invalid, so reset it to the syslog logger.
2638 2490           */
2639 2491          zlogp = &logsys;
2640 2492  
2641 2493          /*
2642 2494           * Now that we are free of any parents, switch to the default locale.
2643 2495           */
2644 2496          (void) setlocale(LC_ALL, DEFAULT_LOCALE);
2645 2497  
2646 2498          /*
2647 2499           * At this point the setup portion of main() is basically done, so
2648 2500           * we reuse this thread to manage the zone console.  When
2649 2501           * serve_console() has returned, we are past the point of no return
2650 2502           * in the life of this zoneadmd.
2651 2503           */
2652 2504          if (zonecfg_in_alt_root()) {
2653 2505                  /*
2654 2506                   * This is just awful, but mounted scratch zones don't (and
2655 2507                   * can't) have consoles.  We just wait for unmount instead.
2656 2508                   */
2657 2509                  while (sema_wait(&scratch_sem) == EINTR)
2658 2510                          ;
2659 2511          } else {
2660 2512                  serve_console(zlogp);
2661 2513                  assert(in_death_throes);
2662 2514          }
2663 2515  
2664 2516          /*
2665 2517           * This is the next-to-last part of the exit interlock.  Upon calling
2666 2518           * fdetach(), the door will go unreferenced; once any
2667 2519           * outstanding requests (like the door thread doing Z_HALT) are
2668 2520           * done, the door will get an UNREF notification; when it handles
2669 2521           * the UNREF, the door server will cause the exit.  It's possible
2670 2522           * that fdetach() can fail because the file is in use, in which
2671 2523           * case we'll retry the operation.
2672 2524           */
2673 2525          assert(!MUTEX_HELD(&lock));
2674 2526          for (;;) {
2675 2527                  if ((fdetach(zone_door_path) == 0) || (errno != EBUSY))
2676 2528                          break;
2677 2529                  yield();
2678 2530          }
2679 2531  
2680 2532          for (;;)
2681 2533                  (void) pause();
2682 2534  
2683 2535  child_out:
2684 2536          assert(pid == 0);
2685 2537          if (shstate != NULL) {
2686 2538                  shstate->status = -1;
2687 2539                  (void) sema_post(&shstate->sem);
2688 2540                  (void) munmap((char *)shstate, shstatelen);
2689 2541          }
2690 2542  
2691 2543          /*
2692 2544           * This might trigger an unref notification, but if so,
2693 2545           * we are still holding the lock, so our call to exit will
2694 2546           * ultimately win the race and will publish the right exit
2695 2547           * code.
2696 2548           */
2697 2549          if (zone_door != -1) {
2698 2550                  assert(MUTEX_HELD(&lock));
2699 2551                  (void) door_revoke(zone_door);
2700 2552                  (void) fdetach(zone_door_path);
2701 2553          }
2702 2554  
2703 2555          if (dld_handle != NULL)
2704 2556                  dladm_close(dld_handle);
2705 2557  
2706 2558          return (1); /* return from main() forcibly exits an MT process */
2707 2559  }
  
    | 
      ↓ open down ↓ | 
    274 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX