mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 09:53:10 +00:00
virinitctl: Expose fifo paths and allow caller to chose one
So far the virInitctlSetRunLevel() is fully automatic. It finds the correct fifo to use to talk to the init and it will set the desired runlevel. Well, callers (so far there is just one) will need to inspect the fifo a bit just before the runlevel is set. Therefore, expose the internal list of fifos and also allow caller to explicitly use one. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
16c123679c
commit
64eca3d5e3
@ -2056,6 +2056,7 @@ virIdentitySetX509DName;
|
|||||||
|
|
||||||
|
|
||||||
# util/virinitctl.h
|
# util/virinitctl.h
|
||||||
|
virInitctlFifos;
|
||||||
virInitctlSetRunLevel;
|
virInitctlSetRunLevel;
|
||||||
|
|
||||||
|
|
||||||
|
@ -3277,7 +3277,7 @@ lxcDomainInitctlCallback(pid_t pid ATTRIBUTE_UNUSED,
|
|||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
int *command = opaque;
|
int *command = opaque;
|
||||||
return virInitctlSetRunLevel(*command);
|
return virInitctlSetRunLevel(NULL, *command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +101,21 @@ struct virInitctlRequest {
|
|||||||
verify(sizeof(struct virInitctlRequest) == 384);
|
verify(sizeof(struct virInitctlRequest) == 384);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/*
|
|
||||||
|
/* List of fifos that inits are known to listen on */
|
||||||
|
const char *virInitctlFifos[] = {
|
||||||
|
"/run/initctl",
|
||||||
|
"/dev/initctl",
|
||||||
|
"/etc/.initctl",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virInitctlSetRunLevel:
|
||||||
|
* @fifo: the path to fifo that init listens on (can be NULL for autodetection)
|
||||||
|
* @level: the desired runlevel
|
||||||
|
*
|
||||||
* Send a message to init to change the runlevel. This function is
|
* Send a message to init to change the runlevel. This function is
|
||||||
* asynchronous-signal-safe (thus safe to use after fork of a
|
* asynchronous-signal-safe (thus safe to use after fork of a
|
||||||
* multithreaded parent) - which is good, because it should only be
|
* multithreaded parent) - which is good, because it should only be
|
||||||
@ -110,18 +124,14 @@ struct virInitctlRequest {
|
|||||||
* Returns 1 on success, 0 if initctl does not exist, -1 on error
|
* Returns 1 on success, 0 if initctl does not exist, -1 on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virInitctlSetRunLevel(virInitctlRunLevel level)
|
virInitctlSetRunLevel(const char *fifo,
|
||||||
|
virInitctlRunLevel level)
|
||||||
{
|
{
|
||||||
struct virInitctlRequest req;
|
struct virInitctlRequest req;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
const char *initctl_fifo = NULL;
|
const int open_flags = O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
const char *initctl_fifos[] = {
|
|
||||||
"/run/initctl",
|
|
||||||
"/dev/initctl",
|
|
||||||
"/etc/.initctl",
|
|
||||||
};
|
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
|
|
||||||
@ -131,17 +141,24 @@ virInitctlSetRunLevel(virInitctlRunLevel level)
|
|||||||
/* Yes it is an 'int' field, but wants a numeric character. Go figure */
|
/* Yes it is an 'int' field, but wants a numeric character. Go figure */
|
||||||
req.runlevel = '0' + level;
|
req.runlevel = '0' + level;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_CARDINALITY(initctl_fifos); i++) {
|
if (fifo) {
|
||||||
initctl_fifo = initctl_fifos[i];
|
if ((fd = open(fifo, open_flags)) < 0) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Cannot open init control %s"),
|
||||||
|
fifo);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; virInitctlFifos[i]; i++) {
|
||||||
|
fifo = virInitctlFifos[i];
|
||||||
|
|
||||||
if ((fd = open(initctl_fifo,
|
if ((fd = open(fifo, open_flags)) >= 0)
|
||||||
O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY)) >= 0)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("Cannot open init control %s"),
|
_("Cannot open init control %s"),
|
||||||
initctl_fifo);
|
fifo);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,11 +168,12 @@ virInitctlSetRunLevel(virInitctlRunLevel level)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (safewrite(fd, &req, sizeof(req)) != sizeof(req)) {
|
if (safewrite(fd, &req, sizeof(req)) != sizeof(req)) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("Failed to send request to init control %s"),
|
_("Failed to send request to init control %s"),
|
||||||
initctl_fifo);
|
fifo);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +184,8 @@ virInitctlSetRunLevel(virInitctlRunLevel level)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int virInitctlSetRunLevel(virInitctlRunLevel level ATTRIBUTE_UNUSED)
|
int virInitctlSetRunLevel(const char *fifo ATTRIBUTE_UNUSED,
|
||||||
|
virInitctlRunLevel level ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
virReportUnsupportedError();
|
virReportUnsupportedError();
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -33,6 +33,10 @@ typedef enum {
|
|||||||
VIR_INITCTL_RUNLEVEL_LAST
|
VIR_INITCTL_RUNLEVEL_LAST
|
||||||
} virInitctlRunLevel;
|
} virInitctlRunLevel;
|
||||||
|
|
||||||
int virInitctlSetRunLevel(virInitctlRunLevel level);
|
|
||||||
|
extern const char *virInitctlFifos[];
|
||||||
|
|
||||||
|
int virInitctlSetRunLevel(const char *fifo,
|
||||||
|
virInitctlRunLevel level);
|
||||||
|
|
||||||
#endif /* LIBVIRT_VIRINITCTL_H */
|
#endif /* LIBVIRT_VIRINITCTL_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user