[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250625231838.1897085-32-pasha.tatashin@soleen.com>
Date: Wed, 25 Jun 2025 23:18:18 +0000
From: Pasha Tatashin <pasha.tatashin@...een.com>
To: pratyush@...nel.org,
jasonmiu@...gle.com,
graf@...zon.com,
changyuanl@...gle.com,
pasha.tatashin@...een.com,
rppt@...nel.org,
dmatlack@...gle.com,
rientjes@...gle.com,
corbet@....net,
rdunlap@...radead.org,
ilpo.jarvinen@...ux.intel.com,
kanie@...ux.alibaba.com,
ojeda@...nel.org,
aliceryhl@...gle.com,
masahiroy@...nel.org,
akpm@...ux-foundation.org,
tj@...nel.org,
yoann.congal@...le.fr,
mmaurer@...gle.com,
roman.gushchin@...ux.dev,
chenridong@...wei.com,
axboe@...nel.dk,
mark.rutland@....com,
jannh@...gle.com,
vincent.guittot@...aro.org,
hannes@...xchg.org,
dan.j.williams@...el.com,
david@...hat.com,
joel.granados@...nel.org,
rostedt@...dmis.org,
anna.schumaker@...cle.com,
song@...nel.org,
zhangguopeng@...inos.cn,
linux@...ssschuh.net,
linux-kernel@...r.kernel.org,
linux-doc@...r.kernel.org,
linux-mm@...ck.org,
gregkh@...uxfoundation.org,
tglx@...utronix.de,
mingo@...hat.com,
bp@...en8.de,
dave.hansen@...ux.intel.com,
x86@...nel.org,
hpa@...or.com,
rafael@...nel.org,
dakr@...nel.org,
bartosz.golaszewski@...aro.org,
cw00.choi@...sung.com,
myungjoo.ham@...sung.com,
yesanishhere@...il.com,
Jonathan.Cameron@...wei.com,
quic_zijuhu@...cinc.com,
aleksander.lobakin@...el.com,
ira.weiny@...el.com,
andriy.shevchenko@...ux.intel.com,
leon@...nel.org,
lukas@...ner.de,
bhelgaas@...gle.com,
wagi@...nel.org,
djeffery@...hat.com,
stuart.w.hayes@...il.com,
ptyadav@...zon.de,
lennart@...ttering.net,
brauner@...nel.org,
linux-api@...r.kernel.org,
linux-fsdevel@...r.kernel.org
Subject: [RFC v1 31/32] libluo: introduce luoctl
From: Pratyush Yadav <ptyadav@...zon.de>
luoctl is a utility to interact with the LUO state machine. It currently
supports viewing and change the current state of LUO. This can be used
by scripts, tools, or developers to control LUO state during the live
update process.
Example usage:
$ luoctl state
normal
$ luoctl prepare
$ luoctl state
prepared
$ luoctl cancel
$ luoctl state
normal
Signed-off-by: Pratyush Yadav <ptyadav@...zon.de>
Signed-off-by: Pasha Tatashin <pasha.tatashin@...een.com>
---
tools/lib/luo/Makefile | 6 +-
tools/lib/luo/cli/.gitignore | 1 +
tools/lib/luo/cli/Makefile | 18 ++++
tools/lib/luo/cli/luoctl.c | 178 +++++++++++++++++++++++++++++++++++
4 files changed, 202 insertions(+), 1 deletion(-)
create mode 100644 tools/lib/luo/cli/.gitignore
create mode 100644 tools/lib/luo/cli/Makefile
create mode 100644 tools/lib/luo/cli/luoctl.c
diff --git a/tools/lib/luo/Makefile b/tools/lib/luo/Makefile
index e851c37d3d0a..e8f6bd3b9e85 100644
--- a/tools/lib/luo/Makefile
+++ b/tools/lib/luo/Makefile
@@ -13,7 +13,7 @@ LIB_NAME = libluo
STATIC_LIB = $(LIB_NAME).a
SHARED_LIB = $(LIB_NAME).so
-.PHONY: all clean install
+.PHONY: all clean install cli
all: $(STATIC_LIB) $(SHARED_LIB)
@@ -26,8 +26,12 @@ $(SHARED_LIB): $(OBJS)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $@
+cli: $(STATIC_LIB)
+ $(MAKE) -C cli
+
clean:
rm -f $(OBJS) $(STATIC_LIB) $(SHARED_LIB)
+ $(MAKE) -C cli clean
install: all
install -d $(DESTDIR)/usr/local/lib
diff --git a/tools/lib/luo/cli/.gitignore b/tools/lib/luo/cli/.gitignore
new file mode 100644
index 000000000000..3a5e2d287f60
--- /dev/null
+++ b/tools/lib/luo/cli/.gitignore
@@ -0,0 +1 @@
+/luoctl
diff --git a/tools/lib/luo/cli/Makefile b/tools/lib/luo/cli/Makefile
new file mode 100644
index 000000000000..6c0cbf92a420
--- /dev/null
+++ b/tools/lib/luo/cli/Makefile
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: LGPL-3.0-or-later
+LUOCTL = luoctl
+INCLUDE_DIR = ../include
+HEADERS = $(wildcard $(INCLUDE_DIR)/*.h)
+
+CC = gcc
+CFLAGS = -Wall -Wextra -O2 -g -I$(INCLUDE_DIR)
+LDFLAGS = -L.. -l:libluo.a
+
+.PHONY: all clean
+
+all: $(LUOCTL)
+
+luoctl: luoctl.c ../libluo.a $(HEADERS)
+ $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
+
+clean:
+ rm -f $(LUOCTL)
diff --git a/tools/lib/luo/cli/luoctl.c b/tools/lib/luo/cli/luoctl.c
new file mode 100644
index 000000000000..39ba0bdd44f0
--- /dev/null
+++ b/tools/lib/luo/cli/luoctl.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: LGPL-3.0-or-later
+/**
+ * @file luoctl.c
+ * @brief Simple utility to interact with LUO
+ *
+ * This utility allows viewing and controlling LUO state.
+ *
+ * Copyright (C) 2025 Amazon.com Inc. or its affiliates.
+ * Author: Pratyush Yadav <ptyadav@...zon.de>
+ */
+
+#include <libluo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
+#define fatal(fmt, ...) \
+ do { \
+ fprintf(stderr, "Error: " fmt, ##__VA_ARGS__); \
+ exit(1); \
+ } while (0)
+
+struct command {
+ char *name;
+ int (*handler)(void);
+};
+
+static void usage(const char *prog_name)
+{
+ printf("Usage: %s [command]\n\n", prog_name);
+ printf("Commands:\n");
+ printf(" state - Show current LUO state\n");
+ printf(" prepare - Prepare for live update\n");
+ printf(" cancel - Cancel live update preparation\n");
+ printf(" finish - Signal completion of restoration\n");
+}
+
+static enum liveupdate_state get_state(void)
+{
+ enum liveupdate_state state;
+ int ret;
+
+ ret = luo_get_state(&state);
+ if (ret)
+ fatal("failed to get LUO state: %s\n", strerror(-ret));
+
+ return state;
+}
+
+static int show_state(void)
+{
+ enum liveupdate_state state;
+
+ state = get_state();
+ printf("%s\n", luo_state_to_string(state));
+ return 0;
+}
+
+static int do_prepare(void)
+{
+ enum liveupdate_state state;
+ int ret;
+
+ state = get_state();
+ if (state != LIVEUPDATE_STATE_NORMAL)
+ fatal("can only switch to prepared state from normal state. Current state: %s\n",
+ luo_state_to_string(state));
+
+ ret = luo_prepare();
+ if (ret)
+ fatal("failed to prepare for live update: %s\n", strerror(-ret));
+
+ return 0;
+}
+
+static int do_cancel(void)
+{
+ enum liveupdate_state state;
+ int ret;
+
+ state = get_state();
+ if (state != LIVEUPDATE_STATE_PREPARED)
+ fatal("can only cancel from normal state. Current state: %s\n",
+ luo_state_to_string(state));
+
+ ret = luo_cancel();
+ if (ret)
+ fatal("failed to cancel live update: %s\n", strerror(-ret));
+
+ return 0;
+}
+
+static int do_finish(void)
+{
+ enum liveupdate_state state;
+ int ret;
+
+ state = get_state();
+ if (state != LIVEUPDATE_STATE_UPDATED)
+ fatal("can only finish from updated state. Current state: %s\n",
+ luo_state_to_string(state));
+
+ ret = luo_finish();
+ if (ret)
+ fatal("failed to finish live update: %s\n", strerror(-ret));
+
+ return 0;
+}
+
+static struct command commands[] = {
+ {"state", show_state},
+ {"prepare", do_prepare},
+ {"cancel", do_cancel},
+ {"finish", do_finish},
+ {NULL, NULL},
+};
+
+int main(int argc, char *argv[])
+{
+ struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+ };
+ struct command *command;
+ int ret = -EINVAL, opt;
+ char *cmd;
+
+ if (!luo_is_available()) {
+ fprintf(stderr, "LUO is not available on this system\n");
+ return 1;
+ }
+
+ while ((opt = getopt_long(argc, argv, "ht:e:", long_options, NULL)) != -1) {
+ switch (opt) {
+ case 'h':
+ usage(argv[0]);
+ return 0;
+ default:
+ fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
+ return 1;
+ }
+ }
+
+ if (argc - optind != 1) {
+ usage(argv[0]);
+ return 1;
+ }
+
+ cmd = argv[optind];
+
+ ret = luo_init();
+ if (ret < 0) {
+ fprintf(stderr, "Failed to initialize LibLUO: %s\n", strerror(-ret));
+ return 1;
+ }
+
+ command = &commands[0];
+ while (command->name) {
+ if (!strcmp(cmd, command->name)) {
+ ret = command->handler();
+ break;
+ }
+ command++;
+ }
+
+ if (!command->name) {
+ fprintf(stderr, "Unknown command %s. Try '%s --help' for more information\n",
+ cmd, argv[0]);
+ ret = -EINVAL;
+ }
+
+ luo_cleanup();
+ return (ret < 0) ? 1 : 0;
+}
--
2.50.0.727.gbf7dc18ff4-goog
Powered by blists - more mailing lists