예제 #1
0
static int
do_volop(struct fssync_state * state, afs_int32 command, SYNC_response * res)
{
    afs_int32 code;
    SYNC_PROTO_BUF_DECL(res_buf);
    SYNC_response res_l;

    if (!res) {
	res = &res_l;
	res->payload.len = SYNC_PROTO_MAX_LEN;
	res->payload.buf = res_buf;
    }

    fprintf(stderr, "calling FSYNC_VolOp with command code %d (%s)\n",
	    command, FSYNC_com2string(command));

    code = FSYNC_VolOp(state->vop->volume,
		       state->vop->partName,
		       command,
		       state->reason,
		       res);

    debug_response(code, res);

    VDisconnectFS();

    return 0;

}
예제 #2
0
/* Try to detect if the fileserver is DAFS, and if so, re-exec as the
 * DAFS-enabled fssync-debug (dafssync_debug). If we fail to detect or
 * exec, just try to proceed anyway as if the server is not DAFS */
static void
dafs_prolog(void)
{
    SYNC_response res;
    SYNC_PROTO_BUF_DECL(res_buf);
    afs_int32 code;
    char *dfssd;

    res.payload.len = SYNC_PROTO_MAX_LEN;
    res.payload.buf = res_buf;

    /* LISTVOLUMES is a no-op; we just want to get the response header flags
     * to see if the server reports itself as DAFS or not */
    code = FSYNC_VolOp(0, NULL, FSYNC_VOL_LISTVOLUMES, FSYNC_WHATEVER, &res);
    if (code) {
	/* probably failed to contact the fileserver; later code will provide
	 * some warning/error indication */
	return;
    }

    if (!(res.hdr.flags & SYNC_FLAG_DAFS_EXTENSIONS)) {
	/* fileserver is not DAFS, so we don't need to do anything */
	return;
    }

    dfssd = afs_exec_alt(fssd_argc, fssd_argv, "da", NULL);

    fprintf(stderr, "\n*** server asserted demand attach extensions, but we failed\n"
                    "*** to exec a DAFS-enabled fssync-debug '%s' (errno=%d);\n"
                    "*** attempting to proceed without it.\n\n", dfssd, errno);

    free(dfssd);
}
예제 #3
0
/**
 * gracefully disconnect a sync client handle.
 *
 * @param[in] state  pointer to sync client handle
 *
 * @return operation status
 *    @retval SYNC_OK success
 */
afs_int32
SYNC_closeChannel(SYNC_client_state * state)
{
    afs_int32 code;
    SYNC_command com;
    SYNC_response res;
    SYNC_PROTO_BUF_DECL(ores);

    if (state->fd == -1)
	return SYNC_OK;

    memset(&com, 0, sizeof(com));
    memset(&res, 0, sizeof(res));

    res.payload.len = SYNC_PROTO_MAX_LEN;
    res.payload.buf = ores;

    com.hdr.command = SYNC_COM_CHANNEL_CLOSE;
    com.hdr.command_len = sizeof(SYNC_command_hdr);
    com.hdr.flags |= SYNC_FLAG_CHANNEL_SHUTDOWN;

    /* in case the other end dropped, don't do any retries */
    state->retry_limit = 0;
    state->hard_timeout = 0;

    SYNC_ask(state, &com, &res);
    SYNC_disconnect(state);

    return SYNC_OK;
}
예제 #4
0
static int
VolOpQuery(struct cmd_syndesc * as, void * rock)
{
    struct state state;
    SYNC_PROTO_BUF_DECL(res_buf);
    SYNC_response res;
    FSSYNC_VolOp_info vop;
    int i;

    res.hdr.response_len = sizeof(res.hdr);
    res.payload.buf = res_buf;
    res.payload.len = SYNC_PROTO_MAX_LEN;

    common_prolog(as, &state);
    common_volop_prolog(as, &state);

    do_volop(&state, FSYNC_VOL_QUERY_VOP, &res);

    if (!(res.hdr.flags & SYNC_FLAG_DAFS_EXTENSIONS)) {
	printf("*** file server not compiled with demand attach extensions.\n");
	printf("*** pending volume operation metadata not available.\n");
    }

    if (res.hdr.response == SYNC_OK) {
	memcpy(&vop, res.payload.buf, sizeof(FSSYNC_VolOp_info));

	printf("pending_vol_op = {\n");

	printf("\tcom = {\n");
	printf("\t\tproto_version  = %u\n", vop.com.proto_version);
	printf("\t\tpkt_seq        = %u\n", vop.com.pkt_seq);
	printf("\t\tcom_seq        = %u\n", vop.com.com_seq);
	printf("\t\tprogramType    = %d (%s)\n", 
	       vop.com.programType, program_type_to_string(vop.com.programType));
	printf("\t\tpid            = %d\n", vop.com.pid);
	printf("\t\ttid            = %d\n", vop.com.tid);
	printf("\t\tcommand        = %d (%s)\n", 
	       vop.com.command, command_code_to_string(vop.com.command));
	printf("\t\treason         = %d (%s)\n", 
	       vop.com.reason, reason_code_to_string(vop.com.reason));
	printf("\t\tcommand_len    = %u\n", vop.com.command_len);
	printf("\t\tflags          = 0x%x\n", vop.com.flags);
	printf("\t}\n");

	printf("\tvop = {\n");
	printf("\t\tvolume         = %u\n", vop.vop.volume);
	if (afs_strnlen(vop.vop.partName, sizeof(vop.vop.partName)) <
	    sizeof(vop.vop.partName)) {
	    printf("\t\tpartName       = '%s'\n", vop.vop.partName);
	} else {
	    printf("\t\tpartName       = (illegal string)\n");
	}
	printf("\t}\n");

	printf("}\n");
    }

    return 0;
}
예제 #5
0
/**
 * write a response structure to a sync socket.
 *
 * @param[in] state  handle to server-side state object
 * @param[in] fd     file descriptor on which to perform i/o
 * @param[in] res    handle to response packet
 *
 * @return operation status
 *    @retval SYNC_OK
 *    @retval SYNC_COM_ERROR
 */
afs_int32
SYNC_putRes(SYNC_server_state_t * state, 
	    int fd,
	    SYNC_response * res)
{
    int n;
    afs_int32 code = SYNC_OK;
    SYNC_PROTO_BUF_DECL(buf);

    if (res->hdr.response_len > (sizeof(res->hdr) + res->payload.len)) {
	Log("SYNC_putRes:  response_len field in response header inconsistent\n");
	code = SYNC_COM_ERROR;
	goto done;
    }

    if (res->hdr.response_len > SYNC_PROTO_MAX_LEN) {
	Log("SYNC_putRes:  internal SYNC buffer too small; please file a bug\n");
	code = SYNC_COM_ERROR;
	goto done;
    }

#ifdef AFS_DEMAND_ATTACH_FS
    res->hdr.flags |= SYNC_FLAG_DAFS_EXTENSIONS;
#endif
    res->hdr.proto_version = state->proto_version;
    res->hdr.pkt_seq = ++state->pkt_seq;
    res->hdr.res_seq = ++state->res_seq;

    memcpy(buf, &res->hdr, sizeof(res->hdr));
    if (res->payload.len) {
	memcpy(buf + sizeof(res->hdr), res->payload.buf, 
	       res->hdr.response_len - sizeof(res->hdr));
    }

#ifdef AFS_NT40_ENV
    n = send(fd, buf, res->hdr.response_len, 0);
#else /* !AFS_NT40_ENV */
    n = write(fd, buf, res->hdr.response_len);
#endif /* !AFS_NT40_ENV */

    if (res->hdr.response_len != n) {
	Log("SYNC_putRes: write failed\n");
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }

 done:
    return code;
}
예제 #6
0
static int
do_volop(struct state * state, afs_int32 command, SYNC_response * res)
{
    afs_int32 code;
    SYNC_PROTO_BUF_DECL(res_buf);
    SYNC_response res_l;

    if (!res) {
	res = &res_l;
	res->payload.len = SYNC_PROTO_MAX_LEN;
	res->payload.buf = res_buf;
    }

    fprintf(stderr, "calling FSYNC_VolOp with command code %d (%s)\n", 
	    command, command_code_to_string(command));

    code = FSYNC_VolOp(state->vop->volume,
		       state->vop->partName,
		       command,
		       state->reason,
		       res);

    switch (code) {
    case SYNC_OK:
    case SYNC_DENIED:
	break;
    default:
	fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
    }

    fprintf(stderr, "FSYNC_VolOp returned %d (%s)\n", code, response_code_to_string(code));
    fprintf(stderr, "protocol response code was %d (%s)\n", 
	    res->hdr.response, response_code_to_string(res->hdr.response));
    fprintf(stderr, "protocol reason code was %d (%s)\n", 
	    res->hdr.reason, reason_code_to_string(res->hdr.reason));

    VDisconnectFS();
}
예제 #7
0
static int
VnQuery(struct cmd_syndesc * as, void * rock)
{
    struct state state;
    SYNC_PROTO_BUF_DECL(res_buf);
    SYNC_response res;
    Vnode v;
    int hi, lo;

    res.hdr.response_len = sizeof(res.hdr);
    res.payload.buf = res_buf;
    res.payload.len = SYNC_PROTO_MAX_LEN;

    common_prolog(as, &state);
    vn_prolog(as, &state);

    do_vnqry(&state, &res);

    if (res.hdr.response == SYNC_OK) {
	memcpy(&v, res.payload.buf, sizeof(Volume));

	printf("vnode = {\n");

	printf("\tvid_hash = {\n");
	printf("\t\tnext = 0x%lx\n", v.vid_hash.next);
	printf("\t\tprev = 0x%lx\n", v.vid_hash.prev);
	printf("\t}\n");

	printf("\thashNext        = 0x%lx\n", v.hashNext);
	printf("\tlruNext         = 0x%lx\n", v.lruNext);
	printf("\tlruPrev         = 0x%lx\n", v.lruPrev);
	printf("\thashIndex       = %hu\n", v.hashIndex);
	printf("\tchanged_newTime = %u\n", (unsigned int) v.changed_newTime);
	printf("\tchanged_oldTime = %u\n", (unsigned int) v.changed_oldTime);
	printf("\tdelete          = %u\n", (unsigned int) v.delete);
	printf("\tvnodeNumber     = %u\n", v.vnodeNumber);
	printf("\tvolumePtr       = 0x%lx\n", v.volumePtr);
	printf("\tnUsers          = %u\n", v.nUsers);
	printf("\tcacheCheck      = %u\n", v.cacheCheck);

#ifdef AFS_DEMAND_ATTACH_FS
	if (!(res.hdr.flags & SYNC_FLAG_DAFS_EXTENSIONS)) {
	    printf("*** fssync-debug built to expect demand attach extensions.  server asserted\n");
	    printf("*** that it was not compiled with demand attach turned on.  please recompile\n");
	    printf("*** fssync-debug to match your server\n");
	    goto done;
	}

	printf("\tnReaders        = %u\n", v.nReaders);
	printf("\tvn_state_flags  = %s\n", vn_flags_to_string(v.vn_state_flags));
	printf("\tvn_state        = %s\n", vn_state_to_string(v.vn_state));
#else
	if (res.hdr.flags & SYNC_FLAG_DAFS_EXTENSIONS) {
	    printf("*** server asserted demand attach extensions. fssync-debug not built to\n");
	    printf("*** recognize those extensions. please recompile fssync-debug if you need\n");
	    printf("*** to dump dafs extended state\n");
	    goto done;
	}
#endif /* !AFS_DEMAND_ATTACH_FS */

	printf("\twriter          = %u\n", v.writer);
	printf("\tvcp             = 0x%lx\n", v.vcp);
	printf("\thandle          = 0x%lx\n", v.handle);

	printf("\tdisk = {\n");
	printf("\t\ttype              = %u\n", v.disk.type);
	printf("\t\tcloned            = %u\n", v.disk.cloned);
	printf("\t\tmodeBits          = %u\n", v.disk.modeBits);
	printf("\t\tlinkCount         = %d\n", v.disk.linkCount);
	printf("\t\tlength            = %u\n", v.disk.length);
	printf("\t\tuniquifier        = %u\n", v.disk.uniquifier);
	printf("\t\tdataVersion       = %u\n", v.disk.dataVersion);
	printf("\t\tvn_ino_lo         = %u\n", v.disk.vn_ino_lo);
	printf("\t\tunixModifyTime    = %u\n", v.disk.unixModifyTime);
	printf("\t\tauthor            = %u\n", v.disk.author);
	printf("\t\towner             = %u\n", v.disk.owner);
	printf("\t\tparent            = %u\n", v.disk.parent);
	printf("\t\tvnodeMagic        = %u\n", v.disk.vnodeMagic);

	printf("\t\tlock = {\n");
	printf("\t\t\tlockCount   = %d\n", v.disk.lock.lockCount);
	printf("\t\t\tlockTime    = %d\n", v.disk.lock.lockTime);
	printf("\t\t}\n");

	printf("\t\tserverModifyTime  = %u\n", v.disk.serverModifyTime);
	printf("\t\tgroup             = %d\n", v.disk.group);
	printf("\t\tvn_ino_hi         = %d\n", v.disk.vn_ino_hi);
	printf("\t\treserved6         = %u\n", v.disk.reserved6);
	printf("\t}\n");

	printf("}\n");
    }
예제 #8
0
static int
VolHdrQuery(struct cmd_syndesc * as, void * rock)
{
    struct state state;
    SYNC_PROTO_BUF_DECL(res_buf);
    SYNC_response res;
    VolumeDiskData v;
    int i;

    res.hdr.response_len = sizeof(res.hdr);
    res.payload.buf = res_buf;
    res.payload.len = SYNC_PROTO_MAX_LEN;

    common_prolog(as, &state);
    common_volop_prolog(as, &state);

    do_volop(&state, FSYNC_VOL_QUERY_HDR, &res);

    if (res.hdr.response == SYNC_OK) {
	memcpy(&v, res.payload.buf, sizeof(VolumeDiskData));

	printf("VolumeDiskData = {\n");
	printf("\tstamp = {\n");
	printf("\t\tmagic   = 0x%x\n", v.stamp.magic);
	printf("\t\tversion = %u\n", v.stamp.version);
	printf("\t}\n");
	
	printf("\tid               = %u\n", v.id);
	printf("\tname             = '%s'\n", v.name);
	if (v.inUse != 0) {
	    printf("\tinUse            = %d (%s)\n", v.inUse, program_type_to_string(v.inUse));
	} else {
	    printf("\tinUse            = %d (no)\n", v.inUse);
	}
	printf("\tinService        = %d\n", v.inService);
	printf("\tblessed          = %d\n", v.blessed);
	printf("\tneedsSalvaged    = %d\n", v.needsSalvaged);
	printf("\tuniquifier       = %u\n", v.uniquifier);
	printf("\ttype             = %d\n", v.type);
	printf("\tparentId         = %u\n", v.parentId);
	printf("\tcloneId          = %u\n", v.cloneId);
	printf("\tbackupId         = %u\n", v.backupId);
	printf("\trestoredFromId   = %u\n", v.restoredFromId);
	printf("\tneedsCallback    = %d\n", v.needsCallback);
	printf("\tdestroyMe        = %d\n", v.destroyMe);
	printf("\tdontSalvage      = %d\n", v.dontSalvage);
	printf("\tmaxquota         = %d\n", v.maxquota);
	printf("\tminquota         = %d\n", v.minquota);
	printf("\tmaxfiles         = %d\n", v.maxfiles);
	printf("\taccountNumber    = %u\n", v.accountNumber);
	printf("\towner            = %u\n", v.owner);
	printf("\tfilecount        = %d\n", v.filecount);
	printf("\tdiskused         = %d\n", v.diskused);
	printf("\tdayUse           = %d\n", v.dayUse);
	for (i = 0; i < 7; i++) {
	    printf("\tweekUse[%d]       = %d\n", i, v.weekUse[i]);
	}
	printf("\tdayUseDate       = %u\n", v.dayUseDate);
	printf("\tcreationDate     = %u\n", v.creationDate);
	printf("\taccessDate       = %u\n", v.accessDate);
	printf("\tupdateDate       = %u\n", v.updateDate);
	printf("\texpirationDate   = %u\n", v.expirationDate);
	printf("\tbackupDate       = %u\n", v.backupDate);
	printf("\tcopyDate         = %u\n", v.copyDate);
#ifdef OPENAFS_VOL_STATS
	printf("\tstat_initialized = %d\n", v.stat_initialized);
#else
        printf("\tmtd              = '%s'\n", v.motd);
#endif
	printf("}\n");
    }

    return 0;
}
예제 #9
0
static int
VolQuery(struct cmd_syndesc * as, void * rock)
{
    struct state state;
    SYNC_PROTO_BUF_DECL(res_buf);
    SYNC_response res;
    Volume v;
    int hi, lo;

    res.hdr.response_len = sizeof(res.hdr);
    res.payload.buf = res_buf;
    res.payload.len = SYNC_PROTO_MAX_LEN;

    common_prolog(as, &state);
    common_volop_prolog(as, &state);

    do_volop(&state, FSYNC_VOL_QUERY, &res);

    if (res.hdr.response == SYNC_OK) {
	memcpy(&v, res.payload.buf, sizeof(Volume));

	printf("volume = {\n");
	printf("\thashid          = %u\n", v.hashid);
	printf("\theader          = 0x%x\n", v.header);
	printf("\tdevice          = %d\n", v.device);
	printf("\tpartition       = 0x%x\n", v.partition);
	printf("\tlinkHandle      = 0x%x\n", v.linkHandle);
	printf("\tnextVnodeUnique = %u\n", v.nextVnodeUnique);
	printf("\tdiskDataHandle  = 0x%x\n", v.diskDataHandle);
	printf("\tvnodeHashOffset = %u\n", v.vnodeHashOffset);
	printf("\tshuttingDown    = %d\n", v.shuttingDown);
	printf("\tgoingOffline    = %d\n", v.goingOffline);
	printf("\tcacheCheck      = %u\n", v.cacheCheck);
	printf("\tnUsers          = %d\n", v.nUsers);
	printf("\tneedsPutBack    = %d\n", v.needsPutBack);
	printf("\tspecialStatus   = %d\n", v.specialStatus);
	printf("\tupdateTime      = %u\n", v.updateTime);
	
	printf("\tvnodeIndex[vSmall] = {\n");
        printf("\t\thandle       = 0x%x\n", v.vnodeIndex[vSmall].handle);
        printf("\t\tbitmap       = 0x%x\n", v.vnodeIndex[vSmall].bitmap);
	printf("\t\tbitmapSize   = %u\n", v.vnodeIndex[vSmall].bitmapSize);
	printf("\t\tbitmapOffset = %u\n", v.vnodeIndex[vSmall].bitmapOffset);
	printf("\t}\n");
	printf("\tvnodeIndex[vLarge] = {\n");
        printf("\t\thandle       = 0x%x\n", v.vnodeIndex[vLarge].handle);
        printf("\t\tbitmap       = 0x%x\n", v.vnodeIndex[vLarge].bitmap);
	printf("\t\tbitmapSize   = %u\n", v.vnodeIndex[vLarge].bitmapSize);
	printf("\t\tbitmapOffset = %u\n", v.vnodeIndex[vLarge].bitmapOffset);
	printf("\t}\n");
#ifdef AFS_DEMAND_ATTACH_FS
	if (res.hdr.flags & SYNC_FLAG_DAFS_EXTENSIONS) {
	    printf("\tupdateTime      = %u\n", v.updateTime);
	    printf("\tattach_state    = %s\n", vol_state_to_string(v.attach_state));
	    printf("\tattach_flags    = %s\n", vol_flags_to_string(v.attach_flags));
	    printf("\tnWaiters        = %d\n", v.nWaiters);
	    printf("\tchainCacheCheck = %d\n", v.chainCacheCheck);
	    
	    /* online salvage structure */
	    printf("\tsalvage = {\n");
	    printf("\t\tprio      = %u\n", v.salvage.prio);
	    printf("\t\treason    = %d\n", v.salvage.reason);
	    printf("\t\trequested = %d\n", v.salvage.requested);
	    printf("\t\tscheduled = %d\n", v.salvage.scheduled);
	    printf("\t}\n");
	    
	    /* statistics structure */
	    printf("\tstats = {\n");

	    printf("\t\thash_lookups = {\n");
	    SplitInt64(v.stats.hash_lookups,hi,lo);
	    printf("\t\t\thi = %u\n", hi);
	    printf("\t\t\tlo = %u\n", lo);
	    printf("\t\t}\n");

	    printf("\t\thash_short_circuits = {\n");
	    SplitInt64(v.stats.hash_short_circuits,hi,lo);
	    printf("\t\t\thi = %u\n", hi);
	    printf("\t\t\tlo = %u\n", lo);
	    printf("\t\t}\n");

	    printf("\t\thdr_loads = {\n");
	    SplitInt64(v.stats.hdr_loads,hi,lo);
	    printf("\t\t\thi = %u\n", hi);
	    printf("\t\t\tlo = %u\n", lo);
	    printf("\t\t}\n");

	    printf("\t\thdr_gets = {\n");
	    SplitInt64(v.stats.hdr_gets,hi,lo);
	    printf("\t\t\thi = %u\n", hi);
	    printf("\t\t\tlo = %u\n", lo);
	    printf("\t\t}\n");
	    
	    printf("\t\tattaches         = %u\n", v.stats.attaches);
	    printf("\t\tsoft_detaches    = %u\n", v.stats.soft_detaches);
	    printf("\t\tsalvages         = %u\n", v.stats.salvages);
	    printf("\t\tvol_ops          = %u\n", v.stats.vol_ops);
	    
	    printf("\t\tlast_attach      = %u\n", v.stats.last_attach);
	    printf("\t\tlast_get         = %u\n", v.stats.last_get);
	    printf("\t\tlast_promote     = %u\n", v.stats.last_promote);
	    printf("\t\tlast_hdr_get     = %u\n", v.stats.last_hdr_get);
	    printf("\t\tlast_hdr_load    = %u\n", v.stats.last_hdr_load);
	    printf("\t\tlast_salvage     = %u\n", v.stats.last_salvage);
	    printf("\t\tlast_salvage_req = %u\n", v.stats.last_salvage_req);
	    printf("\t\tlast_vol_op      = %u\n", v.stats.last_vol_op);
	    printf("\t}\n");
	    
	    /* VLRU state */
	    printf("\tvlru = {\n");
	    printf("\t\tidx = %d (%s)\n", 
		   v.vlru.idx, vlru_idx_to_string(v.vlru.idx));
	    printf("\t}\n");

	    /* volume op state */
	    printf("\tpending_vol_op  = 0x%x\n", v.pending_vol_op);
	}
#else /* !AFS_DEMAND_ATTACH_FS */
	if (res.hdr.flags & SYNC_FLAG_DAFS_EXTENSIONS) {
	    printf("*** server asserted demand attach extensions. fssync-debug not built to\n");
	    printf("*** recognize those extensions. please recompile fssync-debug if you need\n");
	    printf("*** to dump dafs extended state\n");
	}
#endif /* !AFS_DEMAND_ATTACH_FS */
	printf("}\n");
    }

    return 0;
}
예제 #10
0
static int
StatsQuery(struct cmd_syndesc * as, void * rock)
{
    afs_int32 code;
    int command;
    struct cmd_item *ti;
    struct state state;
    SYNC_PROTO_BUF_DECL(res_buf);
    SYNC_response res;
    FSSYNC_StatsOp_hdr scom;
    union {
	void * ptr;
	struct VolPkgStats * vol_stats;
	struct VolumeHashChainStats * hash_stats;
#ifdef AFS_DEMAND_ATTACH_FS
	struct volume_hdr_LRU_stats * hdr_stats;
#endif
	struct DiskPartitionStats64 * vicep_stats;
    } sres;

    sres.ptr = res_buf;
    res.hdr.response_len = sizeof(res.hdr);
    res.payload.buf = res_buf;
    res.payload.len = SYNC_PROTO_MAX_LEN;

    if ((ti = as->parms[CUSTOM_PARMS_OFFSET].items)) {	/* -subcommand */
	if (!strcasecmp(ti->data, "vicep")) {
	    command = FSYNC_VOL_STATS_VICEP;
	} else if (!strcasecmp(ti->data, "hash")) {
	    command = FSYNC_VOL_STATS_HASH;
#ifdef AFS_DEMAND_ATTACH_FS
	} else if (!strcasecmp(ti->data, "hdr")) {
	    command = FSYNC_VOL_STATS_HDR;
	} else if (!strcasecmp(ti->data, "vlru")) {
	    command = FSYNC_VOL_STATS_VLRU;
#endif
	} else if (!strcasecmp(ti->data, "pkg")) {
	    command = FSYNC_VOL_STATS_GENERAL;
	} else if (!strcasecmp(ti->data, "help")) {
	    fprintf(stderr, "fssync-debug stats subcommands:\n");
	    fprintf(stderr, "\tpkg\tgeneral volume package stats\n");
	    fprintf(stderr, "\tvicep\tvice partition stats\n");
	    fprintf(stderr, "\thash\tvolume hash chain stats\n");
#ifdef AFS_DEMAND_ATTACH_FS
	    fprintf(stderr, "\thdr\tvolume header cache stats\n");
	    fprintf(stderr, "\tvlru\tvlru generation stats\n");
#endif
	    exit(0);
	} else {
	    fprintf(stderr, "invalid stats subcommand");
	    exit(1);
	}
    } else {
	command = FSYNC_VOL_STATS_GENERAL;
    }

    if ((ti = as->parms[CUSTOM_PARMS_OFFSET+1].items)) {	/* -arg1 */
	switch (command) {
	case FSYNC_VOL_STATS_VICEP:
	    strlcpy(scom.args.partName, ti->data, sizeof(state.vop->partName));
	    break;
	case FSYNC_VOL_STATS_HASH:
	    scom.args.hash_bucket = atoi(ti->data);
	    break;
	case FSYNC_VOL_STATS_VLRU:
	    scom.args.vlru_generation = atoi(ti->data);
	    break;
	default:
	    fprintf(stderr, "unrecognized arguments\n");
	    exit(1);
	}
    } else {
	switch (command) {
	case FSYNC_VOL_STATS_VICEP:
	case FSYNC_VOL_STATS_HASH:
	case FSYNC_VOL_STATS_VLRU:
	    fprintf(stderr, "this subcommand requires more parameters\n");
	    exit(1);
	}
    }

    common_prolog(as, &state);

    fprintf(stderr, "calling FSYNC_askfs with command code %d (%s)\n", 
	    command, command_code_to_string(command));

    code = FSYNC_StatsOp(&scom, command, FSYNC_WHATEVER, &res);

    switch (code) {
    case SYNC_OK:
    case SYNC_DENIED:
	break;
    default:
	fprintf(stderr, "possible sync protocol error. return code was %d\n", code);
    }

    fprintf(stderr, "FSYNC_VolOp returned %d (%s)\n", code, response_code_to_string(code));
    fprintf(stderr, "protocol response code was %d (%s)\n", 
	    res.hdr.response, response_code_to_string(res.hdr.response));
    fprintf(stderr, "protocol reason code was %d (%s)\n", 
	    res.hdr.reason, reason_code_to_string(res.hdr.reason));

    VDisconnectFS();

    if (res.hdr.response == SYNC_OK) {
	switch (command) {
	case FSYNC_VOL_STATS_GENERAL:
	    print_vol_stats_general(sres.vol_stats);
	    break;
	case FSYNC_VOL_STATS_VICEP:
	    print_vol_stats_viceP(sres.vicep_stats);
	    break;
	case FSYNC_VOL_STATS_HASH:
	    print_vol_stats_hash(sres.hash_stats);
	    break;
#ifdef AFS_DEMAND_ATTACH_FS
	case FSYNC_VOL_STATS_HDR:
	    print_vol_stats_hdr(sres.hdr_stats);
	    break;
#endif /* AFS_DEMAND_ATTACH_FS */
	}
    }

    return 0;
}
예제 #11
0
/**
 * receive a command structure off a sync socket.
 *
 * @param[in]  state  pointer to server-side state object
 * @param[in]  fd     file descriptor on which to perform i/o
 * @param[out] com    sync command object to be populated
 *
 * @return operation status
 *    @retval SYNC_OK command received
 *    @retval SYNC_COM_ERROR there was a socket communications error
 */
afs_int32
SYNC_getCom(SYNC_server_state_t * state,
	    int fd,
	    SYNC_command * com)
{
    int n;
    afs_int32 code = SYNC_OK;
#ifdef AFS_NT40_ENV
    SYNC_PROTO_BUF_DECL(buf);
#else
    struct iovec iov[2];
    int iovcnt;
#endif

#ifdef AFS_NT40_ENV
    n = recv(fd, buf, SYNC_PROTO_MAX_LEN, 0);

    if (n == 0 || (n < 0 && WSAEINTR != WSAGetLastError())) {
	Log("SYNC_getCom:  error receiving command\n");
	code = SYNC_COM_ERROR;
	goto done;
    }
#else /* !AFS_NT40_ENV */
    iov[0].iov_base = (char *)&com->hdr;
    iov[0].iov_len = sizeof(com->hdr);
    if (com->payload.len) {
	iov[1].iov_base = (char *)com->payload.buf;
	iov[1].iov_len = com->payload.len;
	iovcnt = 2;
    } else {
	iovcnt = 1;
    }

    n = readv(fd, iov, iovcnt);
    if (n == 0 || (n < 0 && errno != EINTR)) {
	Log("SYNC_getCom:  error receiving command\n");
	code = SYNC_COM_ERROR;
	goto done;
    }
#endif /* !AFS_NT40_ENV */

    com->recv_len = n;

    if (n < sizeof(com->hdr)) {
	Log("SYNC_getCom:  command too short\n");
	code = SYNC_COM_ERROR;
	goto done;
    }
#ifdef AFS_NT40_ENV
    memcpy(&com->hdr, buf, sizeof(com->hdr));
#endif

    if ((n - sizeof(com->hdr)) > com->payload.len) {
	Log("SYNC_getCom:  command too long\n");
	code = SYNC_COM_ERROR;
	goto done;
    }
#ifdef AFS_NT40_ENV
    memcpy(com->payload.buf, buf + sizeof(com->hdr), n - sizeof(com->hdr));
#endif

 done:
    return code;
}
예제 #12
0
/**
 * send a command to a sync server and wait for a response.
 *
 * @param[in]  state  pointer to sync client handle
 * @param[in]  com    command object
 * @param[out] res    response object
 *
 * @return operation status
 *    @retval SYNC_OK success
 *    @retval SYNC_COM_ERROR communications error
 *
 * @internal
 */
static afs_int32
SYNC_ask_internal(SYNC_client_state * state, SYNC_command * com, SYNC_response * res)
{
    int n;
    SYNC_PROTO_BUF_DECL(buf);
#ifndef AFS_NT40_ENV
    int iovcnt;
    struct iovec iov[2];
#endif

    if (state->fd == -1) {
	Log("SYNC_ask:  invalid sync file descriptor on circuit '%s'\n",
	    state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }

    if (com->hdr.command_len > SYNC_PROTO_MAX_LEN) {
	Log("SYNC_ask:  internal SYNC buffer too small on circuit '%s'; "
	    "please file a bug\n", state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }

    /*
     * fill in some common header fields
     */
    com->hdr.proto_version = state->proto_version;
    com->hdr.pkt_seq = ++state->pkt_seq;
    com->hdr.com_seq = ++state->com_seq;
#ifdef AFS_NT40_ENV
    com->hdr.pid = 0;
    com->hdr.tid = 0;
#else
    com->hdr.pid = getpid();
#ifdef AFS_PTHREAD_ENV
    com->hdr.tid = (afs_int32)pthread_self();
#else
    {
	PROCESS handle = LWP_ThreadId();
	com->hdr.tid = (handle) ? handle->index : 0;
    }
#endif /* !AFS_PTHREAD_ENV */
#endif /* !AFS_NT40_ENV */

    memcpy(buf, &com->hdr, sizeof(com->hdr));
    if (com->payload.len) {
	memcpy(buf + sizeof(com->hdr), com->payload.buf, 
	       com->hdr.command_len - sizeof(com->hdr));
    }

#ifdef AFS_NT40_ENV
    n = send(state->fd, buf, com->hdr.command_len, 0);
    if (n != com->hdr.command_len) {
	Log("SYNC_ask:  write failed on circuit '%s'\n", state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }

    if (com->hdr.command == SYNC_COM_CHANNEL_CLOSE) {
	/* short circuit close channel requests */
	res->hdr.response = SYNC_OK;
	goto done;
    }

    n = recv(state->fd, buf, SYNC_PROTO_MAX_LEN, 0);
    if (n == 0 || (n < 0 && WSAEINTR != WSAGetLastError())) {
	Log("SYNC_ask:  No response on circuit '%s'\n", state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }
#else /* !AFS_NT40_ENV */
    n = write(state->fd, buf, com->hdr.command_len);
    if (com->hdr.command_len != n) {
	Log("SYNC_ask: write failed on circuit '%s'\n", state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }

    if (com->hdr.command == SYNC_COM_CHANNEL_CLOSE) {
	/* short circuit close channel requests */
	res->hdr.response = SYNC_OK;
	goto done;
    }

    /* receive the response */
    iov[0].iov_base = (char *)&res->hdr;
    iov[0].iov_len = sizeof(res->hdr);
    if (res->payload.len) {
	iov[1].iov_base = (char *)res->payload.buf;
	iov[1].iov_len = res->payload.len;
	iovcnt = 2;
    } else {
	iovcnt = 1;
    }
    n = readv(state->fd, iov, iovcnt);
    if (n == 0 || (n < 0 && errno != EINTR)) {
	Log("SYNC_ask: No response on circuit '%s'\n", state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }
#endif /* !AFS_NT40_ENV */

    res->recv_len = n;

    if (n < sizeof(res->hdr)) {
	Log("SYNC_ask:  response too short on circuit '%s'\n", 
	    state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }
#ifdef AFS_NT40_ENV
    memcpy(&res->hdr, buf, sizeof(res->hdr));
#endif

    if ((n - sizeof(res->hdr)) > res->payload.len) {
	Log("SYNC_ask:  response too long on circuit '%s'\n", 
	    state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }
#ifdef AFS_NT40_ENV
    memcpy(res->payload.buf, buf + sizeof(res->hdr), n - sizeof(res->hdr));
#endif

    if (res->hdr.response_len != n) {
	Log("SYNC_ask:  length field in response inconsistent "
	    "on circuit '%s'\n", state->proto_name);
	res->hdr.response = SYNC_COM_ERROR;
	goto done;
    }
    if (res->hdr.response == SYNC_DENIED) {
	Log("SYNC_ask: negative response on circuit '%s'\n", state->proto_name);
    }

  done:
    return res->hdr.response;
}