Print this page
OS-4741 Add support for multiple addresses & IPv6 to lx-branded zones
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>


  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/ctfs.h>
  28 #include <sys/contract/process.h>
  29 #include <sys/socket.h>
  30 #include <sys/time.h>
  31 #include <sys/wait.h>
  32 #include <fcntl.h>
  33 #include <libcontract.h>
  34 #include <libcontract_priv.h>
  35 #include <unistd.h>
  36 #include <stdio.h>
  37 #include <stdlib.h>
  38 #include <string.h>

  39 
  40 #include "dhcpagent_ipc.h"
  41 #include "dhcpagent_util.h"
  42 
  43 /*
  44  * Strings returned by dhcp_status_hdr_string() and
  45  * dhcp_status_reply_to_string(). The first define is the header line, and
  46  * the second defines line printed underneath.
  47  * The spacing of fields must match.
  48  */
  49 #define DHCP_STATUS_HDR "Interface  State         Sent  Recv  Declined  Flags\n"
  50 #define DHCP_STATUS_STR "%-10s %-12s %5d %5d %9d  "
  51 
  52 static const char *time_to_string(time_t abs_time);
  53 
  54 /*
  55  * dhcp_state_to_string(): given a state, provides the state's name
  56  *
  57  *    input: DHCPSTATE: the state to get the name of
  58  *   output: const char *: the state's name


 108         return (fd);
 109 }
 110 
 111 /*
 112  * dhcp_start_agent(): starts the agent if not already running
 113  *
 114  *   input: int: number of seconds to wait for agent to start (-1 is forever)
 115  *  output: int: 0 on success, -1 on failure
 116  */
 117 
 118 int
 119 dhcp_start_agent(int timeout)
 120 {
 121         int                     error;
 122         time_t                  start_time = time(NULL);
 123         dhcp_ipc_request_t      *request;
 124         dhcp_ipc_reply_t        *reply;
 125         int                     ctfd;
 126         pid_t                   childpid;
 127         ctid_t                  ct;


 128 




 129         /*
 130          * just send a dummy request to the agent to find out if it's
 131          * up.  we do this instead of directly connecting to it since
 132          * we want to make sure we follow its IPC conventions
 133          * (otherwise, it will log warnings to syslog).
 134          */
 135 
 136         request = dhcp_ipc_alloc_request(DHCP_PING, "", NULL, 0,
 137             DHCP_TYPE_NONE);
 138         if (request == NULL)
 139                 return (-1);
 140 
 141         error = dhcp_ipc_make_request(request, &reply, 0);
 142         if (error == 0) {
 143                 free(reply);
 144                 free(request);
 145                 return (0);
 146         }
 147         if (error != DHCP_IPC_E_CONNECT)
 148                 goto fail;
 149 
 150         if ((ctfd = init_template()) == -1)
 151                 goto fail;
 152 
 153         childpid = fork();
 154 
 155         (void) ct_tmpl_clear(ctfd);
 156         (void) close(ctfd);
 157 
 158         switch (childpid) {
 159         case -1:
 160                 goto fail;
 161 
 162         case  0:
 163                 (void) execl(DHCP_AGENT_PATH, DHCP_AGENT_PATH, (char *)0);
 164                 _exit(EXIT_FAILURE);
 165 
 166         default:
 167                 break;
 168         }
 169 
 170         /* wait for the daemon to run and then abandon the contract */
 171         (void) waitpid(childpid, NULL, 0);
 172 
 173         if (contract_latest(&ct) != -1)
 174                 (void) contract_abandon_id(ct);
 175 
 176         while ((timeout != -1) && (time(NULL) - start_time < timeout)) {
 177                 error = dhcp_ipc_make_request(request, &reply, 0);
 178                 if (error == 0) {
 179                         free(reply);
 180                         free(request);
 181                         return (0);
 182                 } else if (error != DHCP_IPC_E_CONNECT)
 183                         break;




  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/ctfs.h>
  28 #include <sys/contract/process.h>
  29 #include <sys/socket.h>
  30 #include <sys/time.h>
  31 #include <sys/wait.h>
  32 #include <fcntl.h>
  33 #include <libcontract.h>
  34 #include <libcontract_priv.h>
  35 #include <unistd.h>
  36 #include <stdio.h>
  37 #include <stdlib.h>
  38 #include <string.h>
  39 #include <zone.h>
  40 
  41 #include "dhcpagent_ipc.h"
  42 #include "dhcpagent_util.h"
  43 
  44 /*
  45  * Strings returned by dhcp_status_hdr_string() and
  46  * dhcp_status_reply_to_string(). The first define is the header line, and
  47  * the second defines line printed underneath.
  48  * The spacing of fields must match.
  49  */
  50 #define DHCP_STATUS_HDR "Interface  State         Sent  Recv  Declined  Flags\n"
  51 #define DHCP_STATUS_STR "%-10s %-12s %5d %5d %9d  "
  52 
  53 static const char *time_to_string(time_t abs_time);
  54 
  55 /*
  56  * dhcp_state_to_string(): given a state, provides the state's name
  57  *
  58  *    input: DHCPSTATE: the state to get the name of
  59  *   output: const char *: the state's name


 109         return (fd);
 110 }
 111 
 112 /*
 113  * dhcp_start_agent(): starts the agent if not already running
 114  *
 115  *   input: int: number of seconds to wait for agent to start (-1 is forever)
 116  *  output: int: 0 on success, -1 on failure
 117  */
 118 
 119 int
 120 dhcp_start_agent(int timeout)
 121 {
 122         int                     error;
 123         time_t                  start_time = time(NULL);
 124         dhcp_ipc_request_t      *request;
 125         dhcp_ipc_reply_t        *reply;
 126         int                     ctfd;
 127         pid_t                   childpid;
 128         ctid_t                  ct;
 129         char                    dhcpcmd[MAXPATHLEN];
 130         const char              *zroot = zone_get_nroot();
 131 
 132         /* Prepend the root of the native code in the brand to the command */
 133         (void) snprintf(dhcpcmd, sizeof (dhcpcmd), "%s%s", zroot != NULL ?
 134             zroot : "", DHCP_AGENT_PATH);
 135 
 136         /*
 137          * just send a dummy request to the agent to find out if it's
 138          * up.  we do this instead of directly connecting to it since
 139          * we want to make sure we follow its IPC conventions
 140          * (otherwise, it will log warnings to syslog).
 141          */
 142 
 143         request = dhcp_ipc_alloc_request(DHCP_PING, "", NULL, 0,
 144             DHCP_TYPE_NONE);
 145         if (request == NULL)
 146                 return (-1);
 147 
 148         error = dhcp_ipc_make_request(request, &reply, 0);
 149         if (error == 0) {
 150                 free(reply);
 151                 free(request);
 152                 return (0);
 153         }
 154         if (error != DHCP_IPC_E_CONNECT)
 155                 goto fail;
 156 
 157         if ((ctfd = init_template()) == -1)
 158                 goto fail;
 159 
 160         childpid = fork();
 161 
 162         (void) ct_tmpl_clear(ctfd);
 163         (void) close(ctfd);
 164 
 165         switch (childpid) {
 166         case -1:
 167                 goto fail;
 168 
 169         case  0:
 170                 (void) execl(dhcpcmd, dhcpcmd, (char *)0);
 171                 _exit(EXIT_FAILURE);
 172 
 173         default:
 174                 break;
 175         }
 176 
 177         /* wait for the daemon to run and then abandon the contract */
 178         (void) waitpid(childpid, NULL, 0);
 179 
 180         if (contract_latest(&ct) != -1)
 181                 (void) contract_abandon_id(ct);
 182 
 183         while ((timeout != -1) && (time(NULL) - start_time < timeout)) {
 184                 error = dhcp_ipc_make_request(request, &reply, 0);
 185                 if (error == 0) {
 186                         free(reply);
 187                         free(request);
 188                         return (0);
 189                 } else if (error != DHCP_IPC_E_CONNECT)
 190                         break;