Print this page
Reduce lint


  86 static void
  87 lxi_err(char *msg, ...)
  88 {
  89         char buf[1024];
  90         int len;
  91         va_list ap;
  92 
  93         va_start(ap, msg);
  94         /*LINTED*/
  95         len = vsnprintf(buf, sizeof (buf), msg, ap);
  96         va_end(ap);
  97 
  98         (void) write(1, PREFIX_LOG_ERR, strlen(PREFIX_LOG_ERR));
  99         (void) write(1, buf, len);
 100         (void) write(1, "\n", 1);
 101 
 102         /*
 103          * Since a non-zero exit will cause the zone to reboot, a pause here
 104          * will prevent a mis-configured zone from spinning in a reboot loop.
 105          */
 106         pause();
 107         exit(1);
 108         /*NOTREACHED*/
 109 }
 110 
 111 static void
 112 lxi_warn(char *msg, ...)
 113 {
 114         char buf[1024];
 115         int len;
 116         va_list ap;
 117 
 118         va_start(ap, msg);
 119         /*LINTED*/
 120         len = vsnprintf(buf, sizeof (buf), msg, ap);
 121         va_end(ap);
 122 
 123         (void) write(1, PREFIX_LOG_WARN, strlen(PREFIX_LOG_WARN));
 124         (void) write(1, buf, len);
 125         (void) write(1, "\n", 1);
 126 }


 187 
 188 }
 189 
 190 #if 0 /* XXX KEBE SAYS NOT YET */
 191 static int
 192 zone_find_attr(struct zone_res_attrtab *attrs, const char *name,
 193     const char **result)
 194 {
 195         while (attrs != NULL) {
 196                 if (strncmp(attrs->zone_res_attr_name, name,
 197                     MAXNAMELEN) == 0) {
 198                         *result = attrs->zone_res_attr_value;
 199                         return (0);
 200                 }
 201                 attrs = attrs->zone_res_attr_next;
 202         }
 203         return (-1);
 204 }
 205 #endif /* XXX KEBE SAYS NOT YET */
 206 
 207 void
 208 lxi_svc_start(char *name, char *path, char *fmri)
 209 {
 210         pid_t pid;
 211         int status;
 212         char *const argv[] = {
 213                 name,
 214                 NULL
 215         };
 216         char *const envp[] = {
 217                 fmri,
 218                 NULL
 219         };


 220 
 221         pid = fork();
 222         if (pid == -1) {
 223                 lxi_err("fork() failed: %s", strerror(errno));
 224         }
 225 
 226         if (pid == 0) {
 227                 /* child */
 228                 const char *zroot = zone_get_nroot();
 229                 char cmd[MAXPATHLEN];
 230 
 231                 /*
 232                  * Construct the full path to the binary, including the native
 233                  * system root (e.g. "/native") if in use for this zone:
 234                  */
 235                 (void) snprintf(cmd, sizeof (cmd), "%s%s", zroot != NULL ?
 236                     zroot : "", path);
 237 
 238                 execve(cmd, argv, envp);
 239 
 240                 lxi_err("execve(%s) failed: %s", cmd, strerror(errno));
 241                 /* NOTREACHED */
 242         }
 243 
 244         /* parent */
 245         while (wait(&status) != pid) {
 246                 /* EMPTY */;
 247         }
 248 
 249         if (WIFEXITED(status)) {
 250                 if (WEXITSTATUS(status) != 0) {
 251                         lxi_err("%s[%d] exited: %d", name,
 252                             (int)pid, WEXITSTATUS(status));
 253                 }
 254         } else if (WIFSIGNALED(status)) {
 255                 lxi_err("%s[%d] died on signal: %d", name,
 256                     (int)pid, WTERMSIG(status));
 257         } else {
 258                 lxi_err("%s[%d] failed in unknown way", name,
 259                     (int)pid);
 260         }
 261 }
 262 
 263 void
 264 lxi_net_ipmgmtd_start()
 265 {
 266         lxi_svc_start("ipmgmtd", IPMGMTD_PATH,
 267             "SMF_FMRI=svc:/network/ip-interface-management:default");


 481                     errno, iface, strerror(errno));
 482                 return (-1);
 483         }
 484 
 485         lifr.lifr_flags |= IFF_UP;
 486         if (ioctl(s, SIOCSLIFFLAGS, (caddr_t)&lifr) < 0) {
 487                 lxi_warn("SIOCSLIFFLAGS error %d: bringing up %s: %s",
 488                     errno, iface, strerror(errno));
 489                 return (-1);
 490         }
 491 
 492         (void) close(s);
 493         return (0);
 494 }
 495 
 496 static int
 497 lxi_iface_gateway(const char *iface, const char *dst, int dstpfx,
 498     const char *gwaddr)
 499 {
 500         int idx, len, sockfd;
 501         char rtbuf[RTMBUFSZ];

 502         struct rt_msghdr *rtm = (struct rt_msghdr *)rtbuf;
 503         struct sockaddr_in *dst_sin = (struct sockaddr_in *)
 504             (rtbuf + sizeof (struct rt_msghdr));
 505         struct sockaddr_in *gw_sin = (struct sockaddr_in *)(dst_sin + 1);
 506         struct sockaddr_in *netmask_sin = (struct sockaddr_in *)(gw_sin + 1);
 507 
 508         (void) bzero(rtm, RTMBUFSZ);
 509         rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
 510         rtm->rtm_flags = RTF_UP | RTF_STATIC | RTF_GATEWAY;
 511         rtm->rtm_msglen = sizeof (rtbuf);
 512         rtm->rtm_pid = getpid();
 513         rtm->rtm_type = RTM_ADD;
 514         rtm->rtm_version = RTM_VERSION;
 515 
 516 
 517         /*
 518          * The destination and netmask components have already been zeroed,
 519          * which represents the default gateway.  If we were passed a more
 520          * specific destination network, use that instead.
 521          */
 522         dst_sin->sin_family = AF_INET;
 523         netmask_sin->sin_family = AF_INET;
 524         if (dst != NULL) {


 536                 lxi_warn("bad gateway %s: %s", gwaddr, strerror(errno));
 537                 return (-1);
 538         }
 539 
 540         if (iface != NULL) {
 541                 if ((idx = if_nametoindex(iface)) == 0) {
 542                         lxi_warn("unable to get interface index for %s: %s\n",
 543                             iface, strerror(errno));
 544                         return (-1);
 545                 }
 546                 rtm->rtm_index = idx;
 547         }
 548 
 549         if ((sockfd = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
 550                 lxi_warn("socket(PF_ROUTE): %s\n", strerror(errno));
 551                 return (-1);
 552         }
 553 
 554         if ((len = write(sockfd, rtbuf, rtm->rtm_msglen)) < 0) {
 555                 lxi_warn("could not write rtmsg: %s", strerror(errno));
 556                 close(sockfd);
 557                 return (-1);
 558         } else if (len < rtm->rtm_msglen) {
 559                 lxi_warn("write() rtmsg incomplete");
 560                 close(sockfd);
 561                 return (-1);
 562         }
 563 
 564         close(sockfd);
 565         return (0);
 566 }
 567 
 568 static void
 569 lxi_net_loopback()
 570 {
 571         const char *iface = "lo0";
 572         boolean_t first_ipv4_configured = B_FALSE;
 573 
 574         lxi_net_plumb(iface);
 575         (void) lxi_iface_ip(iface, "127.0.0.1/8", &first_ipv4_configured);
 576         (void) lxi_iface_ipv6_link_local(iface);
 577 }
 578 
 579 
 580 
 581 #if 0 /* XXX KEBE SAYS NOT YET */
 582 /*
 583  * This function is used when the "ips" property doesn't exist in a zone's
 584  * configuration. It may be an older configuration, so we should search for


 831 lxi_config_close(zone_dochandle_t handle)
 832 {
 833         zonecfg_fini_handle(handle);
 834 }
 835 
 836 static void
 837 lxi_init_exec(char **argv)
 838 {
 839         const char *cmd = "/sbin/init";
 840         char *const envp[] = { "container=zone", NULL };
 841         int e;
 842 
 843         argv[0] = "init";
 844 
 845         /*
 846          * systemd uses the 'container' env var to determine it is running
 847          * inside a container. It only supports a few well-known types and
 848          * treats anything else as 'other' but this is enough to make it
 849          * behave better inside a zone. See 'detect_container' in systemd.
 850          */
 851         execve(cmd, argv, envp);
 852         e = errno;
 853 
 854         /*
 855          * Because stdout was closed prior to exec, it must be opened again in
 856          * the face of failure to log the error.
 857          */
 858         lxi_log_open();
 859         lxi_err("execve(%s) failed: %s", cmd, strerror(e));
 860 }
 861 
 862 /*ARGSUSED*/
 863 int
 864 main(int argc, char *argv[])
 865 {
 866         zone_dochandle_t handle;
 867 
 868         lxi_log_open();
 869 
 870         lxi_net_ipmgmtd_start();
 871         lxi_net_ipadm_open();


  86 static void
  87 lxi_err(char *msg, ...)
  88 {
  89         char buf[1024];
  90         int len;
  91         va_list ap;
  92 
  93         va_start(ap, msg);
  94         /*LINTED*/
  95         len = vsnprintf(buf, sizeof (buf), msg, ap);
  96         va_end(ap);
  97 
  98         (void) write(1, PREFIX_LOG_ERR, strlen(PREFIX_LOG_ERR));
  99         (void) write(1, buf, len);
 100         (void) write(1, "\n", 1);
 101 
 102         /*
 103          * Since a non-zero exit will cause the zone to reboot, a pause here
 104          * will prevent a mis-configured zone from spinning in a reboot loop.
 105          */
 106         (void) pause();
 107         exit(1);
 108         /*NOTREACHED*/
 109 }
 110 
 111 static void
 112 lxi_warn(char *msg, ...)
 113 {
 114         char buf[1024];
 115         int len;
 116         va_list ap;
 117 
 118         va_start(ap, msg);
 119         /*LINTED*/
 120         len = vsnprintf(buf, sizeof (buf), msg, ap);
 121         va_end(ap);
 122 
 123         (void) write(1, PREFIX_LOG_WARN, strlen(PREFIX_LOG_WARN));
 124         (void) write(1, buf, len);
 125         (void) write(1, "\n", 1);
 126 }


 187 
 188 }
 189 
 190 #if 0 /* XXX KEBE SAYS NOT YET */
 191 static int
 192 zone_find_attr(struct zone_res_attrtab *attrs, const char *name,
 193     const char **result)
 194 {
 195         while (attrs != NULL) {
 196                 if (strncmp(attrs->zone_res_attr_name, name,
 197                     MAXNAMELEN) == 0) {
 198                         *result = attrs->zone_res_attr_value;
 199                         return (0);
 200                 }
 201                 attrs = attrs->zone_res_attr_next;
 202         }
 203         return (-1);
 204 }
 205 #endif /* XXX KEBE SAYS NOT YET */
 206 
 207 static void
 208 lxi_svc_start(char *name, char *path, char *fmri)
 209 {
 210         pid_t pid;
 211         int status;
 212         char *argv[] = {
 213                 NULL,
 214                 NULL
 215         };
 216         char *envp[] = {
 217                 NULL,
 218                 NULL
 219         };
 220         argv[0] = name;
 221         envp[0] = fmri;
 222 
 223         pid = fork();
 224         if (pid == -1) {
 225                 lxi_err("fork() failed: %s", strerror(errno));
 226         }
 227 
 228         if (pid == 0) {
 229                 /* child */
 230                 const char *zroot = zone_get_nroot();
 231                 char cmd[MAXPATHLEN];
 232 
 233                 /*
 234                  * Construct the full path to the binary, including the native
 235                  * system root (e.g. "/native") if in use for this zone:
 236                  */
 237                 (void) snprintf(cmd, sizeof (cmd), "%s%s", zroot != NULL ?
 238                     zroot : "", path);
 239 
 240                 (void) execve(cmd, argv, envp);
 241 
 242                 lxi_err("execve(%s) failed: %s", cmd, strerror(errno));
 243                 /* NOTREACHED */
 244         }
 245 
 246         /* parent */
 247         while (wait(&status) != pid)
 248                 ;

 249 
 250         if (WIFEXITED(status)) {
 251                 if (WEXITSTATUS(status) != 0) {
 252                         lxi_err("%s[%d] exited: %d", name,
 253                             (int)pid, WEXITSTATUS(status));
 254                 }
 255         } else if (WIFSIGNALED(status)) {
 256                 lxi_err("%s[%d] died on signal: %d", name,
 257                     (int)pid, WTERMSIG(status));
 258         } else {
 259                 lxi_err("%s[%d] failed in unknown way", name,
 260                     (int)pid);
 261         }
 262 }
 263 
 264 void
 265 lxi_net_ipmgmtd_start()
 266 {
 267         lxi_svc_start("ipmgmtd", IPMGMTD_PATH,
 268             "SMF_FMRI=svc:/network/ip-interface-management:default");


 482                     errno, iface, strerror(errno));
 483                 return (-1);
 484         }
 485 
 486         lifr.lifr_flags |= IFF_UP;
 487         if (ioctl(s, SIOCSLIFFLAGS, (caddr_t)&lifr) < 0) {
 488                 lxi_warn("SIOCSLIFFLAGS error %d: bringing up %s: %s",
 489                     errno, iface, strerror(errno));
 490                 return (-1);
 491         }
 492 
 493         (void) close(s);
 494         return (0);
 495 }
 496 
 497 static int
 498 lxi_iface_gateway(const char *iface, const char *dst, int dstpfx,
 499     const char *gwaddr)
 500 {
 501         int idx, len, sockfd;
 502         /* For lint-happy alignment, use a uint32_t array... */
 503         uint32_t rtbuf[RTMBUFSZ / sizeof (uint32_t)];
 504         struct rt_msghdr *rtm = (struct rt_msghdr *)rtbuf;
 505         struct sockaddr_in *dst_sin = (struct sockaddr_in *)(rtm + 1);

 506         struct sockaddr_in *gw_sin = (struct sockaddr_in *)(dst_sin + 1);
 507         struct sockaddr_in *netmask_sin = (struct sockaddr_in *)(gw_sin + 1);
 508 
 509         (void) bzero(rtm, RTMBUFSZ);
 510         rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
 511         rtm->rtm_flags = RTF_UP | RTF_STATIC | RTF_GATEWAY;
 512         rtm->rtm_msglen = sizeof (rtbuf);
 513         rtm->rtm_pid = getpid();
 514         rtm->rtm_type = RTM_ADD;
 515         rtm->rtm_version = RTM_VERSION;
 516 
 517 
 518         /*
 519          * The destination and netmask components have already been zeroed,
 520          * which represents the default gateway.  If we were passed a more
 521          * specific destination network, use that instead.
 522          */
 523         dst_sin->sin_family = AF_INET;
 524         netmask_sin->sin_family = AF_INET;
 525         if (dst != NULL) {


 537                 lxi_warn("bad gateway %s: %s", gwaddr, strerror(errno));
 538                 return (-1);
 539         }
 540 
 541         if (iface != NULL) {
 542                 if ((idx = if_nametoindex(iface)) == 0) {
 543                         lxi_warn("unable to get interface index for %s: %s\n",
 544                             iface, strerror(errno));
 545                         return (-1);
 546                 }
 547                 rtm->rtm_index = idx;
 548         }
 549 
 550         if ((sockfd = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {
 551                 lxi_warn("socket(PF_ROUTE): %s\n", strerror(errno));
 552                 return (-1);
 553         }
 554 
 555         if ((len = write(sockfd, rtbuf, rtm->rtm_msglen)) < 0) {
 556                 lxi_warn("could not write rtmsg: %s", strerror(errno));
 557                 (void) close(sockfd);
 558                 return (-1);
 559         } else if (len < rtm->rtm_msglen) {
 560                 lxi_warn("write() rtmsg incomplete");
 561                 (void) close(sockfd);
 562                 return (-1);
 563         }
 564 
 565         (void) close(sockfd);
 566         return (0);
 567 }
 568 
 569 static void
 570 lxi_net_loopback()
 571 {
 572         const char *iface = "lo0";
 573         boolean_t first_ipv4_configured = B_FALSE;
 574 
 575         lxi_net_plumb(iface);
 576         (void) lxi_iface_ip(iface, "127.0.0.1/8", &first_ipv4_configured);
 577         (void) lxi_iface_ipv6_link_local(iface);
 578 }
 579 
 580 
 581 
 582 #if 0 /* XXX KEBE SAYS NOT YET */
 583 /*
 584  * This function is used when the "ips" property doesn't exist in a zone's
 585  * configuration. It may be an older configuration, so we should search for


 832 lxi_config_close(zone_dochandle_t handle)
 833 {
 834         zonecfg_fini_handle(handle);
 835 }
 836 
 837 static void
 838 lxi_init_exec(char **argv)
 839 {
 840         const char *cmd = "/sbin/init";
 841         char *const envp[] = { "container=zone", NULL };
 842         int e;
 843 
 844         argv[0] = "init";
 845 
 846         /*
 847          * systemd uses the 'container' env var to determine it is running
 848          * inside a container. It only supports a few well-known types and
 849          * treats anything else as 'other' but this is enough to make it
 850          * behave better inside a zone. See 'detect_container' in systemd.
 851          */
 852         (void) execve(cmd, argv, envp);
 853         e = errno;
 854 
 855         /*
 856          * Because stdout was closed prior to exec, it must be opened again in
 857          * the face of failure to log the error.
 858          */
 859         lxi_log_open();
 860         lxi_err("execve(%s) failed: %s", cmd, strerror(e));
 861 }
 862 
 863 /*ARGSUSED*/
 864 int
 865 main(int argc, char *argv[])
 866 {
 867         zone_dochandle_t handle;
 868 
 869         lxi_log_open();
 870 
 871         lxi_net_ipmgmtd_start();
 872         lxi_net_ipadm_open();