1 /****************************************************************************
2 * Copyright (C) 2006-2008 by Jason Ansel, Kapil Arya, and Gene Cooperman *
3 * jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu *
4 * *
5 * This file is part of the dmtcp/src module of DMTCP (DMTCP:dmtcp/src). *
6 * *
7 * DMTCP:dmtcp/src is free software: you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public License as *
9 * published by the Free Software Foundation, either version 3 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * DMTCP:dmtcp/src is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with DMTCP:dmtcp/src. If not, see *
19 * <http://www.gnu.org/licenses/>. *
20 ****************************************************************************/
21
22 #ifndef DMTCPCONNECTION_H
23 #define DMTCPCONNECTION_H
24
25 #include "dmtcpalloc.h"
26 #include "dmtcpworker.h"
27 #include "connectionidentifier.h"
28 #include <vector>
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <map>
32 #include "../jalib/jbuffer.h"
33 #include "../jalib/jserialize.h"
34 #include "../jalib/jassert.h"
35 #include "../jalib/jconvert.h"
36 #include "../jalib/jalloc.h"
37 #include "../jalib/jfilesystem.h"
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <unistd.h>
41
42 namespace jalib { class JSocket; }
43
44 namespace dmtcp
45 {
46
47 class KernelBufferDrainer;
48 class ConnectionRewirer;
49 class TcpConnection;
50 class KernelDeviceToConnection;
51 class ConnectionToFds;
52
53
54 class Connection
55 {
56 public:
57 #ifdef JALIB_ALLOCATOR
58 static void* operator new(size_t nbytes, void* p) { return p; }
59 static void* operator new(size_t nbytes) { JALLOC_HELPER_NEW(nbytes); }
60 static void operator delete(void* p) { JALLOC_HELPER_DELETE(p); }
61 #endif
62 enum ConnectionType
63 {
64 INVALID = 0x0000,
65 TCP = 0x1000,
66 PIPE = 0x2000,
67 PTY = 0x3000,
68 FILE = 0x4000,
69 STDIO = 0x5000,
70 FIFO = 0x6000,
71 TYPEMASK = TCP | PIPE | PTY | FILE | STDIO | FIFO
72 };
73
74 virtual ~Connection() {}
75
76 int conType() const { return _type & TYPEMASK; }
77 bool restoreInSecondIteration() { return _restoreInSecondIteration; }
78
79 const ConnectionIdentifier& id() const { return _id; }
80
81 virtual void preCheckpoint ( const dmtcp::vector<int>& fds, KernelBufferDrainer& ) = 0;
82 virtual void postCheckpoint ( const dmtcp::vector<int>& fds,
83 bool isRestart = false) = 0;
84 virtual void restore ( const dmtcp::vector<int>&, ConnectionRewirer& ) = 0;
85
86 virtual bool isDupConnection ( const Connection& _that,
87 dmtcp::ConnectionToFds& conToFds ) { return false; };
88 virtual void doLocking ( const dmtcp::vector<int>& fds );
89 virtual void saveOptions ( const dmtcp::vector<int>& fds );
90 virtual void restoreOptions ( const dmtcp::vector<int>& fds );
91
92 virtual void doSendHandshakes( const dmtcp::vector<int>& fds, const dmtcp::UniquePid& coordinator ) {};
93 virtual void doRecvHandshakes( const dmtcp::vector<int>& fds, const dmtcp::UniquePid& coordinator ) {};
94
95 //called on restart when _id collides with another connection
96 virtual void mergeWith ( const Connection& that );
97
98 //convert with type checking
99 virtual TcpConnection& asTcp();
100
101 virtual void restartDup2(int oldFd, int newFd);
102
103
104 void serialize ( jalib::JBinarySerializer& o );
105 protected:
106 virtual void serializeSubClass ( jalib::JBinarySerializer& o ) = 0;
107 protected:
108 //only child classes can construct us...
109 Connection ( int t );
110 protected:
111 ConnectionIdentifier _id;
112 int _type;
113 int _fcntlFlags;
114 int _fcntlOwner;
115 int _fcntlSignal;
116 bool _restoreInSecondIteration;
117 };
118
119 class TcpConnection : public Connection
120 {
121 public:
122 enum TcpType
123 {
124 TCP_INVALID = TCP,
125 TCP_ERROR,
126 TCP_CREATED,
127 TCP_BIND,
128 TCP_LISTEN,
129 TCP_ACCEPT,
130 TCP_CONNECT,
131 TCP_PREEXISTING,
132 TCP_EXTERNAL_CONNECT
133 };
134
135 int tcpType() const { return _type; }
136
137 #ifdef EXTERNAL_SOCKET_HANDLING
138 enum PeerType
139 {
140 PEER_UNKNOWN,
141 PEER_INTERNAL,
142 PEER_EXTERNAL
143 };
144
145 enum PeerType peerType() const { return _peerType; }
146
147 void markInternal() {
148 if (_type == TCP_ACCEPT || _type == TCP_CONNECT)
149 _peerType = PEER_INTERNAL;
150 }
151 void markExternal() {
152 if (_type == TCP_ACCEPT || _type == TCP_CONNECT)
153 _peerType = PEER_EXTERNAL;
154 }
155 void preCheckpointPeerLookup ( const dmtcp::vector<int>& fds,
156 dmtcp::vector<TcpConnectionInfo>& conInfoTable);
157 #endif
158
159 //basic commands for updating state as a from wrappers
160 /*onSocket*/ TcpConnection ( int domain, int type, int protocol );
161 void onBind ( const struct sockaddr* addr, socklen_t len );
162 void onListen ( int backlog );
163 void onConnect( int sockfd = -1, const struct sockaddr *serv_addr = NULL,
164 socklen_t addrlen = 0 );
165 /*onAccept*/ TcpConnection ( const TcpConnection& parent, const ConnectionIdentifier& remote );
166 void onError();
167 void onDisconnect(const dmtcp::vector<int>& fds);
168 void addSetsockopt ( int level, int option, const char* value, int len );
169
170 void markPreExisting() { _type = TCP_PREEXISTING; }
171
172 //basic checkpointing commands
173 virtual void preCheckpoint ( const dmtcp::vector<int>& fds
174 , KernelBufferDrainer& drain );
175 virtual void postCheckpoint ( const dmtcp::vector<int>& fds,
176 bool isRestart = false);
177 virtual void restore ( const dmtcp::vector<int>&, ConnectionRewirer& );
178
179 //virtual void doLocking ( const dmtcp::vector<int>& fds );
180
181 virtual void restoreOptions ( const dmtcp::vector<int>& fds );
182
183 virtual void doSendHandshakes( const dmtcp::vector<int>& fds, const dmtcp::UniquePid& coordinator);
184 virtual void doRecvHandshakes( const dmtcp::vector<int>& fds, const dmtcp::UniquePid& coordinator);
185
186 void sendHandshake(jalib::JSocket& sock, const dmtcp::UniquePid& coordinator);
187 void recvHandshake(jalib::JSocket& sock, const dmtcp::UniquePid& coordinator);
188
189 const ConnectionIdentifier& getRemoteId() const { return _acceptRemoteId; }
190
191 //called on restart when _id collides with another connection
192 virtual void mergeWith ( const Connection& that );
193 private:
194 virtual void serializeSubClass ( jalib::JBinarySerializer& o );
195 TcpConnection& asTcp();
196 private:
197 int _sockDomain;
198 int _sockType;
199 int _sockProtocol;
200 int _listenBacklog;
201 #ifdef EXTERNAL_SOCKET_HANDLING
202 enum PeerType _peerType;
203 #endif
204 union {
205 socklen_t _bindAddrlen;
206 socklen_t _connectAddrlen;
207 };
208 union {
209 struct sockaddr_storage _bindAddr;
210 struct sockaddr_storage _connectAddr;
211 };
212 ConnectionIdentifier _acceptRemoteId;
213 dmtcp::map< int, dmtcp::map< int, jalib::JBuffer > > _sockOptions; // _options[level][option] = value
214 };
215
216
217 class PtyConnection : public Connection
218 {
219 public:
220 enum PtyType
221 {
222 PTY_INVALID = PTY,
223 PTY_DEV_TTY,
224 PTY_CTTY,
225 PTY_MASTER,
226 PTY_SLAVE,
227 PTY_BSD_MASTER,
228 PTY_BSD_SLAVE
229
230 // TYPEMASK = PTY_CTTY | PTY_Master | PTY_Slave
231 };
232
233 PtyConnection ( const dmtcp::string& ptsName, const dmtcp::string& uniquePtsName, int type )
234 : Connection ( PTY )
235 , _ptsName ( ptsName )
236 , _uniquePtsName ( uniquePtsName )
237 {
238 _type = type;
239 JTRACE("Creating PtyConnection")(ptsName)(uniquePtsName)(id());
240 //if ( type != PTY_CTTY && filename.compare ( "?" ) == 0 )
241 //{
242 // _type = PTY_INVALID;
243 //}
244 }
245
246 PtyConnection ( const dmtcp::string& device, int type )
247 : Connection ( PTY )
248 , _bsdDeviceName ( device )
249 {
250 _type = type;
251 JTRACE("Creating BSDPtyConnection")(device)(id());
252 }
253
254 PtyConnection()
255 : Connection ( PTY )
256 , _ptsName ( "?" )
257 , _uniquePtsName ( "?" )
258 {
259 _type = PTY_INVALID;
260 JTRACE("Creating empty PtyConnection")(id());
|
Event uninit_member: |
Non-static class member _ptmxIsPacketMode is not initialized in this constructor nor in any functions that it calls. |
| Also see events: |
[member_decl] |
261 }
262
263 int ptyType() { return _type;}// & TYPEMASK ); }
264 dmtcp::string ptsName() { return _ptsName;; }
265 dmtcp::string uniquePtsName() { return _uniquePtsName;; }
266
267 //virtual void doLocking ( const dmtcp::vector<int>& fds );
268 virtual void preCheckpoint ( const dmtcp::vector<int>& fds
269 , KernelBufferDrainer& drain );
270 virtual void postCheckpoint ( const dmtcp::vector<int>& fds,
271 bool isRestart = false);
272 virtual void restore ( const dmtcp::vector<int>&, ConnectionRewirer& );
273 virtual void restoreOptions ( const dmtcp::vector<int>& fds );
274
275 virtual void serializeSubClass ( jalib::JBinarySerializer& o );
276
277 //called on restart when _id collides with another connection
278 virtual void mergeWith ( const Connection& that );
279 private:
280 //PtyType _type;
281 dmtcp::string _ptsName;
282 dmtcp::string _uniquePtsName;
283 dmtcp::string _bsdDeviceName;
|
Event member_decl: |
Class member declaration for _ptmxIsPacketMode. |
| Also see events: |
[uninit_member] |
284 bool _ptmxIsPacketMode;
285
286 };
287
288 class StdioConnection : public Connection
289 {
290 public:
291 enum StdioType
292 {
293 STDIO_IN = STDIO,
294 STDIO_OUT,
295 STDIO_ERR,
296 STDIO_INVALID
297 };
298
299 StdioConnection( int fd ): Connection ( STDIO + fd )
300 {
301 JTRACE("creating stdio connection")(fd)(id());
302 JASSERT( jalib::Between(0, fd, 2) )(fd).Text("invalid fd for StdioConnection");
303 }
304
305 StdioConnection(): Connection ( STDIO_INVALID ) {}
306
307 virtual void preCheckpoint ( const dmtcp::vector<int>& fds
308 , KernelBufferDrainer& drain );
309 virtual void postCheckpoint ( const dmtcp::vector<int>& fds,
310 bool isRestart = false);
311 virtual void restore ( const dmtcp::vector<int>&, ConnectionRewirer& );
312 virtual void restoreOptions ( const dmtcp::vector<int>& fds );
313
314 virtual void serializeSubClass ( jalib::JBinarySerializer& o );
315
316 virtual void mergeWith ( const Connection& that );
317
318 virtual void restartDup2(int oldFd, int newFd);
319 };
320
321 class FileConnection : public Connection
322 {
323 public:
324 enum FileType
325 {
326 FILE_INVALID = FILE,
327 FILE_REGULAR,
328 FILE_DELETED
329 };
330 //called on restart when _id collides with another connection
331 virtual void mergeWith ( const Connection& that );
332
333 inline FileConnection ( const dmtcp::string& path, off_t offset=-1,
334 int type = FILE_REGULAR )
335 : Connection ( FILE )
336 , _path ( path )
337 , _offset ( offset )
338 {
339 _type = type;
340 JTRACE("New File connection created")(_path);
341 }
342
343 virtual void preCheckpoint ( const dmtcp::vector<int>& fds
344 , KernelBufferDrainer& drain );
345 virtual void postCheckpoint ( const dmtcp::vector<int>& fds,
346 bool isRestart = false);
347
348 virtual void restoreOptions ( const dmtcp::vector<int>& fds );
349 virtual void restore ( const dmtcp::vector<int>&, ConnectionRewirer& );
350
351 virtual void serializeSubClass ( jalib::JBinarySerializer& o );
352
353 dmtcp::string filePath() { return _path; }
354
355 bool isDupConnection ( const Connection& _that, dmtcp::ConnectionToFds& conToFds );
356
357 bool fileType() { return _type; }
358
359 private:
360 void saveFile (int fd);
361 int openFile ();
362 void refreshPath();
363 void handleUnlinkedFile();
364 void calculateRelativePath();
365 dmtcp::string getSavedFilePath(const dmtcp::string& path);
366
367 dmtcp::string _path;
368 dmtcp::string _rel_path;
369 dmtcp::string _ckptFilesDir;
370 bool _checkpointed;
371 off_t _offset;
372 struct stat _stat;
373 };
374
375 class FifoConnection : public Connection
376 {
377 public:
378 //called on restart when _id collides with another connection
379 virtual void mergeWith ( const Connection& that );
380
381 inline FifoConnection ( const dmtcp::string& path )
382 : Connection ( FIFO )
383 , _path ( path )
384 {
385 dmtcp::string curDir = jalib::Filesystem::GetCWD();
386 int offs = _path.find(curDir);
387 if( offs < 0 ){
388 _rel_path = "*";
389 }else{
390 offs += curDir.size();
391 offs = _path.find('/',offs);
392 offs++;
393 _rel_path = _path.substr(offs);
394 }
395 JTRACE("New Fifo connection created")(_path)(_rel_path);
396 _in_data.clear();
397 }
398
399 virtual void preCheckpoint ( const dmtcp::vector<int>& fds
400 , KernelBufferDrainer& drain );
401 virtual void postCheckpoint ( const dmtcp::vector<int>& fds,
402 bool isRestart = false);
403
404 virtual void restoreOptions ( const dmtcp::vector<int>& fds );
405 virtual void restore ( const dmtcp::vector<int>&, ConnectionRewirer& );
406
407 virtual void serializeSubClass ( jalib::JBinarySerializer& o );
408
409 //virtual void doLocking ( const dmtcp::vector<int>& fds );
410
411 private:
412 int openFile();
413 void refreshPath();
414 dmtcp::string getSavedFilePath(const dmtcp::string& path);
415 dmtcp::string _path;
416 dmtcp::string _rel_path;
417 dmtcp::string _savedRelativePath;
418 struct stat _stat;
419 bool _has_lock;
420 vector<char> _in_data;
421 int ckptfd;
422 };
423 }
424
425 #endif