SQ: use gmt_tok_common wrappers in vfs_snapper
authorDavid Disseldorp <ddiss@samba.org>
Tue, 16 Oct 2012 15:08:10 +0000 (17:08 +0200)
committerDavid Disseldorp <ddiss@samba.org>
Mon, 15 Apr 2013 16:15:22 +0000 (18:15 +0200)
source3/modules/vfs_snapper.c

index 3e6d95a86c67f1fadca70403e418dc553428b39d..adbed1058242ca542ba8fc274d3fb15c89863060 100644 (file)
@@ -28,8 +28,9 @@
 #include "smbd/smbd.h"
 #include "lib/util/tevent_ntstatus.h"
 
-#define SHADOW_COPY_PREFIX "@GMT-"     /* vfs_shadow_copy format */
-#define SHADOW_COPY_PATH_FORMAT "@GMT-%Y.%m.%d-%H.%M.%S"
+/* include common @GMT token filter code */
+#include "vfs_gmt_tok_common.c"
+
 #define SNAPPER_SIG_LIST_SNAPS_RSP "a(uqutussa{ss})"
 #define SNAPPER_SIG_LIST_CONFS_RSP "a(ssa{ss})"
 #define SNAPPER_SIG_CREATE_SNAP_RSP "u"
@@ -859,6 +860,45 @@ static NTSTATUS snapper_del_snap_unpack(DBusConnection *conn,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS snapper_list_snaps_at_time_pack(const char *snapper_conf,
+                                               time_t time_lower,
+                                               time_t time_upper,
+                                               DBusMessage **req_msg_out)
+{
+       DBusMessage *msg;
+       DBusMessageIter args;
+
+       msg = dbus_message_new_method_call("org.opensuse.Snapper",
+                                          "/org/opensuse/Snapper",
+                                          "org.opensuse.Snapper",
+                                          "ListSnapshotsAtTime");
+       if (msg == NULL) {
+               DEBUG(0, ("failed to create list snaps message\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       dbus_message_iter_init_append(msg, &args);
+       if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,
+                                           &snapper_conf)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT64,
+                                           &time_lower)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT64,
+                                           &time_upper)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       *req_msg_out = msg;
+
+       return NT_STATUS_OK;
+}
+/* no snapper_list_snaps_at_time_unpack, use snapper_list_snaps_unpack */
+
 /*
  * Determine the snapper snapshot id given a path.
  * Ideally this should be determined via a lookup.
@@ -1422,6 +1462,140 @@ err_out:
        return -1;
 }
 
+static NTSTATUS snapper_get_snap_at_time_call(TALLOC_CTX *mem_ctx,
+                                             DBusConnection *dconn,
+                                             const char *conf_name,
+                                             const char *base_path,
+                                             time_t snaptime,
+                                             char **snap_path_out)
+{
+       NTSTATUS status;
+       DBusMessage *req_msg;
+       DBusMessage *rsp_msg;
+       uint32_t num_snaps;
+       struct snapper_snap *snaps;
+       char *snap_path;
+
+       status = snapper_list_snaps_at_time_pack(conf_name,
+                                                snaptime,
+                                                snaptime,
+                                                &req_msg);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto err_out;
+       }
+
+       status = snapper_dbus_msg_xchng(dconn, req_msg, &rsp_msg);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto err_req_free;
+       }
+
+       status = snapper_list_snaps_unpack(mem_ctx, rsp_msg,
+                                          &num_snaps, &snaps);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto err_rsp_free;
+       }
+
+       if (num_snaps == 0) {
+               DEBUG(2, ("no snapshots found with time: %lu\n", snaptime));
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto err_snap_array_free;
+       } else if (num_snaps > 0) {
+               DEBUG(2, ("got %u snapshots for single time %lu, using top\n",
+                         num_snaps, snaptime));
+       }
+
+       status = snapper_snap_id_to_path(mem_ctx, base_path, snaps[0].id,
+                                        &snap_path);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto err_snap_array_free;
+       }
+
+       snapper_snap_array_free(num_snaps, snaps);
+       dbus_message_unref(rsp_msg);
+       dbus_message_unref(req_msg);
+
+       *snap_path_out = snap_path;
+
+       return NT_STATUS_OK;
+
+err_snap_array_free:
+       snapper_snap_array_free(num_snaps, snaps);
+err_rsp_free:
+       dbus_message_unref(rsp_msg);
+err_req_free:
+       dbus_message_unref(req_msg);
+err_out:
+       return status;
+}
+
+/* callout for vfs_gmt_tok_common.c */
+static char *gmt_tok_insert_string(TALLOC_CTX *mem_ctx,
+                                  struct vfs_handle_struct *handle,
+                                  time_t snap_time)
+{
+       DBusConnection *dconn;
+       NTSTATUS status;
+       char *conf_name;
+       char *base_path;
+       char *snap_path;
+       char *snap_path_nobase;
+
+       dconn = snapper_dbus_conn();
+       if (dconn == NULL) {
+               status = NT_STATUS_UNSUCCESSFUL;
+               goto err_out;
+       }
+
+       if (handle->conn->connectpath == NULL) {
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto err_conn_free;
+       }
+
+       status = snapper_get_conf_call(mem_ctx, dconn,
+                                      handle->conn->connectpath,
+                                      &conf_name,
+                                      &base_path);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto err_conn_free;
+       }
+
+       status = snapper_get_snap_at_time_call(mem_ctx, dconn,
+                                              conf_name, base_path, snap_time,
+                                              &snap_path);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto err_conf_name_free;
+       }
+
+       /* strip the base path from the snap path for return */
+       if (strncmp(snap_path, base_path, strlen(base_path)) != 0) {
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto err_snap_path_free;
+       }
+
+       snap_path_nobase = talloc_strdup(mem_ctx, snap_path + strlen(base_path));
+       if (snap_path_nobase == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto err_snap_path_free;
+       }
+
+       talloc_free(snap_path);
+       talloc_free(conf_name);
+       talloc_free(base_path);
+       dbus_connection_unref(dconn);
+
+       return snap_path_nobase;
+
+err_snap_path_free:
+       talloc_free(snap_path);
+err_conf_name_free:
+       talloc_free(conf_name);
+       talloc_free(base_path);
+err_conn_free:
+       dbus_connection_unref(dconn);
+err_out:
+       return NULL;
+}
+
 static struct vfs_fn_pointers snapper_fns = {
        .snap_check_path_fn = snapper_snap_check_path,
        .snap_create_send_fn = snapper_snap_create_send,
@@ -1429,6 +1603,34 @@ static struct vfs_fn_pointers snapper_fns = {
        .snap_delete_send_fn = snapper_snap_delete_send,
        .snap_delete_recv_fn = snapper_snap_delete_recv,
        .get_shadow_copy_data_fn = snapper_get_shadow_copy_data,
+       /* use common @GMT token wrapper fns */
+       .opendir_fn = gmt_tok_opendir,
+       .rename_fn = gmt_tok_rename,
+       .link_fn = gmt_tok_link,
+       .symlink_fn = gmt_tok_symlink,
+       .stat_fn = gmt_tok_stat,
+       .lstat_fn = gmt_tok_lstat,
+       .fstat_fn = gmt_tok_fstat,
+       .open_fn = gmt_tok_open,
+       .unlink_fn = gmt_tok_unlink,
+       .chmod_fn = gmt_tok_chmod,
+       .chown_fn = gmt_tok_chown,
+       .chdir_fn = gmt_tok_chdir,
+       .ntimes_fn = gmt_tok_ntimes,
+       .readlink_fn = gmt_tok_readlink,
+       .mknod_fn = gmt_tok_mknod,
+       .realpath_fn = gmt_tok_realpath,
+       .get_nt_acl_fn = gmt_tok_get_nt_acl,
+       .fget_nt_acl_fn = gmt_tok_fget_nt_acl,
+       .mkdir_fn = gmt_tok_mkdir,
+       .rmdir_fn = gmt_tok_rmdir,
+       .getxattr_fn = gmt_tok_getxattr,
+       .listxattr_fn = gmt_tok_listxattr,
+       .removexattr_fn = gmt_tok_removexattr,
+       .setxattr_fn = gmt_tok_setxattr,
+       .chmod_acl_fn = gmt_tok_chmod_acl,
+       .chflags_fn = gmt_tok_chflags,
+       .get_real_filename_fn = gmt_tok_get_real_filename,
 };
 
 NTSTATUS vfs_snapper_init(void);