mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-08 11:39:39 +00:00
DM: add command module for command monitor
The command module provides interfaces to find a command intance, register handler for specified command, dispatch command and invoke related handler. find_command: find a command instance by name. register_command_handler: register the handler for one command instance. dispatch_command_handlers: dispatch the command and invoke registered handler. v1-->v2: Only support single handler for one command instance. v2-->v3: Remove command id. Add error check to avoid regiter handler to command instance which has handler. Update the second parameter type of register_command_handler to avoid unnecessary type conversion. Tracked-On: #5921 Signed-off-by: Xiangyang Wu <xiangyang.wu@intel.com> Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
26fdfc6a30
commit
a31bd7bb0d
88
devicemodel/core/cmd_monitor/command.c
Normal file
88
devicemodel/core/cmd_monitor/command.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <pthread.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/un.h>
|
||||
#include "command.h"
|
||||
#include "vmmapi.h"
|
||||
#include "log.h"
|
||||
|
||||
#define GEN_CMD_OBJ(cmd_name) \
|
||||
{.name = cmd_name,}
|
||||
#define CMD_OBJS \
|
||||
GEN_CMD_OBJ(DESTROY), \
|
||||
GEN_CMD_OBJ(BLKRESCAN), \
|
||||
|
||||
struct command dm_command_list[CMDS_NUM] = {CMD_OBJS};
|
||||
|
||||
int dispatch_command_handlers(void *arg)
|
||||
{
|
||||
struct command *cmd = (struct command *)arg;
|
||||
int ret = 0;
|
||||
|
||||
pr_info("Handle command %s in command monitor.\n", cmd->name);
|
||||
if (cmd->cmd_handler.fn) {
|
||||
ret = cmd->cmd_handler.fn(cmd->cmd_handler.arg, &cmd->para);
|
||||
pr_info("Command handler ret=%d.\n", ret);
|
||||
} else {
|
||||
pr_info("No handler for command: %s.\r\n", cmd->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
struct command *find_command(const char *name)
|
||||
{
|
||||
for (int i = 0; (i < CMDS_NUM) && (name != NULL); i++) {
|
||||
if (strcmp(dm_command_list[i].name, name) == 0)
|
||||
return &dm_command_list[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int register_command_handler(cmd_handler *fn, struct handler_args *arg, const char *cmd_name)
|
||||
{
|
||||
struct command *cmd;
|
||||
struct handler_args *handler_arg;
|
||||
|
||||
if ((!fn) || (!arg) || (!cmd_name)) {
|
||||
pr_err("%s : Failed to register command_handler.\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cmd = find_command(cmd_name);
|
||||
if (cmd == NULL) {
|
||||
pr_err("%s : invalid command name %s.\r\n", __func__, cmd_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cmd->cmd_handler.fn != NULL) {
|
||||
pr_err("Failed to register command handler since the handler have already been registered.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
cmd->cmd_handler.fn = fn;
|
||||
|
||||
handler_arg = calloc(1, sizeof(*handler_arg));
|
||||
if (!handler_arg) {
|
||||
pr_err("Failed to allocate command handler argument.\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
cmd->cmd_handler.arg = handler_arg;
|
||||
cmd->cmd_handler.arg->channel_arg = arg->channel_arg;
|
||||
cmd->cmd_handler.arg->ctx_arg = arg->ctx_arg;
|
||||
|
||||
return 0;
|
||||
}
|
61
devicemodel/core/cmd_monitor/command.h
Normal file
61
devicemodel/core/cmd_monitor/command.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _COMMAND_H_
|
||||
#define _COMMAND_H_
|
||||
#include <pthread.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
|
||||
#define DESTROY "destroy"
|
||||
#define BLKRESCAN "blkrescan"
|
||||
|
||||
#define CMDS_NUM 2U
|
||||
#define CMD_NAME_MAX 32U
|
||||
#define CMD_ARG_MAX 320U
|
||||
|
||||
typedef int (cmd_handler)(void *arg, void *command_para);
|
||||
struct handler_args {
|
||||
void *channel_arg;
|
||||
void *ctx_arg;
|
||||
};
|
||||
struct command_handler {
|
||||
struct handler_args *arg;
|
||||
cmd_handler *fn;
|
||||
};
|
||||
struct command_parameters {
|
||||
int fd;
|
||||
char option[CMD_ARG_MAX];
|
||||
};
|
||||
struct command {
|
||||
const char name[CMD_NAME_MAX]; /**< command name */
|
||||
struct command_parameters para;
|
||||
|
||||
/* command handler */
|
||||
struct command_handler cmd_handler;
|
||||
};
|
||||
/**
|
||||
* @brief register command handler, other module can use this interface to
|
||||
* register multiple handler for one command.
|
||||
*
|
||||
* @param fn the command handler which will be registered
|
||||
* @param arg the parameter which will be passed into hanlder
|
||||
* @param cmd_name the command name
|
||||
*/
|
||||
int register_command_handler(cmd_handler *fn, struct handler_args *arg, const char *cmd_name);
|
||||
/**
|
||||
* @brief find a command instance by name
|
||||
*
|
||||
* @param name the command name
|
||||
* @return command instance
|
||||
*/
|
||||
struct command *find_command(const char *name);
|
||||
/**
|
||||
* @brief dispatch the command and invoke registered handler.
|
||||
*
|
||||
* @param arg command instance
|
||||
* @return the flag indicates the state of command handler execution
|
||||
*/
|
||||
int dispatch_command_handlers(void *arg);
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user