--- /dev/null
+# DragonflyBSD Makefile
+
+LIB= hammer
+SRCS= crc32.c info.c misc.c
+INCS= libhammer.h
+
+SRCS+= crc32.c
+
+MAN+= libhammer_get_volinfo.3
+
+MLINKS+= libhammer_get_volinfo.3 libhammer_get_next_pfs.3
+MLINKS+= libhammer_get_volinfo.3 libhammer_get_prev_pfs.3
+MLINKS+= libhammer_get_volinfo.3 libhammer_get_first_pfs.3
+MLINKS+= libhammer_get_volinfo.3 libhammer_get_last_pfs.3
+MLINKS+= libhammer_get_volinfo.3 libhammer_free_volinfo.3
+
+.PATH: ${.CURDIR}/../../sys/libkern
+SHLIB_MAJOR= 0
+
+.include <bsd.lib.mk>
--- /dev/null
+/*
+ * Copyright (c) 2011 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Antonio Huete <tuxillo@quantumachine.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <libhammer.h>
+
+static u_int32_t count_snapshots(u_int32_t, char *, char *, int *);
+
+libhammer_volinfo_t
+libhammer_get_volinfo(const char *path)
+{
+ struct hammer_ioc_pseudofs_rw pseudofs;
+ struct hammer_pseudofs_data *pfs_od;
+ struct hammer_ioc_info info;
+ libhammer_pfsinfo_t pfstmp;
+ libhammer_volinfo_t hvi;
+ int pfs_id;
+ int fd;
+
+ hvi = _libhammer_malloc(sizeof(*hvi));
+
+ TAILQ_INIT(&hvi->list_pseudo);
+
+ if ((fd = open(path, O_RDONLY)) < 0)
+ goto error1;
+
+ if ((ioctl(fd, HAMMERIOC_GET_INFO, &info)) < 0)
+ goto error1;
+
+ /* 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->bigblocks = info.bigblocks;
+ hvi->rsvbigblocks = info.rsvbigblocks;
+
+ /*
+ * XXX - By now we iterate the whole range of +65000 possible
+ * pseudofs to discover the ones that are in use. Of course
+ * this is suboptimal. Best way would be to extract the
+ * pseudofs information from the control records in the
+ * B-Tree, that's in kernel land.
+ */
+ pfs_od = _libhammer_malloc(sizeof(*pfs_od));
+
+ for(pfs_id = 0; pfs_id < HAMMER_MAX_PFS; pfs_id++) {
+ /* Clear the struct to be passed to the ioctl. */
+ bzero(&pseudofs, sizeof(pseudofs));
+
+ pfstmp = _libhammer_malloc(sizeof(*pfstmp));
+
+ pseudofs.pfs_id = pfs_id;
+ pseudofs.ondisk = pfs_od;
+ pseudofs.bytes = sizeof(struct hammer_pseudofs_data);
+ pseudofs.version = HAMMER_IOC_PSEUDOFS_VERSION;
+ if (ioctl(fd, HAMMERIOC_GET_PSEUDOFS, &pseudofs) != -1) {
+ /* XXX
+ * It may be completely wrong in the case that we pass a path
+ * that is in PFS 0 but isn't the mount path of it. There's no
+ * easy way to do this.
+ */
+ pfstmp->ismaster = (pfs_od->mirror_flags & HAMMER_PFSD_SLAVE)
+ ? 0 : 1;
+
+ if (pfs_id == 0)
+ pfstmp->mountedon = strdup(path);
+ else
+ pfstmp->mountedon = libhammer_find_pfs_mount(pfs_id,
+ 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 = pseudofs.version;
+ pfstmp->pfs_id = pseudofs.pfs_id;
+ pfstmp->mirror_flags = pfs_od->mirror_flags;
+ pfstmp->snapcount = count_snapshots(hvi->version,
+ pfstmp->snapshots, pfstmp->mountedon, &pfstmp->head.error);
+
+ TAILQ_INSERT_TAIL(&hvi->list_pseudo, pfstmp, entries);
+ }
+ }
+
+ goto end;
+
+error1:
+ libhammer_free_volinfo(hvi);
+ if (fd != -1)
+ close(fd);
+
+end:
+ return (hvi);
+}
+
+void
+libhammer_free_volinfo(libhammer_volinfo_t volinfo)
+{
+ struct libhammer_pfsinfo *pfstmp;
+
+ while(!TAILQ_EMPTY(&volinfo->list_pseudo)) {
+ pfstmp = TAILQ_FIRST(&volinfo->list_pseudo);
+ free(pfstmp->mountedon);
+ TAILQ_REMOVE(&volinfo->list_pseudo, pfstmp, entries);
+ free(pfstmp);
+ }
+ free(volinfo);
+}
+
+static u_int32_t
+count_snapshots(u_int32_t version, char *pfs_snapshots, char *mountedon, int *errorp)
+{
+ struct hammer_ioc_snapshot snapinfo;
+ char *snapshots_path, *fpath;
+ struct dirent *den;
+ struct stat st;
+ DIR *dir;
+ u_int32_t snapshot_count;
+ int fd;
+
+ snapshot_count = 0;
+
+ bzero(&snapinfo, sizeof(struct hammer_ioc_snapshot));
+
+ fd = open(mountedon, O_RDONLY);
+ if (fd < 0) {
+ *errorp = errno;
+ return 0;
+ }
+
+ if (version < 3) {
+ /*
+ * old style: count the number of softlinks in the snapshots dir
+ */
+ if (pfs_snapshots[0])
+ snapshots_path = pfs_snapshots;
+ else
+ asprintf(&snapshots_path, "%s/snapshots", mountedon);
+ if ((dir = opendir(snapshots_path)) != NULL) {
+ while ((den = readdir(dir)) != NULL) {
+ if (den->d_name[0] == '.')
+ continue;
+ asprintf(&fpath, "%s/%s", snapshots_path,
+ den->d_name);
+ if (lstat(fpath, &st) == 0 &&
+ S_ISLNK(st.st_mode))
+ snapshot_count++;
+ free(fpath);
+ }
+ closedir(dir);
+ }
+ } else {
+ /*
+ * new style: file system meta-data
+ */
+ do {
+ if (ioctl(fd, HAMMERIOC_GET_SNAPSHOT, &snapinfo) < 0) {
+ *errorp = errno;
+ goto out;
+ }
+
+ snapshot_count += snapinfo.count;
+ } while (snapinfo.head.error == 0 && snapinfo.count);
+ }
+
+out:
+ if (fd != -1)
+ close(fd);
+ return snapshot_count;
+}
--- /dev/null
+/*
+ * Copyright (c) 2011 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Antonio Huete <tuxillo@quantumachine.net>
+ * by Matthew Dillon <dillon@backplane.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef _LIBHAMMER_H_
+#define _LIBHAMMER_H_
+
+#include <sys/queue.h>
+#include <sys/param.h>
+
+#include <vfs/hammer/hammer_disk.h>
+#include <vfs/hammer/hammer_ioctl.h>
+
+#define TXTLEN 64
+
+#define HAMMER_BUFLISTS 64
+#define HAMMER_BUFLISTMASK (HAMMER_BUFLISTS - 1)
+#define COLLECT_HSIZE 1024
+#define COLLECT_HMASK (COLLECT_HSIZE - 1)
+#define HAMMER_BUFINFO_READAHEAD 0x0001
+/*
+ * WARNING: Do not make the SNAPSHOTS_BASE "/var/snapshots" because
+ * it will interfere with the older HAMMER VERS < 3 snapshots directory
+ * for the /var PFS.
+ */
+#define SNAPSHOTS_BASE "/var/hammer" /* HAMMER VERS >= 3 */
+#define WS " \t\r\n"
+
+#define SERIALBUF_SIZE (512 * 1024)
+#define RD_HSIZE 32768
+#define RD_HMASK (RD_HSIZE - 1)
+
+#define DICTF_MADEDIR 0x01
+#define DICTF_MADEFILE 0x02
+#define DICTF_PARENT 0x04 /* parent attached for real */
+#define DICTF_TRAVERSED 0x80
+#define FLAG_TOOFARLEFT 0x0001
+#define FLAG_TOOFARRIGHT 0x0002
+#define FLAG_BADTYPE 0x0004
+#define FLAG_BADCHILDPARENT 0x0008
+#define FLAG_BADMIRRORTID 0x0010
+
+/*
+ * Hammer information system structures
+ */
+struct libhammer_head {
+ int32_t error;
+ int32_t flags;
+ int32_t rsv[2];
+};
+
+typedef struct libhammer_pfsinfo {
+ struct libhammer_head head; /* Additional error and flags */
+
+ uint32_t snapcount; /* Snapshot count */
+ u_int32_t version; /* HAMMER version */
+ char *mountedon; /* Mount path of the PFS */
+ int ismaster; /* Is a PFS master */
+ int pfs_id; /* PFS ID number */
+ int mirror_flags; /* Misc flags */
+ char snapshots[64]; /* softlink dir for pruning */
+ uuid_t unique_uuid; /* unique uuid of this master/slave */
+ TAILQ_ENTRY(libhammer_pfsinfo) entries;
+} *libhammer_pfsinfo_t;
+
+typedef struct libhammer_volinfo {
+ struct libhammer_head head; /* Additional error and flags */
+
+ char vol_name[TXTLEN]; /* Volume name */
+ uuid_t vol_fsid; /* Filesystem UUID */
+ int version; /* HAMMER version */
+ int nvolumes; /* Number of volumes */
+ int64_t bigblocks; /* Total big blocks */
+ int64_t rsvbigblocks; /* Reserved big blocks */
+ int32_t rsv[8];
+ TAILQ_HEAD(pfslist, libhammer_pfsinfo) list_pseudo;
+} *libhammer_volinfo_t;
+
+/*
+ * INFO directive prototypes
+ */
+__BEGIN_DECLS
+libhammer_volinfo_t libhammer_get_volinfo(const char *);
+void libhammer_free_volinfo(libhammer_volinfo_t);
+__END_DECLS
+
+static __inline libhammer_pfsinfo_t
+libhammer_get_next_pfs(libhammer_pfsinfo_t pfsinfo)
+{
+ return TAILQ_NEXT(pfsinfo, entries);
+}
+
+static __inline libhammer_pfsinfo_t
+libhammer_get_prev_pfs(libhammer_pfsinfo_t pfsinfo)
+{
+ return TAILQ_PREV(pfsinfo, pfslist, entries);
+}
+
+static __inline libhammer_pfsinfo_t
+libhammer_get_first_pfs(libhammer_volinfo_t volinfo)
+{
+ return TAILQ_FIRST(&volinfo->list_pseudo);
+}
+
+static __inline libhammer_pfsinfo_t
+libhammer_get_last_pfs(libhammer_volinfo_t volinfo)
+{
+ return TAILQ_LAST(&volinfo->list_pseudo, pfslist);
+}
+
+#endif
+
+/*
+ * MISC directive prototypes
+ */
+__BEGIN_DECLS
+char *libhammer_find_pfs_mount(int, uuid_t, int);
+void *_libhammer_malloc(size_t);
+__END_DECLS
--- /dev/null
+.\"
+.\" Copyright (c) 2011 The DragonFly Project. All rights reserved.
+.\"
+.\" This code is derived from software contributed to The DragonFly Project
+.\" by Antonio Huete Jimenez <tuxillo@quantumachine.net>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in
+.\" the documentation and/or other materials provided with the
+.\" distribution.
+.\" 3. Neither the name of The DragonFly Project nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific, prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd October 25, 2011
+.Dt LIBHAMMER 3
+.Os
+.Sh NAME
+.Nm libhammer_get_volinfo
+.Nm libhammer_get_next_pfs
+.Nm libhammer_get_prev_pfs
+.Nm libhammer_get_first_pfs
+.Nm libhammer_get_last_pfs
+.Nm libhammer_free_volinfo
+.Nd libhammer information functions
+.Sh LIBRARY
+.Lb libhammer
+.Sh SYNOPSIS
+.In libhammer.h
+.Ft libhammer_volinfo_t
+.Fn libhammer_get_volinfo "const char *path"
+.Ft libhammer_pfsinfo_t
+.Fn libhammer_get_first_pfs "libhammer_volinfo_t volinfo"
+.Ft libhammer_pfsinfo_t
+.Fn libhammer_get_last_pfs "libhammer_volinfo_t volinfo"
+.Ft libhammer_pfsinfo_t
+.Fn libhammer_get_next_pfs "libhammer_pfsinfo_t pfsinfo"
+.Ft libhammer_pfsinfo_t
+.Fn libhammer_get_prev_pfs "libhammer_pfsinfo_t pfsinfo"
+.Ft void
+.Fn libhammer_free_volinfo "libhammer_volinfo_t volinfo"
+.Sh DESCRIPTION
+The
+.Fn libhammer_get_volinfo
+iterates all the PFSs from a given path belonging to a
+.Nm HAMMER
+filesystem and returns
+.Vt libhammer_volinfo_t
+.Fa volinfo
+which holds a
+.Nm TAILQ
+of
+.Vt libhammer_pfsinfo
+structs, one per PFS found.
+.Pp
+The list of found PFSs can be iterated with
+.Fn libhammer_get_first_pfs ,
+.Fn libhammer_get_last_pfs ,
+.Fn libhammer_get_next_pfs
+and
+.Fn libhammer_get_prev_pfs .
+.Pp
+Note that to use the next and previous functions described above you need
+to store the returning
+.Vt libhammer_pfsinfo_t
+value from the first and last functions.
+.Pp
+.Fn libhammer_free_volinfo
+frees up all the memory allocated previously by
+.Fn libhammer_get_volinfo .
+.Sh RETURN VALUES
+.Fn libhammer_get_volinfo
+returns a
+.Vt libhammer_volinfo_t
+in any case where path is in a
+.Nm HAMMER
+filesystem scope or
+.Dv NULL
+if there was any other problem.
+You can check
+.Nm errno
+in the error cases.
+.Pp
+.Fn libhammer_get_first_pfs
+and
+.Fn libhammer_get_last_pfs
+must return a
+.Vt libhammer_pfs_t
+if the
+.Fa volinfo
+passed in is valid.
+.Fn libhammer_get_next_pfs
+and
+.Fn libhammer_get_prev_pfs
+return a
+.Vt libhammer_pfsinfo_t
+or
+.Dv NULL
+in case there are no more elements.
+.Sh SEE ALSO
+.Xr HAMMER 5 ,
+.Xr hammer 8 ,
+.Sh AUTHORS
+This manpage was written by
+.An Antonio Huete Jimenez.
--- /dev/null
+/*
+ * Copyright (c) 2011 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com>
+ * by Antonio Huete <tuxillo@quantumachine.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <fcntl.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <uuid.h>
+
+#include <libhammer.h>
+
+char *
+libhammer_find_pfs_mount(int pfsid, uuid_t parentuuid, int ismaster)
+{
+ struct hammer_ioc_info hi;
+ struct statfs *mntbuf;
+ int mntsize;
+ int curmount;
+ int fd;
+ size_t mntbufsize;
+ char *trailstr;
+ char *retval;
+
+ retval = NULL;
+
+ /* Do not continue if there are no mounted filesystems */
+ mntsize = getfsstat(NULL, 0, MNT_NOWAIT);
+ if (mntsize <= 0)
+ return retval;
+
+ mntbufsize = (mntsize) * sizeof(struct statfs);
+ mntbuf = _libhammer_malloc(mntbufsize);
+ if (mntbuf == NULL) {
+ perror("show_info");
+ exit(EXIT_FAILURE);
+ }
+
+ mntsize = getfsstat(mntbuf, (long)mntbufsize, MNT_NOWAIT);
+ curmount = mntsize - 1;
+
+ asprintf(&trailstr, ":%05d", pfsid);
+
+ /*
+ * Iterate all the mounted points looking for the PFS passed to
+ * this function.
+ */
+ while(curmount >= 0) {
+ /*
+ * We need to avoid that PFS belonging to other HAMMER
+ * filesystems are showed as mounted, so we compare
+ * against the FSID, which is presumable to be unique.
+ */
+ bzero(&hi, sizeof(hi));
+ if ((fd = open(mntbuf[curmount].f_mntfromname, O_RDONLY)) < 0) {
+ curmount--;
+ continue;
+ }
+
+ if ((ioctl(fd, HAMMERIOC_GET_INFO, &hi)) < 0) {
+ curmount--;
+ continue;
+ }
+
+ if (strstr(mntbuf[curmount].f_mntfromname, trailstr) != NULL &&
+ (uuid_compare(&hi.vol_fsid, &parentuuid, NULL)) == 0) {
+ if (ismaster) {
+ if (strstr(mntbuf[curmount].f_mntfromname,
+ "@@-1") != NULL) {
+ retval =
+ strdup(mntbuf[curmount].f_mntonname);
+ break;
+ }
+ } else {
+ if (strstr(mntbuf[curmount].f_mntfromname,
+ "@@0x") != NULL ) {
+ retval =
+ strdup(mntbuf[curmount].f_mntonname);
+ break;
+ }
+ }
+ }
+ curmount--;
+ close(fd);
+ }
+ free(trailstr);
+
+ return retval;
+}
+
+/*
+ * Allocate len bytes of memory and return the pointer.
+ * It'll exit in the case no memory could be allocated.
+ *
+ * To be used only by the library itself.
+ */
+void *
+_libhammer_malloc(size_t len)
+{
+ void *m;
+
+ m = calloc(len, sizeof(char));
+ if (m == NULL)
+ errx(1, "Failed to allocate %zd bytes", len);
+
+ return (m);
+}