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