d983b4cae860905ca0b6cc63adfbca2a7aa3dd32
[openafs.git] / src / vol / fssync-client.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  *
9  * Portions Copyright (c) 2006 Sine Nomine Associates
10  */
11
12 /*
13         System:         VICE-TWO
14         Module:         fssync.c
15         Institution:    The Information Technology Center, Carnegie-Mellon University
16
17  */
18 #ifdef notdef
19
20 /* All this is going away in early 1989 */
21 int newVLDB;                    /* Compatibility flag */
22
23 #endif
24 static int newVLDB = 1;
25
26
27 #ifndef AFS_PTHREAD_ENV
28 #define USUAL_PRIORITY (LWP_MAX_PRIORITY - 2)
29
30 /*
31  * stack size increased from 8K because the HP machine seemed to have trouble
32  * with the smaller stack
33  */
34 #define USUAL_STACK_SIZE        (24 * 1024)
35 #endif /* !AFS_PTHREAD_ENV */
36
37 /*
38    fssync-client.c
39    File server synchronization with external volume utilities.
40    client-side implementation
41  */
42
43 #include <afsconfig.h>
44 #include <afs/param.h>
45
46 RCSID
47     ("$Header$");
48
49 #include <sys/types.h>
50 #include <stdio.h>
51 #ifdef AFS_NT40_ENV
52 #include <winsock2.h>
53 #include <time.h>
54 #else
55 #include <sys/param.h>
56 #include <sys/socket.h>
57 #include <netinet/in.h>
58 #include <netdb.h>
59 #include <sys/time.h>
60 #endif
61 #include <errno.h>
62 #ifdef AFS_PTHREAD_ENV
63 #include <assert.h>
64 #else /* AFS_PTHREAD_ENV */
65 #include <afs/assert.h>
66 #endif /* AFS_PTHREAD_ENV */
67 #include <signal.h>
68 #include <string.h>
69
70 #include <rx/xdr.h>
71 #include <afs/afsint.h>
72 #include "nfs.h"
73 #include <afs/errors.h>
74 #include "daemon_com.h"
75 #include "fssync.h"
76 #include "lwp.h"
77 #include "lock.h"
78 #include <afs/afssyscalls.h>
79 #include "ihandle.h"
80 #include "vnode.h"
81 #include "volume.h"
82 #include "partition.h"
83
84 #ifdef FSSYNC_BUILD_CLIENT
85
86 /*@printflike@*/ extern void Log(const char *format, ...);
87
88 #ifdef osi_Assert
89 #undef osi_Assert
90 #endif
91 #define osi_Assert(e) (void)(e)
92
93 extern int LogLevel;
94
95 static SYNC_client_state fssync_state = 
96     { -1,                    /* file descriptor */
97       2040,                  /* port number */
98       FSYNC_PROTO_VERSION,   /* protocol version */
99       5,                     /* connect retry limit */
100       120,                   /* hard timeout */
101       "FSSYNC",              /* protocol name string */
102     };
103
104 #ifdef AFS_PTHREAD_ENV
105 static pthread_mutex_t vol_fsync_mutex;
106 static volatile vol_fsync_mutex_init = 0;
107 #define VFSYNC_LOCK \
108     assert(pthread_mutex_lock(&vol_fsync_mutex) == 0)
109 #define VFSYNC_UNLOCK \
110     assert(pthread_mutex_unlock(&vol_fsync_mutex) == 0)
111 #else
112 #define VFSYNC_LOCK
113 #define VFSYNC_UNLOCK
114 #endif
115
116 int
117 FSYNC_clientInit(void)
118 {
119 #ifdef AFS_PTHREAD_ENV
120     /* this is safe since it gets called with VOL_LOCK held, or before we go multithreaded */
121     if (!vol_fsync_mutex_init) {
122         assert(pthread_mutex_init(&vol_fsync_mutex, NULL) == 0);
123         vol_fsync_mutex_init = 1;
124     }
125 #endif
126     return SYNC_connect(&fssync_state);
127 }
128
129 void
130 FSYNC_clientFinis(void)
131 {
132     SYNC_closeChannel(&fssync_state);
133 }
134
135 int
136 FSYNC_clientChildProcReconnect(void)
137 {
138     return SYNC_reconnect(&fssync_state);
139 }
140
141 /* fsync client interface */
142 afs_int32
143 FSYNC_askfs(SYNC_command * com, SYNC_response * res)
144 {
145     afs_int32 code;
146
147     VFSYNC_LOCK;
148     code = SYNC_ask(&fssync_state, com, res);
149     VFSYNC_UNLOCK;
150
151     switch (code) {
152     case SYNC_OK:
153     case SYNC_FAILED:
154         break;
155     case SYNC_COM_ERROR:
156     case SYNC_BAD_COMMAND:
157         Log("FSYNC_askfs: fatal FSSYNC protocol error; volume management functionality disabled until next fileserver restart\n");
158         break;
159     case SYNC_DENIED:
160         Log("FSYNC_askfs: FSSYNC request denied for reason=%d\n", res->hdr.reason);
161         break;
162     default:
163         Log("FSYNC_askfs: unknown protocol response %d\n", code);
164         break;
165     }
166     return code;
167 }
168
169 afs_int32
170 FSYNC_GenericOp(void * ext_hdr, size_t ext_len,
171               int command, int reason,
172               SYNC_response * res_in)
173 {
174     SYNC_response res_l, *res;
175     SYNC_command com;
176
177     if (res_in) {
178         res = res_in;
179     } else {
180         res = &res_l;
181         res_l.payload.buf = NULL;
182         res_l.payload.len = 0;
183     }
184
185     memset(&com, 0, sizeof(com));
186
187     com.hdr.programType = programType;
188     com.hdr.command = command;
189     com.hdr.reason = reason;
190     com.hdr.command_len = sizeof(com.hdr) + ext_len;
191     com.payload.buf = ext_hdr;
192     com.payload.len = ext_len;
193
194     return FSYNC_askfs(&com, res);
195 }
196
197 afs_int32
198 FSYNC_VolOp(VolumeId volume, char * partition, 
199             int command, int reason,
200             SYNC_response * res)
201 {
202     FSSYNC_VolOp_hdr vcom;
203
204     memset(&vcom, 0, sizeof(vcom));
205
206     vcom.volume = volume;
207     if (partition)
208         strlcpy(vcom.partName, partition, sizeof(vcom.partName));
209
210     return FSYNC_GenericOp(&vcom, sizeof(vcom), command, reason, res);
211 }
212
213 afs_int32
214 FSYNC_StatsOp(FSSYNC_StatsOp_hdr * scom, int command, int reason,
215               SYNC_response * res)
216 {
217     return FSYNC_GenericOp(scom, sizeof(*scom), command, reason, res);
218 }
219
220
221 #endif /* FSSYNC_BUILD_CLIENT */