예제 #1
0
int
slfid_to_vfsid(slfid_t fid, int *vfsid)
{
	int i, siteid;

	/*
	 * Our client uses this special fid to contact us during mount,
	 * at which time it does not know the site ID yet.
	 *
	 * XXX The client should be able to retrieve the site id from
	 * the slash2 config file.
	 */
	if (fid == SLFID_ROOT) {
		*vfsid = current_vfsid;
		return (0);
	}

	/* only have default file system in the root */
	if (zfs_nmounts == 1) {
		*vfsid = current_vfsid;
		return (0);
	}

	siteid = FID_GET_SITEID(fid);
	for (i = 0; i < zfs_nmounts; i++) {
		if (zfs_mounts[i].zm_siteid == (uint64_t)siteid) {
			*vfsid = i;
			return (0);
		}
	}
	return (-EINVAL);
}
예제 #2
0
int
slc_fcmh_ctor(struct fidc_membh *f, __unusedx int flags)
{
	struct fcmh_cli_info *fci;
	struct sl_resource *res;
	struct sl_site *s;
	sl_siteid_t siteid;
	int i;

	fci = fcmh_get_pri(f);
	slc_fcmh_refresh_age(f);
	INIT_PSC_LISTENTRY(&fci->fci_lentry);
	siteid = FID_GET_SITEID(fcmh_2_fid(f));

	psc_assert(f->fcmh_flags & FCMH_INITING);

	if (fcmh_2_fid(f) != SLFID_ROOT &&
	    siteid != msl_rmc_resm->resm_siteid) {
		s = libsl_siteid2site(siteid);
		if (s == NULL) {
			psclog_errorx("fid "SLPRI_FID" has "
			    "invalid site ID %d",
			    fcmh_2_fid(f), siteid);
			return (ESTALE);
		}
		SITE_FOREACH_RES(s, res, i)
			if (res->res_type == SLREST_MDS) {
				fci->fci_resm = psc_dynarray_getpos(
				    &res->res_members, 0);
				return (0);
			}
		psclog_errorx("fid "SLPRI_FID" has invalid site ID %d",
		    fcmh_2_fid(f), siteid);
		return (ESTALE);
	}
예제 #3
0
int
main(int argc, char *argv[])
{
	char *p, tmbuf[PFL_CTIME_BUFSIZ], *cursor_file = NULL, c;
	uint64_t newtxg = 0, newfid = 0, fid, cycle, newcycle;
	int dump = 0, verbose = 0, fd, rc;
	struct psc_journal_cursor cursor;

	progname = argv[0];
	while ((c = getopt(argc, argv, "c:df:vx:")) != -1)
		switch (c) {
		case 'c':
			cursor_file = optarg;
			break;
		case 'd':
			dump = 1;
			break;
		case 'f':
			newfid = strtol(optarg, NULL, 0);
			break;
		case 'v':
			verbose = 1;
			break;
		case 'x':
			newtxg = strtol(optarg, NULL, 0);
			break;
		default:
			usage();
		}

	argc -= optind;
	if (argc || !cursor_file)
		usage();

	fd = open(cursor_file, O_RDWR);
	if (fd < 0)
		err(1, "failed to open %s", cursor_file);

	rc = pread(fd, &cursor, sizeof(struct psc_journal_cursor), 0);
	if (rc != sizeof(struct psc_journal_cursor))
		err(1, "cursor file read");

	ctime_r((time_t *)&cursor.pjc_timestamp, tmbuf);
	p = strchr(tmbuf, '\n');
	if (p)
		*p = '\0';

	cycle = FID_GET_CYCLE(cursor.pjc_fid);
	if (dump || verbose) {
		printf("Cursor contents of %s:\n"
		    "\tmagic		%"PRIx64"\n"
		    "\tversion		%"PRIx64"\n"
		    "\ttimestamp	%"PRId64" (%s)\n"
		    "\tuuid		%s\n"
		    "\tcommit_txg	%"PRId64"\n"
		    "\tdistill_xid	%"PRId64"\n"
		    "\tfid		%#"PRIx64" "
		      "(flag=%"PRIx64", siteid=%"PRIx64", "
		      "cycle=%"PRIx64", inum=%"PRIx64")\n"
		    "\tseqno_lwm	%"PRIx64"\n"
		    "\tseqno_hwm	%"PRIx64"\n"
		    "\ttail		%"PRIx64"\n"
		    "\tupdate_seqno	%"PRIx64"\n"
		    "\treclaim_seqno	%"PRIx64"\n"
		    "\treplay_xid	%"PRIx64"\n\n",
		    cursor_file,
		    cursor.pjc_magic,
		    cursor.pjc_version,
		    cursor.pjc_timestamp, tmbuf,
		    cursor.pjc_uuid,
		    cursor.pjc_commit_txg,
		    cursor.pjc_distill_xid,
		    cursor.pjc_fid,
		    FID_GET_FLAGS(cursor.pjc_fid),
		    FID_GET_SITEID(cursor.pjc_fid),
		    FID_GET_CYCLE(cursor.pjc_fid),
		    FID_GET_INUM(cursor.pjc_fid),
		    cursor.pjc_seqno_lwm, cursor.pjc_seqno_hwm,
		    cursor.pjc_tail, cursor.pjc_update_seqno,
		    cursor.pjc_reclaim_seqno, cursor.pjc_replay_xid);

		fid = cursor.pjc_fid;
		fid = fid | FID_MAX_INUM;

		printf("The max FID for this cycle is %#"PRIx64"\n", fid);

		if (cycle < ((UINT64_C(1) << SLASH_FID_CYCLE_BITS) - 1)) {
			fid++;
			printf("The first FID for the next cycle is %#"PRIx64"\n", fid);
		}

		if (dump)
			exit(0);
	}

	if (!newtxg && !newfid)
		errx(1, "neither fid nor txg was specified");

	if (newtxg)
		cursor.pjc_commit_txg = newtxg;

	if (newfid) {
		newcycle = FID_GET_CYCLE(newfid);
		if (newcycle <= cycle)
			errx(1, "cycle must be increased when setting a new FID");
		cursor.pjc_fid = newfid;
	}

	rc = pwrite(fd, &cursor, sizeof(struct psc_journal_cursor), 0);
	if (rc != sizeof(struct psc_journal_cursor))
		err(1, "cursor file write");
	if (close(fd) == -1)
		err(1, "cursor file close");
	exit(0);
}
예제 #4
0
파일: rmm.c 프로젝트: jasons-psc/slash2
/*
 * Forward a name space operation to a remote MDS first before
 * replicating the operation locally by our callers.
 */
int
slm_rmm_forward_namespace(int op, struct sl_fidgen *fg,
    struct sl_fidgen *nfg, char *name, char *newname, uint32_t mode,
    const struct slash_creds *crp, struct srt_stat *sstb,
    int32_t to_set)
{
	struct slashrpc_cservice *csvc = NULL;
	struct pscrpc_request *rq = NULL;
	struct sl_resm *resm = NULL;
	struct srm_forward_req *mq;
	struct srm_forward_rep *mp;
	struct sl_resource *res;
	struct sl_site *site;
	int rc, len, i, vfsid;
	sl_siteid_t siteid;

	if (op != SLM_FORWARD_MKDIR  && op != SLM_FORWARD_RMDIR &&
	    op != SLM_FORWARD_CREATE && op != SLM_FORWARD_UNLINK &&
	    op != SLM_FORWARD_RENAME && op != SLM_FORWARD_SETATTR &&
	    op != SLM_FORWARD_SYMLINK)
		return (-PFLERR_NOSYS);

	rc = slfid_to_vfsid(fg->fg_fid, &vfsid);
	if (rc)
		return (rc);

	siteid = FID_GET_SITEID(fg->fg_fid);
	site = libsl_siteid2site(siteid);
	if (site == NULL)
		return (-EBADF);

	SITE_FOREACH_RES(site, res, i) {
		if (res->res_type != SLREST_MDS)
			continue;
		resm = psc_dynarray_getpos(&res->res_members, 0);
		break;
	}
	csvc = slm_getmcsvc_wait(resm);
	if (csvc == NULL) {
		psclog_info("unable to connect to site %d", siteid);
		return (-EIO);
	}

	rc = SL_RSX_NEWREQ(csvc, SRMT_NAMESPACE_FORWARD, rq, mq, mp);
	if (rc)
		goto out;

	mq->op = op;
	mq->fg = *fg;

	if (op == SLM_FORWARD_SETATTR) {
		mq->to_set = to_set;
		mq->req.sstb = *sstb;
	} else
		strlcpy(mq->req.name, name, sizeof(mq->req.name));

	if (op == SLM_FORWARD_RENAME || op == SLM_FORWARD_SYMLINK) {
		if (op == SLM_FORWARD_RENAME)
			mq->nfg	= *nfg;
		len = strlen(name) + 1;
		strlcpy(mq->req.name + len, newname,
		    sizeof(mq->req.name) - len);
	}

	if (op == SLM_FORWARD_MKDIR ||
	    op == SLM_FORWARD_CREATE ||
	    op == SLM_FORWARD_SYMLINK) {
		mq->mode = mode;
		mq->creds.scr_uid = crp->scr_uid;
		mq->creds.scr_gid = crp->scr_gid;
	}

	rc = SL_RSX_WAITREP(csvc, rq, mp);
	if (!rc)
		rc = mp->rc;
	if (!rc && sstb)
		*sstb = mp->attr;

 out:
	if (rq)
		pscrpc_req_finished(rq);
	if (csvc)
		sl_csvc_decref(csvc);
	return (rc);
}