]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-protocol: Add file IO functions for ctdb_rec_buffer
authorAmitay Isaacs <amitay@gmail.com>
Tue, 8 Mar 2016 06:20:30 +0000 (17:20 +1100)
committerMartin Schwenke <martins@samba.org>
Fri, 25 Mar 2016 02:26:15 +0000 (03:26 +0100)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/protocol/protocol_api.h
ctdb/protocol/protocol_types.c
ctdb/tests/src/protocol_types_test.c

index d07b4198d0a086a699394bf85cfde137759d2502..40753a9de976336463e61bdd31c709f50efd6fae 100644 (file)
@@ -52,6 +52,10 @@ int ctdb_rec_buffer_traverse(struct ctdb_rec_buffer *recbuf,
                             ctdb_rec_parser_func_t func,
                             void *private_data);
 
+int ctdb_rec_buffer_write(struct ctdb_rec_buffer *recbuf, int fd);
+int ctdb_rec_buffer_read(int fd, TALLOC_CTX *mem_ctx,
+                        struct ctdb_rec_buffer **out);
+
 size_t ctdb_server_id_len(struct ctdb_server_id *sid);
 void ctdb_server_id_push(struct ctdb_server_id *sid, uint8_t *buf);
 int ctdb_server_id_pull(uint8_t *buf, size_t buflen,
index a0263336319d814dc25238f3710d581ee78e689a..cd04aca0e6423a3bb2c5202396382cdae6072ba2 100644 (file)
@@ -800,6 +800,68 @@ int ctdb_rec_buffer_traverse(struct ctdb_rec_buffer *recbuf,
        return ret;
 }
 
+int ctdb_rec_buffer_write(struct ctdb_rec_buffer *recbuf, int fd)
+{
+       ssize_t n;
+
+       n = write(fd, &recbuf->db_id, sizeof(uint32_t));
+       if (n == -1 || n != sizeof(uint32_t)) {
+               return (errno != 0 ? errno : EIO);
+       }
+       n = write(fd, &recbuf->count, sizeof(uint32_t));
+       if (n == -1 || n != sizeof(uint32_t)) {
+               return (errno != 0 ? errno : EIO);
+       }
+       n = write(fd, &recbuf->buflen, sizeof(size_t));
+       if (n == -1 || n != sizeof(size_t)) {
+               return (errno != 0 ? errno : EIO);
+       }
+       n = write(fd, recbuf->buf, recbuf->buflen);
+       if (n == -1 || n != recbuf->buflen) {
+               return (errno != 0 ? errno : EIO);
+       }
+
+       return 0;
+}
+
+int ctdb_rec_buffer_read(int fd, TALLOC_CTX *mem_ctx,
+                        struct ctdb_rec_buffer **out)
+{
+       struct ctdb_rec_buffer *recbuf;
+       ssize_t n;
+
+       recbuf = talloc(mem_ctx, struct ctdb_rec_buffer);
+       if (recbuf == NULL) {
+               return ENOMEM;
+       }
+
+       n = read(fd, &recbuf->db_id, sizeof(uint32_t));
+       if (n == -1 || n != sizeof(uint32_t)) {
+               return (errno != 0 ? errno : EIO);
+       }
+       n = read(fd, &recbuf->count, sizeof(uint32_t));
+       if (n == -1 || n != sizeof(uint32_t)) {
+               return (errno != 0 ? errno : EIO);
+       }
+       n = read(fd, &recbuf->buflen, sizeof(size_t));
+       if (n == -1 || n != sizeof(size_t)) {
+               return (errno != 0 ? errno : EIO);
+       }
+
+       recbuf->buf = talloc_size(recbuf, recbuf->buflen);
+       if (recbuf->buf == NULL) {
+               return ENOMEM;
+       }
+
+       n = read(fd, recbuf->buf, recbuf->buflen);
+       if (n == -1 || n != recbuf->buflen) {
+               return (errno != 0 ? errno : EIO);
+       }
+
+       *out = recbuf;
+       return 0;
+}
+
 size_t ctdb_traverse_start_len(struct ctdb_traverse_start *traverse)
 {
        return sizeof(struct ctdb_traverse_start);
index 55ee743def57111e7f9f693ff5d611ce6e070b90..e39a2c9a4cf56d66821d5289fffd01ffb78a5971 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "replace.h"
 #include "system/network.h"
+#include "system/filesys.h"
 
 #include <assert.h>
 
@@ -1235,6 +1236,52 @@ DEFINE_TEST(struct ctdb_srvid_message, ctdb_srvid_message);
 DEFINE_TEST(struct ctdb_disable_message, ctdb_disable_message);
 DEFINE_TEST(struct ctdb_g_lock_list, ctdb_g_lock_list);
 
+static void test_ctdb_rec_buffer_read_write(void)
+{
+       TALLOC_CTX *mem_ctx = talloc_new(NULL);
+       struct ctdb_rec_buffer *p1, **p2;
+       const char *filename = "ctdb_rec_buffer_test.dat";
+       int count = 100;
+       int fd, i, ret;
+       off_t offset;
+
+       p1 = talloc_array(mem_ctx, struct ctdb_rec_buffer, count);
+       assert(p1 != NULL);
+       for (i=0; i<count; i++) {
+               fill_ctdb_rec_buffer(mem_ctx, &p1[i]);
+       }
+
+       fd = open(filename, O_RDWR|O_CREAT, 0600);
+       assert(fd != -1);
+       unlink(filename);
+
+       for (i=0; i<count; i++) {
+               ret = ctdb_rec_buffer_write(&p1[i], fd);
+               assert(ret == 0);
+       }
+
+       offset = lseek(fd, 0, SEEK_CUR);
+       assert(offset != -1);
+       offset = lseek(fd, -offset, SEEK_CUR);
+       assert(offset == 0);
+
+       p2 = talloc_array(mem_ctx, struct ctdb_rec_buffer *, count);
+       assert(p2 != NULL);
+
+       for (i=0; i<count; i++) {
+               ret = ctdb_rec_buffer_read(fd, mem_ctx, &p2[i]);
+               assert(ret == 0);
+       }
+
+       close(fd);
+
+       for (i=0; i<count; i++) {
+               verify_ctdb_rec_buffer(&p1[i], p2[i]);
+       }
+
+       talloc_free(mem_ctx);
+}
+
 int main(int argc, char *argv[])
 {
        if (argc == 2) {
@@ -1299,6 +1346,8 @@ int main(int argc, char *argv[])
        TEST_FUNC(ctdb_disable_message)();
        TEST_FUNC(ctdb_g_lock_list)();
 
+       test_ctdb_rec_buffer_read_write();
+
        return 0;
 }