Print this page
        
*** 101,111 ****
  
          /*
           * Since a non-zero exit will cause the zone to reboot, a pause here
           * will prevent a mis-configured zone from spinning in a reboot loop.
           */
!         pause();
          exit(1);
          /*NOTREACHED*/
  }
  
  static void
--- 101,111 ----
  
          /*
           * Since a non-zero exit will cause the zone to reboot, a pause here
           * will prevent a mis-configured zone from spinning in a reboot loop.
           */
!         (void) pause();
          exit(1);
          /*NOTREACHED*/
  }
  
  static void
*** 200,222 ****
                  attrs = attrs->zone_res_attr_next;
          }
          return (-1);
  }
  
! void
  lxi_svc_start(char *name, char *path, char *fmri)
  {
          pid_t pid;
          int status;
!         char *const argv[] = {
!                 name,
                  NULL
          };
!         char *const envp[] = {
!                 fmri,
                  NULL
          };
  
          pid = fork();
          if (pid == -1) {
                  lxi_err("fork() failed: %s", strerror(errno));
          }
--- 200,224 ----
                  attrs = attrs->zone_res_attr_next;
          }
          return (-1);
  }
  
! static void
  lxi_svc_start(char *name, char *path, char *fmri)
  {
          pid_t pid;
          int status;
!         char *argv[] = {
!                 NULL,
                  NULL
          };
!         char *envp[] = {
!                 NULL,
                  NULL
          };
+         argv[0] = name;
+         envp[0] = fmri;
  
          pid = fork();
          if (pid == -1) {
                  lxi_err("fork() failed: %s", strerror(errno));
          }
*** 231,250 ****
                   * system root (e.g. "/native") if in use for this zone:
                   */
                  (void) snprintf(cmd, sizeof (cmd), "%s%s", zroot != NULL ?
                      zroot : "", path);
  
!                 execve(cmd, argv, envp);
  
                  lxi_err("execve(%s) failed: %s", cmd, strerror(errno));
                  /* NOTREACHED */
          }
  
          /* parent */
!         while (wait(&status) != pid) {
!                 /* EMPTY */;
!         }
  
          if (WIFEXITED(status)) {
                  if (WEXITSTATUS(status) != 0) {
                          lxi_err("%s[%d] exited: %d", name,
                              (int)pid, WEXITSTATUS(status));
--- 233,251 ----
                   * system root (e.g. "/native") if in use for this zone:
                   */
                  (void) snprintf(cmd, sizeof (cmd), "%s%s", zroot != NULL ?
                      zroot : "", path);
  
!                 (void) execve(cmd, argv, envp);
  
                  lxi_err("execve(%s) failed: %s", cmd, strerror(errno));
                  /* NOTREACHED */
          }
  
          /* parent */
!         while (wait(&status) != pid)
!                 ;
  
          if (WIFEXITED(status)) {
                  if (WEXITSTATUS(status) != 0) {
                          lxi_err("%s[%d] exited: %d", name,
                              (int)pid, WEXITSTATUS(status));
*** 492,505 ****
  static int
  lxi_iface_gateway(const char *iface, const char *dst, int dstpfx,
      const char *gwaddr)
  {
          int idx, len, sockfd;
!         char rtbuf[RTMBUFSZ];
          struct rt_msghdr *rtm = (struct rt_msghdr *)rtbuf;
!         struct sockaddr_in *dst_sin = (struct sockaddr_in *)
!             (rtbuf + sizeof (struct rt_msghdr));
          struct sockaddr_in *gw_sin = (struct sockaddr_in *)(dst_sin + 1);
          struct sockaddr_in *netmask_sin = (struct sockaddr_in *)(gw_sin + 1);
  
          (void) bzero(rtm, RTMBUFSZ);
          rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
--- 493,506 ----
  static int
  lxi_iface_gateway(const char *iface, const char *dst, int dstpfx,
      const char *gwaddr)
  {
          int idx, len, sockfd;
!         /* For lint-happy alignment, use a uint32_t array... */
!         uint32_t rtbuf[RTMBUFSZ / sizeof (uint32_t)];
          struct rt_msghdr *rtm = (struct rt_msghdr *)rtbuf;
!         struct sockaddr_in *dst_sin = (struct sockaddr_in *)(rtm + 1);
          struct sockaddr_in *gw_sin = (struct sockaddr_in *)(dst_sin + 1);
          struct sockaddr_in *netmask_sin = (struct sockaddr_in *)(gw_sin + 1);
  
          (void) bzero(rtm, RTMBUFSZ);
          rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
*** 547,565 ****
                  return (-1);
          }
  
          if ((len = write(sockfd, rtbuf, rtm->rtm_msglen)) < 0) {
                  lxi_warn("could not write rtmsg: %s", strerror(errno));
!                 close(sockfd);
                  return (-1);
          } else if (len < rtm->rtm_msglen) {
                  lxi_warn("write() rtmsg incomplete");
!                 close(sockfd);
                  return (-1);
          }
  
!         close(sockfd);
          return (0);
  }
  
  static void
  lxi_net_loopback()
--- 548,566 ----
                  return (-1);
          }
  
          if ((len = write(sockfd, rtbuf, rtm->rtm_msglen)) < 0) {
                  lxi_warn("could not write rtmsg: %s", strerror(errno));
!                 (void) close(sockfd);
                  return (-1);
          } else if (len < rtm->rtm_msglen) {
                  lxi_warn("write() rtmsg incomplete");
!                 (void) close(sockfd);
                  return (-1);
          }
  
!         (void) close(sockfd);
          return (0);
  }
  
  static void
  lxi_net_loopback()
*** 570,629 ****
          lxi_net_plumb(iface);
          (void) lxi_iface_ip(iface, "127.0.0.1/8", &first_ipv4_configured);
          (void) lxi_iface_ipv6_link_local(iface);
  }
  
- 
- /*
-  * This function is used when the "ips" property doesn't exist in a zone's
-  * configuration. It may be an older configuration, so we should search for
-  * "ip" and "netmask" and convert them into the new format.
-  */
- static int
- lxi_get_old_ip(struct zone_res_attrtab *attrs, const char **ipaddrs,
-     char *cidraddr, int len)
- {
- 
-         const char *netmask;
-         int prefixlen;
-         struct sockaddr_in mask_sin;
- 
-         lxi_warn("Could not find \"ips\" property for zone. Looking "
-             "for older \"ip\" and \"netmask\" properties, instead.");
- 
-         if (zone_find_attr(attrs, "ip", ipaddrs) != 0) {
-                 return (-1);
-         }
- 
-         if (strcmp(*ipaddrs, "dhcp") == 0) {
-                 return (0);
-         }
- 
-         if (zone_find_attr(attrs, "netmask", &netmask) != 0) {
-                 lxi_err("could not find netmask for interface");
-                 /* NOTREACHED */
-         }
- 
-         /* Convert the netmask to a number */
-         mask_sin.sin_family = AF_INET;
-         if (inet_pton(AF_INET, netmask, &mask_sin.sin_addr) != 1) {
-                 lxi_err("invalid netmask address: %s\n",
-                     strerror(errno));
-                 /* NOTREACHED */
-         }
-         prefixlen = mask2plen((struct sockaddr *)&mask_sin);
- 
-         /*
-          * Write out the IP address in the new format and use
-          * that instead
-          */
-         (void) snprintf(cidraddr, len, "%s/%d", *ipaddrs, prefixlen);
- 
-         *ipaddrs = cidraddr;
-         return (0);
- }
- 
  static void
  lxi_net_setup(zone_dochandle_t handle)
  {
          struct zone_nwiftab lookup;
          boolean_t do_addrconf = B_FALSE;
--- 571,580 ----
*** 632,662 ****
                  return;
          while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
                  const char *iface = lookup.zone_nwif_physical;
                  struct zone_res_attrtab *attrs = lookup.zone_nwif_attrp;
                  const char *ipaddrs, *primary, *gateway;
!                 char ipaddrs_copy[MAXNAMELEN], cidraddr[BUFSIZ],
                      *ipaddr, *tmp, *lasts;
                  boolean_t first_ipv4_configured = B_FALSE;
                  boolean_t *ficp = &first_ipv4_configured;
  
                  lxi_net_plumb(iface);
!                 if (zone_find_attr(attrs, "ips", &ipaddrs) != 0 &&
!                     lxi_get_old_ip(attrs, &ipaddrs, cidraddr, BUFSIZ) != 0) {
!                         lxi_warn("Could not find a valid network configuration "
!                             "for the %s interface", iface);
!                         continue;
                  }
  
                  if (lxi_iface_ipv6_link_local(iface) != 0) {
                          lxi_warn("unable to bring up link-local address on "
                              "interface %s", iface);
                  }
  
                  /*
!                  * If we're going to be doing DHCP, we have to do it first since
!                  * dhcpagent doesn't like to operate on non-zero logical
                   * interfaces.
                   */
                  if (strstr(ipaddrs, "dhcp") != NULL &&
                      lxi_iface_dhcp(iface, ficp) != 0) {
                          lxi_warn("Failed to start DHCP on %s\n", iface);
--- 583,633 ----
                  return;
          while (zonecfg_getnwifent(handle, &lookup) == Z_OK) {
                  const char *iface = lookup.zone_nwif_physical;
                  struct zone_res_attrtab *attrs = lookup.zone_nwif_attrp;
                  const char *ipaddrs, *primary, *gateway;
!                 char ipaddrs_copy[MAXNAMELEN], /* cidraddr[BUFSIZ], */
                      *ipaddr, *tmp, *lasts;
                  boolean_t first_ipv4_configured = B_FALSE;
                  boolean_t *ficp = &first_ipv4_configured;
+                 boolean_t no_zonecfg;
  
+                 /*
+                  * Regardless of whether we're configured in zonecfg(1M), or
+                  * configured by other means, make sure we plumb every
+                  * physical=<foo> for IPv4 and IPv6.
+                  */
                  lxi_net_plumb(iface);
! 
!                 if (zone_find_attr(attrs, "ips", &ipaddrs) != 0 /* &&
!                     lxi_get_old_ip(attrs, &ipaddrs, cidraddr, BUFSIZ) != 0*/) {
!                         /*
!                          * Do not panic.  This interface has no in-zonecfg(1M)
!                          * configuration.  We keep a warning around for now.
!                          */
!                         lxi_warn("Could not find zonecfg(1M) network "
!                             "configuration for the %s interface", iface);
!                         no_zonecfg = B_TRUE;
!                 } else {
!                         no_zonecfg = B_FALSE;
                  }
  
                  if (lxi_iface_ipv6_link_local(iface) != 0) {
                          lxi_warn("unable to bring up link-local address on "
                              "interface %s", iface);
                  }
  
                  /*
!                  * Every thing else below only happens if we have zonecfg(1M)
!                  * network configuration.
!                  */
!                 if (no_zonecfg)
!                         continue;
! 
!                 /*
!                  * If we're going to be doing DHCP, we have to do it first
!                  * since dhcpagent doesn't like to operate on non-zero logical
                   * interfaces.
                   */
                  if (strstr(ipaddrs, "dhcp") != NULL &&
                      lxi_iface_dhcp(iface, ficp) != 0) {
                          lxi_warn("Failed to start DHCP on %s\n", iface);
*** 685,697 ****
                  }
  
                  if (zone_find_attr(attrs, "primary", &primary) == 0 &&
                      strncmp(primary, "true", MAXNAMELEN) == 0 &&
                      zone_find_attr(attrs, "gateway", &gateway) == 0) {
!                         lxi_iface_gateway(iface, NULL, 0, gateway);
                  }
          }
  
          if (do_addrconf) {
                  lxi_net_ndpd_start();
          }
  
--- 656,671 ----
                  }
  
                  if (zone_find_attr(attrs, "primary", &primary) == 0 &&
                      strncmp(primary, "true", MAXNAMELEN) == 0 &&
                      zone_find_attr(attrs, "gateway", &gateway) == 0) {
!                         if (lxi_iface_gateway(iface, NULL, 0, gateway) != 0) {
!                                 lxi_err("default route on %s -> %s failed",
!                                     iface, gateway);
                          }
                  }
+         }
  
          if (do_addrconf) {
                  lxi_net_ndpd_start();
          }
  
*** 830,840 ****
           * systemd uses the 'container' env var to determine it is running
           * inside a container. It only supports a few well-known types and
           * treats anything else as 'other' but this is enough to make it
           * behave better inside a zone. See 'detect_container' in systemd.
           */
!         execve(cmd, argv, envp);
          e = errno;
  
          /*
           * Because stdout was closed prior to exec, it must be opened again in
           * the face of failure to log the error.
--- 804,814 ----
           * systemd uses the 'container' env var to determine it is running
           * inside a container. It only supports a few well-known types and
           * treats anything else as 'other' but this is enough to make it
           * behave better inside a zone. See 'detect_container' in systemd.
           */
!         (void) execve(cmd, argv, envp);
          e = errno;
  
          /*
           * Because stdout was closed prior to exec, it must be opened again in
           * the face of failure to log the error.