205a08953d0175ce5738080dcf9c0da4737d5fec
[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
69 #ifdef HAVE_STRING_H
70 #include <string.h>
71 #else
72 #ifdef HAVE_STRINGS_H
73 #include <strings.h>
74 #endif
75 #endif
76
77
78 #include <rx/xdr.h>
79 #include <afs/afsint.h>
80 #include "nfs.h"
81 #include <afs/errors.h>
82 #include "daemon_com.h"
83 #include "fssync.h"
84 #include "lwp.h"
85 #include "lock.h"
86 #include <afs/afssyscalls.h>
87 #include "ihandle.h"
88 #include "vnode.h"
89 #include "volume.h"
90 #include "partition.h"
91
92 #ifdef FSSYNC_BUILD_CLIENT
93
94 /*@printflike@*/ extern void Log(const char *format, ...);
95
96 #ifdef osi_Assert
97 #undef osi_Assert
98 #endif
99 #define osi_Assert(e) (void)(e)
100
101 extern int LogLevel;
102
103 static SYNC_client_state fssync_state = { -1, 2040, FSYNC_PROTO_VERSION, 5, 120 };
104
105 #ifdef AFS_PTHREAD_ENV
106 static pthread_mutex_t vol_fsync_mutex;
107 static volatile vol_fsync_mutex_init = 0;
108 #define VFSYNC_LOCK \
109     assert(pthread_mutex_lock(&vol_fsync_mutex) == 0)
110 #define VFSYNC_UNLOCK \
111     assert(pthread_mutex_unlock(&vol_fsync_mutex) == 0)
112 #else
113 #define VFSYNC_LOCK
114 #define VFSYNC_UNLOCK
115 #endif
116
117 int
118 FSYNC_clientInit(void)
119 {
120 #ifdef AFS_PTHREAD_ENV
121     /* this is safe since it gets called with VOL_LOCK held, or before we go multithreaded */
122     if (!vol_fsync_mutex_init) {
123         assert(pthread_mutex_init(&vol_fsync_mutex, NULL) == 0);
124         vol_fsync_mutex_init = 1;
125     }
126 #endif
127     return SYNC_connect(&fssync_state);
128 }
129
130 void
131 FSYNC_clientFinis(void)
132 {
133     SYNC_closeChannel(&fssync_state);
134 }
135
136 int
137 FSYNC_clientChildProcReconnect(void)
138 {
139     return SYNC_reconnect(&fssync_state);
140 }
141
142 /* fsync client interface */
143 afs_int32
144 FSYNC_askfs(SYNC_command * com, SYNC_response * res)
145 {
146     afs_int32 code;
147
148     VFSYNC_LOCK;
149     code = SYNC_ask(&fssync_state, com, res);
150     VFSYNC_UNLOCK;
151
152     switch (code) {
153     case SYNC_OK:
154     case SYNC_FAILED:
155         break;
156     case SYNC_COM_ERROR:
157     case SYNC_BAD_COMMAND:
158         Log("FSYNC_askfs: fatal FSSYNC protocol error; volume management functionality disabled until next fileserver restart\n");
159         break;
160     case SYNC_DENIED:
161         Log("FSYNC_askfs: FSSYNC request denied for reason=%d\n", res->hdr.reason);
162         break;
163     default:
164         Log("FSYNC_askfs: unknown protocol response %d\n", code);
165         break;
166     }
167     return code;
168 }
169
170 afs_int32
171 FSYNC_GenericOp(void * ext_hdr, size_t ext_len,
172               int command, int reason,
173               SYNC_response * res_in)
174 {
175     SYNC_response res_l, *res;
176     SYNC_command com;
177
178     if (res_in) {
179         res = res_in;
180     } else {
181         res = &res_l;
182         res_l.payload.buf = NULL;
183         res_l.payload.len = 0;
184     }
185
186     memset(&com, 0, sizeof(com));
187
188     com.hdr.programType = programType;
189     com.hdr.command = command;
190     com.hdr.reason = reason;
191     com.hdr.command_len = sizeof(com.hdr) + ext_len;
192     com.payload.buf = ext_hdr;
193     com.payload.len = ext_len;
194
195     return FSYNC_askfs(&com, res);
196 }
197
198 afs_int32
199 FSYNC_VolOp(VolumeId volume, char * partition, 
200             int command, int reason,
201             SYNC_response * res)
202 {
203     FSSYNC_VolOp_hdr vcom;
204
205     memset(&vcom, 0, sizeof(vcom));
206
207     vcom.volume = volume;
208     if (partition)
209         strlcpy(vcom.partName, partition, sizeof(vcom.partName));
210
211     return FSYNC_GenericOp(&vcom, sizeof(vcom), command, reason, res);
212 }
213
214 afs_int32
215 FSYNC_StatsOp(FSSYNC_StatsOp_hdr * scom, int command, int reason,
216               SYNC_response * res)
217 {
218     return FSYNC_GenericOp(scom, sizeof(*scom), command, reason, res);
219 }
220
221
222 #endif /* FSSYNC_BUILD_CLIENT */