be_access.c revision 336701
1336668Skevans/*
2336668Skevans * be_access.c
3336668Skevans *
4336668Skevans * Copyright (c) 2017 Kyle J. Kneitinger <kyle@kneit.in>
5336668Skevans * All rights reserved.
6336668Skevans *
7336668Skevans * Redistribution and use in source and binary forms, with or without
8336668Skevans * modification, are permitted provided that the following conditions
9336668Skevans * are met:
10336668Skevans * 1. Redistributions of source code must retain the above copyright
11336668Skevans *    notice, this list of conditions and the following disclaimer.
12336668Skevans * 2. Redistributions in binary form must reproduce the above copyright
13336668Skevans *    notice, this list of conditions and the following disclaimer in the
14336668Skevans *    documentation and/or other materials provided with the distribution.
15336668Skevans *
16336668Skevans * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17336668Skevans * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18336668Skevans * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19336668Skevans * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20336668Skevans * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21336668Skevans * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22336668Skevans * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23336668Skevans * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24336668Skevans * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25336668Skevans * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26336668Skevans * SUCH DAMAGE.
27336668Skevans */
28336668Skevans
29336668Skevans#include "be.h"
30336668Skevans#include "be_impl.h"
31336668Skevans
32336668Skevans/*
33336668Skevans * usage
34336668Skevans */
35336668Skevansint
36336668Skevansbe_mount(libbe_handle_t *lbh, char *bootenv, char *mountpoint, int flags,
37336668Skevans    char *result_loc)
38336668Skevans{
39336668Skevans	char be[BE_MAXPATHLEN];
40336668Skevans	char mnt_temp[BE_MAXPATHLEN];
41336668Skevans	zfs_handle_t *zfs_hdl;
42336668Skevans	char *path;
43336668Skevans	int mntflags;
44336668Skevans	int err;
45336668Skevans
46336701Skevans	if (err = be_root_concat(lbh, bootenv, be))
47336668Skevans		return (set_error(lbh, err));
48336668Skevans
49336701Skevans	if (!be_exists(lbh, bootenv))
50336668Skevans		return (set_error(lbh, BE_ERR_NOENT));
51336668Skevans
52336701Skevans	if (is_mounted(lbh->lzh, be, &path))
53336668Skevans		return (set_error(lbh, BE_ERR_MOUNTED));
54336668Skevans
55336668Skevans	mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
56336668Skevans
57336668Skevans	/* Create mountpoint if it is not specified */
58336668Skevans	if (mountpoint == NULL) {
59336668Skevans		strcpy(mnt_temp, "/tmp/be_mount.XXXX");
60336701Skevans		if (mkdtemp(mnt_temp) == NULL)
61336701Skevans			/* XXX TODO: create error for this */
62336668Skevans			return (set_error(lbh, BE_ERR_UNKNOWN));
63336668Skevans	}
64336668Skevans
65336668Skevans	char opt = '\0';
66336668Skevans	if (err = zmount(be, (mountpoint == NULL) ? mnt_temp : mountpoint,
67336701Skevans	    mntflags, MNTTYPE_ZFS, NULL, 0, &opt, 1))
68336701Skevans		/*
69336701Skevans		 * XXX TODO: zmount returns the nmount error, look into what
70336701Skevans		 * kind of errors we can report from that
71336701Skevans		 */
72336668Skevans		return (set_error(lbh, BE_ERR_UNKNOWN));
73336668Skevans
74336701Skevans	if (result_loc != NULL)
75336668Skevans		strcpy(result_loc, mountpoint == NULL ? mnt_temp : mountpoint);
76336668Skevans
77336668Skevans	return (BE_ERR_SUCCESS);
78336668Skevans}
79336668Skevans
80336668Skevans
81336668Skevans/*
82336668Skevans * usage
83336668Skevans */
84336668Skevansint
85336668Skevansbe_unmount(libbe_handle_t *lbh, char *bootenv, int flags)
86336668Skevans{
87336668Skevans	int err, mntflags;
88336668Skevans	char be[BE_MAXPATHLEN];
89336668Skevans	struct statfs *mntbuf;
90336668Skevans	int mntsize;
91336668Skevans	char *mntpath;
92336668Skevans
93336701Skevans	if (err = be_root_concat(lbh, bootenv, be))
94336668Skevans		return (set_error(lbh, err));
95336668Skevans
96336701Skevans	if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
97336701Skevans		/* XXX TODO correct error */
98336668Skevans		return (set_error(lbh, BE_ERR_NOMOUNT));
99336668Skevans
100336668Skevans	mntpath = NULL;
101336668Skevans	for (int i = 0; i < mntsize; ++i) {
102336668Skevans		/* 0x000000de is the type number of zfs */
103336701Skevans		if (mntbuf[i].f_type != 0x000000de)
104336668Skevans			continue;
105336668Skevans
106336668Skevans		if (strcmp(mntbuf[i].f_mntfromname, be) == 0) {
107336668Skevans			mntpath = mntbuf[i].f_mntonname;
108336668Skevans			break;
109336668Skevans		}
110336668Skevans	}
111336668Skevans
112336701Skevans	if (mntpath == NULL)
113336668Skevans		return (set_error(lbh, BE_ERR_NOMOUNT));
114336668Skevans
115336668Skevans	mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
116336668Skevans
117336701Skevans	if (err = unmount(mntpath, mntflags))
118336701Skevans		/* XXX TODO correct error */
119336668Skevans		return (set_error(lbh, BE_ERR_NOMOUNT));
120336668Skevans
121336668Skevans	return (set_error(lbh, BE_ERR_SUCCESS));
122336668Skevans}
123