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