Print this page


Split Close
Expand all
Collapse all
          --- old/usr/src/lib/brand/lx/lx_init/lxinit.c
          +++ new/usr/src/lib/brand/lx/lx_init/lxinit.c
↓ open down ↓ 95 lines elided ↑ open up ↑
  96   96          va_end(ap);
  97   97  
  98   98          (void) write(1, PREFIX_LOG_ERR, strlen(PREFIX_LOG_ERR));
  99   99          (void) write(1, buf, len);
 100  100          (void) write(1, "\n", 1);
 101  101  
 102  102          /*
 103  103           * Since a non-zero exit will cause the zone to reboot, a pause here
 104  104           * will prevent a mis-configured zone from spinning in a reboot loop.
 105  105           */
 106      -        pause();
      106 +        (void) pause();
 107  107          exit(1);
 108  108          /*NOTREACHED*/
 109  109  }
 110  110  
 111  111  static void
 112  112  lxi_warn(char *msg, ...)
 113  113  {
 114  114          char buf[1024];
 115  115          int len;
 116  116          va_list ap;
↓ open down ↓ 78 lines elided ↑ open up ↑
 195  195                  if (strncmp(attrs->zone_res_attr_name, name,
 196  196                      MAXNAMELEN) == 0) {
 197  197                          *result = attrs->zone_res_attr_value;
 198  198                          return (0);
 199  199                  }
 200  200                  attrs = attrs->zone_res_attr_next;
 201  201          }
 202  202          return (-1);
 203  203  }
 204  204  
 205      -void
      205 +static void
 206  206  lxi_svc_start(char *name, char *path, char *fmri)
 207  207  {
 208  208          pid_t pid;
 209  209          int status;
 210      -        char *const argv[] = {
 211      -                name,
      210 +        char *argv[] = {
      211 +                NULL,
 212  212                  NULL
 213  213          };
 214      -        char *const envp[] = {
 215      -                fmri,
      214 +        char *envp[] = {
      215 +                NULL,
 216  216                  NULL
 217  217          };
      218 +        argv[0] = name;
      219 +        envp[0] = fmri;
 218  220  
 219  221          pid = fork();
 220  222          if (pid == -1) {
 221  223                  lxi_err("fork() failed: %s", strerror(errno));
 222  224          }
 223  225  
 224  226          if (pid == 0) {
 225  227                  /* child */
 226  228                  const char *zroot = zone_get_nroot();
 227  229                  char cmd[MAXPATHLEN];
 228  230  
 229  231                  /*
 230  232                   * Construct the full path to the binary, including the native
 231  233                   * system root (e.g. "/native") if in use for this zone:
 232  234                   */
 233  235                  (void) snprintf(cmd, sizeof (cmd), "%s%s", zroot != NULL ?
 234  236                      zroot : "", path);
 235  237  
 236      -                execve(cmd, argv, envp);
      238 +                (void) execve(cmd, argv, envp);
 237  239  
 238  240                  lxi_err("execve(%s) failed: %s", cmd, strerror(errno));
 239  241                  /* NOTREACHED */
 240  242          }
 241  243  
 242  244          /* parent */
 243      -        while (wait(&status) != pid) {
 244      -                /* EMPTY */;
 245      -        }
      245 +        while (wait(&status) != pid)
      246 +                ;
 246  247  
 247  248          if (WIFEXITED(status)) {
 248  249                  if (WEXITSTATUS(status) != 0) {
 249  250                          lxi_err("%s[%d] exited: %d", name,
 250  251                              (int)pid, WEXITSTATUS(status));
 251  252                  }
 252  253          } else if (WIFSIGNALED(status)) {
 253  254                  lxi_err("%s[%d] died on signal: %d", name,
 254  255                      (int)pid, WTERMSIG(status));
 255  256          } else {
↓ open down ↓ 231 lines elided ↑ open up ↑
 487  488  
 488  489          (void) close(s);
 489  490          return (0);
 490  491  }
 491  492  
 492  493  static int
 493  494  lxi_iface_gateway(const char *iface, const char *dst, int dstpfx,
 494  495      const char *gwaddr)
 495  496  {
 496  497          int idx, len, sockfd;
 497      -        char rtbuf[RTMBUFSZ];
      498 +        /* For lint-happy alignment, use a uint32_t array... */
      499 +        uint32_t rtbuf[RTMBUFSZ / sizeof (uint32_t)];
 498  500          struct rt_msghdr *rtm = (struct rt_msghdr *)rtbuf;
 499      -        struct sockaddr_in *dst_sin = (struct sockaddr_in *)
 500      -            (rtbuf + sizeof (struct rt_msghdr));
      501 +        struct sockaddr_in *dst_sin = (struct sockaddr_in *)(rtm + 1);
 501  502          struct sockaddr_in *gw_sin = (struct sockaddr_in *)(dst_sin + 1);
 502  503          struct sockaddr_in *netmask_sin = (struct sockaddr_in *)(gw_sin + 1);
 503  504  
 504  505          (void) bzero(rtm, RTMBUFSZ);
 505  506          rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
 506  507          rtm->rtm_flags = RTF_UP | RTF_STATIC | RTF_GATEWAY;
 507  508          rtm->rtm_msglen = sizeof (rtbuf);
 508  509          rtm->rtm_pid = getpid();
 509  510          rtm->rtm_type = RTM_ADD;
 510  511          rtm->rtm_version = RTM_VERSION;
↓ open down ↓ 31 lines elided ↑ open up ↑
 542  543                  rtm->rtm_index = idx;
 543  544          }
 544  545  
 545  546          if ((sockfd = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
 546  547                  lxi_warn("socket(PF_ROUTE): %s\n", strerror(errno));
 547  548                  return (-1);
 548  549          }
 549  550  
 550  551          if ((len = write(sockfd, rtbuf, rtm->rtm_msglen)) < 0) {
 551  552                  lxi_warn("could not write rtmsg: %s", strerror(errno));
 552      -                close(sockfd);
      553 +                (void) close(sockfd);
 553  554                  return (-1);
 554  555          } else if (len < rtm->rtm_msglen) {
 555  556                  lxi_warn("write() rtmsg incomplete");
 556      -                close(sockfd);
      557 +                (void) close(sockfd);
 557  558                  return (-1);
 558  559          }
 559  560  
 560      -        close(sockfd);
      561 +        (void) close(sockfd);
 561  562          return (0);
 562  563  }
 563  564  
 564  565  static void
 565  566  lxi_net_loopback()
 566  567  {
 567  568          const char *iface = "lo0";
 568  569          boolean_t first_ipv4_configured = B_FALSE;
 569  570  
 570  571          lxi_net_plumb(iface);
 571  572          (void) lxi_iface_ip(iface, "127.0.0.1/8", &first_ipv4_configured);
 572  573          (void) lxi_iface_ipv6_link_local(iface);
 573  574  }
 574  575  
 575      -
 576      -/*
 577      - * This function is used when the "ips" property doesn't exist in a zone's
 578      - * configuration. It may be an older configuration, so we should search for
 579      - * "ip" and "netmask" and convert them into the new format.
 580      - */
 581      -static int
 582      -lxi_get_old_ip(struct zone_res_attrtab *attrs, const char **ipaddrs,
 583      -    char *cidraddr, int len)
 584      -{
 585      -
 586      -        const char *netmask;
 587      -        int prefixlen;
 588      -        struct sockaddr_in mask_sin;
 589      -
 590      -        lxi_warn("Could not find \"ips\" property for zone. Looking "
 591      -            "for older \"ip\" and \"netmask\" properties, instead.");
 592      -
 593      -        if (zone_find_attr(attrs, "ip", ipaddrs) != 0) {
 594      -                return (-1);
 595      -        }
 596      -
 597      -        if (strcmp(*ipaddrs, "dhcp") == 0) {
 598      -                return (0);
 599      -        }
 600      -
 601      -        if (zone_find_attr(attrs, "netmask", &netmask) != 0) {
 602      -                lxi_err("could not find netmask for interface");
 603      -                /* NOTREACHED */
 604      -        }
 605      -
 606      -        /* Convert the netmask to a number */
 607      -        mask_sin.sin_family = AF_INET;
 608      -        if (inet_pton(AF_INET, netmask, &mask_sin.sin_addr) != 1) {
 609      -                lxi_err("invalid netmask address: %s\n",
 610      -                    strerror(errno));
 611      -                /* NOTREACHED */
 612      -        }
 613      -        prefixlen = mask2plen((struct sockaddr *)&mask_sin);
 614      -
 615      -        /*
 616      -         * Write out the IP address in the new format and use
 617      -         * that instead
 618      -         */
 619      -        (void) snprintf(cidraddr, len, "%s/%d", *ipaddrs, prefixlen);
 620      -
 621      -        *ipaddrs = cidraddr;
 622      -        return (0);
 623      -}
 624      -
 625  576  static void
 626  577  lxi_net_setup(zone_dochandle_t handle)
 627  578  {
 628  579          struct zone_nwiftab lookup;
 629  580          boolean_t do_addrconf = B_FALSE;
 630  581  
 631  582          if (zonecfg_setnwifent(handle) != Z_OK)
 632  583                  return;
 633  584          while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
 634  585                  const char *iface = lookup.zone_nwif_physical;
 635  586                  struct zone_res_attrtab *attrs = lookup.zone_nwif_attrp;
 636  587                  const char *ipaddrs, *primary, *gateway;
 637      -                char ipaddrs_copy[MAXNAMELEN], cidraddr[BUFSIZ],
      588 +                char ipaddrs_copy[MAXNAMELEN], /* cidraddr[BUFSIZ], */
 638  589                      *ipaddr, *tmp, *lasts;
 639  590                  boolean_t first_ipv4_configured = B_FALSE;
 640  591                  boolean_t *ficp = &first_ipv4_configured;
      592 +                boolean_t no_zonecfg;
 641  593  
      594 +                /*
      595 +                 * Regardless of whether we're configured in zonecfg(1M), or
      596 +                 * configured by other means, make sure we plumb every
      597 +                 * physical=<foo> for IPv4 and IPv6.
      598 +                 */
 642  599                  lxi_net_plumb(iface);
 643      -                if (zone_find_attr(attrs, "ips", &ipaddrs) != 0 &&
 644      -                    lxi_get_old_ip(attrs, &ipaddrs, cidraddr, BUFSIZ) != 0) {
 645      -                        lxi_warn("Could not find a valid network configuration "
 646      -                            "for the %s interface", iface);
 647      -                        continue;
      600 +
      601 +                if (zone_find_attr(attrs, "ips", &ipaddrs) != 0 /* &&
      602 +                    lxi_get_old_ip(attrs, &ipaddrs, cidraddr, BUFSIZ) != 0*/) {
      603 +                        /*
      604 +                         * Do not panic.  This interface has no in-zonecfg(1M)
      605 +                         * configuration.  We keep a warning around for now.
      606 +                         */
      607 +                        lxi_warn("Could not find zonecfg(1M) network "
      608 +                            "configuration for the %s interface", iface);
      609 +                        no_zonecfg = B_TRUE;
      610 +                } else {
      611 +                        no_zonecfg = B_FALSE;
 648  612                  }
 649  613  
 650  614                  if (lxi_iface_ipv6_link_local(iface) != 0) {
 651  615                          lxi_warn("unable to bring up link-local address on "
 652  616                              "interface %s", iface);
 653  617                  }
 654  618  
 655  619                  /*
 656      -                 * If we're going to be doing DHCP, we have to do it first since
 657      -                 * dhcpagent doesn't like to operate on non-zero logical
      620 +                 * Every thing else below only happens if we have zonecfg(1M)
      621 +                 * network configuration.
      622 +                 */
      623 +                if (no_zonecfg)
      624 +                        continue;
      625 +
      626 +                /*
      627 +                 * If we're going to be doing DHCP, we have to do it first
      628 +                 * since dhcpagent doesn't like to operate on non-zero logical
 658  629                   * interfaces.
 659  630                   */
 660  631                  if (strstr(ipaddrs, "dhcp") != NULL &&
 661  632                      lxi_iface_dhcp(iface, ficp) != 0) {
 662  633                          lxi_warn("Failed to start DHCP on %s\n", iface);
 663  634                  }
 664  635  
 665  636                  /*
 666  637                   * Copy the ipaddrs string, since strtok_r will write NUL
 667  638                   * characters into it.
↓ open down ↓ 12 lines elided ↑ open up ↑
 680  651                                  continue;
 681  652                          } else if (lxi_iface_ip(iface, ipaddr, ficp) < 0) {
 682  653                                  lxi_warn("Unable to add new IP address (%s) "
 683  654                                      "to interface %s", ipaddr, iface);
 684  655                          }
 685  656                  }
 686  657  
 687  658                  if (zone_find_attr(attrs, "primary", &primary) == 0 &&
 688  659                      strncmp(primary, "true", MAXNAMELEN) == 0 &&
 689  660                      zone_find_attr(attrs, "gateway", &gateway) == 0) {
 690      -                        lxi_iface_gateway(iface, NULL, 0, gateway);
      661 +                        if (lxi_iface_gateway(iface, NULL, 0, gateway) != 0) {
      662 +                                lxi_err("default route on %s -> %s failed",
      663 +                                    iface, gateway);
      664 +                        }
 691  665                  }
 692  666          }
 693  667  
 694  668          if (do_addrconf) {
 695  669                  lxi_net_ndpd_start();
 696  670          }
 697  671  
 698  672          (void) zonecfg_endnwifent(handle);
 699  673  }
 700  674  
↓ open down ↓ 124 lines elided ↑ open up ↑
 825  799          int e;
 826  800  
 827  801          argv[0] = "init";
 828  802  
 829  803          /*
 830  804           * systemd uses the 'container' env var to determine it is running
 831  805           * inside a container. It only supports a few well-known types and
 832  806           * treats anything else as 'other' but this is enough to make it
 833  807           * behave better inside a zone. See 'detect_container' in systemd.
 834  808           */
 835      -        execve(cmd, argv, envp);
      809 +        (void) execve(cmd, argv, envp);
 836  810          e = errno;
 837  811  
 838  812          /*
 839  813           * Because stdout was closed prior to exec, it must be opened again in
 840  814           * the face of failure to log the error.
 841  815           */
 842  816          lxi_log_open();
 843  817          lxi_err("execve(%s) failed: %s", cmd, strerror(e));
 844  818  }
 845  819  
↓ open down ↓ 27 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX