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>
16 #include <sys/types.h>
20 #include "cnvldb.h" /* CHANGEME! */
21 #include <netinet/in.h>
22 #include <afs/venus.h>
28 #include "afs/prs_fs.h"
29 #include <afs/afsint.h>
31 #include <afs/cellconfig.h>
36 #define MAXSIZE 2048 /* most I'll get back from PIOCTL */
39 extern struct cmd_syndesc *cmd_CreateSyntax();
40 static char pn[] = "cnvldb";
41 static char tempname[] = "XXnewvldb";
42 static char space[MAXSIZE];
43 static int MaxServers[2] = {30,254};/* max server # permitted in this version*/
45 #ifdef notdef /* postpone this... */
47 saferead (fd,addr,osize)
61 rc = read(fd, ptr, size)) {
75 saferead (fd,addr,osize)
81 rc = read(fd,addr,osize);
82 if (rc != osize && rc != EOF) {
89 #define saferead(fd,addr,siz) read((fd),(addr),(siz))
92 static char tspace[1024]; /* chdir can't handle anything bigger, anyway */
93 /* return a static pointer to a buffer */
94 static char *Parent(apath)
97 strcpy(tspace, apath);
98 tp = rindex(tspace, '/');
102 else strcpy(tspace, ".");
108 /* this function returns TRUE (1) if the file is in AFS, otherwise false (0) */
109 static int InAFS(apath)
110 register char *apath; {
111 struct ViceIoctl blob;
112 register afs_int32 code;
115 blob.out_size = MAXSIZE;
118 code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
120 if ((errno == EINVAL) || (errno == ENOENT)) return 0;
125 QuickPrintStatus(status, name)
126 struct VolumeStatus *status;
128 double QuotaUsed =0.0;
129 double PartUsed =0.0;
132 if (status->MaxQuota != 0) {
133 QuotaUsed = ((((double)status->BlocksInUse)/status->MaxQuota) * 100.0);
137 PartUsed = (100.0 - ((((double)status->PartBlocksAvail)/status->PartMaxBlocks) * 100.0));
141 static ListQuotaCmd(as)
142 register struct cmd_syndesc *as; {
143 register afs_int32 code;
144 struct ViceIoctl blob;
145 register struct cmd_item *ti;
146 struct VolumeStatus *status;
149 for(ti=as->parms[0].items; ti; ti=ti->next) {
151 blob.out_size = MAXSIZE;
154 code = pioctl(ti->data, VIOCGETVOLSTAT, &blob, 1);
159 status = (struct VolumeStatus *)space;
160 name = (char *)status + sizeof(*status);
161 QuickPrintStatus(status, name);
170 char *pathname = NULL,
171 *defaultpath = "/usr/afs/db/vl.DB0";
175 fprintf(stderr, "usage: %s ",pn);
176 fprintf(stderr, "[-name <pathname>] [-help]\n");
185 for (i=1;i<argc;i++) {
188 else if (*(argv[i]) != '-' ) { /* positional params */
192 fprintf(stderr, "%s: Too many parameters!\n");
197 else /* keyword params */
198 switch (argv[i][1]) {
201 fprintf(stderr, "%s: can't specify version with this tool!\n",pn);
205 case 'f' : /* -from */
206 fprintf(stderr, "%s: can't specify version with this tool!\n",pn);
209 case 'n' : /* -name */
211 fprintf(stderr, "%s: -name specified (or implied) twice!\n",pn);
214 pathname = argv[++i];
217 case 'h' : /* -help */
222 case 'g' : /* -gc == No GC */
232 pathname = defaultpath;
235 #include "AFS_component_version_number.c"
241 register afs_int32 code;
244 char ubik[80]; /* space for some ubik header */
247 struct vlheader_1 header1;
248 struct vlheader_2 header2;
249 } oldheader, newheader; /* large enough for either */
252 struct vlentry_1 entry1;
253 struct vlentry_2 entry2;
259 /* should stat() the old vldb, get its size, and see if there's */
260 /* room for another. It might be in AFS, so check the quota, too */
261 if (!(old = open (pathname,O_RDONLY))) {
266 if (chdir(Parent(pathname))) {
271 if (!(new = open(tempname,O_WRONLY|O_CREAT|O_TRUNC,0600))) {
276 if (fromvers == 0) { /* not set */
278 read (old, &fromvers, sizeof(int));
279 fromvers = ntohl(fromvers);
280 lseek(old,0,L_SET); /* go back to beginning */
283 /* skip the UBIK data */
284 read (old, ubik, 64);
286 uvers = ntohs(uvers);
287 uvers += 10; /* hey, if you screw with the VLDB, you lose*/
288 uvers = htons(uvers);
290 write (new, ubik, 64);
292 readheader (old, fromvers, &oldheader);
293 convert_header(new, fromvers, tovers, &oldheader, &newheader);
294 while ((rc=read(old, &vlentry, sizeof(struct vlentry_1))) && rc != EOF) {
295 convert_vlentry(new, fromvers, tovers, &oldheader, &newheader, &vlentry);
300 rewrite_header(new, tovers, &newheader);
309 rename(tempname,pathname);
313 readheader(fd, version, addr)
319 read(fd, addr, sizeof(struct vlheader_2)); /* it's not a bug, it's SAS */
321 else if (version == 2) {
322 read (fd, addr, sizeof(struct vlheader_2));
330 convert_header(fd, fromv, tov, fromaddr, toaddr)
332 char *fromaddr, *toaddr;
334 struct vlheader_2 *tvp1;
335 struct vlheader_2 *tvp2;
338 bcopy (fromaddr, toaddr, sizeof(struct vlheader_2));
339 tvp2 = (struct vlheader_2 *) toaddr;
340 tvp2->vital_header.vldbversion = htonl(2);
342 write (fd, tvp2, sizeof(struct vlheader_2));
344 /* for garbage-collecting... */
347 tvp2->IpMappedAddr[i] = 0;
353 convert_vlentry(new, fromvers, tovers, oldheader, newheader, vlentry)
354 int new, fromvers, tovers;
355 struct vlheader_1 *oldheader, *newheader; /* close enough */
356 struct vlentry_1 *vlentry; /* 1 and 2 are identical */
361 if (fromvers != tovers ) { /* only supports 1 and 2 currently */
364 diff = (tovers == 1 ? sizeof(struct vlheader_1) : sizeof(struct vlheader_2))
365 - (fromvers == 1 ? sizeof(struct vlheader_1) : sizeof(struct vlheader_2));
368 vlentry->nextIdHash[i] = htonl(ntohl(vlentry->nextIdHash[i]) + diff);
370 vlentry->nextNameHash = htonl(ntohl(vlentry->nextNameHash) + diff);
375 ; /* no change, we're just in it for the GC */
380 s = vlentry->serverNumber[i];
383 fprintf(stderr, "%s: Too Many Servers (%d) for this version!\n",pn,s+1);
387 newheader->IpMappedAddr[s] = oldheader->IpMappedAddr[s];
391 write (new, vlentry, sizeof(struct vlentry_2));
397 rewrite_header(new, tovers, newheader)
403 pos = lseek (new, 64, L_SET); /* leave room for ubik */
407 fprintf(stderr, "%s: no garbage collection\n",pn);
410 else if (pos != 64) {
411 fprintf(stderr,"%s: Can't rewind: no garbage collection\n",pn);
416 write (new, newheader, sizeof (struct vlheader_1));
419 write (new, newheader, sizeof (struct vlheader_2));