Beispiel #1
0
/*
 * Share the given filesystem according to the options in the specified
 * protocol specific properties (sharenfs, sharesmb).  We rely
 * on "libshare" to the dirty work for us.
 */
static int
zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
{
    char mountpoint[ZFS_MAXPROPLEN];
    char shareopts[ZFS_MAXPROPLEN];
    char sourcestr[ZFS_MAXPROPLEN];
    libzfs_handle_t *hdl = zhp->zfs_hdl;
    sa_share_t share;
    zfs_share_proto_t *curr_proto;
    zprop_source_t sourcetype;
    int ret;

    if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
        return (0);

    if ((ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
        (void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
                             dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
                             zfs_get_name(zhp), _sa_errorstr != NULL ?
                             _sa_errorstr(ret) : "");
        return (-1);
    }

    for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
        /*
         * Return success if there are no share options.
         */
        if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
                         shareopts, sizeof (shareopts), &sourcetype, sourcestr,
                         ZFS_MAXPROPLEN, B_FALSE) != 0 ||
                strcmp(shareopts, "off") == 0)
            continue;

        /*
         * If the 'zoned' property is set, then zfs_is_mountable()
         * will have already bailed out if we are in the global zone.
         * But local zones cannot be NFS servers, so we ignore it for
         * local zones as well.
         */
        if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
            continue;

        share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
        if (share == NULL) {
            /*
             * This may be a new file system that was just
             * created so isn't in the internal cache
             * (second time through). Rather than
             * reloading the entire configuration, we can
             * assume ZFS has done the checking and it is
             * safe to add this to the internal
             * configuration.
             */
            if (_sa_zfs_process_share(hdl->libzfs_sharehdl,
                                      NULL, NULL, mountpoint,
                                      proto_table[*curr_proto].p_name, sourcetype,
                                      shareopts, sourcestr, zhp->zfs_name) != SA_OK) {
                (void) zfs_error_fmt(hdl,
                                     proto_table[*curr_proto].p_share_err,
                                     dgettext(TEXT_DOMAIN, "cannot share '%s'"),
                                     zfs_get_name(zhp));
                return (-1);
            }
            hdl->libzfs_shareflags |= ZFSSHARE_MISS;
            share = zfs_sa_find_share(hdl->libzfs_sharehdl,
                                      mountpoint);
        }
        if (share != NULL) {
            int err;
            err = zfs_sa_enable_share(share,
                                      proto_table[*curr_proto].p_name);
            if (err != SA_OK) {
                (void) zfs_error_fmt(hdl,
                                     proto_table[*curr_proto].p_share_err,
                                     dgettext(TEXT_DOMAIN, "cannot share '%s'"),
                                     zfs_get_name(zhp));
                return (-1);
            }
        } else {
            (void) zfs_error_fmt(hdl,
                                 proto_table[*curr_proto].p_share_err,
                                 dgettext(TEXT_DOMAIN, "cannot share '%s'"),
                                 zfs_get_name(zhp));
            return (-1);
        }

    }
    return (0);
}
Beispiel #2
0
/*
 * Share the given filesystem according to the options in the specified
 * protocol specific properties (sharenfs, sharesmb).  We rely
 * on "libshare" to the dirty work for us.
 */
static int
zfs_share_proto(zfs_handle_t *zhp, zfs_share_proto_t *proto)
{
	char mountpoint[ZFS_MAXPROPLEN];
	char shareopts[ZFS_MAXPROPLEN];
	char sourcestr[ZFS_MAXPROPLEN];
#if defined(HAVE_ZPL)
	libzfs_handle_t *hdl = zhp->zfs_hdl;
	sa_share_t share;
#endif
	zfs_share_proto_t *curr_proto;
	zprop_source_t sourcetype;
#if defined(HAVE_ZPL)
	int ret;
#endif

	if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL))
		return (0);

#if defined(HAVE_ZPL)
	if ((ret = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
		(void) zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
		    dgettext(TEXT_DOMAIN, "cannot share '%s': %s"),
		    zfs_get_name(zhp), _sa_errorstr != NULL ?
		    _sa_errorstr(ret) : "");
		return (-1);
	}
#endif

	for (curr_proto = proto; *curr_proto != PROTO_END; curr_proto++) {
		/*
		 * Return success if there are no share options.
		 */
		if (zfs_prop_get(zhp, proto_table[*curr_proto].p_prop,
		    shareopts, sizeof (shareopts), &sourcetype, sourcestr,
		    ZFS_MAXPROPLEN, B_FALSE) != 0 ||
		    strcmp(shareopts, "off") == 0)
			continue;

		/*
		 * If the 'zoned' property is set, then zfs_is_mountable()
		 * will have already bailed out if we are in the global zone.
		 * But local zones cannot be NFS servers, so we ignore it for
		 * local zones as well.
		 */
		if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED))
			continue;
#if !defined(HAVE_ZPL)
       if (*curr_proto == PROTO_NFS) {
           int pid;
           int rc;
           if ((pid = fork()) < 0) {
               fprintf(stderr, "cannot share '%s'", zfs_get_name(zhp));
               return -1;
           } else if (pid == 0) {
               /* child process */
               /* exec exportfs */
               char export_string[PATH_MAX];
               char options[100];
               char *argv [] = {
                   "exportfs",
                   "-v",
                   "-i",
                   export_string,
                   "-o",
                   options,
                   NULL
               };
               struct statfs buf;
               int fsid_arr[2];
               uint64_t fsid;

               if (statfs(mountpoint, &buf) < 0)
                   return -1;

               memcpy((void *)fsid_arr, (void *) &buf.f_fsid, sizeof(int) * 2);
               fsid = fsid_arr[0];
               fsid |= (((uint64_t)fsid_arr[1]) << 32);
//               fprintf(stderr, "using fsid=%lu\n", fsid);

               sprintf(export_string, "*:%s", mountpoint);
               sprintf(options, "rw,sync,fsid=%lu", fsid);
               execvp("exportfs", argv);
               return -1;
           }
           /* parent process */
           if (waitpid(pid, &rc, WUNTRACED) != pid) {
               fprintf(stderr, "cannot share '%s'", zfs_get_name(zhp));
               return -1;
           }

           if (!WIFEXITED(rc) || WEXITSTATUS(rc) != 0) {
               fprintf(stderr, "cannot share '%s'", zfs_get_name(zhp));
               return -1;
           }
       }
#else
		share = zfs_sa_find_share(hdl->libzfs_sharehdl, mountpoint);
		if (share == NULL) {
			/*
			 * This may be a new file system that was just
			 * created so isn't in the internal cache
			 * (second time through). Rather than
			 * reloading the entire configuration, we can
			 * assume ZFS has done the checking and it is
			 * safe to add this to the internal
			 * configuration.
			 */
			if (_sa_zfs_process_share(hdl->libzfs_sharehdl,
			    NULL, NULL, mountpoint,
			    proto_table[*curr_proto].p_name, sourcetype,
			    shareopts, sourcestr, zhp->zfs_name) != SA_OK) {
				(void) zfs_error_fmt(hdl,
				    proto_table[*curr_proto].p_share_err,
				    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
				    zfs_get_name(zhp));
				return (-1);
			}
			hdl->libzfs_shareflags |= ZFSSHARE_MISS;
			share = zfs_sa_find_share(hdl->libzfs_sharehdl,
			    mountpoint);
		}
		if (share != NULL) {
			int err;
			err = zfs_sa_enable_share(share,
			    proto_table[*curr_proto].p_name);
			if (err != SA_OK) {
				(void) zfs_error_fmt(hdl,
				    proto_table[*curr_proto].p_share_err,
				    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
				    zfs_get_name(zhp));
				return (-1);
			}
		} else {
			(void) zfs_error_fmt(hdl,
			    proto_table[*curr_proto].p_share_err,
			    dgettext(TEXT_DOMAIN, "cannot share '%s'"),
			    zfs_get_name(zhp));
			return (-1);
		}
#endif
	}
	return (0);
}