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.