From f1ca70d3e1d320fe687348e8a8394b1ea571f279 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Tue, 7 Aug 2018 03:25:28 +0000 Subject: [PATCH] libbe(3): Return some more proper error codes --- lib/libbe/be.h | 3 +++ lib/libbe/be_access.c | 50 ++++++++++++++++++++++++++++++++----------- lib/libbe/libbe.3 | 5 ++++- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/lib/libbe/be.h b/lib/libbe/be.h index a4d0f3954406..dea934af1dad 100644 --- a/lib/libbe/be.h +++ b/lib/libbe/be.h @@ -44,6 +44,8 @@ typedef enum be_error { BE_ERR_PERMS, /* insufficient permissions */ BE_ERR_DESTROYACT, /* cannot destroy active boot env */ BE_ERR_DESTROYMNT, /* destroying a mounted be requires force */ + BE_ERR_BADPATH, /* path not suitable for operation */ + BE_ERR_PATHBUSY, /* requested path is busy */ BE_ERR_PATHLEN, /* provided name exceeds maximum length limit */ BE_ERR_INVORIGIN, /* snapshot origin's mountpoint is not '/' */ BE_ERR_NOORIGIN, /* could not open snapshot's origin */ @@ -51,6 +53,7 @@ typedef enum be_error { BE_ERR_NOMOUNT, /* boot environment is not mounted */ BE_ERR_ZFSOPEN, /* calling zfs_open() failed */ BE_ERR_ZFSCLONE, /* error when calling zfs_clone to create be */ + BE_ERR_IO, /* error when doing some I/O operation */ BE_ERR_UNKNOWN, /* unknown error */ } be_error_t; diff --git a/lib/libbe/be_access.c b/lib/libbe/be_access.c index 55481e04e14b..c0acac215eb7 100644 --- a/lib/libbe/be_access.c +++ b/lib/libbe/be_access.c @@ -121,18 +121,27 @@ be_mount(libbe_handle_t *lbh, char *bootenv, char *mountpoint, int flags, if (mountpoint == NULL) { strcpy(mnt_temp, "/tmp/be_mount.XXXX"); if (mkdtemp(mnt_temp) == NULL) - /* XXX TODO: create error for this */ - return (set_error(lbh, BE_ERR_UNKNOWN)); + return (set_error(lbh, BE_ERR_IO)); } char opt = '\0'; if ((err = zmount(be, (mountpoint == NULL) ? mnt_temp : mountpoint, - mntflags, __DECONST(char *, MNTTYPE_ZFS), NULL, 0, &opt, 1)) != 0) - /* - * XXX TODO: zmount returns the nmount error, look into what - * kind of errors we can report from that - */ - return (set_error(lbh, BE_ERR_UNKNOWN)); + mntflags, __DECONST(char *, MNTTYPE_ZFS), NULL, 0, &opt, 1)) != 0) { + switch (errno) { + case ENAMETOOLONG: + return (set_error(lbh, BE_ERR_PATHLEN)); + case ELOOP: + case ENOENT: + case ENOTDIR: + return (set_error(lbh, BE_ERR_BADPATH)); + case EPERM: + return (set_error(lbh, BE_ERR_PERMS)); + case EBUSY: + return (set_error(lbh, BE_ERR_PATHBUSY)); + default: + return (set_error(lbh, BE_ERR_UNKNOWN)); + } + } if (result_loc != NULL) strcpy(result_loc, mountpoint == NULL ? mnt_temp : mountpoint); @@ -156,9 +165,11 @@ be_unmount(libbe_handle_t *lbh, char *bootenv, int flags) if ((err = be_root_concat(lbh, bootenv, be)) != 0) return (set_error(lbh, err)); - if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) - /* XXX TODO correct error */ + if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { + if (errno == EIO) + return (set_error(lbh, BE_ERR_IO)); return (set_error(lbh, BE_ERR_NOMOUNT)); + } mntpath = NULL; for (int i = 0; i < mntsize; ++i) { @@ -177,9 +188,22 @@ be_unmount(libbe_handle_t *lbh, char *bootenv, int flags) mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0; - if ((err = unmount(mntpath, mntflags)) != 0) - /* XXX TODO correct error */ - return (set_error(lbh, BE_ERR_NOMOUNT)); + if ((err = unmount(mntpath, mntflags)) != 0) { + switch (errno) { + case ENAMETOOLONG: + return (set_error(lbh, BE_ERR_PATHLEN)); + case ELOOP: + case ENOENT: + case ENOTDIR: + return (set_error(lbh, BE_ERR_BADPATH)); + case EPERM: + return (set_error(lbh, BE_ERR_PERMS)); + case EBUSY: + return (set_error(lbh, BE_ERR_PATHBUSY)); + default: + return (set_error(lbh, BE_ERR_UNKNOWN)); + } + } return (set_error(lbh, BE_ERR_SUCCESS)); } diff --git a/lib/libbe/libbe.3 b/lib/libbe/libbe.3 index b6cf5a460112..be026a30e754 100644 --- a/lib/libbe/libbe.3 +++ b/lib/libbe/libbe.3 @@ -30,7 +30,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 25, 2018 +.Dd August 6, 2018 .Dt LIBBE 3 .Os .Sh NAME @@ -190,6 +190,8 @@ BE_ERR_NOENT, BE_ERR_PERMS, BE_ERR_DESTROYACT, BE_ERR_DESTROYMNT, +BE_ERR_BADPATH, +BE_ERR_PATHBUSY, BE_ERR_PATHLEN, BE_ERR_INVORIGIN, BE_ERR_NOORIGIN, @@ -197,6 +199,7 @@ BE_ERR_MOUNTED, BE_ERR_NOMOUNT, BE_ERR_ZFSOPEN, BE_ERR_ZFSCLONE, +BE_ERR_IO, BE_ERR_UNKNOWN .Ed .Sh SEE ALSO