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