2 * Copyright (c) 1995 - 2000, 2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * The callback interface to the cache manager.
38 #include "arla_local.h"
44 * Create an instance of the callback service and start a server.
47 static afsUUID arla_client_uuid
;
52 if (afsUUID_create(&arla_client_uuid
))
53 arla_errx(1, ADEBWARN
, "Failed to create uuid for client");
59 static struct rx_securityClass
*nullSecObjP
;
60 static struct rx_securityClass
*(securityObjects
[1]);
64 nullSecObjP
= rxnull_NewClientSecurityObject ();
65 if (nullSecObjP
== NULL
)
66 arla_errx (1, ADEBWARN
, "Cannot create null security object.");
68 securityObjects
[0] = nullSecObjP
;
70 if (rx_NewService (0, CM_SERVICE_ID
, "cm", securityObjects
,
71 sizeof(securityObjects
) / sizeof(*securityObjects
),
72 RXAFSCB_ExecuteRequest
) == NULL
)
73 arla_errx (1, ADEBWARN
, "Cannot install callback service");
78 * Just tell the host that we're still alive.
82 SRXAFSCB_Probe (struct rx_call
*a_rxCallP
)
84 u_long host
= rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP
)));
85 struct in_addr in_addr
;
87 in_addr
.s_addr
= host
;
88 arla_warnx (ADEBCALLBACK
, "probe (%s)", inet_ntoa(in_addr
));
93 * Handle the callbacks in `a_fidArrayP' and `a_callBackArrayP' (this
94 * array can be shorter).
95 * There are two types of callbacks:
96 * - (volume-id, 0, 0) is a volume callback.
97 * - (volume-id, x, y) is a callback on a file.
101 SRXAFSCB_CallBack (struct rx_call
*a_rxCallP
,
102 const AFSCBFids
*a_fidArrayP
,
103 const AFSCBs
*a_callBackArrayP
)
107 uint32_t host
= rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP
)));
108 struct in_addr in_addr
;
110 in_addr
.s_addr
= host
;
111 arla_warnx (ADEBCALLBACK
, "callback (%s)", inet_ntoa(in_addr
));
112 cell
= poller_host2cell(host
);
114 arla_warnx (ADEBCALLBACK
,
115 "callback from unknown host: %s",
116 inet_ntoa (in_addr
));
117 for (i
= 0; i
< a_fidArrayP
->len
; ++i
) {
119 AFSCallBack broken_callback
= {0, 0, CBDROPPED
};
121 fid
.fid
= a_fidArrayP
->val
[i
];
123 arla_warnx (ADEBCALLBACK
, "%d: (%u, %u, %u)", fid
.Cell
,
124 fid
.fid
.Volume
, fid
.fid
.Vnode
, fid
.fid
.Unique
);
127 * Check if it's a volume callback.
130 if (fid
.fid
.Vnode
== 0 && fid
.fid
.Unique
== 0) {
131 fcache_purge_volume (fid
);
132 volcache_invalidate (fid
.fid
.Volume
, fid
.Cell
);
133 } else if (i
< a_callBackArrayP
->len
)
134 fcache_stale_entry (fid
, a_callBackArrayP
->val
[i
]);
136 fcache_stale_entry (fid
, broken_callback
);
138 cm_check_consistency();
145 SRXAFSCB_GetLock(struct rx_call
*a_rxCallP
,
153 SRXAFSCB_GetCE(struct rx_call
*a_rxCallP
,
155 AFSDBCacheEntry
*dbentry
)
161 SRXAFSCB_XStatsVersion(struct rx_call
*a_rxCallP
,
168 SRXAFSCB_GetXStats(struct rx_call
*a_rxCallP
,
169 int32_t client_version_num
,
170 int32_t collection_number
,
171 int32_t *server_version_number
,
173 AFSCB_CollData
*stats
)
180 * Throw away all callbacks from the `host'
184 init_callback_state(uint32_t host
)
186 struct in_addr in_addr
;
188 cm_check_consistency();
190 in_addr
.s_addr
= host
;
191 arla_warnx (ADEBCALLBACK
, "InitCallBackState (%s)", inet_ntoa(in_addr
));
192 fcache_purge_host (host
);
194 cm_check_consistency();
198 * Init the CallBack address in `addr'. Returns 0 or RXGEN_OPCODE.
202 init_address(interfaceAddr
*addr
)
204 struct ifaddrs
*ifa
, *ifa0
;
207 memset(addr
, 0, sizeof(*addr
));
209 addr
->uuid
= arla_client_uuid
;
211 if (getifaddrs(&ifa0
) != 0)
216 for (ifa
= ifa0
; ifa
!= NULL
; ifa
= ifa
->ifa_next
) {
217 if (ifa
->ifa_addr
== NULL
)
221 if (ifa
->ifa_flags
& IFF_LOOPBACK
)
225 switch (ifa
->ifa_addr
->sa_family
) {
227 struct sockaddr_in
*sin
= (struct sockaddr_in
*)ifa
->ifa_addr
;
228 struct sockaddr_in
*netmask
= (struct sockaddr_in
*)ifa
->ifa_netmask
;
230 if (sin
->sin_addr
.s_addr
== htonl(0x7f000001))
233 addr
->addr_in
[num_addr
] = sin
->sin_addr
.s_addr
;
235 addr
->subnetmask
[num_addr
] = netmask
->sin_addr
.s_addr
;
237 /* dream up something */
238 addr
->subnetmask
[num_addr
] = htonl(0xffffff00);
241 addr
->mtu
[num_addr
] = 1500; /* XXX */
248 if (num_addr
>= AFS_MAX_INTERFACE_ADDR
)
255 /* fail if there was no good ipv4 addresses */
260 addr
->numberOfInterfaces
= num_addr
;
266 SRXAFSCB_InitCallBackState (struct rx_call
*a_rxCallP
)
268 u_long host
= rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP
)));
270 init_callback_state(host
);
276 SRXAFSCB_InitCallBackState2 (struct rx_call
*a_rxCallP
, interfaceAddr
*addr
)
278 u_long host
= rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP
)));
280 init_callback_state(host
);
282 return init_address(addr
);
286 SRXAFSCB_InitCallBackState3 (struct rx_call
*a_rxCallP
,
287 const struct afsUUID
*serverUuid
)
289 u_long host
= rx_HostOf (rx_PeerOf (rx_ConnectionOf (a_rxCallP
)));
291 init_callback_state(host
);
297 SRXAFSCB_WhoAreYou(struct rx_call
*a_rxCallP
,
300 return init_address(addr
);
304 SRXAFSCB_ProbeUUID(struct rx_call
*a_rxCallP
,
305 const struct afsUUID
*uuid
)
307 /* the the uuids are equal, we are the host belive we is */
309 if (afsUUID_equal(uuid
, &arla_client_uuid
))
315 SRXAFSCB_GetCellServDB(struct rx_call
*a_rxCallP
,
316 const int32_t cellIndex
,
318 serverList
*cellHosts
)
324 SRXAFSCB_GetLocalCell(struct rx_call
*a_rxCallP
,
327 strlcpy(cellName
, cell_getthiscell(), AFSNAMEMAX
);
332 SRXAFSCB_GetCacheConfig(struct rx_call
*a_rxCallP
,
333 const uint32_t callerVersion
,
334 uint32_t *serverVersion
,
335 uint32_t *configCount
,
347 SRXAFSCB_GetCellByNum(struct rx_call
*call
,
348 const int32_t cellNumber
,
350 serverList
*cellHosts
)
356 SRXAFSCB_TellMeAboutYourself(struct rx_call
*call
,
357 struct interfaceAddr
*addr
,
358 Capabilities
*capabilities
)
362 memset(addr
, 0, sizeof(*addr
));
364 capabilities
->len
= 1;
365 capabilities
->val
= malloc(sizeof(capabilities
->val
[0]));
366 if (capabilities
->val
== NULL
)
369 capabilities
->val
[0] = 0x1; /* UAE */
371 ret
= init_address(addr
);