/* * path - path of the dataset * count - return value of the number of snapshots for the dataset */ int smbd_vss_get_count(const char *path, uint32_t *count) { char dataset[MAXPATHLEN]; libzfs_handle_t *libhd; zfs_handle_t *zfshd; smbd_vss_count_t vss_count; bzero(&vss_count, sizeof (smbd_vss_count_t)); *count = 0; if (smb_getdataset(path, dataset, MAXPATHLEN) != 0) return (-1); if ((libhd = libzfs_init()) == NULL) return (-1); if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) { libzfs_fini(libhd); return (-1); } (void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_count, (void *)&vss_count); if (vss_count.vc_count > SMBD_VSS_SNAPSHOT_MAX) vss_count.vc_count = SMBD_VSS_SNAPSHOT_MAX; *count = vss_count.vc_count; zfs_close(zfshd); libzfs_fini(libhd); return (0); }
/* * path - path of the dataset for the operation * gmttoken - the @GMT token to be looked up * toktime - time_t used if gmttoken == NULL * snapname - the snapshot name to be returned [MAXPATHLEN] * * Here we are going to get the snapshot name from the @GMT token * The snapname returned by ZFS is : <dataset name>@<snapshot name> * So we are going to make sure there is the @ symbol in * the right place and then just return the snapshot name */ int smbd_vss_map_gmttoken(const char *path, char *gmttoken, time_t toktime, char *snapname) { char dataset[MAXPATHLEN]; libzfs_handle_t *libhd; zfs_handle_t *zfshd; smbd_vss_map_gmttoken_t vss_map_gmttoken; char *zsnap; const char *lsnap; struct tm tm; if (gmttoken != NULL && *gmttoken == '@' && strptime(gmttoken, smbd_vss_gmttoken_fmt, &tm) != NULL) { toktime = timegm(&tm); } vss_map_gmttoken.mg_snaptime = toktime; vss_map_gmttoken.mg_snapname = snapname; *snapname = '\0'; if (smb_getdataset(path, dataset, MAXPATHLEN) != 0) return (-1); if ((libhd = libzfs_init()) == NULL) return (-1); if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) { libzfs_fini(libhd); return (-1); } (void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_map_gmttoken, (void *)&vss_map_gmttoken); /* compare the zfs snapshot name and the local snap name */ zsnap = snapname; lsnap = dataset; while ((*lsnap != '\0') && (*zsnap != '\0') && (*lsnap == *zsnap)) { zsnap++; lsnap++; } /* Now we should be passed the dataset name */ if ((*zsnap == '@') && (*lsnap == '\0')) { zsnap++; (void) strlcpy(snapname, zsnap, MAXPATHLEN); } else { *snapname = '\0'; } zfs_close(zfshd); libzfs_fini(libhd); return (0); }
/* * This method computes ACL on share path from a share name. * Return 0 upon success, -1 upon failure. */ static int srvsvc_shareacl_getpath(smb_share_t *si, char *shr_acl_path) { char dataset[MAXPATHLEN]; char mp[ZFS_MAXPROPLEN]; libzfs_handle_t *libhd; zfs_handle_t *zfshd; int ret = 0; ret = smb_getdataset(si->shr_path, dataset, MAXPATHLEN); if (ret != 0) return (ret); if ((libhd = libzfs_init()) == NULL) return (-1); if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) { libzfs_fini(libhd); return (-1); } if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, mp, sizeof (mp), NULL, NULL, 0, B_FALSE) != 0) { zfs_close(zfshd); libzfs_fini(libhd); return (-1); } zfs_close(zfshd); libzfs_fini(libhd); (void) snprintf(shr_acl_path, MAXPATHLEN, "%s/.zfs/shares/%s", mp, si->shr_name); return (ret); }
void smbd_vss_get_snapshots(const char *path, uint32_t count, uint32_t *return_count, uint32_t *num_gmttokens, char **gmttokenp) { char dataset[MAXPATHLEN]; libzfs_handle_t *libhd; zfs_handle_t *zfshd; smbd_vss_get_uint64_date_t vss_uint64_date; int i; uint64_t *timep; *return_count = 0; *num_gmttokens = 0; if (count == 0) return; if (count > SMBD_VSS_SNAPSHOT_MAX) count = SMBD_VSS_SNAPSHOT_MAX; vss_uint64_date.gd_count = count; vss_uint64_date.gd_return_count = 0; vss_uint64_date.gd_gmt_array = malloc(count * sizeof (uint64_t)); if (vss_uint64_date.gd_gmt_array == NULL) return; if (smb_getdataset(path, dataset, MAXPATHLEN) != 0) { free(vss_uint64_date.gd_gmt_array); return; } if ((libhd = libzfs_init()) == NULL) { free(vss_uint64_date.gd_gmt_array); return; } if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_DATASET)) == NULL) { free(vss_uint64_date.gd_gmt_array); libzfs_fini(libhd); return; } (void) zfs_iter_snapshots(zfshd, smbd_vss_iterate_get_uint64_date, (void *)&vss_uint64_date); *num_gmttokens = vss_uint64_date.gd_return_count; *return_count = vss_uint64_date.gd_return_count; /* * Sort the list since neither zfs nor the client sorts it. */ qsort((char *)vss_uint64_date.gd_gmt_array, vss_uint64_date.gd_return_count, sizeof (uint64_t), smbd_vss_cmp_time); timep = vss_uint64_date.gd_gmt_array; for (i = 0; i < vss_uint64_date.gd_return_count; i++) { *gmttokenp = malloc(SMB_VSS_GMT_SIZE); if (*gmttokenp) smbd_vss_time2gmttoken(*timep, *gmttokenp); else vss_uint64_date.gd_return_count = 0; timep++; gmttokenp++; } free(vss_uint64_date.gd_gmt_array); zfs_close(zfshd); libzfs_fini(libhd); }