Print this page
OS-4361 libzonecfg should be aware of branded zone native root
Reviewed by: Robert Mustacchi <rm@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libzonecfg/common/getzoneent.c
          +++ new/usr/src/lib/libzonecfg/common/getzoneent.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  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   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2015 Joyent, Inc.
  23   24   */
  24   25  
  25   26  
  26   27  /*
  27   28   * This module contains functions used for reading and writing the index file.
  28   29   * setzoneent() opens the file.  getzoneent() parses the file, doing the usual
  29   30   * skipping of comment lines, etc., and using gettok() to deal with the ":"
  30   31   * delimiters.  endzoneent() closes the file.  putzoneent() updates the file,
  31   32   * adding, deleting or modifying lines, locking and unlocking appropriately.
  32   33   */
↓ open down ↓ 130 lines elided ↑ open up ↑
 163  164                  if (uuid_parse(p, ze->zone_uuid) == -1)
 164  165                          uuid_clear(ze->zone_uuid);
 165  166  
 166  167                  break;
 167  168          }
 168  169  
 169  170          return (ze);
 170  171  }
 171  172  
 172  173  static boolean_t
 173      -get_index_path(char *path)
      174 +path_common(char *path, size_t path_size, const char *stem)
 174  175  {
 175      -        return (snprintf(path, MAXPATHLEN, "%s%s", zonecfg_root,
 176      -            ZONE_INDEX_FILE) < MAXPATHLEN);
      176 +        const char *native_root = zone_get_nroot();
      177 +
      178 +        if (native_root == NULL || zonecfg_in_alt_root()) {
      179 +                /*
      180 +                 * Do not prepend the native system root (e.g. "/native") if an
      181 +                 * alternative configuration root has been selected.
      182 +                 */
      183 +                native_root = "";
      184 +        }
      185 +
      186 +        return (snprintf(path, path_size, "%s%s%s", native_root, zonecfg_root,
      187 +            stem) < path_size);
 177  188  }
 178  189  
      190 +static boolean_t
      191 +get_index_path(char *path, size_t path_size)
      192 +{
      193 +        return (path_common(path, path_size, ZONE_INDEX_FILE));
      194 +}
      195 +
      196 +static boolean_t
      197 +get_temp_path(char *path, size_t path_size)
      198 +{
      199 +        return (path_common(path, path_size, _PATH_TMPFILE));
      200 +}
      201 +
 179  202  FILE *
 180  203  setzoneent(void)
 181  204  {
 182  205          char path[MAXPATHLEN];
 183  206  
 184      -        if (!get_index_path(path)) {
      207 +        if (!get_index_path(path, sizeof (path))) {
 185  208                  errno = EINVAL;
 186  209                  return (NULL);
 187  210          }
 188  211          return (fopen(path, "r"));
 189  212  }
 190  213  
 191  214  void
 192  215  endzoneent(FILE *cookie)
 193  216  {
 194  217          if (cookie != NULL)
 195  218                  (void) fclose(cookie);
 196  219  }
 197  220  
 198  221  static int
 199  222  lock_index_file(void)
 200  223  {
 201  224          int lock_fd;
 202  225          struct flock lock;
 203  226          char path[MAXPATHLEN];
 204  227  
 205      -        if (snprintf(path, sizeof (path), "%s%s", zonecfg_root,
 206      -            ZONE_INDEX_LOCK_DIR) >= sizeof (path))
      228 +        if (!path_common(path, sizeof (path), ZONE_INDEX_LOCK_DIR))
 207  229                  return (-1);
 208  230          if ((mkdir(path, S_IRWXU) == -1) && errno != EEXIST)
 209  231                  return (-1);
 210  232          if (strlcat(path, ZONE_INDEX_LOCK_FILE, sizeof (path)) >=
 211  233              sizeof (path))
 212  234                  return (-1);
 213  235          lock_fd = open(path, O_CREAT|O_RDWR, 0644);
 214  236          if (lock_fd == -1)
 215  237                  return (-1);
 216  238  
↓ open down ↓ 45 lines elided ↑ open up ↑
 262  284   * only meaningful when operation == PZE_MODIFY.
 263  285   *
 264  286   * Locking and unlocking is done via the functions above.
 265  287   * The file itself is not modified in place; rather, a copy is made which
 266  288   * is modified, then the copy is atomically renamed back to the main file.
 267  289   */
 268  290  int
 269  291  putzoneent(struct zoneent *ze, zoneent_op_t operation)
 270  292  {
 271  293          FILE *index_file, *tmp_file;
 272      -        char *tmp_file_name, buf[MAX_INDEX_LEN];
      294 +        char buf[MAX_INDEX_LEN];
 273  295          int tmp_file_desc, lock_fd, err;
 274  296          boolean_t exist, need_quotes;
 275  297          char *cp;
      298 +        char tmp_path[MAXPATHLEN];
 276  299          char path[MAXPATHLEN];
 277  300          char uuidstr[UUID_PRINTABLE_STRING_LENGTH];
 278      -        size_t tlen, namelen;
      301 +        size_t namelen;
 279  302          const char *zone_name, *zone_state, *zone_path, *zone_uuid;
 280  303  
 281  304          assert(ze != NULL);
 282  305  
 283  306          /*
 284  307           * Don't allow modification of Global Zone entry
 285  308           * in index file
 286  309           */
 287  310          if ((operation == PZE_MODIFY) &&
 288  311              (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0)) {
↓ open down ↓ 3 lines elided ↑ open up ↑
 292  315          if (operation == PZE_ADD &&
 293  316              (ze->zone_state < 0 || strlen(ze->zone_path) == 0))
 294  317                  return (Z_INVAL);
 295  318  
 296  319          if (operation != PZE_MODIFY && strlen(ze->zone_newname) != 0)
 297  320                  return (Z_INVAL);
 298  321  
 299  322          if ((lock_fd = lock_index_file()) == -1)
 300  323                  return (Z_LOCKING_FILE);
 301  324  
 302      -        /* using sizeof gives us room for the terminating NUL byte as well */
 303      -        tlen = sizeof (_PATH_TMPFILE) + strlen(zonecfg_root);
 304      -        tmp_file_name = malloc(tlen);
 305      -        if (tmp_file_name == NULL) {
      325 +        if (!get_temp_path(tmp_path, sizeof (tmp_path))) {
 306  326                  (void) unlock_index_file(lock_fd);
 307  327                  return (Z_NOMEM);
 308  328          }
 309      -        (void) snprintf(tmp_file_name, tlen, "%s%s", zonecfg_root,
 310      -            _PATH_TMPFILE);
 311  329  
 312      -        tmp_file_desc = mkstemp(tmp_file_name);
      330 +        tmp_file_desc = mkstemp(tmp_path);
 313  331          if (tmp_file_desc == -1) {
 314      -                (void) unlink(tmp_file_name);
 315      -                free(tmp_file_name);
      332 +                (void) unlink(tmp_path);
 316  333                  (void) unlock_index_file(lock_fd);
 317  334                  return (Z_TEMP_FILE);
 318  335          }
 319  336          (void) fchmod(tmp_file_desc, ZONE_INDEX_MODE);
 320  337          (void) fchown(tmp_file_desc, ZONE_INDEX_UID, ZONE_INDEX_GID);
 321  338          if ((tmp_file = fdopen(tmp_file_desc, "w")) == NULL) {
 322  339                  (void) close(tmp_file_desc);
 323  340                  err = Z_MISC_FS;
 324  341                  goto error;
 325  342          }
 326      -        if (!get_index_path(path)) {
      343 +        if (!get_index_path(path, sizeof (path))) {
 327  344                  err = Z_MISC_FS;
 328  345                  goto error;
 329  346          }
 330  347          if ((index_file = fopen(path, "r")) == NULL) {
 331  348                  err = Z_MISC_FS;
 332  349                  goto error;
 333  350          }
 334  351  
 335  352          exist = B_FALSE;
 336  353          zone_name = ze->zone_name;
↓ open down ↓ 120 lines elided ↑ open up ↑
 457  474          }
 458  475  
 459  476          (void) fclose(index_file);
 460  477          index_file = NULL;
 461  478          if (fclose(tmp_file) != 0) {
 462  479                  tmp_file = NULL;
 463  480                  err = Z_MISC_FS;
 464  481                  goto error;
 465  482          }
 466  483          tmp_file = NULL;
 467      -        if (rename(tmp_file_name, path) == -1) {
      484 +        if (rename(tmp_path, path) == -1) {
 468  485                  err = errno == EACCES ? Z_ACCES : Z_MISC_FS;
 469  486                  goto error;
 470  487          }
 471      -        free(tmp_file_name);
 472  488          if (unlock_index_file(lock_fd) != Z_OK)
 473  489                  return (Z_UNLOCKING_FILE);
 474  490          return (Z_OK);
 475  491  
 476  492  error:
 477  493          if (index_file != NULL)
 478  494                  (void) fclose(index_file);
 479  495          if (tmp_file != NULL)
 480  496                  (void) fclose(tmp_file);
 481      -        (void) unlink(tmp_file_name);
 482      -        free(tmp_file_name);
      497 +        (void) unlink(tmp_path);
 483  498          (void) unlock_index_file(lock_fd);
 484  499          return (err);
 485  500  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX