mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-28 00:06:55 +00:00
tools: replace payload[0] of struct mngr_msg with an union
acrn-manager message structure has a flexible member payload[0], that risks to out-of-boundary memory access, and usage of uninitialized variable. And the req/ack message pairs has various types, which extend mngr_msg. mngr_send_msg() requires programmer cast the type of input messages to struct mngr_msg, that is inconvenient. We replace payload[0] with an union, which contains all payload data. So that type cast for mngr_send_msg() is no longer needed. And we can avoid potential out-of-boundary memory accessing and using of uninitialized variable Acked-by: Yan Like <like.yan@intel.com> Signed-off-by: Tao Yuhong <yuhong.tao@intel.com>
This commit is contained in:
parent
ec860097d1
commit
9695d3bd15
@ -58,8 +58,8 @@ unsigned get_wakeup_reason(void)
|
||||
int set_wakeup_timer(time_t t)
|
||||
{
|
||||
int acrnd_fd;
|
||||
struct req_acrnd_timer req;
|
||||
struct ack_acrnd_timer ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
int ret;
|
||||
|
||||
acrnd_fd = mngr_open_un("acrnd", MNGR_CLIENT);
|
||||
@ -67,22 +67,22 @@ int set_wakeup_timer(time_t t)
|
||||
return -1;
|
||||
}
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = ACRND_TIMER;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(req);
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = ACRND_TIMER;
|
||||
req.timestamp = time(NULL);
|
||||
|
||||
req.t = t;
|
||||
strncpy(req.name, vmname, sizeof(req.name));
|
||||
req.data.rtc_timer.t = t;
|
||||
strncpy(req.data.rtc_timer.vmname, vmname,
|
||||
sizeof(req.data.rtc_timer.vmname));
|
||||
|
||||
ret = mngr_send_msg(acrnd_fd, &req.msg, &ack.msg, sizeof(ack), 2);
|
||||
ret = mngr_send_msg(acrnd_fd, &req, &ack, 2);
|
||||
mngr_close(acrnd_fd);
|
||||
if (ret != sizeof(ack)) {
|
||||
fprintf(stderr, "%s %d\r\n", __FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ack.err;
|
||||
return ack.data.err;
|
||||
}
|
||||
|
||||
static LIST_HEAD(vm_ops_list, vm_ops) vm_ops_head;
|
||||
@ -122,18 +122,18 @@ static int monitor_fd = -1;
|
||||
/* handlers */
|
||||
#define ACK_TIMEOUT 1
|
||||
|
||||
#define DEFINE_HANDLER(name, type, func) \
|
||||
#define DEFINE_HANDLER(name, func) \
|
||||
static void name(struct mngr_msg *msg, int client_fd, void *param) \
|
||||
{ \
|
||||
struct req_##type *req = (void*)msg; \
|
||||
struct ack_##type ack; \
|
||||
struct mngr_msg ack; \
|
||||
struct vm_ops *ops; \
|
||||
\
|
||||
int ret = 0; \
|
||||
int count = 0; \
|
||||
\
|
||||
memcpy(&ack.msg, &req->msg, sizeof(req->msg)); \
|
||||
ack.msg.len = sizeof(ack); \
|
||||
ack.magic = MNGR_MSG_MAGIC; \
|
||||
ack.msgid = msg->msgid; \
|
||||
ack.timestamp = msg->timestamp; \
|
||||
\
|
||||
LIST_FOREACH(ops, &vm_ops_head, list) { \
|
||||
if (ops->ops->func) { \
|
||||
@ -143,29 +143,29 @@ static void name(struct mngr_msg *msg, int client_fd, void *param) \
|
||||
} \
|
||||
\
|
||||
if (!count) { \
|
||||
ack.err = -1; \
|
||||
fprintf(stderr, "No handler for id:%u\r\n", req->msg.msgid); \
|
||||
ack.data.err = -1; \
|
||||
fprintf(stderr, "No handler for id:%u\r\n", msg->msgid); \
|
||||
} else \
|
||||
ack.err = ret; \
|
||||
ack.data.err = ret; \
|
||||
\
|
||||
mngr_send_msg(client_fd, &ack.msg, NULL, 0, ACK_TIMEOUT); \
|
||||
mngr_send_msg(client_fd, &ack, NULL, ACK_TIMEOUT); \
|
||||
}
|
||||
|
||||
DEFINE_HANDLER(handle_stop, dm_stop, stop);
|
||||
DEFINE_HANDLER(handle_suspend, dm_suspend, suspend);
|
||||
DEFINE_HANDLER(handle_pause, dm_pause, pause);
|
||||
DEFINE_HANDLER(handle_continue, dm_continue, unpause);
|
||||
DEFINE_HANDLER(handle_stop, stop);
|
||||
DEFINE_HANDLER(handle_suspend, suspend);
|
||||
DEFINE_HANDLER(handle_pause, pause);
|
||||
DEFINE_HANDLER(handle_continue, unpause);
|
||||
|
||||
static void handle_resume(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_dm_resume *req = (void *)msg;
|
||||
struct ack_dm_resume ack;
|
||||
struct mngr_msg ack;
|
||||
struct vm_ops *ops;
|
||||
int ret = 0;
|
||||
int count = 0;
|
||||
|
||||
memcpy(&ack.msg, &req->msg, sizeof(req->msg));
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.magic = MNGR_MSG_MAGIC;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
|
||||
LIST_FOREACH(ops, &vm_ops_head, list) {
|
||||
if (ops->ops->resume) {
|
||||
@ -175,35 +175,34 @@ static void handle_resume(struct mngr_msg *msg, int client_fd, void *param)
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
ack.err = -1;
|
||||
fprintf(stderr, "No handler for id:%u\r\n", req->msg.msgid);
|
||||
ack.data.err = -1;
|
||||
fprintf(stderr, "No handler for id:%u\r\n", msg->msgid);
|
||||
} else
|
||||
ack.err = ret;
|
||||
ack.data.err = ret;
|
||||
|
||||
wakeup_reason = req->reason;
|
||||
wakeup_reason = msg->data.reason;
|
||||
|
||||
mngr_send_msg(client_fd, &ack.msg, NULL, 0, ACK_TIMEOUT);
|
||||
mngr_send_msg(client_fd, &ack, NULL, ACK_TIMEOUT);
|
||||
}
|
||||
|
||||
static void handle_query(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_dm_query *req = (void *)msg;
|
||||
struct ack_dm_query ack;
|
||||
struct mngr_msg ack;
|
||||
struct vm_ops *ops;
|
||||
|
||||
memcpy(&ack.msg, &req->msg, sizeof(req->msg));
|
||||
ack.msg.len = sizeof(ack);
|
||||
|
||||
ack.state = -1;
|
||||
ack.magic = MNGR_MSG_MAGIC;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
ack.data.state = -1;
|
||||
|
||||
LIST_FOREACH(ops, &vm_ops_head, list) {
|
||||
if (ops->ops->query) {
|
||||
ack.state = ops->ops->query(ops->arg);
|
||||
ack.data.state = ops->ops->query(ops->arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mngr_send_msg(client_fd, &ack.msg, NULL, 0, ACK_TIMEOUT);
|
||||
mngr_send_msg(client_fd, &ack, NULL, ACK_TIMEOUT);
|
||||
}
|
||||
|
||||
int monitor_init(struct vmctx *ctx)
|
||||
|
@ -338,93 +338,93 @@ static int cbcd_fd;
|
||||
|
||||
static void handle_shutdown(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_power_state *req = (void *)msg;
|
||||
struct ack_power_state ack;
|
||||
struct mngr_msg ack;
|
||||
|
||||
memcpy(&ack.msg, &req->msg, sizeof(req->msg));
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.err = 0;
|
||||
ack.magic = MNGR_MSG_MAGIC;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
ack.data.err = 0;
|
||||
|
||||
fprintf(stderr, "acrnd agreed to shutdown\n");
|
||||
state_transit(S_ACRND_SHUTDOWN);
|
||||
mngr_send_msg(client_fd, &ack.msg, NULL, 0, 0);
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
}
|
||||
|
||||
static void handle_suspend(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_power_state *req = (void *)msg;
|
||||
struct ack_power_state ack;
|
||||
struct mngr_msg ack;
|
||||
|
||||
memcpy(&ack.msg, &req->msg, sizeof(req->msg));
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.err = 0;
|
||||
ack.magic = MNGR_MSG_MAGIC;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
ack.data.err = 0;
|
||||
|
||||
state_transit(S_ACRND_SUSPEND);
|
||||
mngr_send_msg(client_fd, &ack.msg, NULL, 0, 0);
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
}
|
||||
|
||||
static void handle_reboot(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_power_state *req = (void *)msg;
|
||||
struct ack_power_state ack;
|
||||
struct mngr_msg ack;
|
||||
|
||||
memcpy(&ack.msg, &req->msg, sizeof(req->msg));
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.err = 0;
|
||||
ack.magic = MNGR_MSG_MAGIC;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
|
||||
ack.data.err = 0;
|
||||
|
||||
state_transit(S_ACRND_REBOOT);
|
||||
mngr_send_msg(client_fd, &ack.msg, NULL, 0, 0);
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
}
|
||||
|
||||
static void handle_wakeup_reason(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_wakeup_reason *req = (void *)msg;
|
||||
struct ack_wakeup_reason ack;
|
||||
struct mngr_msg ack;
|
||||
|
||||
memcpy(&ack.msg, &req->msg, sizeof(req->msg));
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.reason = wakeup_reason;
|
||||
mngr_send_msg(client_fd, &ack.msg, NULL, 0, 0);
|
||||
ack.magic = MNGR_MSG_MAGIC;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
|
||||
ack.data.reason = wakeup_reason;
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
}
|
||||
|
||||
static void handle_rtc(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_rtc_timer *req = (void *)msg;
|
||||
struct ack_rtc_timer ack;
|
||||
struct mngr_msg ack;
|
||||
|
||||
memcpy(&ack.msg, &req->msg, sizeof(req->msg));
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.magic = MNGR_MSG_MAGIC;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
|
||||
fprintf(stderr, "%s request rtc timer at %lu, result will be %d\n",
|
||||
req->vmname, req->t, ack.err);
|
||||
msg->data.rtc_timer.vmname, msg->data.rtc_timer.t,
|
||||
ack.data.err);
|
||||
/* Need wait IOC firmware to support RTC */
|
||||
ack.err = -1;
|
||||
ack.data.err = -1;
|
||||
|
||||
mngr_send_msg(client_fd, &ack.msg, NULL, 0, 0);
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
}
|
||||
|
||||
static int send_acrnd_start(void)
|
||||
{
|
||||
int acrnd_fd;
|
||||
int ret;
|
||||
struct req_acrnd_resume req = {
|
||||
.msg = {
|
||||
.msgid = ACRND_RESUME,
|
||||
.magic = MNGR_MSG_MAGIC,
|
||||
.len = sizeof (req),
|
||||
}
|
||||
struct mngr_msg req = {
|
||||
.msgid = ACRND_RESUME,
|
||||
.magic = MNGR_MSG_MAGIC,
|
||||
};
|
||||
struct ack_acrnd_resume ack;
|
||||
struct mngr_msg ack;
|
||||
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.timestamp = time(NULL);
|
||||
acrnd_fd = mngr_open_un(acrnd_name, MNGR_CLIENT);
|
||||
if (acrnd_fd < 0) {
|
||||
fprintf(stderr, "cannot open %s socket\n", acrnd_name);
|
||||
return -1;
|
||||
}
|
||||
ret = mngr_send_msg(acrnd_fd, &req.msg, &ack.msg, sizeof(ack), 2);
|
||||
ret = mngr_send_msg(acrnd_fd, &req, &ack, 2);
|
||||
if (ret > 0)
|
||||
fprintf(stderr, "result %d\n", ack.err);
|
||||
fprintf(stderr, "result %d\n", ack.data.err);
|
||||
mngr_close(acrnd_fd);
|
||||
return ret;
|
||||
}
|
||||
@ -433,26 +433,27 @@ static int send_acrnd_stop(void)
|
||||
{
|
||||
int acrnd_fd;
|
||||
int ret;
|
||||
struct req_acrnd_stop req = {
|
||||
.msg = {
|
||||
.msgid = ACRND_STOP,
|
||||
.magic = MNGR_MSG_MAGIC,
|
||||
.len = sizeof (req),
|
||||
},
|
||||
.force = 0,
|
||||
.timeout = 20,
|
||||
struct mngr_msg req = {
|
||||
.msgid = ACRND_STOP,
|
||||
.magic = MNGR_MSG_MAGIC,
|
||||
.data = {
|
||||
.acrnd_stop = {
|
||||
.force = 0,
|
||||
.timeout = 20,
|
||||
},
|
||||
},
|
||||
};
|
||||
struct ack_acrnd_stop ack;
|
||||
struct mngr_msg ack;
|
||||
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.timestamp = time(NULL);
|
||||
acrnd_fd = mngr_open_un(acrnd_name, MNGR_CLIENT);
|
||||
if (acrnd_fd < 0) {
|
||||
fprintf(stderr, "cannot open %s socket\n", acrnd_name);
|
||||
return -1;
|
||||
}
|
||||
ret = mngr_send_msg(acrnd_fd, &req.msg, &ack.msg, sizeof(ack), 2);
|
||||
ret = mngr_send_msg(acrnd_fd, &req, &ack, 2);
|
||||
if (ret > 0)
|
||||
fprintf(stderr, "result %d\n", ack.err);
|
||||
fprintf(stderr, "result %d\n", ack.data.err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ static int server_parse_buf(struct mngr_fd *mfd, struct mngr_client *client)
|
||||
msg = client->buf + p;
|
||||
|
||||
/* do we out-of-boundary? */
|
||||
if (p + msg->len > client->len) {
|
||||
if (p + sizeof(struct mngr_msg) > client->len) {
|
||||
pdebug();
|
||||
break;
|
||||
}
|
||||
@ -206,7 +206,7 @@ static int server_parse_buf(struct mngr_fd *mfd, struct mngr_client *client)
|
||||
handled = 1;
|
||||
break;
|
||||
}
|
||||
p += msg->len;
|
||||
p += sizeof(struct mngr_msg);
|
||||
} while (p < client->len);
|
||||
|
||||
if (!handled)
|
||||
@ -593,7 +593,7 @@ int mngr_add_handler(int server_fd, unsigned id,
|
||||
}
|
||||
|
||||
int mngr_send_msg(int fd, struct mngr_msg *req, struct mngr_msg *ack,
|
||||
size_t ack_len, unsigned timeout)
|
||||
unsigned timeout)
|
||||
{
|
||||
int socket_fd;
|
||||
struct mngr_fd *mfd;
|
||||
@ -634,8 +634,8 @@ int mngr_send_msg(int fd, struct mngr_msg *req, struct mngr_msg *ack,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = write(socket_fd, req, req->len);
|
||||
if (ret != req->len) {
|
||||
ret = write(socket_fd, req, sizeof(struct mngr_msg));
|
||||
if (ret != sizeof(struct mngr_msg)) {
|
||||
printf("%s %d\n", __FUNCTION__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
@ -651,7 +651,7 @@ int mngr_send_msg(int fd, struct mngr_msg *req, struct mngr_msg *ack,
|
||||
if (!FD_ISSET(socket_fd, &rfd))
|
||||
return 0;
|
||||
|
||||
ret = read(socket_fd, ack, ack_len);
|
||||
ret = read(socket_fd, ack, sizeof(struct mngr_msg));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -14,8 +14,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Basic message format */
|
||||
|
||||
#define MNGR_MSG_MAGIC 0x67736d206d6d76 /* that is char[8] "mngr msg", on X86 */
|
||||
#define VMNAME_LEN 16
|
||||
|
||||
@ -23,8 +21,48 @@ struct mngr_msg {
|
||||
unsigned long long magic; /* Make sure you get a mngr_msg */
|
||||
unsigned int msgid;
|
||||
unsigned long timestamp;
|
||||
size_t len; /* mngr_msg + payload size */
|
||||
char payload[0];
|
||||
union {
|
||||
/* ack of DM_STOP, DM_SUSPEND, DM_RESUME, DM_PAUSE, DM_CONTINUE,
|
||||
ACRND_TIMER, ACRND_STOP, ACRND_RESUME, RTC_TIMER */
|
||||
int err;
|
||||
|
||||
/* ack of WAKEUP_REASON */
|
||||
int reason;
|
||||
|
||||
/* ack of DM_QUERY */
|
||||
int state;
|
||||
|
||||
/* req of ACRND_TIMER */
|
||||
struct req_acrnd_timer {
|
||||
char name[VMNAME_LEN];
|
||||
time_t t;
|
||||
} acrnd_timer;
|
||||
|
||||
/* req of ACRND_STOP */
|
||||
struct req_acrnd_stop {
|
||||
int force;
|
||||
unsigned timeout;
|
||||
} acrnd_stop;
|
||||
|
||||
/* req of ACRND_SUSPEND */
|
||||
struct req_acrnd_suspend {
|
||||
int force;
|
||||
unsigned timeout;
|
||||
} acrnd_suspend;
|
||||
|
||||
/* req of ACRND_RESUME */
|
||||
struct req_acrnd_resume {
|
||||
int force;
|
||||
unsigned timeout;
|
||||
} acrnd_resume;
|
||||
|
||||
/* req of RTC_TIMER */
|
||||
struct req_rtc_timer {
|
||||
char vmname[VMNAME_LEN];
|
||||
time_t t;
|
||||
} rtc_timer;
|
||||
|
||||
} data;
|
||||
};
|
||||
|
||||
/* mngr_msg event types */
|
||||
@ -47,61 +85,6 @@ enum dm_msgid {
|
||||
|
||||
/* DM handled message req/ack pairs */
|
||||
|
||||
struct req_dm_stop {
|
||||
struct mngr_msg msg; /* req DM_STOP */
|
||||
};
|
||||
|
||||
struct ack_dm_stop {
|
||||
struct mngr_msg msg; /* ack DM_STOP */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_dm_suspend {
|
||||
struct mngr_msg msg; /* req DM_SUSPEND */
|
||||
};
|
||||
|
||||
struct ack_dm_suspend {
|
||||
struct mngr_msg msg; /* ack DM_SUSPEND */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_dm_resume {
|
||||
struct mngr_msg msg; /* req DM_RESUME */
|
||||
int reason;
|
||||
};
|
||||
|
||||
struct ack_dm_resume {
|
||||
struct mngr_msg msg; /* ack DM_RESUME */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_dm_pause {
|
||||
struct mngr_msg msg; /* req DM_PAUSE */
|
||||
};
|
||||
|
||||
struct ack_dm_pause {
|
||||
struct mngr_msg msg; /* ack DM_PAUSE */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_dm_continue {
|
||||
struct mngr_msg msg; /* req DM_CONTINUE */
|
||||
};
|
||||
|
||||
struct ack_dm_continue {
|
||||
struct mngr_msg msg; /* ack DM_CONTINUE */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_dm_query {
|
||||
struct mngr_msg msg; /* req DM_QUERY */
|
||||
};
|
||||
|
||||
struct ack_dm_query {
|
||||
struct mngr_msg msg; /* ack DM_QUERY */
|
||||
int state;
|
||||
};
|
||||
|
||||
/* Acrnd handled message event types */
|
||||
enum acrnd_msgid {
|
||||
/* DM -> Acrnd */
|
||||
@ -119,67 +102,6 @@ enum acrnd_msgid {
|
||||
|
||||
/* Acrnd handled message req/ack pairs */
|
||||
|
||||
struct req_acrnd_timer {
|
||||
struct mngr_msg msg; /* req ACRND_TIMER */
|
||||
char name[VMNAME_LEN];
|
||||
time_t t;
|
||||
};
|
||||
|
||||
struct ack_acrnd_timer {
|
||||
struct mngr_msg msg; /* ack ACRND_TIMER */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_acrnd_reason {
|
||||
struct mngr_msg msg; /* req ACRND_REASON */
|
||||
};
|
||||
|
||||
struct ack_acrnd_reason {
|
||||
struct mngr_msg msg; /* ack ACRND_REASON */
|
||||
int reason;
|
||||
};
|
||||
|
||||
struct req_dm_notify {
|
||||
struct mngr_msg msg; /* req DM_NOTIFY */
|
||||
int state;
|
||||
};
|
||||
|
||||
struct ack_dm_notify {
|
||||
struct mngr_msg msg; /* ack DM_NOTIFY */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_acrnd_stop {
|
||||
struct mngr_msg msg; /* req ACRND_STOP */
|
||||
int force;
|
||||
unsigned timeout;
|
||||
};
|
||||
|
||||
struct ack_acrnd_stop {
|
||||
struct mngr_msg msg; /* ack ACRND_STOP */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_acrnd_suspend {
|
||||
struct mngr_msg msg; /* req ACRND_SUSPEND */
|
||||
int force;
|
||||
unsigned timeout;
|
||||
};
|
||||
|
||||
struct ack_acrnd_suspend {
|
||||
struct mngr_msg msg; /* ack ACRND_SUSPEND */
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_acrnd_resume {
|
||||
struct mngr_msg msg; /* req ACRND_RESUME */
|
||||
};
|
||||
|
||||
struct ack_acrnd_resume {
|
||||
struct mngr_msg msg; /* ack ACRND_RESUME */
|
||||
int err;
|
||||
};
|
||||
|
||||
/* SOS-LCS handled message event types */
|
||||
enum sos_lcs_msgid {
|
||||
WAKEUP_REASON = ACRND_MAX + 1, /* Acrnd/Acrnctl request wakeup reason */
|
||||
@ -189,37 +111,6 @@ enum sos_lcs_msgid {
|
||||
REBOOT,
|
||||
};
|
||||
|
||||
/* SOS-LCS handled message req/ack pairs */
|
||||
|
||||
struct req_wakeup_reason {
|
||||
struct mngr_msg msg;
|
||||
};
|
||||
|
||||
struct ack_wakeup_reason {
|
||||
struct mngr_msg msg;
|
||||
int reason;
|
||||
};
|
||||
|
||||
struct req_rtc_timer {
|
||||
struct mngr_msg msg;
|
||||
char vmname[VMNAME_LEN];
|
||||
time_t t;
|
||||
};
|
||||
|
||||
struct ack_rtc_timer {
|
||||
struct mngr_msg msg;
|
||||
int err;
|
||||
};
|
||||
|
||||
struct req_power_state {
|
||||
struct mngr_msg msg;
|
||||
};
|
||||
|
||||
struct ack_power_state {
|
||||
struct mngr_msg msg;
|
||||
int err;
|
||||
};
|
||||
|
||||
/* helper functions */
|
||||
#define MNGR_SERVER 1 /* create a server fd, which you can add handlers onto it */
|
||||
#define MNGR_CLIENT 0 /* create a client, just send req and read ack */
|
||||
@ -260,11 +151,10 @@ int mngr_add_handler(int desc, unsigned id,
|
||||
* @param desc: descripter created using mngr_open_un
|
||||
* @param req: pointer to message to send
|
||||
* @param ack: pointer to ack struct, NULL if no ack required
|
||||
* @param ack_len: size in byte of the expected ack message
|
||||
* @param timeout: time to wait for ack, zero to blocking waiting
|
||||
* @return len of ack messsage (0 if ack is NULL) on succes, errno on error
|
||||
*/
|
||||
int mngr_send_msg(int desc, struct mngr_msg *req, struct mngr_msg *ack,
|
||||
size_t ack_len, unsigned timeout);
|
||||
unsigned timeout);
|
||||
|
||||
#endif /* ACRN_MANAGER_H */
|
||||
|
@ -60,29 +60,26 @@ struct vmmngr_struct *vmmngr_find(char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int send_msg(char *vmname, struct mngr_msg *req,
|
||||
struct mngr_msg *ack, size_t ack_len);
|
||||
static int send_msg(char *vmname, struct mngr_msg *req, struct mngr_msg *ack);
|
||||
|
||||
static int query_state(const char *name)
|
||||
{
|
||||
struct req_dm_query req;
|
||||
struct ack_dm_query ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
int ret;
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = DM_QUERY;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(req);
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = DM_QUERY;
|
||||
req.timestamp = time(NULL);
|
||||
|
||||
ret = send_msg(vmname, (struct mngr_msg *)&req,
|
||||
(struct mngr_msg *)&ack, sizeof(ack));
|
||||
ret = send_msg(vmname, &req, &ack);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (ack.state < 0)
|
||||
if (ack.data.state < 0)
|
||||
pdebug();
|
||||
|
||||
return ack.state;
|
||||
return ack.data.state;
|
||||
}
|
||||
|
||||
/* find all the running DM process, which has */
|
||||
@ -270,7 +267,7 @@ int shell_cmd(const char *cmd, char *outbuf, int len)
|
||||
}
|
||||
|
||||
static int send_msg(char *vmname, struct mngr_msg *req,
|
||||
struct mngr_msg *ack, size_t ack_len)
|
||||
struct mngr_msg *ack)
|
||||
{
|
||||
int fd, ret;
|
||||
|
||||
@ -286,7 +283,7 @@ static int send_msg(char *vmname, struct mngr_msg *req,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = mngr_send_msg(fd, req, ack, ack_len, 1);
|
||||
ret = mngr_send_msg(fd, req, ack, 1);
|
||||
if (ret < 0) {
|
||||
printf("%s: Unable to send msg\n", __FUNCTION__);
|
||||
mngr_close(fd);
|
||||
@ -326,99 +323,89 @@ int start_vm(char *vmname)
|
||||
|
||||
int stop_vm(char *vmname)
|
||||
{
|
||||
struct req_dm_stop req;
|
||||
struct ack_dm_stop ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = DM_STOP;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(req);
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = DM_STOP;
|
||||
req.timestamp = time(NULL);
|
||||
|
||||
send_msg(vmname, (struct mngr_msg *)&req,
|
||||
(struct mngr_msg *)&ack, sizeof(ack));
|
||||
if (ack.err) {
|
||||
send_msg(vmname, &req, &ack);
|
||||
if (ack.data.err) {
|
||||
printf("Error happens when try to stop vm. errno(%d)\n",
|
||||
ack.err);
|
||||
ack.data.err);
|
||||
}
|
||||
|
||||
return ack.err;
|
||||
return ack.data.err;
|
||||
}
|
||||
|
||||
int pause_vm(char *vmname)
|
||||
{
|
||||
struct req_dm_pause req;
|
||||
struct ack_dm_pause ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = DM_PAUSE;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(req);
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = DM_PAUSE;
|
||||
req.timestamp = time(NULL);
|
||||
|
||||
send_msg(vmname, (struct mngr_msg *)&req,
|
||||
(struct mngr_msg *)&ack, sizeof(ack));
|
||||
if (ack.err) {
|
||||
printf("Unable to pause vm. errno(%d)\n", ack.err);
|
||||
send_msg(vmname, &req, &ack);
|
||||
if (ack.data.err) {
|
||||
printf("Unable to pause vm. errno(%d)\n", ack.data.err);
|
||||
}
|
||||
|
||||
return ack.err;
|
||||
return ack.data.err;
|
||||
}
|
||||
|
||||
int continue_vm(char *vmname)
|
||||
{
|
||||
struct req_dm_continue req;
|
||||
struct ack_dm_continue ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = DM_CONTINUE;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(req);
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = DM_CONTINUE;
|
||||
req.timestamp = time(NULL);
|
||||
|
||||
send_msg(vmname, (struct mngr_msg *)&req,
|
||||
(struct mngr_msg *)&ack, sizeof(ack));
|
||||
send_msg(vmname, &req, &ack);
|
||||
|
||||
if (ack.err) {
|
||||
printf("Unable to continue vm. errno(%d)\n", ack.err);
|
||||
if (ack.data.err) {
|
||||
printf("Unable to continue vm. errno(%d)\n", ack.data.err);
|
||||
}
|
||||
|
||||
return ack.err;
|
||||
return ack.data.err;
|
||||
}
|
||||
|
||||
int suspend_vm(char *vmname)
|
||||
{
|
||||
struct req_dm_suspend req;
|
||||
struct ack_dm_suspend ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = DM_SUSPEND;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(req);
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = DM_SUSPEND;
|
||||
req.timestamp = time(NULL);
|
||||
|
||||
send_msg(vmname, (struct mngr_msg *)&req,
|
||||
(struct mngr_msg *)&ack, sizeof(ack));
|
||||
send_msg(vmname, &req, &ack);
|
||||
|
||||
if (ack.err) {
|
||||
printf("Unable to suspend vm. errno(%d)\n", ack.err);
|
||||
if (ack.data.err) {
|
||||
printf("Unable to suspend vm. errno(%d)\n", ack.data.err);
|
||||
}
|
||||
|
||||
return ack.err;
|
||||
return ack.data.err;
|
||||
}
|
||||
|
||||
int resume_vm(char *vmname)
|
||||
{
|
||||
struct req_dm_resume req;
|
||||
struct ack_dm_resume ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = DM_RESUME;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(req);
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = DM_RESUME;
|
||||
req.timestamp = time(NULL);
|
||||
|
||||
send_msg(vmname, (struct mngr_msg *)&req,
|
||||
(struct mngr_msg *)&ack, sizeof(ack));
|
||||
send_msg(vmname, &req, &ack);
|
||||
|
||||
if (ack.err) {
|
||||
printf("Unable to resume vm. errno(%d)\n", ack.err);
|
||||
if (ack.data.err) {
|
||||
printf("Unable to resume vm. errno(%d)\n", ack.data.err);
|
||||
}
|
||||
|
||||
return ack.err;
|
||||
return ack.data.err;
|
||||
}
|
||||
|
@ -263,8 +263,8 @@ static int acrnd_fd = -1;
|
||||
unsigned get_sos_wakeup_reason(void)
|
||||
{
|
||||
int client_fd, ret = 0;
|
||||
struct req_wakeup_reason req;
|
||||
struct ack_wakeup_reason ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
|
||||
client_fd = mngr_open_un(SOS_LCS_SOCK, MNGR_CLIENT);
|
||||
if (client_fd <= 0) {
|
||||
@ -273,16 +273,14 @@ unsigned get_sos_wakeup_reason(void)
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = WAKEUP_REASON;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(struct req_wakeup_reason);
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = WAKEUP_REASON;
|
||||
req.timestamp = time(NULL);
|
||||
|
||||
if (mngr_send_msg(client_fd, (void *)&req, (void *)&ack, sizeof(ack),
|
||||
DEFAULT_TIMEOUT))
|
||||
if (mngr_send_msg(client_fd, &req, &ack, DEFAULT_TIMEOUT))
|
||||
fprintf(stderr, "Failed to get wakeup_reason from SOS, err(%d)\n", ret);
|
||||
else
|
||||
ret = ack.reason;
|
||||
ret = ack.data.reason;
|
||||
|
||||
mngr_close(client_fd);
|
||||
EXIT:
|
||||
@ -291,42 +289,40 @@ unsigned get_sos_wakeup_reason(void)
|
||||
|
||||
static void handle_timer_req(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_acrnd_timer *req = (void *)msg;
|
||||
struct ack_acrnd_timer ack;
|
||||
struct mngr_msg ack;
|
||||
struct vmmngr_struct *vm;
|
||||
struct work_arg arg = {};
|
||||
|
||||
ack.msg.msgid = req->msg.msgid;
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.msg.timestamp = req->msg.timestamp;
|
||||
ack.err = -1;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
ack.data.err = -1;
|
||||
|
||||
vmmngr_update();
|
||||
vm = vmmngr_find(req->name);
|
||||
vm = vmmngr_find(msg->data.acrnd_timer.name);
|
||||
if (!vm) {
|
||||
pdebug();
|
||||
goto reply_ack;
|
||||
}
|
||||
|
||||
strncpy(arg.name, req->name, sizeof(arg.name) - 1);
|
||||
strncpy(arg.name, msg->data.acrnd_timer.name, sizeof(arg.name) - 1);
|
||||
|
||||
if (acrnd_add_work(acrnd_vm_timer_func, &arg, req->t)) {
|
||||
if (acrnd_add_work(acrnd_vm_timer_func, &arg, msg->data.acrnd_timer.t)) {
|
||||
pdebug();
|
||||
goto reply_ack;
|
||||
}
|
||||
|
||||
ack.err = 0;
|
||||
ack.data.err = 0;
|
||||
reply_ack:
|
||||
if (client_fd > 0)
|
||||
mngr_send_msg(client_fd, (void *)&ack, NULL, 0, 0);
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
}
|
||||
|
||||
static int set_sos_timer(time_t due_time)
|
||||
{
|
||||
int client_fd, ret;
|
||||
int retry = 1;
|
||||
struct req_rtc_timer req;
|
||||
struct ack_rtc_timer ack;
|
||||
struct mngr_msg req;
|
||||
struct mngr_msg ack;
|
||||
|
||||
client_fd = mngr_open_un(SOS_LCS_SOCK, MNGR_CLIENT);
|
||||
if (client_fd <= 0) {
|
||||
@ -335,16 +331,14 @@ static int set_sos_timer(time_t due_time)
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
req.msg.magic = MNGR_MSG_MAGIC;
|
||||
req.msg.msgid = RTC_TIMER;
|
||||
req.msg.timestamp = time(NULL);
|
||||
req.msg.len = sizeof(struct req_rtc_timer);
|
||||
req.t = due_time;
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
req.msgid = RTC_TIMER;
|
||||
req.timestamp = time(NULL);
|
||||
req.data.rtc_timer.t = due_time;
|
||||
|
||||
RETRY:
|
||||
ret =
|
||||
mngr_send_msg(client_fd, (void *)&req, (void *)&ack, sizeof(ack),
|
||||
DEFAULT_TIMEOUT);
|
||||
mngr_send_msg(client_fd, &req, &ack, DEFAULT_TIMEOUT);
|
||||
while (ret != 0 && retry < 5) {
|
||||
printf("Fail to set sos wakeup timer(err:%d), retry %d...\n",
|
||||
ret, retry++);
|
||||
@ -437,37 +431,33 @@ static int _handle_acrnd_stop(unsigned int timeout)
|
||||
|
||||
static void handle_acrnd_stop(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_acrnd_stop *req = (void *)msg;
|
||||
struct ack_acrnd_stop ack;
|
||||
struct mngr_msg ack;
|
||||
|
||||
ack.msg.msgid = req->msg.msgid;
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.msg.timestamp = req->msg.timestamp;
|
||||
ack.err = _handle_acrnd_stop(req->timeout);
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
ack.data.err = _handle_acrnd_stop(msg->data.acrnd_stop.timeout);
|
||||
|
||||
store_timer_list();
|
||||
|
||||
if (client_fd > 0)
|
||||
mngr_send_msg(client_fd, (void *)&ack, NULL, 0, 0);
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
}
|
||||
|
||||
void handle_acrnd_resume(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct req_acrnd_resume *req = (void *)msg;
|
||||
struct ack_acrnd_resume ack;
|
||||
struct mngr_msg ack;
|
||||
struct stat st;
|
||||
int wakeup_reason;
|
||||
|
||||
ack.msg.msgid = req->msg.msgid;
|
||||
ack.msg.len = sizeof(ack);
|
||||
ack.msg.timestamp = req->msg.timestamp;
|
||||
ack.err = 0;
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
ack.data.err = 0;
|
||||
|
||||
/* Do we have a timer list file to load? */
|
||||
if (!stat(TIMER_LIST_FILE, &st))
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
ack.err = load_timer_list();
|
||||
if (ack.err)
|
||||
ack.data.err = load_timer_list();
|
||||
if (ack.data.err)
|
||||
pdebug();
|
||||
goto reply_ack;
|
||||
}
|
||||
@ -480,13 +470,13 @@ void handle_acrnd_resume(struct mngr_msg *msg, int client_fd, void *param)
|
||||
goto reply_ack;
|
||||
}
|
||||
|
||||
ack.err = active_all_vms();
|
||||
ack.data.err = active_all_vms();
|
||||
|
||||
reply_ack:
|
||||
unlink(TIMER_LIST_FILE);
|
||||
|
||||
if (client_fd > 0)
|
||||
mngr_send_msg(client_fd, (void *)&ack, NULL, 0, 0);
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
}
|
||||
|
||||
static void handle_on_exit(void)
|
||||
|
Loading…
Reference in New Issue
Block a user