Skip to content

Commit

Permalink
feat(seamless_upgrades): make zfs compatible with version 3 and 4 (#2…
Browse files Browse the repository at this point in the history
…32) (#12) (#15)

Signed-off-by: Vitta <[email protected]>
  • Loading branch information
mynktl authored and vishnuitta committed Jun 4, 2019
1 parent ccd1c6c commit b8f4717
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 67 deletions.
1 change: 1 addition & 0 deletions include/zrepl_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ typedef struct zvol_rebuild_scanner_info_s {
uint32_t flags;
};
int fd;
uint16_t version;
} zvol_rebuild_scanner_info_t;

typedef struct thread_args_s {
Expand Down
11 changes: 11 additions & 0 deletions include/zrepl_prot.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ extern "C" {
* properly aligned (and packed).
*/

#define MIN_SUPPORTED_REPLICA_VERSION 3

#define REPLICA_VERSION 4
#define MAX_NAME_LEN 256
#define MAX_IP_LEN 64
Expand Down Expand Up @@ -119,6 +121,15 @@ struct zvol_op_open_data {

typedef struct zvol_op_open_data zvol_op_open_data_t;

struct zvol_op_open_data_ver_3 {
uint32_t tgt_block_size; // used block size for rw in bytes
uint32_t timeout; // replica timeout in seconds
char volname[MAX_NAME_LEN];
} __attribute__((packed));

typedef struct zvol_op_open_data_ver_3 zvol_op_open_data_ver_3_t;


/*
* Payload data send in response to handshake on control connection. It tells
* IP, port where replica listens for data connection to zvol.
Expand Down
51 changes: 41 additions & 10 deletions src/data_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ uzfs_zvol_read_header(int fd, zvol_io_hdr_t *hdr)
if (rc != 0)
return (-1);

if (hdr->version != REPLICA_VERSION) {
if ((hdr->version > REPLICA_VERSION) ||
(hdr->version < MIN_SUPPORTED_REPLICA_VERSION)) {
LOG_ERR("invalid replica protocol version %d",
hdr->version);
return (1);
Expand Down Expand Up @@ -1384,7 +1385,7 @@ uzfs_zvol_rebuild_scanner_callback(off_t offset, size_t len,
warg = (zvol_rebuild_scanner_info_t *)args;
zinfo = warg->zinfo;

hdr.version = REPLICA_VERSION;
hdr.version = warg->version;
hdr.opcode = ZVOL_OPCODE_READ;
hdr.io_seq = metadata->io_num;
hdr.offset = offset;
Expand Down Expand Up @@ -1435,16 +1436,16 @@ uzfs_zvol_rebuild_scanner_callback(off_t offset, size_t len,
return (0);
}

void
static void
uzfs_zvol_send_zio_cmd(zvol_info_t *zinfo, zvol_io_hdr_t *hdrp,
zvol_op_code_t opcode, int fd, char *payload, uint64_t payload_size,
uint64_t checkpointed_io_seq)
uint64_t checkpointed_io_seq, zvol_rebuild_scanner_info_t *warg)
{

zvol_io_cmd_t *zio_cmd;
bzero(hdrp, sizeof (*hdrp));
hdrp->status = ZVOL_OP_STATUS_OK;
hdrp->version = REPLICA_VERSION;
hdrp->version = warg->version;
hdrp->opcode = opcode;
hdrp->checkpointed_io_seq = checkpointed_io_seq;
hdrp->len = payload_size; // MAX_NAME_LEN + 1;
Expand Down Expand Up @@ -1583,6 +1584,7 @@ uzfs_zvol_rebuild_scanner(void *arg)
KM_SLEEP);
warg->zinfo = zinfo;
warg->fd = fd;
warg->version = hdr.version;
uzfs_zvol_append_to_rebuild_scanner(zinfo, warg);

kmem_free(name, hdr.len);
Expand Down Expand Up @@ -1636,7 +1638,7 @@ uzfs_zvol_rebuild_scanner(void *arg)
}
uzfs_zvol_send_zio_cmd(zinfo, &hdr,
ZVOL_OPCODE_REBUILD_ALL_SNAP_DONE,
fd, NULL, 0, 0);
fd, NULL, 0, 0, warg);
all_snap_done = B_TRUE;
}
if (ZINFO_IS_DEGRADED(zinfo))
Expand All @@ -1661,7 +1663,7 @@ uzfs_zvol_rebuild_scanner(void *arg)

uzfs_zvol_send_zio_cmd(zinfo, &hdr,
ZVOL_OPCODE_REBUILD_STEP_DONE,
fd, NULL, 0, 0);
fd, NULL, 0, 0, warg);
goto read_socket;

case ZVOL_OPCODE_REBUILD_COMPLETE:
Expand All @@ -1686,7 +1688,7 @@ uzfs_zvol_rebuild_scanner(void *arg)
uzfs_zvol_send_zio_cmd(zinfo, &hdr,
ZVOL_OPCODE_REBUILD_SNAP_DONE,
fd, payload, payload_size,
checkpointed_io_seq + 1);
checkpointed_io_seq + 1, warg);
free(payload);
/* Close snapshot dataset */
LOG_INFO("closing snap %s", snap_zv->zv_name);
Expand Down Expand Up @@ -2081,6 +2083,32 @@ find_apt_zvol_status(zvol_info_t *zinfo, zvol_op_open_data_t *open_data)
return (ZVOL_STATUS_DEGRADED);
}

uint64_t
get_open_opcode_data_len(zvol_io_hdr_t *hdr)
{
switch (hdr->version) {
case 3:
return (sizeof (zvol_op_open_data_ver_3_t));
case 4:
return (sizeof (zvol_op_open_data_t));
default:
return (-1);
}
}

void
fill_default_values_for_version_change(zvol_io_hdr_t *hdr,
zvol_op_open_data_t *op)
{
switch (hdr->version) {
case 3:
op->replication_factor = 0;
break;
default:
break;
}
}

/*
* Process open request on data connection, the first message.
*
Expand All @@ -2101,6 +2129,7 @@ open_zvol(int fd, zvol_info_t **zinfopp)
thread_args_t *thrd_arg;
int rele_dataset_on_error = 0;
zvol_status_t status;
uint64_t exp_len;

/*
* If we don't know the version yet, be more careful when
Expand All @@ -2114,16 +2143,18 @@ open_zvol(int fd, zvol_info_t **zinfopp)
LOG_ERR("zvol must be opened first");
return (-1);
}
if (hdr.len != sizeof (open_data)) {
exp_len = get_open_opcode_data_len(&hdr);
if (hdr.len != exp_len) {
LOG_ERR("Invalid payload length for open");
return (-1);
}
rc = uzfs_zvol_socket_read(fd, (char *)&open_data, sizeof (open_data));
rc = uzfs_zvol_socket_read(fd, (char *)&open_data, exp_len);
if (rc != 0) {
LOG_ERR("Payload read failed");
return (-1);
}

fill_default_values_for_version_change(&hdr, &open_data);
open_data.volname[MAX_NAME_LEN - 1] = '\0';
zinfo = uzfs_zinfo_lookup(open_data.volname);
if (zinfo == NULL) {
Expand Down
Loading

0 comments on commit b8f4717

Please sign in to comment.