Remove zvol.c when updating in update-zfs.sh Linux version available.
[zfs.git] / lib / libzfs / libzfs_mount.c
index 7c5c7f3..7810e5d 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -74,7 +74,6 @@
 #include <unistd.h>
 #include <zone.h>
 #include <sys/mntent.h>
-#include <sys/mnttab.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
 
@@ -236,18 +235,9 @@ dir_is_empty(const char *dirname)
 boolean_t
 is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where)
 {
-       struct mnttab search = { 0 }, entry;
-
-       /*
-        * Search for the entry in /etc/mnttab.  We don't bother getting the
-        * mountpoint, as we can just search for the special device.  This will
-        * also let us find mounts when the mountpoint is 'legacy'.
-        */
-       search.mnt_special = (char *)special;
-       search.mnt_fstype = MNTTYPE_ZFS;
+       struct mnttab entry;
 
-       rewind(zfs_hdl->libzfs_mnttab);
-       if (getmntany(zfs_hdl->libzfs_mnttab, &entry, &search) != 0)
+       if (libzfs_mnttab_find(zfs_hdl, special, &entry) != 0)
                return (B_FALSE);
 
        if (where != NULL)
@@ -358,12 +348,14 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
                } else {
                        zfs_error_aux(hdl, strerror(errno));
                }
-
                return (zfs_error_fmt(hdl, EZFS_MOUNTFAILED,
                    dgettext(TEXT_DOMAIN, "cannot mount '%s'"),
                    zhp->zfs_name));
        }
 
+       /* add the mounted entry into our cache */
+       libzfs_mnttab_add(hdl, zfs_get_name(zhp), mountpoint,
+           mntopts);
        return (0);
 }
 
@@ -389,26 +381,23 @@ unmount_one(libzfs_handle_t *hdl, const char *mountpoint, int flags)
 int
 zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
 {
-       struct mnttab search = { 0 }, entry;
+       libzfs_handle_t *hdl = zhp->zfs_hdl;
+       struct mnttab entry;
        char *mntpt = NULL;
 
-       /* check to see if need to unmount the filesystem */
-       search.mnt_special = zhp->zfs_name;
-       search.mnt_fstype = MNTTYPE_ZFS;
-       rewind(zhp->zfs_hdl->libzfs_mnttab);
+       /* check to see if we need to unmount the filesystem */
        if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
-           getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry, &search) == 0)) {
-
+           libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0)) {
                /*
                 * mountpoint may have come from a call to
                 * getmnt/getmntany if it isn't NULL. If it is NULL,
-                * we know it comes from getmntany which can then get
-                * overwritten later. We strdup it to play it safe.
+                * we know it comes from libzfs_mnttab_find which can
+                * then get freed later. We strdup it to play it safe.
                 */
                if (mountpoint == NULL)
-                       mntpt = zfs_strdup(zhp->zfs_hdl, entry.mnt_mountp);
+                       mntpt = zfs_strdup(hdl, entry.mnt_mountp);
                else
-                       mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint);
+                       mntpt = zfs_strdup(hdl, mountpoint);
 
                /*
                 * Unshare and unmount the filesystem
@@ -416,11 +405,12 @@ zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
                if (zfs_unshare_proto(zhp, mntpt, share_all_proto) != 0)
                        return (-1);
 
-               if (unmount_one(zhp->zfs_hdl, mntpt, flags) != 0) {
+               if (unmount_one(hdl, mntpt, flags) != 0) {
                        free(mntpt);
                        (void) zfs_shareall(zhp);
                        return (-1);
                }
+               libzfs_mnttab_remove(hdl, zhp->zfs_name);
                free(mntpt);
        }
 
@@ -849,7 +839,7 @@ unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
        char *mntpt;
        /*
         * Mountpoint could get trashed if libshare calls getmntany
-        * which id does during API initialization, so strdup the
+        * which it does during API initialization, so strdup the
         * value.
         */
        mntpt = zfs_strdup(hdl, mountpoint);
@@ -887,18 +877,17 @@ int
 zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint,
     zfs_share_proto_t *proto)
 {
-       struct mnttab search = { 0 }, entry;
+       libzfs_handle_t *hdl = zhp->zfs_hdl;
+       struct mnttab entry;
        char *mntpt = NULL;
 
        /* check to see if need to unmount the filesystem */
-       search.mnt_special = (char *)zfs_get_name(zhp);
-       search.mnt_fstype = MNTTYPE_ZFS;
        rewind(zhp->zfs_hdl->libzfs_mnttab);
        if (mountpoint != NULL)
-               mntpt = zfs_strdup(zhp->zfs_hdl, mountpoint);
+               mountpoint = mntpt = zfs_strdup(hdl, mountpoint);
 
        if (mountpoint != NULL || ((zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) &&
-           getmntany(zhp->zfs_hdl->libzfs_mnttab, &entry, &search) == 0)) {
+           libzfs_mnttab_find(hdl, zfs_get_name(zhp), &entry) == 0)) {
                zfs_share_proto_t *curr_proto;
 
                if (mountpoint == NULL)
@@ -907,8 +896,8 @@ zfs_unshare_proto(zfs_handle_t *zhp, const char *mountpoint,
                for (curr_proto = proto; *curr_proto != PROTO_END;
                    curr_proto++) {
 
-                       if (is_shared(zhp->zfs_hdl, mntpt, *curr_proto) &&
-                           unshare_one(zhp->zfs_hdl, zhp->zfs_name,
+                       if (is_shared(hdl, mntpt, *curr_proto) &&
+                           unshare_one(hdl, zhp->zfs_name,
                            mntpt, *curr_proto) != 0) {
                                if (mntpt != NULL)
                                        free(mntpt);
@@ -1191,10 +1180,12 @@ zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
 
        /*
         * And mount all the datasets, keeping track of which ones
-        * succeeded or failed. By using zfs_alloc(), the good pointer
-        * will always be non-NULL.
+        * succeeded or failed.
         */
-       good = zfs_alloc(zhp->zpool_hdl, cb.cb_used * sizeof (int));
+       if ((good = zfs_alloc(zhp->zpool_hdl,
+           cb.cb_used * sizeof (int))) == NULL)
+               goto out;
+
        ret = 0;
        for (i = 0; i < cb.cb_used; i++) {
                if (zfs_mount(cb.cb_datasets[i], mntopts, flags) != 0)