Exemple #1
0
/*
 * Pull POSIX ACLs from an fcmh via RPCs to MDS.
 */
acl_t
slc_acl_get_fcmh(struct pscfs_req *pfr, const struct pscfs_creds *pcr,
    struct fidc_membh *f)
{
	char trybuf[64] = { 0 };
	void *buf = NULL;
	size_t retsz = 0;
	ssize_t rc;
	acl_t a;

	rc = slc_getxattr(pfr, pcr, ACL_EA_ACCESS, trybuf,
	    sizeof(trybuf), f, &retsz);
	if (rc == 0) {
		buf = trybuf;
	} else if (rc == ERANGE) {
		buf = PSCALLOC(retsz);
		rc = slc_getxattr(pfr, pcr, ACL_EA_ACCESS, buf, retsz,
		    f, &retsz);
		if (rc) {
			PSCFREE(buf);
			return (NULL);
		}
	} else
		return (NULL);

	a = pfl_acl_from_xattr(buf, retsz);

	if (buf != trybuf)
		PSCFREE(buf);
	return (a);
}
Exemple #2
0
void
mod_destroy(struct wok_module *wm)
{
	dlclose(wm->wm_handle);
	PSCFREE(wm->wm_path);
	PSCFREE(wm);
}
Exemple #3
0
struct wok_module *
mod_load(const char *path, const char *opts, char *errbuf,
    size_t errlen)
{
	int (*loadf)(struct pscfs *);
	struct wok_module *wm;
	void *h;
	int rc;

	h = dlopen(path, RTLD_NOW);
	if (h == NULL) {
		snprintf(errbuf, LINE_MAX, "%s\n", dlerror()); 
		fprintf(stderr, errbuf);
		return (NULL);
	}

	loadf = dlsym(h, "pscfs_module_load");
	if (loadf == NULL) {
		dlclose(h);
		snprintf(errbuf, LINE_MAX,
		    "symbol pscfs_module_load undefined.\n");
		fprintf(stderr, errbuf);
		return (NULL);
	}

	wm = PSCALLOC(sizeof(*wm));
	wm->wm_path = pfl_strdup(path);
	wm->wm_handle = h;
	wm->wm_opts = pfl_strdup(opts);
	wm->wm_module.pf_private = wm;
	pflfs_module_init(&wm->wm_module, opts);
	rc = loadf(&wm->wm_module);

	/*
	 * XXX XXX XXX
	 * This is a complete hack but this flush somehow avoids a bunch
	 * of zeroes from ending up in the log...
	 * XXX XXX XXX
	 */
	fflush(stderr);

	if (rc) {
		wm->wm_module.pf_handle_destroy = NULL;
		pflfs_module_destroy(&wm->wm_module);

		dlclose(h);
		PSCFREE(wm->wm_path);
		PSCFREE(wm);
		psclog_warnx("module failed to load: rc=%d module=%s",
		    rc, path);
		strlcpy(errbuf, strerror(rc), errlen);
		return (NULL);
	}
	return (wm);
}
Exemple #4
0
void
pfl_odt_release(struct pfl_odt *t)
{
	if (t->odt_bitmap)
		psc_vbitmap_free(t->odt_bitmap);

	t->odt_ops.odtop_close(t);

	pfl_opstat_destroy(t->odt_iostats.rd);
	pfl_opstat_destroy(t->odt_iostats.wr);

	PSCFREE(t->odt_hdr);
	PSCFREE(t);
}
Exemple #5
0
void
pfl_odt_check(struct pfl_odt *t,
    void (*cbf)(void *, int64_t, void *), void *arg)
{
	struct pfl_odt_slotftr *f;
	struct pfl_odt_hdr *h;
	struct pfl_meter mtr;
	uint64_t crc;
	void *p;

	h = t->odt_hdr;

	pfl_meter_init(&mtr, 0, "odt-%s", t->odt_name);
	mtr.pm_max = h->odth_nitems;

#define i mtr.pm_cur
	for (i = 0; i < h->odth_nitems; i++) {
		pfl_odt_getslot(t, i, &p, &f);

		if (f->odtf_slotno != i)
			PFLOG_ODT(PLL_FATAL, t, "footercheck: i=%"PRIu64, i);

		if (h->odth_options & ODTBL_OPT_CRC) {
			psc_crc64_init(&crc);
			if (f->odtf_flags & ODT_FTRF_INUSE)
				psc_crc64_add(&crc, p, h->odth_itemsz);
			psc_crc64_add(&crc, f, sizeof(*f) -
			    sizeof(f->odtf_crc));
			psc_crc64_fini(&crc);

			if (crc != f->odtf_crc)
				PFLOG_ODT(PLL_FATAL, t,
				    "CRC failed; slot=%"PRId64" "
				    "mem_crc=%"PSCPRIxCRC64" "
				    "ftr_crc=%"PSCPRIxCRC64,
				    i, crc, f->odtf_crc);
		}

		if (f->odtf_flags & ODT_FTRF_INUSE) {
			psc_vbitmap_set(t->odt_bitmap, i);
			if (cbf)
				cbf(p, i, arg);
		}
		PSCFREE(p);
		PSCFREE(f);
	}
#undef i

	pfl_meter_destroy(&mtr);
}
void
slm_fcmh_dtor(struct fidc_membh *f)
{
	struct fcmh_mds_info *fmi;
	int rc, vfsid;

	fmi = fcmh_2_fmi(f);

	if (fcmh_isreg(f)) {
		psc_assert(psc_dynarray_len(&fmi->fmi_ptrunc_clients) == 0);
		psc_dynarray_free(&fmi->fmi_ptrunc_clients);
	}

	if (fcmh_isreg(f) || fcmh_isdir(f)) {
		/* XXX Need to worry about other modes here */
		if (!fmi->fmi_ctor_rc) {
			slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
			rc = mdsio_release(vfsid, &rootcreds,
			    fcmh_2_mfh(f));
			psc_assert(rc == 0);
		}
	}

	if (fcmh_isdir(f)) {
		slfid_to_vfsid(fcmh_2_fid(f), &vfsid);
		rc = mdsio_release(vfsid, &rootcreds,
		    fcmh_2_dino_mfh(f));
		psc_assert(rc == 0);
	}

	if (fmi->fmi_inodeh.inoh_extras)
		PSCFREE(fmi->fmi_inodeh.inoh_extras);
}
Exemple #7
0
/*
 * Handle a NAMESPACE_UPDATE request from another MDS.
 */
int
slm_rmm_handle_namespace_update(struct pscrpc_request *rq)
{
	struct srt_update_entry *entryp;
	struct srm_update_req *mq;
	struct srm_update_rep *mp;
	struct sl_mds_peerinfo *p;
	struct sl_resource *res;
	struct sl_site *site;
	struct iovec iov;
	int i, len, count;

	SL_RSX_ALLOCREP(rq, mq, mp);

	count = mq->count;
	if (count <= 0 || mq->size > LNET_MTU) {
		mp->rc = -EINVAL;
		return (mp->rc);
	}

	iov.iov_len = mq->size;
	iov.iov_base = PSCALLOC(mq->size);

	mp->rc = slrpc_bulkserver(rq, BULK_GET_SINK, SRMM_BULK_PORTAL,
	    &iov, 1);
	if (mp->rc)
		goto out;

	/* Search for the peer information by the given site ID. */
	site = libsl_siteid2site(mq->siteid);
	p = NULL;
	if (site)
		SITE_FOREACH_RES(site, res, i)
			if (res->res_type == SLREST_MDS) {
				p = res2rpmi(res)->rpmi_info;
				break;
			}
	if (p == NULL) {
		psclog_info("fail to find site ID %d", mq->siteid);
		PFL_GOTOERR(out, mp->rc = -EINVAL);
	}

	/*
	 * Iterate through the namespace update buffer and apply updates.
	 * If we fail to apply an update, we still report success to our
	 * peer because reporting an error does not help our cause.
	 */
	entryp = iov.iov_base;
	for (i = 0; i < count; i++) {
		slm_rmm_apply_update(entryp);
		len = UPDATE_ENTRY_LEN(entryp);
		entryp = PSC_AGP(entryp, len);
	}
	zfsslash2_wait_synced(0);

 out:
	PSCFREE(iov.iov_base);
	return (mp->rc);
}
/**
 * pflnet_freeifaddrs - Release network interface addresses.
 * @ifa: addresses to free.
 */
void
pflnet_freeifaddrs(struct ifaddrs *ifa)
{
#ifdef HAVE_GETIFADDRS
	freeifaddrs(ifa);
#else
	PSCFREE(ifa);
#endif
}
Exemple #9
0
void
pfl_opstat_destroy_pos(int pos)
{
	struct pfl_opstat *opst;

	LOCK_ENSURE(&pfl_opstats_lock);
	opst = psc_dynarray_getpos(&pfl_opstats, pos);
	psc_dynarray_splice(&pfl_opstats, pos, 1, NULL, 0);
	PSCFREE(opst);
}
Exemple #10
0
void
pfl_opstats_grad_destroy(struct pfl_opstats_grad *og)
{
	struct pfl_opstat_bucket *ob;
	int i;

	for (i = 0, ob = og->og_buckets; i < og->og_nbuckets; i++, ob++)
		pfl_opstat_destroy(ob->ob_opst);
	PSCFREE(og->og_buckets);
}
Exemple #11
0
int
main(int argc, char *argv[])
{
	size_t sz;
	void *p;

	pfl_init();
	if (getopt(argc, argv, "") != -1)
		usage();
	argc -= optind;
	if (argc)
		usage();

	p = PSCALLOC(213);
	p = psc_realloc(p, 65536, 0);
	p = psc_realloc(p, 0, 0);
	p = psc_realloc(p, 128, 0);
	p = psc_realloc(p, 0, 0);
	PSCFREE(p);

	p = PSCALLOC(128);
	PSCFREE(p);

	p = psc_alloc(24, PAF_PAGEALIGN);
	psc_free(p, PAF_PAGEALIGN);

	p = PSCALLOC(24);
	p = psc_realloc(p, 128, 0);
	PSCFREE(p);

	p = psc_alloc(8, PAF_LOCK);
	*(uint64_t *)p = 0;
	psc_free(p, PAF_LOCK, (size_t)8);

	sz = 1024;
	p = psc_alloc(sz, PAF_LOCK | PAF_PAGEALIGN);
	memset(p, 0, sz);
	psc_free(p, PAF_LOCK | PAF_PAGEALIGN, sz);

	exit(0);
}
Exemple #12
0
__static int
pflnet_rtexists_sysctl(const struct sockaddr *sa)
{
	union {
		struct rt_msghdr *rtm;
		char *ch;
		void *p;
	} u;
	union pfl_sockaddr_ptr s, os;
	int rc = 0, mib[6];
	char *buf = NULL;
	size_t len;

	os.cp = sa;

	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;		/* protocol */
	mib[3] = AF_INET;
	mib[4] = NET_RT_DUMP;
	mib[5] = 0;		/* no flags */
	if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) == -1)
		psc_fatal("route-sysctl-estimate");
	if (len) {
		buf = PSCALLOC(len);
		if (sysctl(mib, nitems(mib), buf, &len, NULL, 0) == -1)
			psc_fatal("actual retrieval of routing table");
	}

	for (u.p = buf; u.ch && u.ch < buf + len;
	    u.ch += u.rtm->rtm_msglen) {
		if (u.rtm->rtm_version != RTM_VERSION)
			continue;
		s.p = u.rtm + 1;

		if (s.s->sin.sin_addr.s_addr ==
		    os.s->sin.sin_addr.s_addr) {
			rc = 1;
			break;
		}
	}

	PSCFREE(buf);

	return (rc);
}
Exemple #13
0
/*
 * Traverse a file hierarchy and perform an operation on each file
 * system entry.
 * @fn: file root.
 * @flags: behavorial flags.
 * @cmpf: optional dirent comparator for ordering.
 * @cbf: callback to invoke on each file.
 * @arg: optional argument to supply to callback.
 * Notes: the callback will be invoked with a fully resolved absolute
 *	path name unless the file in question is a symbolic link.
 */
int
pfl_filewalk(const char *fn, int flags, void *cmpf, int (*cbf)(FTSENT *,
    void *), void *arg)
{
	char * const pathv[] = { (char *)fn, NULL };
	int rc = 0, f_flags = 0;
	struct stat stb;
	FTSENT *f;
	FTS *fp;

	if (flags & PFL_FILEWALKF_RECURSIVE) {
		if (flags & PFL_FILEWALKF_NOSTAT)
			f_flags |= FTS_NOSTAT;
		if (flags & PFL_FILEWALKF_NOCHDIR)
			f_flags |= FTS_NOCHDIR;
		fp = pfl_fts_open(pathv, f_flags | FTS_COMFOLLOW |
		    FTS_PHYSICAL, cmpf);
		if (fp == NULL)
			psc_fatal("fts_open %s", fn);
		while ((f = pfl_fts_read(fp)) != NULL) {
			switch (f->fts_info) {
			case FTS_NS:
				psclog_warnx("%s: %s", f->fts_path,
				    strerror(f->fts_errno));
				break;
			case FTS_F:
			case FTS_D:
			case FTS_SL:
				if (flags & PFL_FILEWALKF_VERBOSE)
					warnx("processing %s%s",
					    fn, f->fts_info == FTS_D ?
					    "/" : "");
			case FTS_DP:
				rc = cbf(f, arg);
				if (rc) {
					pfl_fts_close(fp);
					return (rc);
				}
				break;
			default:
				if (f->fts_errno == 0)
					f->fts_errno = EOPNOTSUPP;
				psclog_warnx("%s: %s", f->fts_path,
				    strerror(f->fts_errno));
				break;
			}
		}
		pfl_fts_close(fp);
	} else {
		const char *basefn;
		size_t baselen;

		if (lstat(fn, &stb) == -1)
			err(1, "%s", fn);
		basefn = pfl_basename(fn);
		baselen = strlen(basefn);

		f = PSCALLOC(sizeof(*f) + baselen);
		f->fts_accpath = (char *)fn;
		f->fts_path = (char *)fn;
		f->fts_pathlen = strlen(fn);
		strlcpy(f->fts_name, basefn, baselen + 1);
		f->fts_namelen = baselen;
		f->fts_ino = stb.st_ino;
		f->fts_statp = &stb;
		switch (stb.st_mode & S_IFMT) {
		case S_IFDIR: f->fts_info = FTS_D; break;
		case S_IFREG: f->fts_info = FTS_F; break;
		case S_IFLNK: f->fts_info = FTS_SL; break;
		case S_IFBLK: f->fts_info = FTS_DEFAULT; break;
		default:
			psclog_warnx("%s: %s", fn,
			    strerror(EOPNOTSUPP));
			break;
		}
		rc = cbf(f, arg);
		PSCFREE(f);
	}
	return (rc);
}
Exemple #14
0
/*
 * Free aligned memory.
 * @p: memory chunk to free.
 */
void
psc_freen(void *p)
{
	/* XXX recover original pointer value. */
	PSCFREE(p);
}
Exemple #15
0
void
slab_free(struct slab *slb)
{
	PSCFREE(slb->slb_base);
	psc_pool_return(slab_pool, slb);
}
Exemple #16
0
int
main(int argc, char *argv[])
{
	int c, i, rc, verbose = 0, oflg = ODTBL_FLG_RDONLY, tflg = ODTBL_OPT_CRC;
	struct pfl_odt *t;
	char *p, *fn;

	pfl_init();
	pscthr_init(0, NULL, 0, "odtable");

	while ((c = getopt(argc, argv, "CcdF:n:osvX:z:")) != -1)
		switch (c) {
		case 'C':
			create_table = 1;
			break;
		case 'c':
			tflg |= ODTBL_OPT_CRC;
			break;
		case 'd':
			dump = 1;
			break;
		case 'F':
			num_free = atoi(optarg);
			oflg &= ~ODTBL_FLG_RDONLY;
			break;
		case 'n':
			num_puts = atoi(optarg);
			oflg &= ~ODTBL_FLG_RDONLY;
			break;
		case 'o':
			overwrite = 1;
			break;
		case 's':
			item_size = atoi(optarg);
			break;
		case 'v':
			verbose = 1;
			break;
		case 'X':
			fmt = optarg;
			break;
		case 'z':
			nitems = atoi(optarg);
			break;
		default:
			usage();
		}

	argc -= optind;
	argv += optind;
	if (argc != 1)
		usage();

	fn = argv[0];

	if (create_table) {
		rc = pfl_odt_create(fn, nitems, item_size, overwrite,
		    ODT_ITEM_START, 0, tflg);
		if (!rc && verbose)
			warnx("created od-table %s "
			    "(elemsize=%zu, nitems=%zu)",
			    fn, item_size, nitems);
		exit(0);
	}

	pfl_odt_load(&t, &pfl_odtops, oflg, fn, "%s", fn);
	pfl_odt_check(t, visit, &t);

	for (i = 0; i < num_puts; i++) {
		size_t elem;

		elem = pfl_odt_allocslot(t);
		pfl_odt_allocitem(t, (void **)&p);
		snprintf(p, item_size, "... put_number=%d ...", i);
		pfl_odt_putitem(t, elem, p, 1);
		PSCFREE(p);
	}

	/* XXX find in-use slot to free */
	for (i = 0; i < num_free; i++)
		pfl_odt_freeitem(t, i);

	pfl_odt_release(t);
	exit(0);
}
Exemple #17
0
/**
 * pjournal_dump - Dump the contents of a journal file.
 * @fn: journal filename to query.
 * @verbose: whether to report stats summary or full dump.
 *
 * Each time mds restarts, it writes log entries starting from the very
 * first slot of the log.  Anyway, the function dumps all log entries,
 * some of them may be from previous incarnations of the MDS.
 */
void
pjournal_dump(const char *fn)
{
	int i, ntotal, nmagic, nchksum, nformat, ndump, first = 1;
	uint32_t slot, highest_slot = -1, lowest_slot = -1;
	uint64_t chksum, highest_xid = 0, lowest_xid = 0;
	struct psc_journal_enthdr *pje;
	struct psc_journal_hdr *pjh;
	struct psc_journal *pj;
	struct stat statbuf;
	unsigned char *jbuf;
	ssize_t nb, pjhlen;
	time_t ts;

	ntotal = nmagic = nchksum = nformat = ndump = 0;

	pj = PSCALLOC(sizeof(*pj));

	strlcpy(pj->pj_name, pfl_basename(fn), sizeof(pj->pj_name));

	pj->pj_fd = open(fn, O_RDWR | O_DIRECT);
	if (pj->pj_fd == -1)
		psc_fatal("failed to open journal %s", fn);
	if (fstat(pj->pj_fd, &statbuf) == -1)
		psc_fatal("failed to stat journal %s", fn);

	/*
	 * O_DIRECT may impose alignment restrictions so align the
	 * buffer and perform I/O in multiples of file system block
	 * size.
	 */
	pjhlen = PSC_ALIGN(sizeof(*pjh), statbuf.st_blksize);
	pjh = psc_alloc(pjhlen, PAF_PAGEALIGN);
	nb = pread(pj->pj_fd, pjh, pjhlen, 0);
	if (nb != pjhlen)
		psc_fatal("failed to read journal header");

	pj->pj_hdr = pjh;
	if (pjh->pjh_magic != PJH_MAGIC)
		psc_fatalx("journal header has a bad magic number "
		    "%#"PRIx64, pjh->pjh_magic);

	if (pjh->pjh_version != PJH_VERSION)
		psc_fatalx("journal header has an invalid version "
		    "number %d", pjh->pjh_version);

	psc_crc64_init(&chksum);
	psc_crc64_add(&chksum, pjh, offsetof(struct psc_journal_hdr,
	    pjh_chksum));
	psc_crc64_fini(&chksum);

	if (pjh->pjh_chksum != chksum)
		psc_fatalx("journal header has an invalid checksum "
		    "value %"PSCPRIxCRC64" vs %"PSCPRIxCRC64,
		    pjh->pjh_chksum, chksum);

	if (S_ISREG(statbuf.st_mode) && statbuf.st_size !=
	    (off_t)(pjhlen + pjh->pjh_nents * PJ_PJESZ(pj)))
		psc_fatalx("size of the journal log %"PSCPRIdOFFT"d does "
		    "not match specs in its header", statbuf.st_size);

	if (pjh->pjh_nents % pjh->pjh_readsize)
		psc_fatalx("number of entries %d is not a multiple of the "
		    "readsize %d", pjh->pjh_nents, pjh->pjh_readsize);

	ts = pjh->pjh_timestamp;

	printf("%s:\n"
	    "  version: %u\n"
	    "  entry size: %u\n"
	    "  number of entries: %u\n"
	    "  batch read size: %u\n"
	    "  entry start offset: %"PRId64"\n"
	    "  format time: %s"
	    "  uuid: %"PRIx64"\n"
	    "  %4s  %3s %4s %4s %s\n",
	    fn, pjh->pjh_version, PJ_PJESZ(pj), pjh->pjh_nents,
	    pjh->pjh_readsize, pjh->pjh_start_off,
	    ctime(&ts), pjh->pjh_fsuuid,
	    "idx", "typ", "xid", "txg", "details");

	jbuf = psc_alloc(PJ_PJESZ(pj) * pj->pj_hdr->pjh_readsize,
	    PAF_PAGEALIGN);
	for (slot = 0; slot < pjh->pjh_nents;
	    slot += pjh->pjh_readsize) {
		nb = pread(pj->pj_fd, jbuf, PJ_PJESZ(pj) *
		    pjh->pjh_readsize, PJ_GETENTOFF(pj, slot));
		if (nb != PJ_PJESZ(pj) * pjh->pjh_readsize)
			warn("failed to read %d log entries at slot %d",
			    pjh->pjh_readsize, slot);

		for (i = 0; i < pjh->pjh_readsize; i++) {
			ntotal++;
			pje = (void *)&jbuf[PJ_PJESZ(pj) * i];
			if (pje->pje_magic != PJE_MAGIC) {
				nmagic++;
				warnx("journal slot %d has a bad magic"
				    "number", slot + i);
				continue;
			}

			/*
			 * If we hit a new entry that is never used, we
			 * assume that the rest of the journal is never
			 * used.
			 */
			if (pje->pje_type == PJE_FORMAT) {
				nformat = nformat + pjh->pjh_nents -
				    (slot + i);
				goto done;
			}

			psc_crc64_init(&chksum);
			psc_crc64_add(&chksum, pje, offsetof(
			    struct psc_journal_enthdr, pje_chksum));
			psc_crc64_add(&chksum, pje->pje_data,
			    pje->pje_len);
			psc_crc64_fini(&chksum);

			if (pje->pje_chksum != chksum) {
				nchksum++;
				warnx("journal slot %d has a corrupt "
				    "checksum", slot + i);
				goto done;
			}
			ndump++;
			if (verbose)
				pjournal_dump_entry(slot + i, pje);
			if (first) {
				first = 0;
				highest_xid = lowest_xid = pje->pje_xid;
				highest_slot = lowest_slot = slot + i;
				continue;
			}
			if (highest_xid < pje->pje_xid) {
				highest_xid = pje->pje_xid;
				highest_slot = slot + i;
			}
			if (lowest_xid > pje->pje_xid) {
				lowest_xid = pje->pje_xid;
				lowest_slot = slot + i;
			}
		}

	}

 done:
	if (close(pj->pj_fd) == -1)
		printf("failed closing journal %s", fn);

	psc_free(jbuf, PAF_PAGEALIGN, PJ_PJESZ(pj));
	PSCFREE(pj);

	printf("----------------------------------------------\n"
	    "%8d slot(s) scanned\n"
	    "%8d in use\n"
	    "%8d formatted\n"
	    "%8d bad magic\n"
	    "%8d bad checksum(s)\n"
	    "lowest transaction ID=%#"PRIx64" (slot=%d)\n"
	    "highest transaction ID=%#"PRIx64" (slot=%d)\n",
	    ntotal, ndump, nformat, nmagic, nchksum,
	    lowest_xid, lowest_slot,
	    highest_xid, highest_slot);
}