Autoconf selinux support
[zfs.git] / lib / libzfs / libzfs_mount.c
index 0675ec2..9950bf9 100644 (file)
@@ -72,6 +72,9 @@
 #include <sys/mntent.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
+#ifdef HAVE_LIBSELINUX
+#include <selinux/selinux.h>
+#endif /* HAVE_LIBSELINUX */
 
 #include <libzfs.h>
 
@@ -81,6 +84,7 @@
 #include <sys/systeminfo.h>
 #define        MAXISALEN       257     /* based on sysinfo(2) man page */
 
+#ifdef HAVE_ZPL
 static int zfs_share_proto(zfs_handle_t *, zfs_share_proto_t *);
 zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **,
     zfs_share_proto_t);
@@ -270,6 +274,18 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags)
        else
                (void) strlcpy(mntopts, options, sizeof (mntopts));
 
+       /*
+        * If the pool is imported read-only then all mounts must be read-only
+        */
+       if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL))
+               flags |= MS_RDONLY;
+
+#ifdef HAVE_LIBSELINUX
+       if (is_selinux_enabled())
+               (void) strlcat(mntopts, ",context=\"system_u:"
+                   "object_r:file_t:s0\"", sizeof (mntopts));
+#endif /* HAVE_LIBSELINUX */
+
        if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
                return (0);
 
@@ -437,18 +453,14 @@ zfs_is_shared(zfs_handle_t *zhp)
 int
 zfs_share(zfs_handle_t *zhp)
 {
-       if (ZFS_IS_VOLUME(zhp))
-               return (0);
-
+       assert(!ZFS_IS_VOLUME(zhp));
        return (zfs_share_proto(zhp, share_all_proto));
 }
 
 int
 zfs_unshare(zfs_handle_t *zhp)
 {
-       if (ZFS_IS_VOLUME(zhp))
-               return (0);
-
+       assert(!ZFS_IS_VOLUME(zhp));
        return (zfs_unshareall(zhp));
 }
 
@@ -464,7 +476,7 @@ zfs_is_shared_proto(zfs_handle_t *zhp, char **where, zfs_share_proto_t proto)
        if (!zfs_is_mounted(zhp, &mountpoint))
                return (SHARED_NOT_SHARED);
 
-       if (rc = is_shared(zhp->zfs_hdl, mountpoint, proto)) {
+       if ((rc = is_shared(zhp->zfs_hdl, mountpoint, proto))) {
                if (where != NULL)
                        *where = mountpoint;
                else
@@ -516,8 +528,12 @@ static void (*_sa_update_sharetab_ts)(sa_handle_t);
  * values to be used later. This is triggered by the runtime loader.
  * Make sure the correct ISA version is loaded.
  */
-
+#ifdef __GNUC__
+static void
+_zfs_init_libshare(void) __attribute__((constructor));
+#else
 #pragma init(_zfs_init_libshare)
+#endif
 static void
 _zfs_init_libshare(void)
 {
@@ -979,18 +995,29 @@ remove_mountpoint(zfs_handle_t *zhp)
        }
 }
 
-typedef struct mount_cbdata {
-       zfs_handle_t    **cb_datasets;
-       int             cb_used;
-       int             cb_alloc;
-} mount_cbdata_t;
+void
+libzfs_add_handle(get_all_cb_t *cbp, zfs_handle_t *zhp)
+{
+       if (cbp->cb_alloc == cbp->cb_used) {
+               size_t newsz;
+               void *ptr;
+
+               newsz = cbp->cb_alloc ? cbp->cb_alloc * 2 : 64;
+               ptr = zfs_realloc(zhp->zfs_hdl,
+                   cbp->cb_handles, cbp->cb_alloc * sizeof (void *),
+                   newsz * sizeof (void *));
+               cbp->cb_handles = ptr;
+               cbp->cb_alloc = newsz;
+       }
+       cbp->cb_handles[cbp->cb_used++] = zhp;
+}
 
 static int
 mount_cb(zfs_handle_t *zhp, void *data)
 {
-       mount_cbdata_t *cbp = data;
+       get_all_cb_t *cbp = data;
 
-       if (!(zfs_get_type(zhp) & (ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME))) {
+       if (!(zfs_get_type(zhp) & ZFS_TYPE_FILESYSTEM)) {
                zfs_close(zhp);
                return (0);
        }
@@ -1000,25 +1027,16 @@ mount_cb(zfs_handle_t *zhp, void *data)
                return (0);
        }
 
-       if (cbp->cb_alloc == cbp->cb_used) {
-               void *ptr;
-
-               if ((ptr = zfs_realloc(zhp->zfs_hdl,
-                   cbp->cb_datasets, cbp->cb_alloc * sizeof (void *),
-                   cbp->cb_alloc * 2 * sizeof (void *))) == NULL)
-                       return (-1);
-               cbp->cb_datasets = ptr;
-
-               cbp->cb_alloc *= 2;
+       libzfs_add_handle(cbp, zhp);
+       if (zfs_iter_filesystems(zhp, mount_cb, cbp) != 0) {
+               zfs_close(zhp);
+               return (-1);
        }
-
-       cbp->cb_datasets[cbp->cb_used++] = zhp;
-
-       return (zfs_iter_filesystems(zhp, mount_cb, cbp));
+       return (0);
 }
 
-static int
-dataset_cmp(const void *a, const void *b)
+int
+libzfs_dataset_cmp(const void *a, const void *b)
 {
        zfs_handle_t **za = (zfs_handle_t **)a;
        zfs_handle_t **zb = (zfs_handle_t **)b;
@@ -1056,7 +1074,7 @@ dataset_cmp(const void *a, const void *b)
 int
 zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
 {
-       mount_cbdata_t cb = { 0 };
+       get_all_cb_t cb = { 0 };
        libzfs_handle_t *hdl = zhp->zpool_hdl;
        zfs_handle_t *zfsp;
        int i, ret = -1;
@@ -1065,23 +1083,17 @@ zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
        /*
         * Gather all non-snap datasets within the pool.
         */
-       if ((cb.cb_datasets = zfs_alloc(hdl, 4 * sizeof (void *))) == NULL)
-               return (-1);
-       cb.cb_alloc = 4;
-
        if ((zfsp = zfs_open(hdl, zhp->zpool_name, ZFS_TYPE_DATASET)) == NULL)
                goto out;
 
-       cb.cb_datasets[0] = zfsp;
-       cb.cb_used = 1;
-
+       libzfs_add_handle(&cb, zfsp);
        if (zfs_iter_filesystems(zfsp, mount_cb, &cb) != 0)
                goto out;
-
        /*
         * Sort the datasets by mountpoint.
         */
-       qsort(cb.cb_datasets, cb.cb_used, sizeof (void *), dataset_cmp);
+       qsort(cb.cb_handles, cb.cb_used, sizeof (void *),
+           libzfs_dataset_cmp);
 
        /*
         * And mount all the datasets, keeping track of which ones
@@ -1093,7 +1105,7 @@ zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
 
        ret = 0;
        for (i = 0; i < cb.cb_used; i++) {
-               if (zfs_mount(cb.cb_datasets[i], mntopts, flags) != 0)
+               if (zfs_mount(cb.cb_handles[i], mntopts, flags) != 0)
                        ret = -1;
                else
                        good[i] = 1;
@@ -1106,7 +1118,7 @@ zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
         * zfs_alloc is supposed to exit if memory isn't available.
         */
        for (i = 0; i < cb.cb_used; i++) {
-               if (good[i] && zfs_share(cb.cb_datasets[i]) != 0)
+               if (good[i] && zfs_share(cb.cb_handles[i]) != 0)
                        ret = -1;
        }
 
@@ -1114,8 +1126,8 @@ zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
 
 out:
        for (i = 0; i < cb.cb_used; i++)
-               zfs_close(cb.cb_datasets[i]);
-       free(cb.cb_datasets);
+               zfs_close(cb.cb_handles[i]);
+       free(cb.cb_handles);
 
        return (ret);
 }
@@ -1266,3 +1278,53 @@ out:
 
        return (ret);
 }
+
+#else  /* HAVE_ZPL */
+
+int
+zfs_unshare_iscsi(zfs_handle_t *zhp)
+{
+       return 0;
+}
+
+int
+zfs_unmount(zfs_handle_t *zhp, const char *mountpoint, int flags)
+{
+       return 0;
+}
+
+void
+remove_mountpoint(zfs_handle_t *zhp) {
+       return;
+}
+
+boolean_t
+is_mounted(libzfs_handle_t *zfs_hdl, const char *special, char **where)
+{
+       return B_FALSE;
+}
+
+boolean_t
+zfs_is_mounted(zfs_handle_t *zhp, char **where)
+{
+       return is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), where);
+}
+
+boolean_t
+zfs_is_shared(zfs_handle_t *zhp)
+{
+       return B_FALSE;
+}
+
+int
+zpool_enable_datasets(zpool_handle_t *zhp, const char *mntopts, int flags)
+{
+       return B_FALSE;
+}
+
+int
+zpool_disable_datasets(zpool_handle_t *zhp, boolean_t force)
+{
+       return B_FALSE;
+}
+#endif /* HAVE_ZPL */