Print this page
OS-4348 libnsl should seek netconfig file in native root
Reviewed by: Robert Mustacchi <rm@joyent.com>
OS-3812 lxbrand nfs mounting fails

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libnsl/netselect/netselect.c
          +++ new/usr/src/lib/libnsl/netselect/netselect.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  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 2007 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
       25 + * Copyright 2015 Joyent, Inc.
  25   26   */
  26   27  
  27   28  /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T     */
  28   29  /*        All Rights Reserved   */
  29   30  
  30   31  /*
  31   32   * Portions of this source code were derived from Berkeley 4.3 BSD
  32   33   * under license from the Regents of the University of California.
  33   34   */
  34   35  
  35      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  36      -
  37   36  #include "mt.h"
  38   37  #include "../rpc/rpc_mt.h"              /* for MT declarations only */
  39   38  #include <rpc/types.h>
  40   39  #include <stdio.h>
  41   40  #include <stdlib.h>
  42   41  #include <string.h>
  43   42  #include <ctype.h>
  44   43  #include <netconfig.h>
  45   44  #include <malloc.h>
  46   45  #include <libintl.h>
  47   46  #include <syslog.h>
       47 +#include <zone.h>
  48   48  #include "netcspace.h"
  49   49  
  50   50  #define FAILURE  (unsigned)(-1)
  51   51  
  52   52  /*
  53   53   *      Local routines used by the library procedures
  54   54   */
  55   55  
  56   56  static int blank(char *);
  57   57  static int comment(char *);
↓ open down ↓ 5 lines elided ↑ open up ↑
  63   63  static unsigned int getnlookups(char *);
  64   64  static char *gettoken(char *, int);
  65   65  static unsigned int getvalue(char *, struct nc_data nc_data[]);
  66   66  static void shift1left(char *);
  67   67  static void netlist_free(struct netconfig ***);
  68   68  static void free_entry(void *);
  69   69  static struct netconfig *netconfig_dup(struct netconfig *);
  70   70  
  71   71  extern const char __nsl_dom[];
  72   72  
       73 +static int (*brand_get_sz)(void) = NULL;
       74 +static struct netconfig *(*brand_get_net_ent)(int) = NULL;
       75 +
  73   76  /*
  74   77   *      Static global variables used by the library procedures:
  75   78   *
  76   79   *      netpp - points to the beginning of the list of netconfig
  77   80   *              entries used by setnetconfig() and setnetpath().
  78   81   *              Once netpp is initialized, that memory is *never*
  79   82   *              released.  This was necessary to improve performance.
  80   83   *
  81   84   *      linenum - the current line number of the /etc/netconfig
  82   85   *                file (used for debugging and for nc_perror()).
↓ open down ↓ 165 lines elided ↑ open up ↑
 248  251  /*
 249  252   *      freenetconfigent frees the data allocated by getnetconfigent()
 250  253   */
 251  254  
 252  255  void
 253  256  freenetconfigent(struct netconfig *netp)
 254  257  {
 255  258          netconfig_free(netp);
 256  259  }
 257  260  
      261 +void
      262 +_nsl_brand_set_hooks(int (*set_sz_func)(void),
      263 +    struct netconfig *(*get_ent_func)(int))
      264 +{
      265 +        brand_get_sz = set_sz_func;
      266 +        brand_get_net_ent = get_ent_func;
      267 +}
      268 +
 258  269  /*
 259  270   *      getnetlist() reads the netconfig file and creates a
 260  271   *      NULL-terminated list of entries.
 261  272   *      Returns the pointer to the head of the list or a NULL
 262  273   *      on failure.
 263  274   */
 264  275  
 265  276  static struct netconfig **
 266  277  getnetlist(void)
 267  278  {
 268      -        char line[BUFSIZ];      /* holds each line of NETCONFIG */
 269      -        FILE *fp;               /* file stream for NETCONFIG */
      279 +        FILE *fp = NULL;        /* file stream for NETCONFIG */
 270  280          struct netconfig **listpp; /* the beginning of the netconfig list */
 271  281          struct netconfig **tpp; /* used to traverse the netconfig list */
 272  282          int count;              /* the number of entries in file */
      283 +        char nc_path[MAXPATHLEN];
      284 +        const char *zroot = zone_get_nroot();
 273  285  
 274      -        if ((fp = fopen(NETCONFIG, "rF")) == NULL) {
 275      -                nc_error = NC_OPENFAIL;
 276      -                return (NULL);
 277      -        }
      286 +        /*
      287 +         * If we are running in a branded zone, ensure we use the "/native"
      288 +         * prefix when opening the netconfig file:
      289 +         */
      290 +        (void) snprintf(nc_path, sizeof (nc_path), "%s%s", zroot != NULL ?
      291 +            zroot : "", NETCONFIG);
 278  292  
 279      -        count = 0;
 280      -        while (fgets(line, BUFSIZ, fp)) {
 281      -                if (!(blank(line) || comment(line))) {
 282      -                        ++count;
      293 +        if (brand_get_sz != NULL) {
      294 +                count = brand_get_sz();
      295 +        } else {
      296 +                char line[BUFSIZ];      /* holds each line of NETCONFIG */
      297 +
      298 +                if ((fp = fopen(nc_path, "rF")) == NULL) {
      299 +                        nc_error = NC_OPENFAIL;
      300 +                        return (NULL);
 283  301                  }
      302 +
      303 +                count = 0;
      304 +                while (fgets(line, BUFSIZ, fp)) {
      305 +                        if (!(blank(line) || comment(line))) {
      306 +                                ++count;
      307 +                        }
      308 +                }
      309 +                rewind(fp);
 284  310          }
 285      -        rewind(fp);
 286  311  
 287  312          if (count == 0) {
 288  313                  nc_error = NC_NOTFOUND;
 289      -                (void) fclose(fp);
      314 +                if (fp != NULL)
      315 +                        (void) fclose(fp);
 290  316                  return (NULL);
 291  317          }
      318 +
 292  319          if ((listpp = malloc((count + 1) *
 293  320              sizeof (struct netconfig *))) == NULL) {
 294  321                  nc_error = NC_NOMEM;
 295      -                (void) fclose(fp);
      322 +                if (fp != NULL)
      323 +                        (void) fclose(fp);
 296  324                  return (NULL);
 297  325          }
 298  326  
 299      -        /*
 300      -         *      The following loop fills in the list (loops until
 301      -         *      fgetnetconfig() returns a NULL) and counts the
 302      -         *      number of entries placed in the list.  Note that
 303      -         *      when the loop is completed, the last entry in the
 304      -         *      list will contain a NULL (signifying the end of
 305      -         *      the list).
 306      -         */
 307      -        linenum = 0;
 308      -        for (tpp = listpp; *tpp = fgetnetconfig(fp, NULL); tpp++)
 309      -                ;
 310      -        (void) fclose(fp);
      327 +        if (brand_get_net_ent != NULL) {
      328 +                int i;
 311  329  
 312      -        if (nc_error != NC_NOMOREENTRIES) /* Something is screwed up */
 313      -                netlist_free(&listpp);
      330 +                tpp = listpp;
      331 +                for (i = 0; i < count; i++) {
      332 +                        *tpp = brand_get_net_ent(i);
      333 +                        tpp++;
      334 +                }
      335 +                *tpp = NULL;
      336 +                nc_error = NC_NOMOREENTRIES;
      337 +        } else {
      338 +                /*
      339 +                 *      The following loop fills in the list (loops until
      340 +                 *      fgetnetconfig() returns a NULL) and counts the
      341 +                 *      number of entries placed in the list.  Note that
      342 +                 *      when the loop is completed, the last entry in the
      343 +                 *      list will contain a NULL (signifying the end of
      344 +                 *      the list).
      345 +                 */
      346 +                linenum = 0;
      347 +                for (tpp = listpp; *tpp = fgetnetconfig(fp, NULL); tpp++)
      348 +                        ;
      349 +                (void) fclose(fp);
      350 +
      351 +                if (nc_error != NC_NOMOREENTRIES) /* Something is screwed up */
      352 +                        netlist_free(&listpp);
      353 +        }
      354 +
 314  355          return (listpp);
 315  356  }
 316  357  
 317  358  /*
 318  359   *      fgetnetconfig() parses a line of the netconfig file into
 319  360   *      a netconfig structure.  It returns a pointer to the
 320  361   *      structure of success and a NULL on failure or EOF.
 321  362   */
 322  363  
 323  364  static struct netconfig *
↓ open down ↓ 632 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX