static char *
get_zfs_dataset(sa_handle_impl_t impl_handle, char *path,
    boolean_t search_mnttab)
{
	size_t i, count = 0;
	char *dataset = NULL;
	zfs_handle_t **zlist;
	char mountpoint[ZFS_MAXPROPLEN];
	char canmount[ZFS_MAXPROPLEN];

	get_all_filesystems(impl_handle, &zlist, &count);
	qsort(zlist, count, sizeof (void *), mountpoint_compare);
	for (i = 0; i < count; i++) {
		/* must have a mountpoint */
		if (zfs_prop_get(zlist[i], ZFS_PROP_MOUNTPOINT, mountpoint,
		    sizeof (mountpoint), NULL, NULL, 0, B_FALSE) != 0) {
			/* no mountpoint */
			continue;
		}

		/* mountpoint must be a path */
		if (strcmp(mountpoint, ZFS_MOUNTPOINT_NONE) == 0 ||
		    strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) == 0) {
			/*
			 * Search mmttab for mountpoint and get dataset.
			 */

			if (search_mnttab == B_TRUE &&
			    get_legacy_mountpoint(path, mountpoint,
			    sizeof (mountpoint), NULL, 0) == 0) {
				dataset = mountpoint;
				break;
			}
			continue;
		}

		/* canmount must be set */
		canmount[0] = '\0';
		if (zfs_prop_get(zlist[i], ZFS_PROP_CANMOUNT, canmount,
		    sizeof (canmount), NULL, NULL, 0, B_FALSE) != 0 ||
		    strcmp(canmount, "off") == 0)
			continue;

		/*
		 * have a mountable handle but want to skip those marked none
		 * and legacy
		 */
		if (strcmp(mountpoint, path) == 0) {
			dataset = (char *)zfs_get_name(zlist[i]);
			break;
		}

	}

	if (dataset != NULL)
		dataset = strdup(dataset);

	return (dataset);
}
Exemple #2
0
static char *
get_zfs_dataset(sa_handle_impl_t impl_handle, char *path,
    boolean_t search_mnttab)
{
	size_t i, count = 0;
	zfs_handle_t **zlist;
	char *cutpath;
	zfs_handle_t *handle_from_path;
	char *ret = NULL;

	/*
	 * First we optimistically assume that the mount path for the filesystem
	 * is the same as the name of the filesystem (minus some number of
	 * leading slashes). If this is true, then zfs_open should properly open
	 * the filesystem. We duplicate the error checking done later in the
	 * function for consistency. If anything fails, we resort to the
	 * (extremely slow) search of all the filesystems.
	 */
	cutpath = path + strspn(path, "/");

	assert(impl_handle->zfs_libhandle != NULL);
	if ((handle_from_path = zfs_open(impl_handle->zfs_libhandle, cutpath,
	    ZFS_TYPE_FILESYSTEM)) != NULL)
		if ((ret = verify_zfs_handle(handle_from_path, path,
		    search_mnttab)) != NULL)
			return (ret);
	/*
	 * Couldn't find a filesystem optimistically, check all the handles we
	 * can.
	 */
	get_all_filesystems(impl_handle, &zlist, &count);
	for (i = 0; i < count; i++) {
		assert(zlist[i]);
		if ((ret = verify_zfs_handle(zlist[i], path,
		    search_mnttab)) != NULL)
			return (ret);
	}

	/* Couldn't find a matching dataset */
	return (NULL);
}
int
main(void)
{
    int i, state = 0, ret;
    int (*states[])() = {
        partition_menu,
        filesystem,
        mountpoint,
        mountpoint_manual,
        fixup, // never does an INPUT, just handles the manual mountpoint result
        NULL
    };

    /* FIXME: How can we tell which file system modules to load?  */
    char *file_system_modules[] = {"ext2", "ext3", "reiserfs", "jfs", "xfs", NULL};

    debconf = debconfclient_new();
    debconf_capb(debconf, "backup");
    ped_exception_set_handler(my_exception_handler);

    for (i = 0; file_system_modules[i]; i++)
	modprobe(file_system_modules[i]);

    if (check_proc_mounts("")) {
        // Chicken out if /target is already mounted
        debconf_set(debconf,"partconf/already-mounted", "no");
        debconf_input(debconf, "critical", "partconf/already-mounted");
        debconf_go(debconf);
        debconf_get(debconf,"partconf/already-mounted");
        if (strcmp(debconf->value, "false") == 0)
            return 0;
    }
    if (!umount_target()) {
        debconf_input(debconf, "critical", "partconf/umount-failed");
        debconf_go(debconf);
        return 1;
    }
    if ((part_count = get_all_partitions(parts, MAX_PARTS, false, 0)) <= 0) {
        debconf_input(debconf, "critical", "partconf/no-partitions");
        debconf_go(debconf);
        return 1;
    }
    if (get_all_filesystems() <= 0) {
        debconf_input(debconf, "critical", "partconf/no-filesystems");
        debconf_go(debconf);
        return 1;
    }
    fschoices = build_fs_choices();
    while (state >= 0) {
        ret = states[state]();
        if (ret < 0)
	    return 10;
        else if (ret == 0 && debconf_go(debconf) == 0)
            state++;
        else
            state--;
        if (states[state] == NULL)
            state = 0;
    }
    return ret;
}
int
sa_get_zfs_shares(sa_handle_t handle, char *groupname)
{
	sa_group_t zfsgroup;
	boolean_t nfs;
	boolean_t nfs_inherited;
	boolean_t smb;
	boolean_t smb_inherited;
	zfs_handle_t **zlist;
	char nfsshareopts[ZFS_MAXPROPLEN];
	char smbshareopts[ZFS_MAXPROPLEN];
	sa_share_t share;
	zprop_source_t source;
	char nfssourcestr[ZFS_MAXPROPLEN];
	char smbsourcestr[ZFS_MAXPROPLEN];
	char mountpoint[ZFS_MAXPROPLEN];
	size_t count = 0, i;
	libzfs_handle_t *zfs_libhandle;
	int err = SA_OK;

	/*
	 * If we can't access libzfs, don't bother doing anything.
	 */
	zfs_libhandle = ((sa_handle_impl_t)handle)->zfs_libhandle;
	if (zfs_libhandle == NULL)
		return (SA_SYSTEM_ERR);

	zfsgroup = find_or_create_group(handle, groupname, NULL, &err);
	/* Not an error, this could be a legacy condition */
	if (zfsgroup == NULL)
		return (SA_OK);

	/*
	 * need to walk the mounted ZFS pools and datasets to
	 * find shares that are possible.
	 */
	get_all_filesystems((sa_handle_impl_t)handle, &zlist, &count);
	qsort(zlist, count, sizeof (void *), mountpoint_compare);

	for (i = 0; i < count; i++) {
		char *dataset;

		source = ZPROP_SRC_ALL;
		/* If no mountpoint, skip. */
		if (zfs_prop_get(zlist[i], ZFS_PROP_MOUNTPOINT,
		    mountpoint, sizeof (mountpoint), NULL, NULL, 0,
		    B_FALSE) != 0)
			continue;

		/*
		 * zfs_get_name value must not be freed. It is just a
		 * pointer to a value in the handle.
		 */
		if ((dataset = (char *)zfs_get_name(zlist[i])) == NULL)
			continue;

		/*
		 * only deal with "mounted" file systems since
		 * unmounted file systems can't actually be shared.
		 */

		if (!zfs_is_mounted(zlist[i], NULL))
			continue;

		nfs = nfs_inherited = B_FALSE;

		if (zfs_prop_get(zlist[i], ZFS_PROP_SHARENFS, nfsshareopts,
		    sizeof (nfsshareopts), &source, nfssourcestr,
		    ZFS_MAXPROPLEN, B_FALSE) == 0 &&
		    strcmp(nfsshareopts, "off") != 0) {
			if (source & ZPROP_SRC_INHERITED)
				nfs_inherited = B_TRUE;
			else
				nfs = B_TRUE;
		}

		smb = smb_inherited = B_FALSE;
		if (zfs_prop_get(zlist[i], ZFS_PROP_SHARESMB, smbshareopts,
		    sizeof (smbshareopts), &source, smbsourcestr,
		    ZFS_MAXPROPLEN, B_FALSE) == 0 &&
		    strcmp(smbshareopts, "off") != 0) {
			if (source & ZPROP_SRC_INHERITED)
				smb_inherited = B_TRUE;
			else
				smb = B_TRUE;
		}

		/*
		 * If the mountpoint is already shared, it must be a
		 * non-ZFS share. We want to remove the share from its
		 * parent group and reshare it under ZFS.
		 */
		share = sa_find_share(handle, mountpoint);
		if (share != NULL &&
		    (nfs || smb || nfs_inherited || smb_inherited)) {
			err = sa_remove_share(share);
			share = NULL;
		}

		/*
		 * At this point, we have the information needed to
		 * determine what to do with the share.
		 *
		 * If smb or nfs is set, we have a new sub-group.
		 * If smb_inherit and/or nfs_inherit is set, then
		 * place on an existing sub-group. If both are set,
		 * the existing sub-group is the closest up the tree.
		 */
		if (nfs || smb) {
			/*
			 * Non-inherited is the straightforward
			 * case. sa_zfs_process_share handles it
			 * directly. Make sure that if the "other"
			 * protocol is inherited, that we treat it as
			 * non-inherited as well.
			 */
			if (nfs || nfs_inherited) {
				err = sa_zfs_process_share(handle, zfsgroup,
				    share, mountpoint, "nfs",
				    0, nfsshareopts,
				    nfssourcestr, dataset);
				share = sa_find_share(handle, mountpoint);
			}
			if (smb || smb_inherited) {
				err = sa_zfs_process_share(handle, zfsgroup,
				    share, mountpoint, "smb",
				    0, smbshareopts,
				    smbsourcestr, dataset);
			}
		} else if (nfs_inherited || smb_inherited) {
			char *grpdataset;
			/*
			 * If we only have inherited groups, it is
			 * important to find the closer of the two if
			 * the protocols are set at different
			 * levels. The closest sub-group is the one we
			 * want to work with.
			 */
			if (nfs_inherited && smb_inherited) {
				if (strcmp(nfssourcestr, smbsourcestr) <= 0)
					grpdataset = nfssourcestr;
				else
					grpdataset = smbsourcestr;
			} else if (nfs_inherited) {
				grpdataset = nfssourcestr;
			} else if (smb_inherited) {
				grpdataset = smbsourcestr;
			}
			if (nfs_inherited) {
				err = sa_zfs_process_share(handle, zfsgroup,
				    share, mountpoint, "nfs",
				    ZPROP_SRC_INHERITED, nfsshareopts,
				    grpdataset, dataset);
				share = sa_find_share(handle, mountpoint);
			}
			if (smb_inherited) {
				err = sa_zfs_process_share(handle, zfsgroup,
				    share, mountpoint, "smb",
				    ZPROP_SRC_INHERITED, smbshareopts,
				    grpdataset, dataset);
			}
		}
	}
	/*
	 * Don't need to free the "zlist" variable since it is only a
	 * pointer to a cached value that will be freed when
	 * sa_fini() is called.
	 */
	return (err);
}