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); }
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); }