From cb7575e6a89409a2041a37fcfc22ce9e41297ab8 Mon Sep 17 00:00:00 2001 From: Antonio Huete Jimenez Date: Wed, 26 Oct 2011 00:34:24 +0200 Subject: [PATCH] libhammer - HAMMER filesystem library. Initial work to bring a library to help operating HAMMER filesystems from userland. It's barebones as of now, only "info" directive is adapted, progressively the rest of the directives will be migrated Help-from: @swildner, @sjg --- lib/libhammer/Makefile | 20 +++ lib/libhammer/info.c | 210 ++++++++++++++++++++++++++ lib/libhammer/libhammer.h | 150 ++++++++++++++++++ lib/libhammer/libhammer_get_volinfo.3 | 124 +++++++++++++++ lib/libhammer/misc.c | 142 +++++++++++++++++ 5 files changed, 646 insertions(+) create mode 100644 lib/libhammer/Makefile create mode 100644 lib/libhammer/info.c create mode 100644 lib/libhammer/libhammer.h create mode 100644 lib/libhammer/libhammer_get_volinfo.3 create mode 100644 lib/libhammer/misc.c diff --git a/lib/libhammer/Makefile b/lib/libhammer/Makefile new file mode 100644 index 0000000000..da99a10799 --- /dev/null +++ b/lib/libhammer/Makefile @@ -0,0 +1,20 @@ +# 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 diff --git a/lib/libhammer/info.c b/lib/libhammer/info.c new file mode 100644 index 0000000000..532cd35b36 --- /dev/null +++ b/lib/libhammer/info.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2011 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Antonio Huete + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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; +} diff --git a/lib/libhammer/libhammer.h b/lib/libhammer/libhammer.h new file mode 100644 index 0000000000..915cca7a75 --- /dev/null +++ b/lib/libhammer/libhammer.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2011 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Antonio Huete + * by Matthew Dillon + * + * 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 +#include + +#include +#include + +#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 diff --git a/lib/libhammer/libhammer_get_volinfo.3 b/lib/libhammer/libhammer_get_volinfo.3 new file mode 100644 index 0000000000..5df6651f66 --- /dev/null +++ b/lib/libhammer/libhammer_get_volinfo.3 @@ -0,0 +1,124 @@ +.\" +.\" Copyright (c) 2011 The DragonFly Project. All rights reserved. +.\" +.\" This code is derived from software contributed to The DragonFly Project +.\" by Antonio Huete Jimenez +.\" +.\" 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. diff --git a/lib/libhammer/misc.c b/lib/libhammer/misc.c new file mode 100644 index 0000000000..a1b6d8eb73 --- /dev/null +++ b/lib/libhammer/misc.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2011 The DragonFly Project. All rights reserved. + * + * This code is derived from software contributed to The DragonFly Project + * by Matthew Dillon + * by Antonio Huete + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +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); +} -- 2.41.0