vol-osi-assert-20080401
[openafs.git] / src / vol / salvsync-client.c
1 /*
2  * Copyright 2006-2008, Sine Nomine Associates 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
10 /*
11  * salvsync-client.c
12  *
13  * OpenAFS demand attach fileserver
14  * Salvage server synchronization with fileserver.
15  */
16
17 #include <afsconfig.h>
18 #include <afs/param.h>
19
20 RCSID
21     ("$Header$");
22
23 #include <sys/types.h>
24 #include <stdio.h>
25 #ifdef AFS_NT40_ENV
26 #include <winsock2.h>
27 #include <time.h>
28 #else
29 #include <sys/param.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <netdb.h>
33 #include <sys/time.h>
34 #endif
35 #include <errno.h>
36 #include <assert.h>
37 #include <signal.h>
38 #include <string.h>
39
40 #include <rx/xdr.h>
41 #include <afs/afsint.h>
42 #include "nfs.h"
43 #include <afs/errors.h>
44 #include "salvsync.h"
45 #include "lwp.h"
46 #include "lock.h"
47 #include <afs/afssyscalls.h>
48 #include "ihandle.h"
49 #include "vnode.h"
50 #include "volume.h"
51 #include "partition.h"
52 #include <rx/rx_queue.h>
53
54 /*@printflike@*/ extern void Log(const char *format, ...);
55
56 #ifdef AFS_DEMAND_ATTACH_FS
57 /*
58  * SALVSYNC is a feature specific to the demand attach fileserver
59  */
60
61 extern int LogLevel;
62 extern int VInit;
63 extern pthread_mutex_t vol_salvsync_mutex;
64
65 static SYNC_client_state salvsync_client_state = 
66     { -1,                     /* file descriptor */
67       SALVSYNC_ENDPOINT_DECL, /* server endpoint */
68       SALVSYNC_PROTO_VERSION, /* protocol version */
69       5,                      /* connect retry limit */
70       120,                    /* hard timeout */
71       "SALVSYNC",             /* protocol name string */
72     };
73
74 /*
75  * client-side routines
76  */
77
78 int
79 SALVSYNC_clientInit(void)
80 {
81     return SYNC_connect(&salvsync_client_state);
82 }
83
84 int
85 SALVSYNC_clientFinis(void)
86 {
87     SYNC_closeChannel(&salvsync_client_state);
88     return 1;
89 }
90
91 int
92 SALVSYNC_clientReconnect(void)
93 {
94     return SYNC_reconnect(&salvsync_client_state);
95 }
96
97 afs_int32
98 SALVSYNC_askSalv(SYNC_command * com, SYNC_response * res)
99 {
100     afs_int32 code;
101     SALVSYNC_command_hdr * scom = com->payload.buf;
102
103     scom->hdr_version = SALVSYNC_PROTO_VERSION;
104
105     VSALVSYNC_LOCK;
106     code = SYNC_ask(&salvsync_client_state, com, res);
107     VSALVSYNC_UNLOCK;
108
109     switch (code) {
110     case SYNC_OK:
111     case SYNC_FAILED:
112       break;
113     case SYNC_COM_ERROR:
114     case SYNC_BAD_COMMAND:
115         Log("SALVSYNC_askSalv: fatal SALVSYNC protocol error; online salvager functionality disabled until next fileserver restart\n");
116         break;
117     case SYNC_DENIED:
118         Log("SALVSYNC_askSalv: SALVSYNC request denied for reason=%d\n", res->hdr.reason);
119         break;
120     default:
121         Log("SALVSYNC_askSalv: unknown protocol response %d\n", code);
122         break;
123     }
124
125     return code;
126 }
127
128 afs_int32
129 SALVSYNC_SalvageVolume(VolumeId volume, char *partName, int command, int reason, 
130                        afs_uint32 prio, SYNC_response * res_in)
131 {
132     SYNC_command com;
133     SYNC_response res_l, *res;
134     SALVSYNC_command_hdr scom;
135     SALVSYNC_response_hdr sres;
136     int n, tot;
137
138     memset(&com, 0, sizeof(com));
139     memset(&scom, 0, sizeof(scom));
140
141     if (res_in) {
142         res = res_in;
143     } else {
144         memset(&res_l, 0, sizeof(res_l));
145         memset(&sres, 0, sizeof(sres));
146         res_l.payload.buf = (void *) &sres;
147         res_l.payload.len = sizeof(sres);
148         res = &res_l;
149     }
150
151     com.payload.buf = (void *) &scom;
152     com.payload.len = sizeof(scom);
153     com.hdr.command = command;
154     com.hdr.reason = reason;
155     com.hdr.command_len = sizeof(com.hdr) + sizeof(scom);
156     scom.volume = volume;
157     scom.parent = volume;
158     scom.prio = prio;
159
160     if (partName) {
161         strlcpy(scom.partName, partName, sizeof(scom.partName));
162     } else {
163         scom.partName[0] = '\0';
164     }
165
166     return SALVSYNC_askSalv(&com, res);
167 }
168
169 afs_int32
170 SALVSYNC_LinkVolume(VolumeId parent, 
171                     VolumeId clone,
172                     char * partName,
173                     SYNC_response * res_in)
174 {
175     SYNC_command com;
176     SYNC_response res_l, *res;
177     SALVSYNC_command_hdr scom;
178     SALVSYNC_response_hdr sres;
179     int n, tot;
180
181     memset(&com, 0, sizeof(com));
182     memset(&scom, 0, sizeof(scom));
183
184     if (res_in) {
185         res = res_in;
186     } else {
187         memset(&res_l, 0, sizeof(res_l));
188         memset(&sres, 0, sizeof(sres));
189         res_l.payload.buf = (void *) &sres;
190         res_l.payload.len = sizeof(sres);
191         res = &res_l;
192     }
193
194     com.payload.buf = (void *) &scom;
195     com.payload.len = sizeof(scom);
196     com.hdr.command = SALVSYNC_OP_LINK;
197     com.hdr.reason = SALVSYNC_REASON_WHATEVER;
198     com.hdr.command_len = sizeof(com.hdr) + sizeof(scom);
199     scom.volume = clone;
200     scom.parent = parent;
201
202     if (partName) {
203         strlcpy(scom.partName, partName, sizeof(scom.partName));
204     } else {
205         scom.partName[0] = '\0';
206     }
207
208     return SALVSYNC_askSalv(&com, res);
209 }
210
211 #endif /* AFS_DEMAND_ATTACH_FS */