Пример #1
0
int
afscp_GetStatus(const struct afscp_venusfid *fid, struct AFSFetchStatus *s)
{
    struct afscp_volume *v;
    struct afscp_server *server;
    struct AFSCallBack cb;
    struct AFSVolSync vs;
    struct AFSFid tf = fid->fid;
    struct afscp_statent *stored, key;
    void *cached;
    int code, i, j;
    time_t now;

    v = afscp_VolumeById(fid->cell, fid->fid.Volume);
    if (v == NULL) {
	return -1;
    }
    memset(&key, 0, sizeof(key));
    memcpy(&key.me, fid, sizeof(*fid));

    cached = tfind(&key, &v->statcache, statcompare);
    if (cached != NULL) {
	stored = *(struct afscp_statent **)cached;
	pthread_mutex_lock(&(stored->mtx));
	memmove(s, &stored->status, sizeof(*s));
	afs_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n",
		     fid->cell->id, fid->fid.Volume, fid->fid.Vnode,
		     fid->fid.Unique));
	if (stored->nwaiters)
	    pthread_cond_broadcast(&(stored->cv));
	pthread_mutex_unlock(&(stored->mtx));
	return 0;
    }

    code = ENOENT;
    for (i = 0; i < v->nservers; i++) {
	server = afscp_ServerByIndex(v->servers[i]);
	if (server && server->naddrs > 0) {
	    for (j = 0; j < server->naddrs; j++) {
		time(&now);
		code = RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs);
		if (code == 0) {
		    afscp_AddCallBack(server, &fid->fid, s, &cb, now);	/* calls _StatStuff */
		    afs_dprintf(("Stat %d.%lu.%lu.%lu"
				 " ok: type %ld size %ld\n",
				 fid->cell->id,
				 afs_printable_uint32_lu(fid->fid.Volume),
				 afs_printable_uint32_lu(fid->fid.Vnode),
				 afs_printable_uint32_lu(fid->fid.Unique),
				 afs_printable_int32_ld(s->FileType),
				 afs_printable_int32_ld(s->Length)));
		    return 0;
		}
	    }
	}
    }
    afscp_errno = code;
    return -1;
}
Пример #2
0
/* bc_openTextFile - This function opens a temp file to read in the
 * config text recd from the bu server. On Unix, an unlink() is done on
 * the file as soon as it is opened, so when the program exits, the file will
 * be removed automatically, while being invisible while in use.
 * On NT, however, the file must be explicitly deleted after use with an unlink()
 * Input:
 *  Pointer to a udhClientTextP struct. The open stream ptr is stored in
 *           the udbClientTextP.textStream member.
 * Output: The temp file name is returned in tmpFileName. This should be used
 *   to delete the file when done with it.
 * Return Values:
 *     !0: error code
 *     0: Success.
 */
int
bc_openTextFile(udbClientTextP ctPtr, char *tmpFileName)
{
    int code = 0;
    int fd;

    if (ctPtr->textStream != NULL) {
	fclose(ctPtr->textStream);
	ctPtr->textStream = NULL;
    }

    sprintf(tmpFileName, "%s/bu_XXXXXX", gettmpdir());
    fd = mkstemp(tmpFileName);
    if (fd == -1)
	ERROR(BUDB_INTERNALERROR);
    ctPtr->textStream = fdopen(fd, "w+");
    if (ctPtr->textStream == NULL)
	ERROR(BUDB_INTERNALERROR);

#ifndef AFS_NT40_ENV		/* This can't be done on NT */
    /* make the file invisible to others */
    code = unlink(tmpFileName);
    if (code)
	ERROR(errno);
#endif

    afs_dprintf(("file is %s\n", tmpFileName));

  normal_exit:
    return code;

  error_exit:
    if (ctPtr->textStream != NULL) {
	fclose(ctPtr->textStream);
	ctPtr->textStream = NULL;
    }
    goto normal_exit;
}
Пример #3
0
struct afscp_volume *
afscp_VolumeByName(struct afscp_cell *cell, const char *vname,
                   afs_int32 intype)
{
    union allvldbentry u;
    struct afscp_volume *ret, key;
    struct afscp_server *server;
    afs_int32 code, vtype, type, srv;
    void *s;
#ifdef AFSCP_DEBUG
    struct in_addr i;
#endif
    if (intype == RWVOL)
        vtype = VLSF_RWVOL;
    else if (intype == ROVOL)
        vtype = VLSF_ROVOL;
    else if (intype == BACKVOL)
        vtype = VLSF_BACKVOL;
    else {
        afscp_errno = EINVAL;
        return NULL;
    }

    memset(&key, 0, sizeof(key));
    strlcpy(key.name, vname, sizeof(key.name));
    key.voltype = vtype;
    s = tfind(&key, &cell->volsbyname, ncompare);
    if (s) {
        ret = *(struct afscp_volume **)s;
        return ret;
    }

    type = 0;
    code = ubik_VL_GetEntryByNameU(cell->vlservers, 0, (char *)vname, &u.u);
    if (code == RXGEN_OPCODE) {
        type = 1;
        code =
            ubik_VL_GetEntryByNameN(cell->vlservers, 0, (char *)vname, &u.n);
        if (code == RXGEN_OPCODE) {
            type = 2;
            code = ubik_VL_GetEntryByNameO(cell->vlservers, 0, (char *)vname,
                                           &u.o);
        }
    }
    if (code != 0) {
        afscp_errno = code;
        return NULL;
    }
    ret = calloc(1, sizeof(struct afscp_volume));
    if (ret == NULL) {
        afscp_errno = ENOMEM;
        return NULL;
    }
    strlcpy(ret->name, u.u.name, sizeof(ret->name));
    ret->nservers = 0;
    ret->cell = cell;
    switch (type) {
    case 0:
        ret->id = u.u.volumeId[intype];
        for (srv = 0; srv < u.u.nServers; srv++) {
            if ((u.u.serverFlags[srv] & vtype) == 0)
                continue;
            afs_dprintf(("uvldbentry server %d flags: %x\n", srv,
                         u.u.serverFlags[srv]));

            if ((u.u.serverFlags[srv] & VLSF_UUID) == 0)
                server =
                    afscp_ServerByAddr(cell, u.u.serverNumber[srv].time_low);
            else
                server = afscp_ServerById(cell, &u.u.serverNumber[srv]);
            if (!server)
                continue;
            ret->servers[ret->nservers++] = server->index;
        }
        break;
    case 1:
        ret->id = u.n.volumeId[intype];
        for (srv = 0; srv < u.n.nServers; srv++) {
            if ((u.n.serverFlags[srv] & vtype) == 0)
                continue;
            server = afscp_ServerByAddr(cell, u.n.serverNumber[srv]);
            if (!server)
                continue;
            ret->servers[ret->nservers++] = server->index;
        }
        break;
    case 2:
        ret->id = u.o.volumeId[intype];
        for (srv = 0; srv < u.o.nServers; srv++) {
            if ((u.o.serverFlags[srv] & vtype) == 0)
                continue;
            server = afscp_ServerByAddr(cell, u.o.serverNumber[srv]);
            if (!server)
                continue;
            ret->servers[ret->nservers++] = server->index;
        }
        break;
    }
    if (!ret->nservers || !ret->id) {
        free(ret);
        return NULL;
    }

    ret->voltype = intype;
#ifdef AFSCP_DEBUG
    server = afscp_ServerByIndex(ret->servers[0]);
    if (server != NULL)
        i.s_addr = server->addrs[0];
    else
        i.s_addr = 0;
#endif
    afs_dprintf(("New volume BYNAME %s (%lu) on %s (%d)\n", ret->name,
                 afs_printable_uint32_lu(ret->id),
                 inet_ntoa(i), ret->servers[0]));
    s = tsearch(&key, &cell->volsbyname, ncompare);
    if (s)
        *(struct afscp_volume **)s = ret;
    key.id = ret->id;
    s = tsearch(&key, &cell->volsbyid, icompare);
    if (s)
        *(struct afscp_volume **)s = ret;
    return ret;
}
Пример #4
0
struct afscp_volume *
afscp_VolumeById(struct afscp_cell *cell, afs_uint32 id)
{
    union allvldbentry u;
    struct afscp_volume *ret, key;
    struct afscp_server *server;
    afs_int32 code, vtype, type, srv;
    int voltype = -1;
    char idbuffer[16];
    void *s;
#ifdef AFSCP_DEBUG
    struct in_addr i;
#endif

    memset(&key, 0, sizeof(key));
    key.id = id;
    s = tfind(&key, &cell->volsbyid, icompare);
    if (s) {
        ret = *(struct afscp_volume **)s;
        return ret;
    }

    snprintf(idbuffer, sizeof(idbuffer), "%lu", afs_printable_uint32_lu(id));
    type = 0;
    code = ubik_VL_GetEntryByNameU(cell->vlservers, 0, idbuffer, &u.u);
    if (code == RXGEN_OPCODE) {
        type = 1;
        code = ubik_VL_GetEntryByIDN(cell->vlservers, 0, id, -1, &u.n);
        if (code == RXGEN_OPCODE) {
            type = 2;
            code = ubik_VL_GetEntryByID(cell->vlservers, 0, id, -1, &u.o);
        }
    }
    if (code != 0) {
        afscp_errno = code;
        return NULL;
    }
    ret = calloc(1, sizeof(struct afscp_volume));
    if (ret == NULL) {
        afscp_errno = ENOMEM;
        return NULL;
    }
    strlcpy(ret->name, u.u.name, sizeof(ret->name));
    ret->nservers = 0;
    ret->cell = cell;

    switch (type) {
    case 0:
        if (id == u.u.volumeId[RWVOL]) {
            vtype = VLSF_RWVOL;
            voltype = RWVOL;
        } else if (id == u.u.volumeId[ROVOL]) {
            vtype = VLSF_ROVOL;
            voltype = ROVOL;
        } else if (id == u.u.volumeId[BACKVOL]) {
            vtype = VLSF_BACKVOL;
            voltype = BACKVOL;
        } else {
            vtype = 0;
            voltype = -1;
        }
        for (srv = 0; srv < u.u.nServers; srv++) {
            if ((u.u.serverFlags[srv] & vtype) == 0)
                continue;
            if ((u.u.serverFlags[srv] & VLSF_UUID) == 0)
                server =
                    afscp_ServerByAddr(cell, u.u.serverNumber[srv].time_low);
            else
                server = afscp_ServerById(cell, &u.u.serverNumber[srv]);
            if (!server)
                continue;
            ret->servers[ret->nservers++] = server->index;
        }
        break;
    case 1:
        if (id == u.n.volumeId[RWVOL]) {
            vtype = VLSF_RWVOL;
            voltype = RWVOL;
        } else if (id == u.n.volumeId[ROVOL]) {
            vtype = VLSF_ROVOL;
            voltype = ROVOL;
        } else if (id == u.n.volumeId[BACKVOL]) {
            vtype = VLSF_BACKVOL;
            voltype = BACKVOL;
        } else {
            vtype = 0;
            voltype = -1;
        }
        for (srv = 0; srv < u.n.nServers; srv++) {
            if ((u.n.serverFlags[srv] & vtype) == 0)
                continue;
            server = afscp_ServerByAddr(cell, u.n.serverNumber[srv]);
            if (server == NULL)
                continue;
            ret->servers[ret->nservers++] = server->index;
        }
        break;
    case 2:
        if (id == u.o.volumeId[RWVOL]) {
            vtype = VLSF_RWVOL;
            voltype = RWVOL;
        } else if (id == u.o.volumeId[ROVOL]) {
            vtype = VLSF_ROVOL;
            voltype = ROVOL;
        } else if (id == u.o.volumeId[BACKVOL]) {
            vtype = VLSF_BACKVOL;
            voltype = BACKVOL;
        } else {
            vtype = 0;
            voltype = -1;
        }
        for (srv = 0; srv < u.o.nServers; srv++) {
            if ((u.o.serverFlags[srv] & vtype) == 0)
                continue;
            server = afscp_ServerByAddr(cell, u.o.serverNumber[srv]);
            if (server == NULL)
                continue;
            ret->servers[ret->nservers++] = server->index;
        }
        break;
    }
    ret->voltype = voltype;
#ifdef AFSCP_DEBUG
    server = afscp_ServerByIndex(ret->servers[0]);
    if (server)
        i.s_addr = server->addrs[0];
    else
        i.s_addr = 0;
#endif
    afs_dprintf(("New volume BYID %s (%lu) on %s (%d)\n", ret->name,
                 afs_printable_uint32_lu(ret->id), inet_ntoa(i),
                 ret->servers[0]));
    s = tsearch(&key, &cell->volsbyid, icompare);
    if (s)
        *(struct afscp_volume **)s = ret;
    strlcpy(key.name, ret->name, sizeof(key.name));
    s = tsearch(&key, &cell->volsbyname, ncompare);
    if (s)
        *(struct afscp_volume **)s = ret;
    return ret;
}
Пример #5
0
/* takes server in host byte order */
struct afscp_server *
afscp_ServerByAddr(struct afscp_cell *thecell, afs_uint32 addr)
{
    /* implement uniquifiers? */
    int i, j;
    struct afscp_server **newlist;
    struct afscp_server **newall;
    struct afscp_server *ret = NULL;
    afsUUID uuid;
    bulkaddrs addrs;
    struct ListAddrByAttributes attrs;
    afs_int32 nentries, code, uniq;

    if (thecell == NULL)
	return ret;		/* cannot continue without thecell */

    for (i = 0; i < thecell->nservers; i++) {
	ret = thecell->fsservers[i];
	for (j = 0; j < ret->naddrs; j++)
	    if (ret->addrs[j] == htonl(addr)) {
		return ret;
	    }
    }

    if (thecell->nservers >= thecell->srvsalloced) {
	if (thecell->srvsalloced)
	    thecell->srvsalloced = thecell->srvsalloced * 2;
	else
	    thecell->srvsalloced = 4;
	newlist = realloc(thecell->fsservers,
			  thecell->srvsalloced * sizeof(struct afscp_server));
	if (newlist == NULL) {
	    return NULL;
	}
	thecell->fsservers = newlist;
    }
    ret = malloc(sizeof(struct afscp_server));
    if (ret == NULL) {
	return NULL;
    }
    memset(ret, 0, sizeof(struct afscp_server));
    thecell->fsservers[thecell->nservers] = ret;
    ret->cell = thecell->id;
    memset(&uuid, 0, sizeof(uuid));
    memset(&addrs, 0, sizeof(addrs));
    memset(&attrs, 0, sizeof(attrs));
    attrs.Mask = VLADDR_IPADDR;
    attrs.ipaddr = addr;

    code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &uuid,
			     &uniq, &nentries, &addrs);
    if (code != 0) {
	memset(&ret->id, 0, sizeof(uuid));
	ret->naddrs = 1;
	ret->addrs[0] = htonl(addr);
	ret->conns[0] = rx_NewConnection(ret->addrs[0],
					 htons(AFSCONF_FILEPORT),
					 1, thecell->security,
					 thecell->scindex);
    } else {
	char s[512];

	afsUUID_to_string(&uuid, s, 511);
	afs_dprintf(("GetServerByAddr 0x%x -> uuid %s\n", addr, s));

	if (nentries > AFS_MAXHOSTS) {
	    nentries = AFS_MAXHOSTS;
	    /* XXX I don't want to do *that* much dynamic allocation */
	    abort();
	}
	memmove(&ret->id, &uuid, sizeof(afsUUID));

	ret->naddrs = nentries;
	for (i = 0; i < nentries; i++) {
	    ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]);
	    ret->conns[i] = rx_NewConnection(ret->addrs[i],
					     htons(AFSCONF_FILEPORT),
					     1, thecell->security,
					     thecell->scindex);
	}
	_xdr_free(_xdr_bulkaddrs, &addrs);
    }

    thecell->nservers++;
    if (afscp_nservers >= afscp_srvsalloced) {
	if (afscp_srvsalloced)
	    afscp_srvsalloced = afscp_srvsalloced * 2;
	else
	    afscp_srvsalloced = 4;
	newall = realloc(allservers,
			 afscp_srvsalloced * sizeof(struct afscp_server *));
	if (newall == NULL) {
	    return ret;
	}
	allservers = newall;
    }
    ret->index = afscp_nservers;
    allservers[afscp_nservers++] = ret;
    return ret;
}
Пример #6
0
/* takes server in host byte order */
struct afscp_server *
afscp_ServerById(struct afscp_cell *thecell, afsUUID * u)
{
    /* impliment uniquifiers? */
    int i, code;
    struct afscp_server **newlist;
    struct afscp_server **newall;
    struct afscp_server *ret = NULL;
    afsUUID tmp;
    bulkaddrs addrs;
    struct ListAddrByAttributes attrs;
    afs_int32 nentries, uniq;
    char s[512];
    afsUUID_to_string(u, s, 511);
    afs_dprintf(("GetServerByID %s\n", s));

    for (i = 0; i < thecell->nservers; i++) {
	if (afs_uuid_equal(&thecell->fsservers[i]->id, u)) {
	    return thecell->fsservers[i];
	}
    }

    if (thecell->nservers >= thecell->srvsalloced) {
	if (thecell->srvsalloced)
	    thecell->srvsalloced = thecell->srvsalloced * 2;
	else
	    thecell->srvsalloced = 4;
	newlist = realloc(thecell->fsservers,
			  thecell->srvsalloced *
			  sizeof(struct afscp_server *));
	if (newlist == NULL) {
	    return NULL;
	}
	thecell->fsservers = newlist;
    }
    ret = malloc(sizeof(struct afscp_server));
    if (ret == NULL) {
	return NULL;
    }
    memset(ret, 0, sizeof(struct afscp_server));
    thecell->fsservers[thecell->nservers] = ret;
    memmove(&ret->id, u, sizeof(afsUUID));
    ret->cell = thecell->id;
    memset(&tmp, 0, sizeof(tmp));
    memset(&addrs, 0, sizeof(addrs));
    memset(&attrs, 0, sizeof(attrs));
    attrs.Mask = VLADDR_UUID;
    memmove(&attrs.uuid, u, sizeof(afsUUID));

    code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &tmp,
			     &uniq, &nentries, &addrs);
    if (code != 0) {
	return NULL;
    }
    if (nentries > AFS_MAXHOSTS) {
	nentries = AFS_MAXHOSTS;
	/* XXX I don't want to do *that* much dynamic allocation */
	abort();
    }

    ret->naddrs = nentries;
    for (i = 0; i < nentries; i++) {
	ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]);
	ret->conns[i] = rx_NewConnection(ret->addrs[i],
					 htons(AFSCONF_FILEPORT),
					 1, thecell->security,
					 thecell->scindex);
    }
    _xdr_free(_xdr_bulkaddrs, &addrs);
    thecell->nservers++;

    if (afscp_nservers >= afscp_srvsalloced) {
	if (afscp_srvsalloced)
	    afscp_srvsalloced = afscp_srvsalloced * 2;
	else
	    afscp_srvsalloced = 4;
	newall = realloc(allservers,
			 afscp_srvsalloced * sizeof(struct afscp_server *));
	if (newall == NULL) {
	    return ret;
	}
	allservers = newall;
    }
    ret->index = afscp_nservers;
    allservers[afscp_nservers++] = ret;
    return ret;
}
Пример #7
0
int
bcdb_SaveTextFile(udbClientTextP ctPtr)
{
    afs_int32 bufferSize;
    afs_int32 offset, chunkSize, fileSize;
    charListT charList;
    afs_int32 code = 0;

    /* allocate a buffer */
    bufferSize = 1024;
    charList.charListT_val = malloc(bufferSize);
    if (charList.charListT_val == 0)
	ERROR(BUDB_INTERNALERROR);
    charList.charListT_len = bufferSize;

    if (ctPtr->textStream == NULL)
	ERROR(BUDB_INTERNALERROR);
    rewind(ctPtr->textStream);

    fileSize = (afs_int32) filesize(ctPtr->textStream);

    afs_dprintf(("filesize is %d\n", fileSize));

    rewind(ctPtr->textStream);

    /* special case empty files */
    if (fileSize == 0) {
	charList.charListT_len = 0;
	code =
	    ubik_BUDB_SaveText(udbHandle.uh_client, 0,
		      ctPtr->lockHandle, ctPtr->textType, 0,
		      BUDB_TEXT_COMPLETE, &charList);
	goto error_exit;
    }

    offset = 0;
    while (fileSize != 0) {
	chunkSize = min(fileSize, bufferSize);
	code =
	    fread(charList.charListT_val, sizeof(char), chunkSize,
		  ctPtr->textStream);

	if (code != chunkSize)
	    printf("code = %d\n", code);
	if (ferror(ctPtr->textStream))
	    ERROR(BUDB_INTERNALERROR);

	charList.charListT_len = chunkSize;
	code =
	    ubik_BUDB_SaveText(udbHandle.uh_client, 0,
		      ctPtr->lockHandle, ctPtr->textType, offset,
		      (chunkSize == fileSize) ? BUDB_TEXT_COMPLETE : 0,
		      &charList);
	if (code)
	    ERROR(code);

	fileSize -= chunkSize;
	offset += chunkSize;
    }

  error_exit:
    /* if ( ctPtr->textStream >= 0 )
     * close(ctPtr->textStream); */
    if (charList.charListT_val)
	free(charList.charListT_val);
    return (code);
}