[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/2] drbd: implement replicated checkpointing disk
Implement remus-drbd-replicated-checkpointing-disk based on generic remus devices framework. Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> --- tools/hotplug/Linux/Makefile | 1 + tools/hotplug/Linux/block-drbd-probe | 84 +++++++++++++++++ tools/libxl/Makefile | 2 +- tools/libxl/libxl_remus_device.c | 1 + tools/libxl/libxl_remus_device.h | 1 + tools/libxl/libxl_remus_disk_drbd.c | 164 ++++++++++++++++++++++++++++++++++ 6 files changed, 252 insertions(+), 1 deletions(-) create mode 100755 tools/hotplug/Linux/block-drbd-probe create mode 100644 tools/libxl/libxl_remus_disk_drbd.c diff --git a/tools/hotplug/Linux/Makefile b/tools/hotplug/Linux/Makefile index baaaa41..31d9e00 100644 --- a/tools/hotplug/Linux/Makefile +++ b/tools/hotplug/Linux/Makefile @@ -23,6 +23,7 @@ XEN_SCRIPTS += xen-hotplug-cleanup XEN_SCRIPTS += external-device-migrate XEN_SCRIPTS += vscsi XEN_SCRIPTS += block-iscsi +XEN_SCRIPTS += block-drbd-probe XEN_SCRIPTS += $(XEN_SCRIPTS-y) XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh diff --git a/tools/hotplug/Linux/block-drbd-probe b/tools/hotplug/Linux/block-drbd-probe new file mode 100755 index 0000000..163ad04 --- /dev/null +++ b/tools/hotplug/Linux/block-drbd-probe @@ -0,0 +1,84 @@ +#! /bin/bash +# +# Copyright (C) 2014 FUJITSU LIMITED +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Usage: +# block-drbd-probe devicename +# +# Return value: +# 0: the device is drbd device +# 1: the device is not drbd device +# 2: unkown error +# 3: the drbd device does not use protocol D +# 4: the drbd device is not ready + +drbd_res= + +function get_res_name() +{ + local drbd_dev=$1 + local drbd_dev_list=($(drbdadm sh-dev all)) + local drbd_res_list=($(drbdadm sh-resource all)) + local temp_drbd_dev temp_drbd_res + local found=0 + + for temp_drbd_dev in ${drbd_dev_list[@]}; do + if [[ "$temp_drbd_dev" == "$drbd_dev" ]]; then + found=1 + break + fi + done + + if [[ $found -eq 0 ]]; then + return 1 + fi + + for temp_drbd_res in ${drbd_res_list[@]}; do + temp_drbd_dev=$(drbdadm sh-dev $temp_drbd_res) + if [[ "$temp_drbd_dev" == "$drbd_dev" ]]; then + drbd_res="$temp_drbd_res" + return 0 + fi + done + + # OOPS + return 2 +} + +get_res_name $1 +if [[ $? -ne 0 ]]; then + exit $? +fi + +# check protocol +drbdsetup $1 show | grep -q "protocol D;" +if [[ $? -ne 0 ]]; then + exit 3 +fi + +# check connect status +state=$(drbdadm cstate "$drbd_res") +if [[ "$state" != "Connected" ]]; then + exit 4 +fi + +# check role +role=$(drbdadm role "$drbd_res") +if [[ "$role" != "Primary/Secondary" ]]; then + exit 4 +fi + +exit 0 diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 8398386..53461ab 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -52,7 +52,7 @@ else LIBXL_OBJS-y += libxl_nonetbuffer.o endif -LIBXL_OBJS-y += libxl_remus.o libxl_remus_device.o +LIBXL_OBJS-y += libxl_remus.o libxl_remus_device.o libxl_remus_disk_drbd.o LIBXL_OBJS-$(CONFIG_X86) += libxl_cpuid.o libxl_x86.o LIBXL_OBJS-$(CONFIG_ARM) += libxl_nocpuid.o libxl_arm.o diff --git a/tools/libxl/libxl_remus_device.c b/tools/libxl/libxl_remus_device.c index 1564bd1..c323773 100644 --- a/tools/libxl/libxl_remus_device.c +++ b/tools/libxl/libxl_remus_device.c @@ -38,6 +38,7 @@ typedef struct libxl__remus_device_state { static libxl__remus_device_type *device_types[] = { &remus_device_nic, + &remus_device_drbd_disk, }; int libxl__remus_device_postsuspend(libxl__remus_state *remus_state) diff --git a/tools/libxl/libxl_remus_device.h b/tools/libxl/libxl_remus_device.h index 30b368d..4b41021 100644 --- a/tools/libxl/libxl_remus_device.h +++ b/tools/libxl/libxl_remus_device.h @@ -95,5 +95,6 @@ struct libxl__remus_device { }; extern libxl__remus_device_type remus_device_nic; +extern libxl__remus_device_type remus_device_drbd_disk; #endif diff --git a/tools/libxl/libxl_remus_disk_drbd.c b/tools/libxl/libxl_remus_disk_drbd.c new file mode 100644 index 0000000..583b8a3 --- /dev/null +++ b/tools/libxl/libxl_remus_disk_drbd.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2014 FUJITSU LIMITED + * Author Lai Jiangshan <laijs@xxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +#include "libxl_osdeps.h" /* must come before any other headers */ + +#include "libxl_internal.h" + +#include "libxl_remus_device.h" + +/*** drbd implementation ***/ +const int DRBD_SEND_CHECKPOINT = 20; +const int DRBD_WAIT_CHECKPOINT_ACK = 30; + +typedef struct libxl__remus_drbd_disk { + libxl__remus_device remus_dev; + int ctl_fd; + int ackwait; + const char *path; +} libxl__remus_drbd_disk; + +typedef struct libxl__remus_drbd_state { + char *drbd_probe_script; + libxl__ao *ao; +} libxl__remus_drbd_state; + +static int drbd_postsuspend(libxl__remus_device *remus_dev) +{ + libxl__remus_drbd_disk *drbd_disk = + CONTAINER_OF(remus_dev, *drbd_disk, remus_dev); + + if (!drbd_disk->ackwait) { + if (ioctl(drbd_disk->ctl_fd, DRBD_SEND_CHECKPOINT, 0) <= 0) + drbd_disk->ackwait = 1; + } + + return 0; +} + +static int drbd_preresume(libxl__remus_device *remus_dev) +{ + libxl__remus_drbd_disk *drbd_disk = + CONTAINER_OF(remus_dev, *drbd_disk, remus_dev); + + if (drbd_disk->ackwait) { + ioctl(drbd_disk->ctl_fd, DRBD_WAIT_CHECKPOINT_ACK, 0); + drbd_disk->ackwait = 0; + } + + return 0; +} + +static int drbd_commit(libxl__remus_device *remus_dev) +{ + /* nothing to do, all work are done by DRBD's protocal-D. */ + return 0; +} + +static int drbd_init(libxl__remus_device_type *self, + libxl__remus_state *remus_state) +{ + libxl__remus_drbd_state *drbd_state; + + STATE_AO_GC(remus_state->dss->ao); + + GCNEW(drbd_state); + self->data = drbd_state; + drbd_state->ao = ao; + drbd_state->drbd_probe_script = GCSPRINTF("%s/block-drbd-probe", + libxl__xen_script_dir_path()); + + + return REMUS_OK; +} + +static void drbd_destroy(libxl__remus_device_type *self) +{ + return; +} + +static int drbd_match(const libxl__remus_device_type *self, + const void *libxl_device, int device_type, + libxl_async_exec *async_exec) +{ + int arraysize, nr = 0; + const libxl_device_disk *disk = libxl_device; + libxl__remus_drbd_state *drbd_state = self->data; + STATE_AO_GC(drbd_state->ao); + + if (device_type != REMUS_DISK) + return REMUS_NOT_SUPPORT; + + /* setup env & args */ + arraysize = 1; + GCNEW_ARRAY(async_exec->env, arraysize); + async_exec->env[nr++] = NULL; + assert(nr <= arraysize); + + arraysize = 3; + nr = 0; + GCNEW_ARRAY(async_exec->args, arraysize); + async_exec->args[nr++] = drbd_state->drbd_probe_script; + async_exec->args[nr++] = disk->pdev_path; + async_exec->args[nr++] = NULL; + assert(nr <= arraysize); + + async_exec->allow_fail = true; + async_exec->timeout = LIBXL_HOTPLUG_TIMEOUT; + + if (libxl_async_exec_script(gc, async_exec)) + return REMUS_FAIL; + + return REMUS_INPROGRESS; +} + +static int drbd_setup(libxl__remus_device *remus_dev, + libxl_async_exec *async_exec) +{ + libxl__remus_drbd_disk *drbd_disk = + CONTAINER_OF(remus_dev, *drbd_disk, remus_dev); + const libxl_device_disk *disk = remus_dev->libxl_device; + + drbd_disk->path = disk->pdev_path; + drbd_disk->ctl_fd = open(drbd_disk->path, O_RDONLY); + drbd_disk->ackwait = 0; + + if (drbd_disk->ctl_fd < 0) + return REMUS_FAIL; + + return REMUS_OK; +} + +static int drbd_teardown(libxl__remus_device *remus_dev, + libxl_async_exec *async_exec) +{ + libxl__remus_drbd_disk *drbd_disk = + CONTAINER_OF(remus_dev, *drbd_disk, remus_dev); + + close(drbd_disk->ctl_fd); + return REMUS_OK; +} + +libxl__remus_device_type remus_device_drbd_disk = { + .init = drbd_init, + .destroy = drbd_destroy, + .postsuspend = drbd_postsuspend, + .preresume = drbd_preresume, + .commit = drbd_commit, + .match = drbd_match, + .setup = drbd_setup, + .teardown = drbd_teardown, + .size = sizeof(libxl__remus_drbd_disk), +}; -- 1.7.4.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |