2 * Copyright 2000, International Business Machines Corporation 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
10 #include <afsconfig.h>
11 #include <afs/param.h>
17 #include <sys/types.h>
21 #include "cnvldb.h" /* CHANGEME! */
22 #include <netinet/in.h>
23 #include <afs/venus.h>
29 #include "afs/prs_fs.h"
30 #include <afs/afsint.h>
32 #include <afs/cellconfig.h>
37 #define MAXSIZE 2048 /* most I'll get back from PIOCTL */
40 extern struct cmd_syndesc *cmd_CreateSyntax();
41 static char pn[] = "cnvldb";
42 static char tempname[] = "XXnewvldb";
43 static char space[MAXSIZE];
44 static int MaxServers[2] = { 30, 254 }; /* max server # permitted in this version */
46 #ifdef notdef /* postpone this... */
48 saferead(fd, addr, osize)
62 rc = read(fd, ptr, size)) {
76 saferead(fd, addr, osize)
82 rc = read(fd, addr, osize);
83 if (rc != osize && rc != EOF) {
90 #define saferead(fd,addr,siz) read((fd),(addr),(siz))
93 static char tspace[1024]; /* chdir can't handle anything bigger, anyway */
94 /* return a static pointer to a buffer */
100 strcpy(tspace, apath);
101 tp = strrchr(tspace, '/');
111 /* this function returns TRUE (1) if the file is in AFS, otherwise false (0) */
114 register char *apath;
116 struct ViceIoctl blob;
117 register afs_int32 code;
120 blob.out_size = MAXSIZE;
123 code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
125 if ((errno == EINVAL) || (errno == ENOENT))
131 QuickPrintStatus(status, name)
132 struct VolumeStatus *status;
135 double QuotaUsed = 0.0;
136 double PartUsed = 0.0;
139 if (status->MaxQuota != 0) {
141 ((((double)status->BlocksInUse) / status->MaxQuota) * 100.0);
147 ((((double)status->PartBlocksAvail) / status->PartMaxBlocks) *
154 register struct cmd_syndesc *as;
156 register afs_int32 code;
157 struct ViceIoctl blob;
158 register struct cmd_item *ti;
159 struct VolumeStatus *status;
162 for (ti = as->parms[0].items; ti; ti = ti->next) {
164 blob.out_size = MAXSIZE;
167 code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
172 status = (struct VolumeStatus *)space;
173 name = (char *)status + sizeof(*status);
174 QuickPrintStatus(status, name);
180 int gc = 1, fromvers = 1, tovers = 2;
181 char *pathname = NULL, *defaultpath = "/usr/afs/db/vl.DB0";
185 fprintf(stderr, "usage: %s ", pn);
186 fprintf(stderr, "[-name <pathname>] [-help]\n");
196 for (i = 1; i < argc; i++) {
199 else if (*(argv[i]) != '-') { /* positional params */
203 fprintf(stderr, "%s: Too many parameters!\n");
207 } else /* keyword params */
208 switch (argv[i][1]) {
211 fprintf(stderr, "%s: can't specify version with this tool!\n",
216 case 'f': /* -from */
217 fprintf(stderr, "%s: can't specify version with this tool!\n",
221 case 'n': /* -name */
224 "%s: -name specified (or implied) twice!\n", pn);
227 pathname = argv[++i];
230 case 'h': /* -help */
235 case 'g': /* -gc == No GC */
246 pathname = defaultpath;
249 #include "AFS_component_version_number.c"
255 register afs_int32 code;
258 char ubik[80]; /* space for some ubik header */
261 struct vlheader_1 header1;
262 struct vlheader_2 header2;
263 } oldheader, newheader; /* large enough for either */
266 struct vlentry_1 entry1;
267 struct vlentry_2 entry2;
273 /* should stat() the old vldb, get its size, and see if there's */
274 /* room for another. It might be in AFS, so check the quota, too */
275 if (!(old = open(pathname, O_RDONLY))) {
280 if (chdir(Parent(pathname))) {
285 if (!(new = open(tempname, O_WRONLY | O_CREAT | O_TRUNC, 0600))) {
290 if (fromvers == 0) { /* not set */
291 lseek(old, 64, L_SET);
292 read(old, &fromvers, sizeof(int));
293 fromvers = ntohl(fromvers);
294 lseek(old, 0, L_SET); /* go back to beginning */
297 /* skip the UBIK data */
300 uvers = ntohs(uvers);
301 uvers += 10; /* hey, if you screw with the VLDB, you lose */
302 uvers = htons(uvers);
304 write(new, ubik, 64);
306 readheader(old, fromvers, &oldheader);
307 convert_header(new, fromvers, tovers, &oldheader, &newheader);
308 while ((rc = read(old, &vlentry, sizeof(struct vlentry_1))) && rc != EOF) {
309 convert_vlentry(new, fromvers, tovers, &oldheader, &newheader,
315 rewrite_header(new, tovers, &newheader);
324 rename(tempname, pathname);
328 readheader(fd, version, addr)
334 read(fd, addr, sizeof(struct vlheader_2)); /* it's not a bug, it's SAS */
335 } else if (version == 2) {
336 read(fd, addr, sizeof(struct vlheader_2));
344 convert_header(fd, fromv, tov, fromaddr, toaddr)
346 char *fromaddr, *toaddr;
348 struct vlheader_2 *tvp1;
349 struct vlheader_2 *tvp2;
352 memcpy(toaddr, fromaddr, sizeof(struct vlheader_2));
353 tvp2 = (struct vlheader_2 *)toaddr;
354 tvp2->vital_header.vldbversion = htonl(2);
356 write(fd, tvp2, sizeof(struct vlheader_2));
358 /* for garbage-collecting... */
360 for (i = 0; i < 254; i++)
361 tvp2->IpMappedAddr[i] = 0;
367 convert_vlentry(new, fromvers, tovers, oldheader, newheader, vlentry)
368 int new, fromvers, tovers;
369 struct vlheader_1 *oldheader, *newheader; /* close enough */
370 struct vlentry_1 *vlentry; /* 1 and 2 are identical */
375 if (fromvers != tovers) { /* only supports 1 and 2 currently */
380 1 ? sizeof(struct vlheader_1) : sizeof(struct vlheader_2))
382 1 ? sizeof(struct vlheader_1) : sizeof(struct vlheader_2));
384 for (i = 0; i < 3; i++)
385 vlentry->nextIdHash[i] =
386 htonl(ntohl(vlentry->nextIdHash[i]) + diff);
388 vlentry->nextNameHash = htonl(ntohl(vlentry->nextNameHash) + diff);
392 ; /* no change, we're just in it for the GC */
396 for (i = 0; i < 8; i++) {
397 s = vlentry->serverNumber[i];
401 "%s: Too Many Servers (%d) for this version!\n", pn,
405 newheader->IpMappedAddr[s] = oldheader->IpMappedAddr[s];
409 write(new, vlentry, sizeof(struct vlentry_2));
415 rewrite_header(new, tovers, newheader)
421 pos = lseek(new, 64, L_SET); /* leave room for ubik */
425 fprintf(stderr, "%s: no garbage collection\n", pn);
427 } else if (pos != 64) {
428 fprintf(stderr, "%s: Can't rewind: no garbage collection\n", pn);
433 write(new, newheader, sizeof(struct vlheader_1));
435 write(new, newheader, sizeof(struct vlheader_2));