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