Skip to content

Commit

Permalink
vfs: add snapshot create/delete hooks
Browse files Browse the repository at this point in the history
This change adds three new VFS hooks covering snapshot manipulation:
- snap_check_path
  Check whether a path supports snapshots.
- snap_create
  Request the creation of a snapshot of the provided path.
- snap_delete
  Request the deletion of a snapshot.

These VFS call-outs will be used in future by Samba's File Server Remote
VSS Protocol (FSRVP) server.

MS-FSVRP states:
  At any given time, Windows servers allow only one shadow copy set to
  be going through the creation process.
Therefore, only provide synchronous hooks for now, which can be
converted to asynchronous _send/_recv functions when the corresponding
DCE/RPC server infrastructure is in place.

Signed-off-by: David Disseldorp <[email protected]>
Reviewed-by: Jeremy Allison <[email protected]>
  • Loading branch information
ddiss authored and jrasamba committed Mar 31, 2015
1 parent 13fa1b8 commit 67ee428
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 3 deletions.
3 changes: 3 additions & 0 deletions docs-xml/manpages/vfs_full_audit.8.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
<member>set_nt_acl</member>
<member>set_quota</member>
<member>setxattr</member>
<member>snap_check_path</member>
<member>snap_create</member>
<member>snap_delete</member>
<member>stat</member>
<member>statvfs</member>
<member>symlink</member>
Expand Down
30 changes: 30 additions & 0 deletions examples/VFS/skel_opaque.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,33 @@ static DIR *skel_opendir(vfs_handle_struct *handle, const char *fname,
return NULL;
}

static NTSTATUS skel_snap_check_path(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *service_path,
char **base_volume)
{
return NT_STATUS_NOT_SUPPORTED;
}

static NTSTATUS skel_snap_create(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *base_volume,
time_t *tstamp,
bool rw,
char **base_path,
char **snap_path)
{
return NT_STATUS_NOT_SUPPORTED;
}

static NTSTATUS skel_snap_delete(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
char *base_path,
char *snap_path)
{
return NT_STATUS_NOT_SUPPORTED;
}

static DIR *skel_fdopendir(vfs_handle_struct *handle, files_struct *fsp,
const char *mask, uint32 attr)
{
Expand Down Expand Up @@ -830,6 +857,9 @@ struct vfs_fn_pointers skel_opaque_fns = {
.statvfs_fn = skel_statvfs,
.fs_capabilities_fn = skel_fs_capabilities,
.get_dfs_referrals_fn = skel_get_dfs_referrals,
.snap_check_path_fn = skel_snap_check_path,
.snap_create_fn = skel_snap_create,
.snap_delete_fn = skel_snap_delete,

/* Directory operations */

Expand Down
32 changes: 32 additions & 0 deletions examples/VFS/skel_transparent.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,35 @@ static DIR *skel_opendir(vfs_handle_struct *handle, const char *fname,
return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
}

static NTSTATUS skel_snap_check_path(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *service_path,
char **base_volume)
{
return SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path,
base_volume);
}

static NTSTATUS skel_snap_create(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *base_volume,
time_t *tstamp,
bool rw,
char **base_path,
char **snap_path)
{
return SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp,
rw, base_path, snap_path);
}

static NTSTATUS skel_snap_delete(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
char *base_path,
char *snap_path)
{
return SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path, snap_path);
}

static DIR *skel_fdopendir(vfs_handle_struct *handle, files_struct *fsp,
const char *mask, uint32 attr)
{
Expand Down Expand Up @@ -939,6 +968,9 @@ struct vfs_fn_pointers skel_transparent_fns = {
.statvfs_fn = skel_statvfs,
.fs_capabilities_fn = skel_fs_capabilities,
.get_dfs_referrals_fn = skel_get_dfs_referrals,
.snap_check_path_fn = skel_snap_check_path,
.snap_create_fn = skel_snap_create,
.snap_delete_fn = skel_snap_delete,

/* Directory operations */

Expand Down
31 changes: 31 additions & 0 deletions source3/include/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
/* Version 32 - Remove unnecessary SMB_VFS_DISK_FREE() small_query parameter */
/* Bump to version 33 - Samba 4.3 will ship with that. */
/* Version 33 - change fallocate mode flags param from enum->uint32_t */
/* Version 33 - Add snapshot create/delete calls */

#define SMB_VFS_INTERFACE_VERSION 33

Expand Down Expand Up @@ -656,6 +657,21 @@ struct vfs_fn_pointers {
TALLOC_CTX *mem_ctx,
struct files_struct *fsp,
uint16_t compression_fmt);
NTSTATUS (*snap_check_path_fn)(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *service_path,
char **base_volume);
NTSTATUS (*snap_create_fn)(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *base_volume,
time_t *tstamp,
bool rw,
char **base_path,
char **snap_path);
NTSTATUS (*snap_delete_fn)(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
char *base_path,
char *snap_path);

NTSTATUS (*streaminfo_fn)(struct vfs_handle_struct *handle,
struct files_struct *fsp,
Expand Down Expand Up @@ -1151,6 +1167,21 @@ NTSTATUS smb_vfs_call_set_compression(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
struct files_struct *fsp,
uint16_t compression_fmt);
NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *service_path,
char **base_volume);
NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *base_volume,
time_t *tstamp,
bool rw,
char **base_path,
char **snap_path);
NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
char *base_path,
char *snap_path);
NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
uint32 security_info,
Expand Down
15 changes: 15 additions & 0 deletions source3/include/vfs_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,21 @@
#define SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp, compression_fmt) \
smb_vfs_call_set_compression((handle)->next, (mem_ctx), (fsp), (compression_fmt))

#define SMB_VFS_SNAP_CHECK_PATH(conn, mem_ctx, service_path, base_volume) \
smb_vfs_call_snap_check_path((conn)->vfs_handles, (mem_ctx), (service_path), (base_volume))
#define SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path, base_volume) \
smb_vfs_call_snap_check_path((handle)->next, (mem_ctx), (service_path), (base_volume))

#define SMB_VFS_SNAP_CREATE(conn, mem_ctx, base_volume, tstamp, rw, base_path, snap_path) \
smb_vfs_call_snap_create((conn)->vfs_handles, (mem_ctx), (base_volume), (tstamp), (rw), (base_path), (snap_path))
#define SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp, rw, base_path, snap_path) \
smb_vfs_call_snap_create((handle)->next, (mem_ctx), (base_volume), (tstamp), (rw), (base_path), (snap_path))

#define SMB_VFS_SNAP_DELETE(conn, mem_ctx, base_path, snap_path) \
smb_vfs_call_snap_delete((conn)->vfs_handles, (mem_ctx), (base_path), (snap_path))
#define SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path, snap_path) \
smb_vfs_call_snap_delete((handle)->next, (mem_ctx), (base_path), (snap_path))

#define SMB_VFS_FGET_NT_ACL(fsp, security_info, mem_ctx, ppdesc) \
smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc))
#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc) \
Expand Down
30 changes: 30 additions & 0 deletions source3/modules/vfs_default.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,33 @@ static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
return NT_STATUS_OK;
}

static NTSTATUS vfswrap_snap_check_path(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *service_path,
char **base_volume)
{
return NT_STATUS_NOT_SUPPORTED;
}

static NTSTATUS vfswrap_snap_create(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *base_volume,
time_t *tstamp,
bool rw,
char **base_path,
char **snap_path)
{
return NT_STATUS_NOT_SUPPORTED;
}

static NTSTATUS vfswrap_snap_delete(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
char *base_path,
char *snap_path)
{
return NT_STATUS_NOT_SUPPORTED;
}

/* Directory operations */

static DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
Expand Down Expand Up @@ -2544,6 +2571,9 @@ static struct vfs_fn_pointers vfs_default_fns = {
.statvfs_fn = vfswrap_statvfs,
.fs_capabilities_fn = vfswrap_fs_capabilities,
.get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
.snap_check_path_fn = vfswrap_snap_check_path,
.snap_create_fn = vfswrap_snap_create,
.snap_delete_fn = vfswrap_snap_delete,

/* Directory operations */

Expand Down
56 changes: 55 additions & 1 deletion source3/modules/vfs_full_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_GET_SHADOW_COPY_DATA,
SMB_VFS_OP_STATVFS,
SMB_VFS_OP_FS_CAPABILITIES,
SMB_VFS_OP_SNAP_CHECK_PATH,
SMB_VFS_OP_SNAP_CREATE,
SMB_VFS_OP_SNAP_DELETE,

/* Directory operations */

Expand Down Expand Up @@ -228,6 +231,9 @@ static struct {
{ SMB_VFS_OP_GET_SHADOW_COPY_DATA, "get_shadow_copy_data" },
{ SMB_VFS_OP_STATVFS, "statvfs" },
{ SMB_VFS_OP_FS_CAPABILITIES, "fs_capabilities" },
{ SMB_VFS_OP_SNAP_CHECK_PATH, "snap_check_path" },
{ SMB_VFS_OP_SNAP_CREATE, "snap_create" },
{ SMB_VFS_OP_SNAP_DELETE, "snap_delete" },
{ SMB_VFS_OP_OPENDIR, "opendir" },
{ SMB_VFS_OP_FDOPENDIR, "fdopendir" },
{ SMB_VFS_OP_READDIR, "readdir" },
Expand Down Expand Up @@ -674,7 +680,6 @@ static int smb_full_audit_get_quota(struct vfs_handle_struct *handle,
return result;
}


static int smb_full_audit_set_quota(struct vfs_handle_struct *handle,
enum SMB_QUOTA_TYPE qtype, unid_t id,
SMB_DISK_QUOTA *qt)
Expand Down Expand Up @@ -726,6 +731,52 @@ static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle,
return result;
}

static NTSTATUS smb_full_audit_snap_check_path(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *service_path,
char **base_volume)
{
NTSTATUS status;

status = SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path,
base_volume);
do_log(SMB_VFS_OP_SNAP_CHECK_PATH, NT_STATUS_IS_OK(status),
handle, "");

return status;
}

static NTSTATUS smb_full_audit_snap_create(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *base_volume,
time_t *tstamp,
bool rw,
char **base_path,
char **snap_path)
{
NTSTATUS status;

status = SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp,
rw, base_path, snap_path);
do_log(SMB_VFS_OP_SNAP_CREATE, NT_STATUS_IS_OK(status), handle, "");

return status;
}

static NTSTATUS smb_full_audit_snap_delete(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
char *base_path,
char *snap_path)
{
NTSTATUS status;

status = SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path,
snap_path);
do_log(SMB_VFS_OP_SNAP_DELETE, NT_STATUS_IS_OK(status), handle, "");

return status;
}

static DIR *smb_full_audit_opendir(vfs_handle_struct *handle,
const char *fname, const char *mask, uint32 attr)
{
Expand Down Expand Up @@ -2199,6 +2250,9 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
.get_shadow_copy_data_fn = smb_full_audit_get_shadow_copy_data,
.statvfs_fn = smb_full_audit_statvfs,
.fs_capabilities_fn = smb_full_audit_fs_capabilities,
.snap_check_path_fn = smb_full_audit_snap_check_path,
.snap_create_fn = smb_full_audit_snap_create,
.snap_delete_fn = smb_full_audit_snap_delete,
.opendir_fn = smb_full_audit_opendir,
.fdopendir_fn = smb_full_audit_fdopendir,
.readdir_fn = smb_full_audit_readdir,
Expand Down
76 changes: 74 additions & 2 deletions source3/modules/vfs_time_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,78 @@ static uint32_t smb_time_audit_fs_capabilities(struct vfs_handle_struct *handle,
return result;
}

static NTSTATUS smb_time_audit_snap_check_path(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *service_path,
char **base_volume)
{
NTSTATUS status;
struct timespec ts1,ts2;
double timediff;

clock_gettime_mono(&ts1);
status = SMB_VFS_NEXT_SNAP_CHECK_PATH(handle, mem_ctx, service_path,
base_volume);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;

if (timediff > audit_timeout) {
smb_time_audit_log("snap_check_path", timediff);
}

return status;
}

static NTSTATUS smb_time_audit_snap_create(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const char *base_volume,
time_t *tstamp,
bool rw,
char **base_path,
char **snap_path)
{
NTSTATUS status;
struct timespec ts1,ts2;
double timediff;

clock_gettime_mono(&ts1);
status = SMB_VFS_NEXT_SNAP_CREATE(handle, mem_ctx, base_volume, tstamp,
rw, base_path, snap_path);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2 ,&ts1) * 1.0e-9;

if (timediff > audit_timeout) {
smb_time_audit_log("snap_create", timediff);
}

return status;
}

static NTSTATUS smb_time_audit_snap_delete(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
char *base_path,
char *snap_path)
{
NTSTATUS status;
struct timespec ts1,ts2;
double timediff;

clock_gettime_mono(&ts1);
status = SMB_VFS_NEXT_SNAP_DELETE(handle, mem_ctx, base_path,
snap_path);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;

if (timediff > audit_timeout) {
smb_time_audit_log("snap_delete", timediff);
}

return status;
}

static DIR *smb_time_audit_opendir(vfs_handle_struct *handle,
const char *fname,
const char *mask, uint32 attr)
const char *fname,
const char *mask, uint32 attr)
{
DIR *result;
struct timespec ts1,ts2;
Expand Down Expand Up @@ -2383,6 +2452,9 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
.get_shadow_copy_data_fn = smb_time_audit_get_shadow_copy_data,
.statvfs_fn = smb_time_audit_statvfs,
.fs_capabilities_fn = smb_time_audit_fs_capabilities,
.snap_check_path_fn = smb_time_audit_snap_check_path,
.snap_create_fn = smb_time_audit_snap_create,
.snap_delete_fn = smb_time_audit_snap_delete,
.opendir_fn = smb_time_audit_opendir,
.fdopendir_fn = smb_time_audit_fdopendir,
.readdir_fn = smb_time_audit_readdir,
Expand Down
Loading

0 comments on commit 67ee428

Please sign in to comment.