Пример #1
0
int
libhammer_pfs_get_snapshots(libhammer_fsinfo_t fip, libhammer_pfsinfo_t pip)
{
	struct hammer_snapshot_data *snapdata = NULL;
	struct hammer_ioc_snapshot snap;
	libhammer_snapinfo_t sip;
	libhammer_pfsinfo_t pfs0;
	char *path = NULL;
	int ret = 0;
	int fd;
	u_int i;

	assert(pip != NULL);
	assert(fip != NULL);

	/*
	 * Still need a path to open so, when not mounted, try
	 * to figure out the PFS path access in order to open(2)
	 * Note that this will fail for slave PFS that were created
	 * with pfs-slave directive since they don't have any transaction
	 * recorded and nlookup can't find them. For those we simply
	 * return the error in the head structure of libhammer_pfsinfo_t
	 * for the caller to handle the situation.
	 */
	pfs0 = libhammer_get_first_pfs(fip);
	if (pip->mountedon == NULL)
		libhammer_pfs_canonical_path(pfs0->mountedon, pip, &path);
	else
		path = strdup(pip->mountedon);

	if (path == NULL || (fd = open(path, O_RDONLY)) < 0) {
		pip->head.error = errno;
		ret = -1;
		goto out;
	}

	bzero(&snap, sizeof(snap));

	/*
	 * Loop while there are snapshots returned from the ioctl(2) call.
	 *
	 * For more information on how the snapshots are returned
	 * to userland please check sys/vfs/hammer/hammer_ioctl.c
	 */
	do {
		if (ioctl(fd, HAMMERIOC_GET_SNAPSHOT, &snap) < 0) {
			pip->head.error = errno;
			ret = -1;
			close(fd);
			goto out;
		}
		for (i = 0; i < snap.count; i++) {
			snapdata = &snap.snaps[i];
			sip = _libhammer_malloc(sizeof(*sip));
			sip->tid = snapdata->tid;
			sip->ts = snapdata->ts;
			if (strlen(snapdata->label))
				sprintf(sip->label, "%s", snapdata->label);
			else
				sip->label[0] = '\0';
			TAILQ_INSERT_TAIL(&pip->list_snap, sip, entries);
			pip->snapcount++;
		}
	} while (snap.head.error == 0 && snap.count);
	close(fd);

out:
	if (path)
		free(path);

	return (ret);
}
Пример #2
0
libhammer_volinfo_t
libhammer_get_volinfo(const char *path)
{
	struct hammer_pseudofs_data *pfs_od;
	struct hammer_ioc_pfs_iterate pi;
	struct hammer_ioc_info info;
	libhammer_pfsinfo_t pfstmp;
	libhammer_volinfo_t hvi;
	int error = 0;
	int fd;

	if ((fd = open(path, O_RDONLY)) < 0)
		return NULL;

	hvi = _libhammer_malloc(sizeof(*hvi));
	TAILQ_INIT(&hvi->list_pseudo);
	if ((ioctl(fd, HAMMERIOC_GET_INFO, &info)) < 0) {
		libhammer_free_volinfo(hvi);
		close(fd);
		return NULL;
	}

	/* Fill volume information */
	snprintf(hvi->vol_name, TXTLEN, "%s", info.vol_name);
	hvi->vol_fsid = info.vol_fsid;
	hvi->version = info.version;
	hvi->nvolumes = info.nvolumes;
	hvi->inodes = info.inodes;
	hvi->bigblocks = info.bigblocks;
	hvi->freebigblocks = info.freebigblocks;
	hvi->rsvbigblocks = info.rsvbigblocks;

	bzero(&pi, sizeof(pi));
	pi.ondisk = _libhammer_malloc(sizeof(*pfs_od));
	while(error == 0) {
		error = ioctl(fd, HAMMERIOC_PFS_ITERATE, &pi);
		if (error == 0 &&
		    ((pi.head.flags & HAMMER_PFSD_DELETED) == 0)) {
			/*
			 * XXX - In the case the path passed is on PFS#0 but it
			 * is not the mountpoint itself, it could produce a
			 * wrong type of PFS.
			 */
			pfstmp = _libhammer_malloc(sizeof(*pfstmp));
			pfs_od = pi.ondisk;
			pfstmp->ismaster =
			    (pfs_od->mirror_flags & HAMMER_PFSD_SLAVE) ? 0 : 1;

			if (pi.pos == 0)
				pfstmp->mountedon = strdup(path);
			else
				pfstmp->mountedon =
				    libhammer_find_pfs_mount(pi.pos,
					hvi->vol_fsid, pfstmp->ismaster);
			/*
			 * Fill in structs used in the library. We don't rely on
			 * HAMMER own struct but we do fill our own.
			 */
			pfstmp->version = hvi->version;
			pfstmp->pfs_id = pi.pos;
			pfstmp->mirror_flags = pfs_od->mirror_flags;
			pfstmp->beg_tid = pfs_od->sync_beg_tid;
			pfstmp->end_tid = pfs_od->sync_end_tid;
			pfstmp->snapcount = count_snapshots(hvi->version,
			    pfstmp->snapshots, pfstmp->mountedon,
			    &pfstmp->head.error);

			TAILQ_INSERT_TAIL(&hvi->list_pseudo, pfstmp, entries);
		}
		pi.pos++;
	}
	free(pi.ondisk);

	close (fd);

	return (hvi);
}