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