~ubuntu-branches/ubuntu/wily/globus-gfork/wily-proposed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
#include "globus_common.h"
#include "globus_xio.h"
#include "globus_xio_tcp_driver.h"
#include "globus_xio_file_driver.h"
#include "globus_gfork.h"

#define GFORK_CROWDED_MESSAGE "421 Too busy!\r\n"


#if !defined(GFORK_I_H)
#define GFORK_I_H 1

#ifdef __GNUC__
#define GForkFuncName(func) static const char * _gfork_func_name __attribute__((__unused__)) = #func
#else
#define GForkFuncName(func) static const char * _gfork_func_name = #func
#endif

#define GForkErrorErrno(_msg, _errno) \
    globus_error_put(GForkErrorObjErrno(_msg, _errno))

#define GForkErrorObjErrno(_msg, _errno)                                    \
        globus_error_wrap_errno_error(                                      \
            GLOBUS_GFORK_CHILD_MODULE,                                      \
            (_errno),                                                       \
            GLOBUS_GFORK_ERROR_ERRNO,                                       \
            __FILE__,                                                       \
            _gfork_func_name,                                               \
            __LINE__,                                                       \
            "System error in %s",                                           \
            _msg)

#define GForkErrorStr(_msg) \
    globus_error_put(GForkErrorObjStr(_msg))

#define GForkErrorObjStr(str)                                               \
        globus_error_construct_error(                                       \
            GLOBUS_GFORK_CHILD_MODULE,                                      \
            NULL,                                                           \
            GLOBUS_GFORK_ERROR_STR,                                         \
            __FILE__,                                                       \
            _gfork_func_name,                                               \
            __LINE__,                                                       \
            "GFork error: %s",                                              \
            (str))

GlobusDebugDeclare(GLOBUS_GFORK);

#define GlobusGForkDebugPrintf(level, message)                              \
    GlobusDebugPrintf(GLOBUS_GFORK, level, message)

#define GlobusGForkDebugEnter()                                             \
    GlobusGForkDebugPrintf(                                                 \
        GLOBUS_GFORK_DEBUG_TRACE,                                           \
        ("[%s] Entering\n", _xio_name))

#define GlobusGForkDebugExit()                                              \
    GlobusGForkDebugPrintf(                                                 \
        GLOBUS_GFORK_DEBUG_TRACE,                                           \
        ("[%s] Exiting\n", _xio_name))

#define GlobusGForkDebugExitWithError()                                     \
    GlobusGForkDebugPrintf(                                                 \
        GLOBUS_GFORK_DEBUG_TRACE,                                           \
        ("[%s] Exiting with error\n", _xio_name))

#define GlobusGForkDebugState(_old, _new, _event)                           \
    GlobusGForkDebugPrintf(                                                 \
        GLOBUS_GFORK_DEBUG_STATE,                                           \
        ("State Change from %s to %s when %s\n", _old, _new, _event))

enum
{
    GLOBUS_GFORK_ERROR_ERRNO = 1,
    GLOBUS_GFORK_ERROR_STR
};

typedef enum gfork_i_msg_type_e
{
    GLOBUS_GFORK_MSG_OPEN = 'O',
    GLOBUS_GFORK_MSG_CLOSE = 'C',
    GLOBUS_GFORK_MSG_DATA = 'D'
} gfork_i_msg_type_t;

typedef struct gfork_i_msg_header_s
{
    uint64_t                size;
    pid_t                   from_pid;
    pid_t                   to_pid;
    gfork_i_msg_type_t      type;
} gfork_i_msg_header_t;

typedef struct gfork_i_msg_data_s
{
    int                                 ref;
    globus_byte_t                       buffer[1];
} gfork_i_msg_data_t;

typedef struct gfork_i_msg_s
{
    gfork_i_msg_header_t                header;
    struct gfork_i_child_handle_s *     to_kid;
    struct gfork_i_child_handle_s *     from_kid;
    void *                              user_arg;
    globus_xio_iovec_t *                iov;
    int                                 iovc;
    globus_size_t                       nbytes;
    globus_xio_iovec_t                  write_iov[2];
    globus_xio_iovec_callback_t         client_cb;
    globus_xio_iovec_callback_t         cb;
    gfork_i_msg_data_t *                data;
    globus_byte_t *                     buffer;
    struct gfork_i_lib_handle_s *       lib_handle;
} gfork_i_msg_t;

typedef enum gfork_i_state_e
{
    GFORK_STATE_NONE = 0,
    GFORK_STATE_OPEN,
    GFORK_STATE_OPENING,
    GFORK_STATE_OPENING_AND_CLOSING,
    GFORK_STATE_CLOSING,
    GFORK_STATE_CLOSED,
    GFORK_STATE_COUNT
} gfork_i_state_t;

typedef enum gfork_i_events_s
{
    GFORK_EVENT_NONE = 0,
    GFORK_EVENT_ACCEPT_CB,
    GFORK_EVENT_OPEN_RETURNS,
    GFORK_EVENT_SIGCHILD,
    GFORK_EVENT_CLOSE_RETURNS,
    GFORK_EVENT_COUNT
} gfork_i_events_t;

typedef struct gfork_i_options_s
{
    char *                              id;
    globus_list_t *                     protocol_list;
    char *                              server;
    globus_list_t *                     server_arg_list;
    int                                 port;
    int                                 instances;
    int                                 nice;
    char *                              interface;
    globus_list_t *                     env_list;
    uid_t                               master_user;
    char *                              master;
    int                                 master_nice;
    globus_list_t *                     master_arg_list;
    void *                              user_arg;
    globus_bool_t                       quiet;
    char *                              conf_file;
    int                                 log_level;
    FILE *                              log_fptr;

    char *                              crowded_msg;
    int                                 crowded_msg_len;

    globus_list_t *                     master_list;
} gfork_i_options_t;

typedef struct gfork_i_handle_s
{
    globus_xio_stack_t                  stack;
    char **                             server_argv;
    char **                             master_argv;
    globus_list_t *                     loaded_drivers;
    globus_xio_driver_t                 tcp_driver;
    globus_xio_server_t                 server_xio;
    gfork_i_options_t *                 opts;

    globus_list_t *                     master_list;
} gfork_i_handle_t;

typedef struct gfork_i_child_handle_s
{
    pid_t                               pid;
    int                                 write_fd;
    int                                 read_fd;
    globus_xio_handle_t                 write_xio_handle;
    globus_xio_handle_t                 read_xio_handle;
    gfork_i_handle_t *                  whos_my_daddy;
    void *                              user_arg;
    gfork_i_state_t                     state;
    globus_bool_t                       dead;
    globus_fifo_t                       write_q;
    globus_bool_t                       writting;
    globus_bool_t                       master;
} gfork_i_child_handle_t;

typedef struct gfork_i_lib_handle_s
{
    globus_xio_handle_t                 read_xio;
    globus_xio_handle_t                 write_xio;
    gfork_i_msg_header_t                header;
    globus_byte_t *                     data;
    globus_gfork_incoming_cb_t          incoming_cb;
    globus_gfork_open_func_t            open_cb;
    globus_gfork_closed_func_t          close_cb;
    globus_gfork_error_func_t           error_cb;
    globus_bool_t                       master;
    void *                              user_arg;
    globus_mutex_t                      mutex;
    gfork_i_state_t                     state;
    globus_fifo_t                       write_q;
    globus_bool_t                       writing;
    globus_object_t *                    error_obj;
} gfork_i_lib_handle_t;

typedef struct gfork_i_master_program_ent_s
{
    char *                              master;
    uid_t                               master_uid;
    int                                 master_nice;
    globus_list_t *                     master_arg_list;    
    globus_list_t *                     master_env;
} gfork_i_master_program_ent_t;

globus_result_t
gfork_i_make_xio_handle(
    globus_xio_handle_t *               xio_handle,
    int                                 fd);

void
gfork_i_state_init();

gfork_i_state_t
gfork_i_state_next(
    gfork_i_state_t                 current_state,
    gfork_i_events_t                event);

globus_result_t
globus_i_opts_to_handle(
    gfork_i_options_t *                 opts,
    gfork_i_handle_t *                  handle);

extern globus_xio_stack_t               gfork_i_file_stack;
extern globus_xio_attr_t                gfork_i_file_attr;
extern globus_xio_driver_t              gfork_i_file_driver;

extern globus_options_entry_t           gfork_l_opts_table[];

#endif