Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ifneq ($(MAKECMDGOALS),rpm-dkms)
ifneq ($(MAKECMDGOALS),srpm)
ifneq ($(MAKECMDGOALS),deb)
ifneq ($(MAKECMDGOALS),dsc)
ifneq ($(MAKECMDGOALS),upgrade)
cd $@ && $(MAKE) $(MAKECMDGOALS)
casadm: modules
cd $@ && $(MAKE) $(MAKECMDGOALS)
Expand All @@ -31,6 +32,7 @@ endif
endif
endif
endif
endif

archives:
@tools/pckgen.sh $(PWD) tar zip
Expand All @@ -49,3 +51,26 @@ deb:

dsc:
@tools/pckgen.sh $(PWD) dsc

# In-flight upgrade: replace the installed release with this one and swap
# the running cas_cache for the fallback one built against the loaded cas_bd.
# The new cas_bd is loaded after reboot.
UPGRADE_DIR = $(PWD)/.upgrade

upgrade:
@cd modules && $(MAKE) upgrade_check
@trap 'udevadm control --start-exec-queue' EXIT; \
trap 'exit 1' INT TERM HUP; \
set -e; \
udevadm control --stop-exec-queue; \
(cd modules && $(MAKE) upgrade_unload); \
rm -rf $(UPGRADE_DIR); \
(cd modules && $(MAKE) upgrade_preserve UPGRADE_DIR=$(UPGRADE_DIR)); \
(cd utils && $(MAKE) upgrade_preserve UPGRADE_DIR=$(UPGRADE_DIR)); \
(cd modules && $(MAKE) uninstall_files); \
for dir in casadm utils extra; do (cd $$dir && $(MAKE) uninstall); done; \
(cd modules && $(MAKE) install_files); \
for dir in casadm utils extra; do (cd $$dir && $(MAKE) install); done; \
(cd utils && $(MAKE) upgrade_restore UPGRADE_DIR=$(UPGRADE_DIR)); \
(cd modules && $(MAKE) upgrade_load UPGRADE_DIR=$(UPGRADE_DIR)); \
rm -rf $(UPGRADE_DIR)
101 changes: 95 additions & 6 deletions modules/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ ifneq ($(M),)
include $(M)/config.mk

obj-y += cas_cache/
ifneq ($(FALLBACK_BUILD),1)
obj-y += cas_bd/
endif

# Otherwise we were called directly from the command
# line; invoke the kernel build system.
Expand All @@ -32,6 +34,28 @@ MODULES_DIR=/lib/modules/$(KERNEL_VERSION)/extra/block/opencas

CACHE_MODULE = cas_cache
DISK_MODULE = cas_bd
DISK_SYMVERS = $(DISK_MODULE).symvers

# In-flight upgrade support. When FALLBACK_SYMVERS points at the symvers
# of the loaded cas_bd, a second cas_cache.ko is built against it. 'make
# upgrade' installs it under FALLBACK_INSTALL_DIR (outside /lib/modules/, so
# depmod ignores it) next to a copy of the loaded cas_bd, and loads it in
# place of the old cas_cache; after reboot the new cas_bd + cas_cache from
# the standard location take over.
FALLBACK_BUILD_DIR = $(PWD)/.fallback
FALLBACK_CACHE_KO = $(FALLBACK_BUILD_DIR)/cas_cache/$(CACHE_MODULE).ko
FALLBACK_BASE_SYMVERS = $(FALLBACK_BUILD_DIR)/$(DISK_SYMVERS)
FALLBACK_INSTALL_DIR ?= /lib/opencas/fallback/$(KERNEL_VERSION)

# Directory holding the files of the loaded cas_bd: the standard location,
# or the fallback one if an upgrade was not followed by reboot
LOADED_DISK_DIR = $(shell loaded=$$(cat /sys/module/$(DISK_MODULE)/srcversion 2>/dev/null); \
for dir in $(MODULES_DIR) $(FALLBACK_INSTALL_DIR); do \
if [ -n "$$loaded" ] && [ -f $$dir/$(DISK_SYMVERS) ] && \
[ "$$(modinfo -F srcversion $$dir/$(DISK_MODULE).ko 2>/dev/null)" = "$$loaded" ]; then \
echo $$dir; break; \
fi; \
done)

DEPMOD:=$(shell which depmod)
RMMOD :=$(shell which rmmod)
Expand All @@ -48,6 +72,22 @@ endif

default: sync check_configured_kernel
cd $(KERNEL_DIR) && $(MAKE) M=$(PWD) modules
ifneq ($(FALLBACK_SYMVERS),)
@test -f $(FALLBACK_SYMVERS) || { \
echo "ERROR: FALLBACK_SYMVERS=$(FALLBACK_SYMVERS) not found" >&2; \
exit 1; \
}
@echo "=== Building fallback $(CACHE_MODULE) against $(FALLBACK_SYMVERS) ==="
@rm -rf $(FALLBACK_BUILD_DIR)
@mkdir -p $(FALLBACK_BUILD_DIR)
@find $(PWD) -mindepth 1 -maxdepth 1 ! -name .fallback \
-exec cp -a {} $(FALLBACK_BUILD_DIR)/ \;
@cd $(KERNEL_DIR) && $(MAKE) M=$(FALLBACK_BUILD_DIR) FALLBACK_BUILD=1 clean
cd $(KERNEL_DIR) && $(MAKE) M=$(FALLBACK_BUILD_DIR) FALLBACK_BUILD=1 \
METADATA_DIR=$(PWD)/../.metadata \
KBUILD_EXTRA_SYMBOLS=$(FALLBACK_SYMVERS) modules
@cp $(FALLBACK_SYMVERS) $(FALLBACK_BASE_SYMVERS)
endif

# generated_defines.h describes the kernel API './configure' probed. Compiling
# it against another kernel produces code for an API that kernel may not have,
Expand All @@ -65,35 +105,84 @@ check_configured_kernel:

clean:
cd $(KERNEL_DIR) && make M=$(PWD) clean
@rm -rf $(FALLBACK_BUILD_DIR)
distclean: clean distsync
@rm -f $(PWD)/generated_defines.h
@rm -f $(PWD)/$(DISK_SYMVERS)

install: install_files
@$(DEPMOD)
@$(MODPROBE) $(CACHE_MODULE) || ( \
echo "See dmesg for more information" >&2 && \
rm -f $(DESTDIR)$(MODULES_DIR)/$(CACHE_MODULE).ko && exit 1 \
)
@$(MODPROBE) $(CACHE_MODULE) || { \
echo "See dmesg for more information" >&2; exit 1; \
}


install_files:
@echo "Installing Open-CAS modules"
@install -m 644 -D cas_cache/$(CACHE_MODULE).ko $(DESTDIR)$(MODULES_DIR)/$(CACHE_MODULE).ko
@install -m 644 -D cas_bd/$(DISK_MODULE).ko $(DESTDIR)$(MODULES_DIR)/$(DISK_MODULE).ko
@grep 'cas_bd/$(DISK_MODULE)' Module.symvers > $(PWD)/$(DISK_SYMVERS)
@install -m 644 -D $(PWD)/$(DISK_SYMVERS) $(DESTDIR)$(MODULES_DIR)/$(DISK_SYMVERS)

uninstall:
@echo "Uninstalling Open-CAS modules"
@echo "Unloading Open-CAS modules"
$(call remove-module,$(CACHE_MODULE))
$(call remove-module,$(DISK_MODULE))
@$(MAKE) uninstall_files

uninstall_files:
@echo "Uninstalling Open-CAS modules"
$(call remove-file,$(DESTDIR)$(MODULES_DIR)/$(CACHE_MODULE).ko)
$(call remove-file,$(DESTDIR)$(MODULES_DIR)/$(DISK_MODULE).ko)
$(call remove-file,$(DESTDIR)$(MODULES_DIR)/$(DISK_SYMVERS))
$(call remove-directory,$(DESTDIR)$(MODULES_DIR))

@rm -rf $(DESTDIR)$(FALLBACK_INSTALL_DIR)

@$(DEPMOD)

reinstall: uninstall install

.PHONY: all default check_configured_kernel clean distclean sync distsync install uninstall
# Steps of the in-flight upgrade, driven by 'make upgrade' in the top
# directory, which also passes UPGRADE_DIR to keep the preserved files in
upgrade_check:
@test -f $(FALLBACK_CACHE_KO) || { \
echo "ERROR: Fallback $(CACHE_MODULE).ko not built, rebuild with" \
"FALLBACK_SYMVERS=<symvers of the loaded $(DISK_MODULE)>" >&2; \
exit 1; \
}
@test -n "$(LOADED_DISK_DIR)" || { \
echo "ERROR: $(DISK_MODULE) not loaded or its installed files" \
"do not match the loaded module" >&2; \
exit 1; \
}
@cmp -s $(FALLBACK_BASE_SYMVERS) $(LOADED_DISK_DIR)/$(DISK_SYMVERS) || { \
echo "ERROR: Fallback $(CACHE_MODULE).ko was not built against" \
"the loaded $(DISK_MODULE), rebuild with" \
"FALLBACK_SYMVERS=$(LOADED_DISK_DIR)/$(DISK_SYMVERS)" >&2; \
exit 1; \
}

upgrade_unload:
@echo "Unloading $(CACHE_MODULE) module"
@$(RMMOD) $(CACHE_MODULE)

upgrade_preserve:
@echo "Preserving loaded $(DISK_MODULE)"
@install -m 644 -D $(LOADED_DISK_DIR)/$(DISK_MODULE).ko $(UPGRADE_DIR)/$(DISK_MODULE).ko
@install -m 644 -D $(LOADED_DISK_DIR)/$(DISK_SYMVERS) $(UPGRADE_DIR)/$(DISK_SYMVERS)

upgrade_load:
@$(DEPMOD)
@echo "Installing fallback $(CACHE_MODULE) to $(FALLBACK_INSTALL_DIR)"
@install -m 644 -D $(UPGRADE_DIR)/$(DISK_MODULE).ko $(FALLBACK_INSTALL_DIR)/$(DISK_MODULE).ko
@install -m 644 -D $(UPGRADE_DIR)/$(DISK_SYMVERS) $(FALLBACK_INSTALL_DIR)/$(DISK_SYMVERS)
@install -m 644 -D $(FALLBACK_CACHE_KO) $(FALLBACK_INSTALL_DIR)/$(CACHE_MODULE).ko
@insmod $(FALLBACK_INSTALL_DIR)/$(CACHE_MODULE).ko || { \
echo "See dmesg for more information" >&2; exit 1; \
}

.PHONY: all default check_configured_kernel clean distclean sync distsync install install_files \
uninstall uninstall_files upgrade_check upgrade_unload upgrade_preserve upgrade_load

endif
2 changes: 1 addition & 1 deletion modules/cas_bd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ include $(M)/config.mk

obj-m := cas_bd.o

cas_bd-c = $(shell find $(M)/cas_bd -name \*.c)
cas_bd-c = $(shell find $(M)/cas_bd -name \*.c ! -name \*.mod.c)
cas_bd-objs = $(patsubst $(M)/cas_bd/%.c,%.o,$(cas_bd-c))
2 changes: 1 addition & 1 deletion modules/cas_cache/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ include $(M)/config.mk

obj-m := cas_cache.o

cas_cache-c = $(shell find $(M)/cas_cache -name \*.c)
cas_cache-c = $(shell find $(M)/cas_cache -name \*.c ! -name \*.mod.c)
cas_cache-objs = $(patsubst $(M)/cas_cache/%.c,%.o,$(cas_cache-c))
5 changes: 3 additions & 2 deletions modules/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
# SPDX-License-Identifier: BSD-3-Clause
#

VERSION_FILE := $(M)/../.metadata/cas_version
BUILD_CONFIG_FILE := $(M)/../.metadata/cas_config
METADATA_DIR ?= $(M)/../.metadata
VERSION_FILE := $(METADATA_DIR)/cas_version
BUILD_CONFIG_FILE := $(METADATA_DIR)/cas_config

check_cflag=$(shell echo "" | \
gcc -c -xc ${1} -o /dev/null - 2>/dev/null; \
Expand Down
4 changes: 4 additions & 0 deletions test/functional/tests/upgrade/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#
# Copyright(c) 2026 Unvertical
# SPDX-License-Identifier: BSD-3-Clause
#
Loading
Loading