test_kinit_export_keytab: reset pw of the test account and test --only-current-keys
[samba.git] / source3 / modules / vfs_aio_fork.c
index 4069d935d2471917fae339c6f3d3765e60b0c5a8..87dcbdd6270e2b60ea620e4382a0d357aaec30f4 100644 (file)
@@ -30,6 +30,7 @@
 #include "lib/util/sys_rw_data.h"
 #include "lib/util/msghdr.h"
 #include "smbprofile.h"
+#include "lib/global_contexts.h"
 
 #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && !defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS)
 # error Can not pass file descriptors
 #define MAP_FILE 0
 #endif
 
+struct aio_child_list;
+
 struct aio_fork_config {
        bool erratic_testing_mode;
+       struct aio_child_list *children;
 };
 
 struct mmap_area {
@@ -149,11 +153,6 @@ struct aio_child_list {
        struct tevent_timer *cleanup_event;
 };
 
-static void free_aio_children(void **p)
-{
-       TALLOC_FREE(*p);
-}
-
 static ssize_t read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
 {
        struct iovec iov[1];
@@ -258,7 +257,7 @@ static void aio_child_cleanup(struct tevent_context *event_ctx,
                /*
                 * Re-schedule the next cleanup round
                 */
-               list->cleanup_event = tevent_add_timer(server_event_context(), list,
+               list->cleanup_event = tevent_add_timer(global_event_context(), list,
                                                      timeval_add(&now, 30, 0),
                                                      aio_child_cleanup, list);
 
@@ -267,19 +266,19 @@ static void aio_child_cleanup(struct tevent_context *event_ctx,
 
 static struct aio_child_list *init_aio_children(struct vfs_handle_struct *handle)
 {
-       struct aio_child_list *data = NULL;
+       struct aio_fork_config *config;
+       struct aio_child_list *children;
 
-       if (SMB_VFS_HANDLE_TEST_DATA(handle)) {
-               SMB_VFS_HANDLE_GET_DATA(handle, data, struct aio_child_list,
-                                       return NULL);
-       }
+       SMB_VFS_HANDLE_GET_DATA(handle, config, struct aio_fork_config,
+                               return NULL);
 
-       if (data == NULL) {
-               data = talloc_zero(NULL, struct aio_child_list);
-               if (data == NULL) {
+       if (config->children == NULL) {
+               config->children = talloc_zero(config, struct aio_child_list);
+               if (config->children == NULL) {
                        return NULL;
                }
        }
+       children = config->children;
 
        /*
         * Regardless of whether the child_list had been around or not, make
@@ -287,22 +286,18 @@ static struct aio_child_list *init_aio_children(struct vfs_handle_struct *handle
         * delete itself when it finds that no children are around anymore.
         */
 
-       if (data->cleanup_event == NULL) {
-               data->cleanup_event = tevent_add_timer(server_event_context(), data,
-                                                     timeval_current_ofs(30, 0),
-                                                     aio_child_cleanup, data);
-               if (data->cleanup_event == NULL) {
-                       TALLOC_FREE(data);
+       if (children->cleanup_event == NULL) {
+               children->cleanup_event =
+                       tevent_add_timer(global_event_context(), children,
+                                        timeval_current_ofs(30, 0),
+                                        aio_child_cleanup, children);
+               if (children->cleanup_event == NULL) {
+                       TALLOC_FREE(config->children);
                        return NULL;
                }
        }
 
-       if (!SMB_VFS_HANDLE_TEST_DATA(handle)) {
-               SMB_VFS_HANDLE_SET_DATA(handle, data, free_aio_children,
-                                       struct aio_child_list, return False);
-       }
-
-       return data;
+       return children;
 }
 
 static void aio_child_loop(int sockfd, struct mmap_area *map)
@@ -337,7 +332,7 @@ static void aio_child_loop(int sockfd, struct mmap_area *map)
                         * common parent state
                         */
                        generate_random_buffer(&randval, sizeof(randval));
-                       msecs = randval + 20;
+                       msecs = (randval%20)+1;
                        DEBUG(10, ("delaying for %u msecs\n", msecs));
                        smb_msleep(msecs);
                }
@@ -348,7 +343,7 @@ static void aio_child_loop(int sockfd, struct mmap_area *map)
 
                switch (cmd_struct.cmd) {
                case READ_CMD:
-                       ret_struct.size = sys_pread(
+                       ret_struct.size = sys_pread_full(
                                fd, discard_const(map->ptr), cmd_struct.n,
                                cmd_struct.offset);
 #if 0
@@ -359,7 +354,7 @@ static void aio_child_loop(int sockfd, struct mmap_area *map)
 #endif
                        break;
                case WRITE_CMD:
-                       ret_struct.size = sys_pwrite(
+                       ret_struct.size = sys_pwrite_full(
                                fd, discard_const(map->ptr), cmd_struct.n,
                                cmd_struct.offset);
                        break;
@@ -425,9 +420,9 @@ static int aio_child_destructor(struct aio_child *child)
 static struct files_struct *close_fsp_fd(struct files_struct *fsp,
                                         void *private_data)
 {
-       if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
-               close(fsp->fh->fd);
-               fsp->fh->fd = -1;
+       if ((fsp->fh != NULL) && (fsp_get_pathref_fd(fsp) != -1)) {
+               close(fsp_get_pathref_fd(fsp));
+               fsp_set_fd(fsp, -1);
        }
        return NULL;
 }
@@ -540,6 +535,8 @@ static int get_idle_child(struct vfs_handle_struct *handle,
 
 struct aio_fork_pread_state {
        struct aio_child *child;
+       size_t n;
+       void *data;
        ssize_t ret;
        struct vfs_aio_state vfs_aio_state;
 };
@@ -568,6 +565,8 @@ static struct tevent_req *aio_fork_pread_send(struct vfs_handle_struct *handle,
        if (req == NULL) {
                return NULL;
        }
+       state->n = n;
+       state->data = data;
 
        if (n > 128*1024) {
                /* TODO: support variable buffers */
@@ -587,7 +586,7 @@ static struct tevent_req *aio_fork_pread_send(struct vfs_handle_struct *handle,
        cmd.cmd = READ_CMD;
        cmd.erratic_testing_mode = config->erratic_testing_mode;
 
-       DEBUG(10, ("sending fd %d to child %d\n", fsp->fh->fd,
+       DEBUG(10, ("sending fd %d to child %d\n", fsp_get_io_fd(fsp),
                   (int)state->child->pid));
 
        /*
@@ -595,7 +594,7 @@ static struct tevent_req *aio_fork_pread_send(struct vfs_handle_struct *handle,
         * domain socket. This should never block.
         */
        written = write_fd(state->child->sockfd, &cmd, sizeof(cmd),
-                          fsp->fh->fd);
+                          fsp_get_io_fd(fsp));
        if (written == -1) {
                err = errno;
 
@@ -635,12 +634,20 @@ static void aio_fork_pread_done(struct tevent_req *subreq)
                return;
        }
 
-       state->child->busy = false;
-
        retbuf = (struct rw_ret *)buf;
        state->ret = retbuf->size;
        state->vfs_aio_state.error = retbuf->ret_errno;
        state->vfs_aio_state.duration = retbuf->duration;
+
+       if ((size_t)state->ret > state->n) {
+               tevent_req_error(req, EIO);
+               state->child->busy = false;
+               return;
+       }
+       memcpy(state->data, state->child->map->ptr, state->ret);
+
+       state->child->busy = false;
+
        tevent_req_done(req);
 }
 
@@ -697,13 +704,15 @@ static struct tevent_req *aio_fork_pwrite_send(
                return tevent_req_post(req, ev);
        }
 
+       memcpy(state->child->map->ptr, data, n);
+
        ZERO_STRUCT(cmd);
        cmd.n = n;
        cmd.offset = offset;
        cmd.cmd = WRITE_CMD;
        cmd.erratic_testing_mode = config->erratic_testing_mode;
 
-       DEBUG(10, ("sending fd %d to child %d\n", fsp->fh->fd,
+       DEBUG(10, ("sending fd %d to child %d\n", fsp_get_io_fd(fsp),
                   (int)state->child->pid));
 
        /*
@@ -711,7 +720,7 @@ static struct tevent_req *aio_fork_pwrite_send(
         * domain socket. This should never block.
         */
        written = write_fd(state->child->sockfd, &cmd, sizeof(cmd),
-                          fsp->fh->fd);
+                          fsp_get_io_fd(fsp));
        if (written == -1) {
                err = errno;
 
@@ -811,7 +820,7 @@ static struct tevent_req *aio_fork_fsync_send(
        cmd.cmd = FSYNC_CMD;
        cmd.erratic_testing_mode = config->erratic_testing_mode;
 
-       DEBUG(10, ("sending fd %d to child %d\n", fsp->fh->fd,
+       DEBUG(10, ("sending fd %d to child %d\n", fsp_get_io_fd(fsp),
                   (int)state->child->pid));
 
        /*
@@ -819,7 +828,7 @@ static struct tevent_req *aio_fork_fsync_send(
         * domain socket. This should never block.
         */
        written = write_fd(state->child->sockfd, &cmd, sizeof(cmd),
-                          fsp->fh->fd);
+                          fsp_get_io_fd(fsp));
        if (written == -1) {
                err = errno;
 
@@ -919,7 +928,7 @@ static struct vfs_fn_pointers vfs_aio_fork_fns = {
        .fsync_recv_fn = aio_fork_fsync_recv,
 };
 
-NTSTATUS vfs_aio_fork_init(TALLOC_CTX *);
+static_decl_vfs;
 NTSTATUS vfs_aio_fork_init(TALLOC_CTX *ctx)
 {
        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,