be_access.c revision 336701
1/*
2 * be_access.c
3 *
4 * Copyright (c) 2017 Kyle J. Kneitinger <kyle@kneit.in>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include "be.h"
30#include "be_impl.h"
31
32/*
33 * usage
34 */
35int
36be_mount(libbe_handle_t *lbh, char *bootenv, char *mountpoint, int flags,
37    char *result_loc)
38{
39	char be[BE_MAXPATHLEN];
40	char mnt_temp[BE_MAXPATHLEN];
41	zfs_handle_t *zfs_hdl;
42	char *path;
43	int mntflags;
44	int err;
45
46	if (err = be_root_concat(lbh, bootenv, be))
47		return (set_error(lbh, err));
48
49	if (!be_exists(lbh, bootenv))
50		return (set_error(lbh, BE_ERR_NOENT));
51
52	if (is_mounted(lbh->lzh, be, &path))
53		return (set_error(lbh, BE_ERR_MOUNTED));
54
55	mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
56
57	/* Create mountpoint if it is not specified */
58	if (mountpoint == NULL) {
59		strcpy(mnt_temp, "/tmp/be_mount.XXXX");
60		if (mkdtemp(mnt_temp) == NULL)
61			/* XXX TODO: create error for this */
62			return (set_error(lbh, BE_ERR_UNKNOWN));
63	}
64
65	char opt = '\0';
66	if (err = zmount(be, (mountpoint == NULL) ? mnt_temp : mountpoint,
67	    mntflags, MNTTYPE_ZFS, NULL, 0, &opt, 1))
68		/*
69		 * XXX TODO: zmount returns the nmount error, look into what
70		 * kind of errors we can report from that
71		 */
72		return (set_error(lbh, BE_ERR_UNKNOWN));
73
74	if (result_loc != NULL)
75		strcpy(result_loc, mountpoint == NULL ? mnt_temp : mountpoint);
76
77	return (BE_ERR_SUCCESS);
78}
79
80
81/*
82 * usage
83 */
84int
85be_unmount(libbe_handle_t *lbh, char *bootenv, int flags)
86{
87	int err, mntflags;
88	char be[BE_MAXPATHLEN];
89	struct statfs *mntbuf;
90	int mntsize;
91	char *mntpath;
92
93	if (err = be_root_concat(lbh, bootenv, be))
94		return (set_error(lbh, err));
95
96	if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0)
97		/* XXX TODO correct error */
98		return (set_error(lbh, BE_ERR_NOMOUNT));
99
100	mntpath = NULL;
101	for (int i = 0; i < mntsize; ++i) {
102		/* 0x000000de is the type number of zfs */
103		if (mntbuf[i].f_type != 0x000000de)
104			continue;
105
106		if (strcmp(mntbuf[i].f_mntfromname, be) == 0) {
107			mntpath = mntbuf[i].f_mntonname;
108			break;
109		}
110	}
111
112	if (mntpath == NULL)
113		return (set_error(lbh, BE_ERR_NOMOUNT));
114
115	mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
116
117	if (err = unmount(mntpath, mntflags))
118		/* XXX TODO correct error */
119		return (set_error(lbh, BE_ERR_NOMOUNT));
120
121	return (set_error(lbh, BE_ERR_SUCCESS));
122}
123