.. versionadded:: 2018.3.3

    Verify that this mount is represented in the filesystems, change the mount
    to match the data passed, or add the mount if it is not present on AIX

        Provide information if the path is mounted

    :param name:          The name of the mount point where the device is mounted.
    :param device:        The device that is being mounted.
    :param vfstype:       The file system that is used (AIX has two fstypes, fstype and vfstype - similar to Linux fstype)
    :param opts:          Additional options used when mounting the device.
    :param mount:         Mount if not mounted, default True.
    :param config:        Configuration file, default /etc/filesystems.
    :param match:         File systems type to match on, default auto

    CLI Example:

    .. code-block:: bash

        salt '*' mount.set_filesystems /mnt/foo /dev/sdz1 jfs2

def set_filesystems(
        name,
        device,
        vfstype,
        opts='-',
        mount='true',
        config='/etc/filesystems',
        test=False,
        match_on='auto',
        **kwargs):
    '''
    .. versionadded:: 2018.3.3

    Verify that this mount is represented in the filesystems, change the mount
    to match the data passed, or add the mount if it is not present on AIX

        Provide information if the path is mounted

    :param name:          The name of the mount point where the device is mounted.
    :param device:        The device that is being mounted.
    :param vfstype:       The file system that is used (AIX has two fstypes, fstype and vfstype - similar to Linux fstype)
    :param opts:          Additional options used when mounting the device.
    :param mount:         Mount if not mounted, default True.
    :param config:        Configuration file, default /etc/filesystems.
    :param match:         File systems type to match on, default auto

    CLI Example:

    .. code-block:: bash

        salt '*' mount.set_filesystems /mnt/foo /dev/sdz1 jfs2
    '''
    # Fix the opts type if it is a list
    if isinstance(opts, list):
        opts = ','.join(opts)

    # preserve arguments for updating
    entry_args = {
        'name': name,
        'dev': device.replace('\\ ', '\\040'),
        'vfstype': vfstype,
        'opts': opts,
        'mount': mount,
    }

    view_lines = []
    ret = None

    if 'AIX' not in __grains__['kernel']:
        return ret

    # Transform match_on into list--items will be checked later
    if isinstance(match_on, list):
        pass
    elif not isinstance(match_on, six.string_types):
        raise CommandExecutionError('match_on must be a string or list of strings')
    elif match_on == 'auto':
        # Try to guess right criteria for auto....
        # added IBM types from sys/vmount.h after btrfs
        # NOTE: missing some special fstypes here
        specialFSes = frozenset([
            'none',
            'tmpfs',
            'sysfs',
            'proc',
            'fusectl',
            'debugfs',
            'securityfs',
            'devtmpfs',
            'cgroup',
            'btrfs',
            'cdrfs',
            'procfs',
            'jfs',
            'jfs2',
            'nfs',
            'sfs',
            'nfs3',
            'cachefs',
            'udfs',
            'cifs',
            'namefs',
            'pmemfs',
            'ahafs',
            'nfs4',
            'autofs',
            'stnfs'])

        if vfstype in specialFSes:
            match_on = ['name']
        else:
            match_on = ['dev']
    else:
        match_on = [match_on]

    # generate entry and criteria objects, handle invalid keys in match_on
    entry_ip = _FileSystemsEntry.from_line(entry_args, kwargs)
    try:
        criteria = entry_ip.pick(match_on)

    except KeyError:
        filterFn = lambda key: key not in _FileSystemsEntry.compatibility_keys
        invalid_keys = filter(filterFn, match_on)
        raise CommandExecutionError('Unrecognized keys in match_on: "{0}"'.format(invalid_keys))

    # parse file, use ret to cache status
    if not os.path.isfile(config):
        raise CommandExecutionError('Bad config file "{0}"'.format(config))

    # read in block of filesystem, block starts with '/' till empty line
    try:
        fsys_filedict = _filesystems(config, False)
        for fsys_view in six.viewitems(fsys_filedict):
            if criteria.match(fsys_view):
                ret = 'present'
                if entry_ip.match(fsys_view):
                    view_lines.append(fsys_view)
                else:
                    ret = 'change'
                    kv = entry_ip['name']
                    view_lines.append((kv, entry_ip))
            else:
                view_lines.append(fsys_view)

    except (IOError, OSError) as exc:
        raise CommandExecutionError('Couldn\'t read from {0}: {1}'.format(config, exc))

    # add line if not present or changed
    if ret is None:
        for dict_view in six.viewitems(entry_ip.dict_from_entry()):
            view_lines.append(dict_view)
        ret = 'new'

    if ret != 'present':  # ret in ['new', 'change']:
        try:
            with salt.utils.files.fopen(config, 'wb') as ofile:
                # The line was changed, commit it!
                for fsys_view in view_lines:
                    entry = fsys_view[1]
                    mystrg = _FileSystemsEntry.dict_to_lines(entry)
                    ofile.writelines(salt.utils.data.encode(mystrg))
        except (IOError, OSError):
            raise CommandExecutionError('File not writable {0}'.format(config))

    return ret