2 * Copyright 2006, Sine Nomine Associates and others.
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
12 * fileserver state serialization
15 #include <afsconfig.h>
16 #include <afs/param.h>
24 #include <afs/afsint.h>
25 #include <afs/rxgen_consts.h>
27 #include <afs/errors.h>
28 #include <afs/ihandle.h>
30 #include <afs/ptclient.h>
31 #include <afs/prs_fs.h>
32 #include <afs/afsutil.h>
34 #include <afs/cellconfig.h>
36 #include "../viced/viced_prototypes.h"
37 #include "../viced/viced.h"
38 #include "../viced/host.h"
39 #include "../viced/callback.h"
40 #include "serialize_state.h"
42 #ifdef AFS_DEMAND_ATTACH_FS
48 * in order to make state dump/restore as fast as possible,
49 * we use memory mapped files
51 * if this causes problems on certain platforms, the APIs
52 * have been written so that it will be very simple to go
53 * back to standard I/O for just those poorly written platforms
56 #define FS_STATE_USE_MMAP 1
59 #ifdef FS_STATE_USE_MMAP
60 #define FS_STATE_INIT_FILESIZE (8 * 1024 * 1024) /* truncate to 8MB initially */
66 static int fs_stateCreateDump(struct fs_dump_state
* state
);
67 static int fs_stateLoadDump(struct fs_dump_state
* state
);
68 static int fs_stateInvalidateDump(struct fs_dump_state
* state
);
69 static int fs_stateCommitDump(struct fs_dump_state
* state
);
70 static int fs_stateCloseDump(struct fs_dump_state
* state
);
72 #ifdef FS_STATE_USE_MMAP
73 static int fs_stateSizeFile(struct fs_dump_state
* state
);
74 static int fs_stateResizeFile(struct fs_dump_state
* state
, size_t min_add
);
75 static int fs_stateTruncateFile(struct fs_dump_state
* state
);
77 static int fs_stateMapFile(struct fs_dump_state
* state
, int preserve_flag
);
78 static int fs_stateUnmapFile(struct fs_dump_state
* state
);
80 static int fs_stateIncCursor(struct fs_dump_state
* state
, size_t len
);
81 static int fs_stateCheckIOSafety(struct fs_dump_state
* state
,
85 static int fs_stateFillHeader(struct fs_state_header
* hdr
);
86 static int fs_stateCheckHeader(struct fs_state_header
* hdr
);
88 static int fs_stateAlloc(struct fs_dump_state
* state
);
89 static int fs_stateFree(struct fs_dump_state
* state
);
91 extern afsUUID FS_HostUUID
;
92 extern char cml_version_number
[];
95 fs_stateFileOpen(struct fs_dump_state
*state
)
98 return(state
->fd
!= -1);
100 return(state
->fd
>= 0);
107 * save all fileserver state
112 int ret
= 0, verified
= 1;
113 struct fs_dump_state state
;
115 /* save and restore need to be atomic wrt other host package operations */
118 ViceLog(0, ("fs_stateSave: commencing fileserver state dump\n"));
120 if (fs_stateAlloc(&state
)) {
121 ViceLog(0, ("fs_stateSave: memory allocation failed; dump aborted\n"));
127 * on busy servers, these checks will inevitably fail since stuff drops H_LOCK
128 * all over the place (with structs left in inconsistent states) while RPCs to
129 * clients happen (grumble, grumble, the host package needs to be rewritten...)
131 * the current hack is to force the background threads that deal with host and
132 * callback state offline early in the shutdown process, do VShutdown, come
133 * back and wait for those threads to die, THEN do the state dump
135 * BUT, this still has one flaw -- what do we do about rx worker threads that
136 * are blocked in the host package making an RPC call to a cm???
138 * currently we try to detect if a host struct is in an inconsistent state
139 * when we go to save it to disk, and just skip the hosts that we think may
140 * be inconsistent (see h_isBusy_r in host.c). This has the problem of causing
141 * more InitCallBackState's when we come back up, but the number of hosts in
142 * such a state should be small. In the future, we could try to lock hosts
143 * (with some deadline so we don't wait forever) before serializing, but at
144 * least for now it does not seem worth the trouble.
147 if (fs_state
.options
.fs_state_verify_before_save
) {
148 ViceLog(0, ("fs_stateSave: performing internal consistency checks before proceeding with state dump\n"));
150 if (h_stateVerify(&state
)) {
151 ViceLog(0, ("fs_stateSave: error: host table consistency checks failed; state dump will not be marked clean\n"));
156 if (cb_stateVerify(&state
)) {
157 ViceLog(0, ("fs_stateSave: error: callback table consistency checks failed; state dump will not be marked clean\n"));
162 /* if a consistency check asserted the bail flag, reset it */
165 ViceLog(0, ("fs_stateSave: proceeding with dump\n"));
168 if (fs_stateCreateDump(&state
)) {
169 ViceLog(0, ("fs_stateSave: error: dump create failed\n"));
174 if (h_stateSave(&state
)) {
175 ViceLog(0, ("fs_stateSave: error: host state dump failed\n"));
180 if (cb_stateSave(&state
)) {
181 ViceLog(0, ("fs_stateSave: error: callback state dump failed\n"));
190 if (fs_stateCommitDump(&state
)) {
191 ViceLog(0, ("fs_stateSave: error: dump commit failed\n"));
197 ViceLog(0, ("fs_stateSave: fileserver state dump completed successfully\n"));
199 ViceLog(0, ("fs_stateSave: fileserver state dump completed, but not marked clean.\n"));
200 ViceLog(0, ("fs_stateSave: please save a copy of '%s' for use by technical support\n",
205 if (fs_stateFileOpen(&state
))
206 fs_stateCloseDump(&state
);
207 fs_stateFree(&state
);
214 * restore all fileserver state
216 * this function must appear as one atomic operation to the host and callback
217 * packages, hence H_LOCK is held for the entirety of the process.
220 fs_stateRestore(void)
223 struct fs_dump_state state
;
225 /* save and restore need to be atomic wrt other host package operations */
228 ViceLog(0, ("fs_stateRestore: commencing fileserver state restore\n"));
230 if (fs_stateAlloc(&state
)) {
231 ViceLog(0, ("fs_stateRestore: memory allocation failed\n"));
236 if (fs_stateLoadDump(&state
)) {
237 ViceLog(0, ("fs_stateRestore: failed to load dump file '%s'\n", state
.fn
));
242 if (fs_stateInvalidateDump(&state
)) {
243 ViceLog(0, ("fs_stateRestore: failed to invalidate dump file '%s'\n", state
.fn
));
249 if (state
.flags
.do_host_restore
) {
250 if (h_stateRestore(&state
)) {
251 ViceLog(0, ("fs_stateRestore: error: host state restore failed. exiting avoid further corruption\n"));
254 ViceLog(0, ("fs_stateRestore: host table restored\n"));
256 if (cb_stateRestore(&state
)) {
257 ViceLog(0, ("fs_stateRestore: error: callback state restore failed. exiting to avoid further corruption\n"));
260 ViceLog(0, ("fs_stateRestore: FileEntry and CallBack tables restored\n"));
262 if (h_stateRestoreIndices(&state
)) {
263 ViceLog(0, ("fs_stateRestore: error: host index remapping failed. exiting to avoid further corruption\n"));
266 ViceLog(0, ("fs_stateRestore: host table indices remapped\n"));
268 if (cb_stateRestoreIndices(&state
)) {
269 ViceLog(0, ("fs_stateRestore: error: callback index remapping failed. exiting to avoid further corruption\n"));
272 ViceLog(0, ("fs_stateRestore: FileEntry and CallBack indices remapped\n"));
275 ViceLog(0, ("fs_stateRestore: restore phase complete\n"));
277 if (fs_state
.options
.fs_state_verify_after_restore
) {
278 ViceLog(0, ("fs_stateRestore: beginning state verification phase\n"));
280 if (state
.flags
.do_host_restore
) {
281 if (h_stateVerify(&state
)) {
282 ViceLog(0, ("fs_stateRestore: error: host table consistency checks failed; exiting to avoid further corruption\n"));
286 if (cb_stateVerify(&state
)) {
287 ViceLog(0, ("fs_stateRestore: error: callback table consistency checks failed; exiting to avoid further corruption\n"));
292 ViceLog(0, ("fs_stateRestore: fileserver state verification complete\n"));
295 ViceLog(0, ("fs_stateRestore: restore was successful\n"));
299 fs_stateInvalidateDump(&state
);
300 fs_stateCloseDump(&state
);
302 fs_stateFree(&state
);
308 fs_stateCreateDump(struct fs_dump_state
* state
)
311 char savedump
[MAXPATHLEN
];
312 struct afs_stat status
;
314 snprintf(savedump
, sizeof(savedump
), "%s.old", state
->fn
);
316 if (afs_stat(state
->fn
, &status
) == 0) {
317 rk_rename(state
->fn
, savedump
);
320 if (((fd
= afs_open(state
->fn
,
321 O_RDWR
| O_CREAT
| O_TRUNC
,
322 S_IRUSR
| S_IWUSR
)) == -1) ||
323 (afs_fstat(fd
, &status
) == -1)) {
324 ViceLog(0, ("fs_stateCreateDump: failed to create state dump file '%s'\n",
331 state
->mode
= FS_STATE_DUMP_MODE
;
332 memset(state
->hdr
, 0, sizeof(struct fs_state_header
));
333 fs_stateIncEOF(state
, sizeof(struct fs_state_header
));
335 #ifdef FS_STATE_USE_MMAP
336 if (fs_stateSizeFile(state
)) {
337 ViceLog(0, ("fs_stateCreateDump: failed to resize state dump file '%s'\n",
343 if (fs_stateMapFile(state
, 0)) {
344 ViceLog(0, ("fs_stateCreateDump: failed to memory map state dump file '%s'\n",
351 ret
= fs_stateInvalidateDump(state
);
358 fs_stateInvalidateDump(struct fs_dump_state
* state
)
362 struct fs_state_header hdr
;
364 #ifdef FS_STATE_USE_MMAP
365 if (state
->mmap
.map
== NULL
) {
370 memcpy(&hdr
, state
->hdr
, sizeof(hdr
));
374 /* write a bogus header to flag dump in progress */
375 if (fs_stateWriteHeader(state
, &z
, &hdr
, sizeof(hdr
))) {
376 ViceLog(0, ("fs_stateInvalidateDump: failed to invalidate old dump file header '%s'\n",
381 if (fs_stateSync(state
)) {
382 ViceLog(0, ("fs_stateInvalidateDump: failed to sync changes to disk\n"));
392 fs_stateCommitDump(struct fs_dump_state
* state
)
399 #ifdef FS_STATE_USE_MMAP
400 if (fs_stateTruncateFile(state
)) {
401 ViceLog(0, ("fs_stateCommitDump: failed to truncate dump file to proper size\n"));
407 /* ensure that all pending data I/Os for the state file have been committed
408 * _before_ we make the metadata I/Os */
409 if (fs_stateSync(state
)) {
410 ViceLog(0, ("fs_stateCommitDump: failed to sync changes to disk\n"));
415 #ifdef FS_STATE_USE_MMAP
416 /* XXX madvise may not exist on all platforms, so
417 * we may need to add some ifdefs at some point... */
419 madvise((((char *)state
->mmap
.map
) + sizeof(struct fs_state_header
)),
420 state
->mmap
.size
- sizeof(struct fs_state_header
),
425 /* build the header, and write it to disk */
426 fs_stateFillHeader(state
->hdr
);
428 state
->hdr
->valid
= 0;
430 if (fs_stateWriteHeader(state
, &z
, state
->hdr
, sizeof(struct fs_state_header
))) {
431 ViceLog(0, ("fs_stateCommitDump: failed to write header to dump file '%s'\n",
436 if (fs_stateSync(state
)) {
437 ViceLog(0, ("fs_stateCommitDump: failed to sync new header to disk\n"));
447 fs_stateLoadDump(struct fs_dump_state
* state
)
451 struct afs_stat status
;
452 afs_int32 now
= time(NULL
);
456 if ((fd
= afs_open(state
->fn
, O_RDWR
)) == -1 ||
457 (afs_fstat(fd
, &status
) == -1)) {
458 ViceLog(0, ("fs_stateLoadDump: failed to load state dump file '%s'\n",
464 state
->mode
= FS_STATE_LOAD_MODE
;
465 state
->file_len
= status
.st_size
;
467 #ifdef FS_STATE_USE_MMAP
468 if (fs_stateMapFile(state
, 0)) {
469 ViceLog(0, ("fs_stateLoadDump: failed to memory map state dump file '%s'\n",
476 if (fs_stateReadHeader(state
, &z
, state
->hdr
, sizeof(struct fs_state_header
))) {
477 ViceLog(0, ("fs_stateLoadDump: failed to read header from dump file '%s'\n",
483 /* check the validity of the header */
484 if (fs_stateCheckHeader(state
->hdr
)) {
485 ViceLog(1, ("fs_stateLoadDump: header failed validity checks; not restoring '%s'\n",
491 if ((state
->hdr
->timestamp
+ HOST_STATE_VALID_WINDOW
) >= now
) {
492 state
->flags
.do_host_restore
= 1;
494 ViceLog(0, ("fs_stateLoadDump: warning: dump is too old for host and callback restore; skipping those steps\n"));
502 fs_stateCloseDump(struct fs_dump_state
* state
)
504 #ifdef FS_STATE_USE_MMAP
505 fs_stateUnmapFile(state
);
512 fs_stateWrite(struct fs_dump_state
* state
,
513 void * buf
, size_t len
)
517 #ifdef FS_STATE_USE_MMAP
518 if (fs_stateCheckIOSafety(state
, len
)) {
519 if (fs_stateResizeFile(state
, len
)) {
520 ViceLog(0, ("fs_stateWrite: could not resize dump file '%s'\n",
527 memcpy(state
->mmap
.cursor
, buf
, len
);
528 fs_stateIncCursor(state
, len
);
530 if (write(state
->fd
, buf
, len
) != len
) {
531 ViceLog(0, ("fs_stateWrite: write failed\n"));
542 fs_stateRead(struct fs_dump_state
* state
,
543 void * buf
, size_t len
)
547 #ifdef FS_STATE_USE_MMAP
548 if (fs_stateCheckIOSafety(state
, len
)) {
549 ViceLog(0, ("fs_stateRead: read beyond EOF for dump file '%s'\n",
555 memcpy(buf
, state
->mmap
.cursor
, len
);
556 fs_stateIncCursor(state
, len
);
558 if (read(state
->fd
, buf
, len
) != len
) {
559 ViceLog(0, ("fs_stateRead: read failed\n"));
570 fs_stateWriteV(struct fs_dump_state
* state
,
571 struct iovec
* iov
, int niov
)
576 for (i
=0; i
< niov
; i
++) {
577 len
+= iov
[i
].iov_len
;
580 #ifdef FS_STATE_USE_MMAP
581 if (fs_stateCheckIOSafety(state
, len
)) {
582 if (fs_stateResizeFile(state
, len
)) {
583 ViceLog(0, ("fs_stateWrite: could not resize dump file '%s'\n",
590 for (i
=0; i
< niov
; i
++) {
591 memcpy(state
->mmap
.cursor
, iov
[i
].iov_base
, iov
[i
].iov_len
);
592 fs_stateIncCursor(state
, iov
[i
].iov_len
);
596 if (writev(state
->fd
, iov
, niov
) != len
) {
597 ViceLog(0, ("fs_stateWriteV: write failed\n"));
601 #else /* AFS_NT40_ENV */
602 for (i
=0; i
< niov
; i
++) {
603 if (write(state
->fd
, iov
[i
].iov_base
, iov
[i
].iov_len
) != iov
[i
].iov_len
) {
604 ViceLog(0, ("fs_stateWriteV: write failed\n"));
609 #endif /* AFS_NT40_ENV */
617 fs_stateReadV(struct fs_dump_state
* state
,
618 struct iovec
* iov
, int niov
)
623 for (i
=0; i
< niov
; i
++) {
624 len
+= iov
[i
].iov_len
;
627 #ifdef FS_STATE_USE_MMAP
628 if (fs_stateCheckIOSafety(state
, len
)) {
629 ViceLog(0, ("fs_stateRead: read beyond EOF for dump file '%s'\n",
635 for (i
=0; i
< niov
; i
++) {
636 memcpy(iov
[i
].iov_base
, state
->mmap
.cursor
, iov
[i
].iov_len
);
637 fs_stateIncCursor(state
, iov
[i
].iov_len
);
641 if (readv(state
->fd
, iov
, niov
) != len
) {
642 ViceLog(0, ("fs_stateReadV: read failed\n"));
647 for (i
=0; i
< niov
; i
++) {
648 if (read(state
->fd
, iov
[i
].iov_base
, iov
[i
].iov_len
) != iov
[i
].iov_len
) {
649 ViceLog(0, ("fs_stateReadV: read failed\n"));
654 #endif /* AFS_NT40_ENV */
662 fs_stateWriteHeader(struct fs_dump_state
* state
,
664 void * hdr
, size_t len
)
668 if (fs_stateSeek(state
, offset
)) {
669 ViceLog(0, ("fs_stateWriteHeader: could not seek to correct position in dump file '%s'\n",
675 if (fs_stateWrite(state
, hdr
, len
)) {
676 ViceLog(0, ("fs_stateWriteHeader: write failed\n"));
686 fs_stateReadHeader(struct fs_dump_state
* state
,
688 void * hdr
, size_t len
)
692 if (fs_stateSeek(state
, offset
)) {
693 ViceLog(0, ("fs_stateReadHeader: could not seek to correct position in dump file '%s'\n",
699 if (fs_stateRead(state
, hdr
,len
)) {
700 ViceLog(0, ("fs_stateReadHeader: read failed\n"));
709 #ifdef FS_STATE_USE_MMAP
711 fs_stateSizeFile(struct fs_dump_state
* state
)
714 state
->file_len
= FS_STATE_INIT_FILESIZE
;
715 if (afs_ftruncate(state
->fd
, state
->file_len
) != 0)
721 fs_stateResizeFile(struct fs_dump_state
* state
, size_t min_add
)
726 fs_stateUnmapFile(state
);
728 inc
= ((min_add
/ FS_STATE_INIT_FILESIZE
)+1) * FS_STATE_INIT_FILESIZE
;
729 state
->file_len
+= inc
;
731 if (afs_ftruncate(state
->fd
, state
->file_len
) != 0) {
732 ViceLog(0, ("fs_stateResizeFile: truncate failed\n"));
737 if (fs_stateMapFile(state
, 1)) {
738 ViceLog(0, ("fs_stateResizeFile: remapping memory mapped file failed\n"));
748 fs_stateTruncateFile(struct fs_dump_state
* state
)
752 if (afs_ftruncate(state
->fd
, state
->eof_offset
) != 0) {
760 fs_stateMapFile(struct fs_dump_state
* state
, int preserve_flag
)
764 switch(state
->mode
) {
765 case FS_STATE_LOAD_MODE
:
766 flags
= PROT_READ
| PROT_WRITE
; /* loading involves a header invalidation */
768 case FS_STATE_DUMP_MODE
:
772 ViceLog(0, ("fs_stateMapFile: invalid dump state mode\n"));
776 state
->mmap
.map
= afs_mmap(NULL
,
783 if (state
->mmap
.map
== MAP_FAILED
) {
784 state
->mmap
.size
= 0;
785 state
->mmap
.map
= NULL
;
786 ViceLog(0, ("fs_stateMapFile: failed to memory map file '%s'\n",
792 state
->mmap
.size
= state
->file_len
;
793 state
->mmap
.cursor
= state
->mmap
.map
;
796 /* don't lose track of where we are during a file resize */
797 afs_foff_t curr_offset
= state
->mmap
.offset
;
799 state
->mmap
.offset
= 0;
800 fs_stateIncCursor(state
, curr_offset
);
801 } else { /* reset offset */
802 state
->mmap
.offset
= 0;
804 /* for state loading, accesses will be sequential, so let's give
805 * the VM subsystem a heads up */
806 if (state
->mode
== FS_STATE_LOAD_MODE
) {
807 /* XXX madvise may not exist on all platforms, so
808 * we may need to add some ifdefs at some point... */
809 flags
= MADV_SEQUENTIAL
| MADV_WILLNEED
;
810 #ifdef AFS_SUN510_ENV
811 flags
|= MADV_ACCESS_LWP
; /* added in solaris 9 12/02 */
813 madvise(state
->mmap
.map
, state
->mmap
.size
, flags
);
821 fs_stateUnmapFile(struct fs_dump_state
* state
)
825 if (munmap(state
->mmap
.map
, state
->mmap
.size
) == -1) {
826 ViceLog(0, ("fs_stateUnmapFile: failed to unmap dump file '%s'\n",
837 fs_stateSync(struct fs_dump_state
* state
)
841 msync(state
->mmap
.map
, state
->mmap
.size
, MS_SYNC
);
845 #else /* !FS_STATE_USE_MMAP */
847 fs_stateSync(struct fs_dump_state
* state
)
851 if (fsync(state
->fd
) == -1)
856 #endif /* !FS_STATE_USE_MMAP */
859 fs_stateIncEOF(struct fs_dump_state
* state
, afs_int32 len
)
862 FillInt64(temp
, 0, len
);
863 AddUInt64(state
->eof_offset
, temp
, &state
->eof_offset
);
867 #ifdef FS_STATE_USE_MMAP
869 fs_stateIncCursor(struct fs_dump_state
* state
, size_t len
)
873 state
->mmap
.offset
+= len
;
875 p
= (char *) state
->mmap
.cursor
;
877 state
->mmap
.cursor
= (void *) p
;
883 fs_stateCheckIOSafety(struct fs_dump_state
* state
, size_t len
)
887 if ((state
->mmap
.offset
+ len
) > state
->mmap
.size
) {
892 #endif /* FS_STATE_USE_MMAP */
894 #ifdef FS_STATE_USE_MMAP
896 fs_stateSeek(struct fs_dump_state
* state
, afs_uint64
* offset
)
902 p
= (char *) state
->mmap
.map
;
904 state
->mmap
.cursor
= (void *) p
;
907 state
->mmap
.offset
= *offset
;
911 #else /* !FS_STATE_USE_MMAP */
913 fs_stateSeek(struct fs_dump_state
* state
, afs_uint64
* offset
)
917 if (afs_lseek(state
->fd
, *offset
, SEEK_SET
) == -1)
922 #endif /* !FS_STATE_USE_MMAP */
925 fs_stateFillHeader(struct fs_state_header
* hdr
)
927 hdr
->stamp
.magic
= FS_STATE_MAGIC
;
928 hdr
->stamp
.version
= FS_STATE_VERSION
;
930 hdr
->sys_name
= SYS_NAME_ID
;
932 hdr
->sys_name
= 0xFFFFFFFF;
934 hdr
->timestamp
= time(NULL
);
935 hdr
->server_uuid
= FS_HostUUID
;
937 #ifdef WORDS_BIGENDIAN
942 hdr
->stats_detailed
= 1;
943 if (strlcpy(hdr
->server_version_string
, cml_version_number
, sizeof(hdr
->server_version_string
))
944 >= sizeof(hdr
->server_version_string
)) {
945 ViceLog(0, ("fs_stateFillHeader: WARNING -- cml_version_number field truncated\n"));
951 fs_stateCheckHeader(struct fs_state_header
* hdr
)
956 ViceLog(0, ("fs_stateCheckHeader: dump was previously flagged invalid\n"));
959 #ifdef WORDS_BIGENDIAN
960 else if (!hdr
->endianness
) {
961 ViceLog(0, ("fs_stateCheckHeader: wrong endianness\n"));
964 #else /* AFSLITTLE_ENDIAN */
965 else if (hdr
->endianness
) {
966 ViceLog(0, ("fs_stateCheckHeader: wrong endianness\n"));
969 #endif /* AFSLITTLE_ENDIAN */
971 else if (hdr
->stamp
.magic
!= FS_STATE_MAGIC
) {
972 ViceLog(0, ("fs_stateCheckHeader: invalid dump header\n"));
975 else if (hdr
->stamp
.version
!= FS_STATE_VERSION
) {
976 ViceLog(0, ("fs_stateCheckHeader: unknown dump format version number\n"));
980 else if (!hdr
->stats_detailed
) {
981 ViceLog(0, ("fs_stateCheckHeader: wrong config flags\n"));
985 else if (!afs_uuid_equal(&hdr
->server_uuid
, &FS_HostUUID
)) {
986 ViceLog(0, ("fs_stateCheckHeader: server UUID does not match this server's UUID\n"));
990 /* the cml_version_string is included for informational purposes only. If someone ever
991 * wants to limit state dump reloading based upon the contents of this string, just
992 * uncomment the following code. uncommenting this code is _strongly discouraged_ because
993 * we already make use of the version stamps in the various dump headers to deal with
994 * data structure version incompatabilities.
995 else if (strncmp(hdr->server_version_string, cml_version_number,
996 sizeof(hdr->server_version_string)) != 0) {
997 ViceLog(0, ("fs_stateCheckHeader: dump from different server version\n"));
1002 else if (strncmp(hdr
->server_version_string
, cml_version_number
,
1003 sizeof(hdr
->server_version_string
)) != 0) {
1004 ViceLog(0, ("fs_stateCheckHeader: dump from different server version ; attempting state reload anyway\n"));
1012 fs_stateAlloc(struct fs_dump_state
* state
)
1015 memset(state
, 0, sizeof(struct fs_dump_state
));
1017 state
->fn
= (char *)AFSDIR_SERVER_FSSTATE_FILEPATH
;
1018 state
->hdr
= malloc(sizeof(struct fs_state_header
));
1019 state
->h_hdr
= malloc(sizeof(struct host_state_header
));
1020 state
->cb_hdr
= malloc(sizeof(struct callback_state_header
));
1021 state
->cb_timeout_hdr
=
1022 malloc(sizeof(struct callback_state_timeout_header
));
1023 state
->cb_fehash_hdr
=
1024 malloc(sizeof(struct callback_state_fehash_header
));
1025 if ((state
->hdr
== NULL
) || (state
->h_hdr
== NULL
) || (state
->cb_hdr
== NULL
) ||
1026 (state
->cb_timeout_hdr
== NULL
) || (state
->cb_fehash_hdr
== NULL
))
1032 fs_stateFree(struct fs_dump_state
* state
)
1039 free(state
->cb_hdr
);
1040 if (state
->cb_timeout_hdr
)
1041 free(state
->cb_timeout_hdr
);
1042 if (state
->cb_fehash_hdr
)
1043 free(state
->cb_fehash_hdr
);
1044 if (state
->h_map
.entries
)
1045 free(state
->h_map
.entries
);
1046 if (state
->fe_map
.entries
)
1047 free(state
->fe_map
.entries
);
1048 if (state
->cb_map
.entries
)
1049 free(state
->cb_map
.entries
);
1053 #endif /* AFS_DEMAND_ATTACH_FS */