Example #1
0
/* this is not yet 64-bit clean */
ssize_t
afscp_PRead(const struct afscp_venusfid * fid, void *buffer,
	    size_t count, off_t offset)
{
    struct AFSFetchStatus fst;
    struct AFSVolSync vs;
    struct AFSCallBack cb;
    struct AFSFid tf = fid->fid;
    struct afscp_volume *vol;
    struct afscp_server *server;
    struct rx_call *c = NULL;
    int code, code2 = 0;
    int i, j, bytes, totalbytes = 0;
    int bytesremaining;
    char *p;
    time_t now;

    vol = afscp_VolumeById(fid->cell, fid->fid.Volume);
    if (vol == NULL) {
	afscp_errno = ENOENT;
	return -1;
    }
    code = ENOENT;
    for (i = 0; i < vol->nservers; i++) {
	server = afscp_ServerByIndex(vol->servers[i]);
	if (server && server->naddrs > 0) {
	    for (j = 0; j < server->naddrs; j++) {
		c = rx_NewCall(server->conns[j]);
		if (c != 0) {
		    p = buffer;
		    code = StartRXAFS_FetchData(c, &tf, offset, count);
		    if (code != 0) {
			code = rx_EndCall(c, code);
			continue;
		    }
		    bytes =
			rx_Read(c, (char *)&bytesremaining,
				sizeof(afs_int32));
		    if (bytes != sizeof(afs_int32)) {
			code = rx_EndCall(c, bytes);
			continue;
		    }
		    bytesremaining = ntohl(bytesremaining);
		    totalbytes = 0;
		    while (bytesremaining > 0) {
			bytes = rx_Read(c, p, bytesremaining);
			if (bytes <= 0)
			    break;
			p += bytes;
			totalbytes += bytes;
			bytesremaining -= bytes;
		    }
		    if (bytesremaining == 0) {
			time(&now);
			code2 = EndRXAFS_FetchData(c, &fst, &cb, &vs);
			if (code2 == 0)
			    afscp_AddCallBack(server, &fid->fid, &fst, &cb,
					      now);
		    }
		    code = rx_EndCall(c, code2);
		}
		if (code == 0) {
		    return totalbytes;
		}
	    }
	}
    }
    afscp_errno = code;
    return -1;
}
Example #2
0
/* Cannot have static linkage--called from BPrefetch (afs_daemons) */
afs_int32
afs_PrefetchNoCache(struct vcache *avc,
		    afs_ucred_t *acred,
		    struct nocache_read_request *bparms)
{
    struct uio *auio;
#ifndef UKERNEL
    struct iovec *iovecp;
#endif
    struct vrequest *areq;
    afs_int32 code = 0;
    struct rx_connection *rxconn;
#ifdef AFS_64BIT_CLIENT
    afs_int32 length_hi, bytes, locked;
#endif

    struct afs_conn *tc;
    struct rx_call *tcall;
    struct tlocal1 {
	struct AFSVolSync tsync;
	struct AFSFetchStatus OutStatus;
	struct AFSCallBack CallBack;
    };
    struct tlocal1 *tcallspec;

    auio = bparms->auio;
    areq = bparms->areq;
#ifndef UKERNEL
    iovecp = auio->uio_iov;
#endif

    tcallspec = osi_Alloc(sizeof(struct tlocal1));
    do {
	tc = afs_Conn(&avc->f.fid, areq, SHARED_LOCK /* ignored */, &rxconn);
	if (tc) {
	    avc->callback = tc->parent->srvr->server;
	    tcall = rx_NewCall(rxconn);
#ifdef AFS_64BIT_CLIENT
	    if (!afs_serverHasNo64Bit(tc)) {
		code = StartRXAFS_FetchData64(tcall,
					      (struct AFSFid *) &avc->f.fid.Fid,
					      auio->uio_offset,
					      bparms->length);
		if (code == 0) {
		    COND_GUNLOCK(locked);
		    bytes = rx_Read(tcall, (char *)&length_hi,
				    sizeof(afs_int32));
		    COND_RE_GLOCK(locked);

		    if (bytes != sizeof(afs_int32)) {
			length_hi = 0;
			code = rx_Error(tcall);
			COND_GUNLOCK(locked);
			code = rx_EndCall(tcall, code);
			COND_RE_GLOCK(locked);
			tcall = NULL;
		    }
		}
	    } /* afs_serverHasNo64Bit */
	    if (code == RXGEN_OPCODE || afs_serverHasNo64Bit(tc)) {
		if (auio->uio_offset > 0x7FFFFFFF) {
		    code = EFBIG;
		} else {
		    afs_int32 pos;
		    pos = auio->uio_offset;
		    COND_GUNLOCK(locked);
		    if (!tcall)
			tcall = rx_NewCall(rxconn);
		    code = StartRXAFS_FetchData(tcall,
					(struct AFSFid *) &avc->f.fid.Fid,
					pos, bparms->length);
		    COND_RE_GLOCK(locked);
		}
		afs_serverSetNo64Bit(tc);
	    }
#else
	    code = StartRXAFS_FetchData(tcall,
			                (struct AFSFid *) &avc->f.fid.Fid,
					auio->uio_offset, bparms->length);
#endif
	    if (code == 0) {
		code = afs_NoCacheFetchProc(tcall, avc, auio,
				            1 /* release_pages */,
					    bparms->length);
	    } else {
		afs_warn("BYPASS: StartRXAFS_FetchData failed: %d\n", code);
		unlock_and_release_pages(auio);
		goto done;
	    }
	    if (code == 0) {
		code = EndRXAFS_FetchData(tcall, &tcallspec->OutStatus,
					  &tcallspec->CallBack,
					  &tcallspec->tsync);
	    } else {
		afs_warn("BYPASS: NoCacheFetchProc failed: %d\n", code);
	    }
	    code = rx_EndCall(tcall, code);
	} else {
	    afs_warn("BYPASS: No connection.\n");
	    code = -1;
	    unlock_and_release_pages(auio);
	    goto done;
	}
    } while (afs_Analyze(tc, rxconn, code, &avc->f.fid, areq,
						 AFS_STATS_FS_RPCIDX_FETCHDATA,
						 SHARED_LOCK,0));
done:
    /*
     * Copy appropriate fields into vcache
     */

    if (!code)
	afs_ProcessFS(avc, &tcallspec->OutStatus, areq);

    osi_Free(areq, sizeof(struct vrequest));
    osi_Free(tcallspec, sizeof(struct tlocal1));
    osi_Free(bparms, sizeof(struct nocache_read_request));
#ifndef UKERNEL
    /* in UKERNEL, the "pages" are passed in */
    osi_Free(iovecp, auio->uio_iovcnt * sizeof(struct iovec));
    osi_Free(auio, sizeof(struct uio));
#endif
    return code;
}
Example #3
0
int
main(int argc, char **argv)
{
    char scell[MAXCELLCHARS], dcell[MAXCELLCHARS];
    afs_uint32 ssrv, dsrv;
    char *databuffer, *srcf = NULL, *destd = NULL, *destf = NULL, *destpath = NULL;
    struct stat statbuf;

    struct AFSStoreStatus sst;
    struct AFSFetchStatus fst, dfst;
    struct AFSVolSync vs;
    struct AFSCallBack scb, dcb;
    struct AFSFid sf, dd, df;

    int filesz = 0;
    int ch, blksize, bytesremaining, bytes;
    struct timeval start, finish;
    struct timezone tz;
    struct rx_securityClass *ssc = 0, *dsc = 0;
    int sscindex, dscindex;
    struct rx_connection *sconn = NULL, *dconn = NULL;
    struct rx_call *scall = NULL, *dcall = NULL;
    int code = 0, fetchcode, storecode, printcallerrs = 0;
    int slcl = 0, dlcl = 0, unlock = 0;
    int sfd = 0, dfd = 0, unauth = 0;

    struct AFSCBFids theFids;
    struct AFSCBs theCBs;


    blksize = 8 * 1024;

    while ((ch = getopt(argc, argv, "iouUb:")) != -1) {
	switch (ch) {
	case 'b':
	    blksize = atoi(optarg);
	    break;
	case 'i':
	    slcl = 1;
	    break;
	case 'o':
	    dlcl = 1;
	    break;
	case 'u':
	    unauth = 1;
	    break;
	case 'U':
	    unlock = 1;
	    break;
	default:
	    printf("Unknown option '%c'\n", ch);
	    exit(1);
	}
    }


    if (argc - optind + unlock < 2) {
	fprintf(stderr,
		"Usage: afscp [-i|-o]] [-b xfersz] [-u] [-U] source [dest]\n");
	fprintf(stderr, "  -b   Set block size\n");
	fprintf(stderr, "  -i   Source is local (copy into AFS)\n");
	fprintf(stderr, "  -o   Dest is local (copy out of AFS)\n");
	fprintf(stderr, "  -u   Run unauthenticated\n");
	fprintf(stderr, "  -U   Send an unlock request for source. (dest path not required)\n");
	fprintf(stderr, "source and dest can be paths or specified as:\n");
	fprintf(stderr, "     @afs:cellname:servername:volume:vnode:uniq\n");
	exit(1);
    }
    srcf = argv[optind++];
    if (!unlock) {
	destpath = argv[optind++];
	destd = strdup(destpath);
	if (!destd) {
	    perror("strdup");
	    exit(1);
	}
	if ((destf = strrchr(destd, '/'))) {
	    *destf++ = 0;
	} else {
	    destf = destd;
	    destd = ".";
	}
    } else if (slcl) {
	fprintf(stderr, "-i and -U cannot be used together\n");
    }

    if (!slcl && statfile(srcf, scell, &ssrv, &sf)) {
	fprintf(stderr, "Cannot get attributes of %s\n", srcf);
	exit(1);
    }
    if (!unlock && !dlcl && statfile(destd, dcell, &dsrv, &dd)) {
	fprintf(stderr, "Cannot get attributes of %s\n", destd);
	exit(1);
    }

    if ((databuffer = malloc(blksize)) == NULL) {
	perror("malloc");
	exit(1);
    }

    if (do_rx_Init())
	exit(1);

    if (start_cb_server()) {
	printf("Cannot start callback service\n");
	goto Fail_rx;
    }

    if (!slcl) {
	sscindex = scindex_RXKAD;
	if (unauth || (ssc = get_sc(scell)) == NULL) {
	    ssc = rxnull_NewClientSecurityObject();
	    sscindex = scindex_NULL;
	    /*printf("Cannot get authentication for cell %s; running unauthenticated\n", scell); */
	}
	sscindex = scindex_NULL;

	if ((sconn =
	     rx_NewConnection(ssrv, htons(AFSCONF_FILEPORT), 1, ssc,
			      sscindex))
	    == NULL) {
	    struct in_addr s;
	    s.s_addr = ssrv;
	    printf("Cannot initialize rx connection to source server (%s)\n",
		   inet_ntoa(s));
	    goto Fail_sc;
	}
    }

    if (!dlcl && !unlock) {
	if (!slcl && ssrv == dsrv) {
	    dconn = sconn;
	    dsc = NULL;
	} else {
	    if (slcl || strcmp(scell, dcell)) {
		dscindex = scindex_RXKAD;
		if (unauth || (dsc = get_sc(dcell)) == NULL) {
		    dsc = rxnull_NewClientSecurityObject();
		    dscindex = scindex_NULL;
		    /*printf("Cannot get authentication for cell %s; running unauthenticated\n", dcell); */
		}
		dscindex = scindex_NULL;
	    } else {
		dsc = ssc;
		dscindex = sscindex;
	    }

	    if ((dconn =
		 rx_NewConnection(dsrv, htons(AFSCONF_FILEPORT), 1, dsc,
				  dscindex))
		== NULL) {
		struct in_addr s;
		s.s_addr = dsrv;
		printf
		    ("Cannot initialize rx connection to dest server (%s)\n",
		     inet_ntoa(s));
		goto Fail_sconn;
	    }
	}
    }


    memset(&sst, 0, sizeof(struct AFSStoreStatus));

    if (dlcl && !unlock) {
	dfd = open(destpath, O_RDWR | O_CREAT | O_EXCL, 0666);
	if (dfd < 0 && errno == EEXIST) {
	    printf("%s already exists, overwriting\n", destpath);
	    dfd = open(destpath, O_RDWR | O_TRUNC, 0666);
	    if (dfd < 0) {
		fprintf(stderr, "Cannot open %s (%s)\n", destpath,
			afs_error_message(errno));
		goto Fail_dconn;
	    }
	} else if (dfd < 0) {
	    fprintf(stderr, "Cannot open %s (%s)\n", destpath,
		    afs_error_message(errno));
	    goto Fail_dconn;
	}
    } else if (!unlock) {
	if ((code =
	     RXAFS_CreateFile(dconn, &dd, destf, &sst, &df, &fst, &dfst, &dcb,
			      &vs))) {
	    if (code == EEXIST) {
		printf("%s already exits, overwriting\n", destpath);
		if (statfile(destpath, dcell, &dsrv, &df))
		    fprintf(stderr, "Cannot get attributes of %s\n",
			    destpath);
		else
		    code = 0;
	    } else {
		printf("Cannot create %s (%s)\n", destpath,
		       afs_error_message(code));
		if (code)
		    goto Fail_dconn;
	    }
	}
    }

    if (slcl) {
	sfd = open(srcf, O_RDONLY, 0);
	if (sfd < 0) {
	    fprintf(stderr, "Cannot open %s (%s)\n", srcf,
		    afs_error_message(errno));
	    goto Fail_dconn;
	}
	if (fstat(sfd, &statbuf) < 0) {
	    fprintf(stderr, "Cannot stat %s (%s)\n", srcf,
		    afs_error_message(errno));
	    close(sfd);
	    goto Fail_dconn;
	}
    } else {
	if ((code = RXAFS_FetchStatus(sconn, &sf, &fst, &scb, &vs))) {
	    printf("Cannot fetchstatus of %d.%d (%s)\n", sf.Volume, sf.Vnode,
		   afs_error_message(code));
	    goto Fail_dconn;
	}
    }



    if (slcl) {
	filesz = statbuf.st_size;
    } else {
	filesz = fst.Length;
    }

    printcallerrs = 0;
    fetchcode = 0;
    storecode = 0;
    if (!slcl && !unlock)
	scall = rx_NewCall(sconn);
    if (!dlcl && !unlock)
	dcall = rx_NewCall(dconn);
    gettimeofday(&start, &tz);
    if (unlock) {
	if (fst.lockCount) {
	    printf("Sending 1 unlock for %s (%d locks)\n", srcf, fst.lockCount);
	    if ((code = RXAFS_ReleaseLock(sconn, &sf, &vs))) {
		printf("Unable to unlock %s (%s)\n", srcf,
		       afs_error_message(code));
	    }
	} else {
	    printf("No locks for %s\n", srcf);
	}
	fetchcode = code;
	goto Finish;
    }

    if (!slcl) {
	if ((code = StartRXAFS_FetchData(scall, &sf, 0, filesz))) {
	    printf("Unable to fetch data from %s (%s)\n", srcf,
		   afs_error_message(code));
	    goto Fail_call;
	}
    }

    if (!dlcl) {
	if (slcl) {
	    sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
	    sst.ClientModTime = statbuf.st_mtime;
	    sst.UnixModeBits =
		statbuf.st_mode & ~(S_IFMT | S_ISUID | S_ISGID);
	} else {
	    sst.Mask = AFS_SETMODTIME | AFS_SETMODE;
	    sst.ClientModTime = fst.ClientModTime;
	    sst.UnixModeBits =
		fst.UnixModeBits & ~(S_IFMT | S_ISUID | S_ISGID);
	}

	if ((code =
	     StartRXAFS_StoreData(dcall, &df, &sst, 0, filesz, filesz))) {
	    printf("Unable to store data to %s (%s)\n", destpath,
		   afs_error_message(code));
	    goto Fail_call;
	}
    }

    if (slcl) {
	bytesremaining = statbuf.st_size;
    } else {
	rx_Read(scall, (char *)&bytesremaining, sizeof(afs_int32));
	bytesremaining = ntohl(bytesremaining);
    }

    while (bytesremaining > 0) {
	/*printf("%d bytes remaining\n",bytesremaining); */
	if (slcl) {
	    if ((bytes =
		 read(sfd, databuffer, min(blksize, bytesremaining))) <= 0) {
		fetchcode = errno;
		break;
	    }
	} else {
	    if ((bytes =
		 rx_Read(scall, databuffer,
			 min(blksize, bytesremaining))) <= 0)
		break;
	}
	if (dlcl) {
	    if (write(dfd, databuffer, bytes) != bytes) {
		storecode = errno;
		break;
	    }
	} else {
	    if (rx_Write(dcall, databuffer, bytes) != bytes)
		break;
	}
	bytesremaining -= bytes;
	/*printf("%d bytes copied\n",bytes); */
    }


    if (bytesremaining > 0) {
	printf("Some network error occured while copying data\n");
	goto Fail_call;
    }

    if (!slcl)
	fetchcode = EndRXAFS_FetchData(scall, &fst, &scb, &vs);
    if (!dlcl)
	storecode = EndRXAFS_StoreData(dcall, &fst, &vs);
    printcallerrs = 1;
  Fail_call:

    if (slcl) {
	if (close(sfd) && !fetchcode)
	    fetchcode = errno;
    } else {
	fetchcode = rx_EndCall(scall, fetchcode);
    }
    if (fetchcode && printcallerrs)
	printf("Error returned from fetch: %s\n", afs_error_message(fetchcode));

    if (dlcl) {
	if (close(dfd) && !storecode)
	    storecode = errno;
    } else if (!unlock) {
	storecode = rx_EndCall(dcall, storecode);
    }
    if (storecode && printcallerrs)
	printf("Error returned from store: %s\n", afs_error_message(storecode));
Finish:
    gettimeofday(&finish, &tz);

    if (!slcl) {
	theFids.AFSCBFids_len = 1;
	theFids.AFSCBFids_val = &sf;
	theCBs.AFSCBs_len = 1;
	theCBs.AFSCBs_val = &scb;
	scb.CallBackType = CB_DROPPED;
	if ((code = RXAFS_GiveUpCallBacks(sconn, &theFids, &theCBs)))
	    printf("Could not give up source callback: %s\n",
		   afs_error_message(code));
    }

    if (!dlcl) {
	theFids.AFSCBFids_len = 1;
	theFids.AFSCBFids_val = &df;
	theCBs.AFSCBs_len = 1;
	theCBs.AFSCBs_val = &dcb;
	dcb.CallBackType = CB_DROPPED;
	if ((code = RXAFS_GiveUpCallBacks(dconn, &theFids, &theCBs)))
	    printf("Could not give up target callback: %s\n",
		   afs_error_message(code));
    }

    if (code == 0)
	code = storecode;
    if (code == 0)
	code = fetchcode;

  Fail_dconn:
    if (!dlcl && !unlock && (slcl || dconn != sconn))
	rx_DestroyConnection(dconn);
  Fail_sconn:
    if (!slcl)
	rx_DestroyConnection(sconn);
  Fail_sc:
    if (dsc && dsc != ssc)
	RXS_Close(dsc);
    if (ssc)
	RXS_Close(ssc);
  Fail_rx:
    rx_Finalize();

    free(databuffer);
    if (printcallerrs && !unlock) {
	double rate, size, time;
	if (finish.tv_sec == start.tv_sec) {
	    printf("Copied %d bytes in %d microseconds\n", filesz,
		   (int)(finish.tv_usec - start.tv_usec));
	} else {
	    printf("Copied %d bytes in %d seconds\n", filesz,
		   (int)(finish.tv_sec - start.tv_sec));
	}

	size = filesz / 1024.0;
	time =
	    finish.tv_sec - start.tv_sec + (finish.tv_usec -
					    start.tv_usec) / 1e+06;
	rate = size / time;
	printf("Transfer rate %g Kbytes/sec\n", rate);

    }

    exit(code != 0);
}