Add flags to the Casper services.

CASPER_SERVICE_STDIO - Casper will not close the first three descriptors (stdin,
		       stdout and stderr) this can be helpful for debugging.
CASPER_SERVICE_FD - Capser will not close all other descriptors, this can
		    be useful for a filesystem service.
This commit is contained in:
Mariusz Zaborski 2016-06-08 02:03:53 +00:00
parent 311219368a
commit 920be817aa
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=301572
10 changed files with 79 additions and 47 deletions

View File

@ -46,11 +46,11 @@ bool fd_is_valid(int fd);
/* Private service functions. */
struct service *service_alloc(const char *name,
service_limit_func_t *limitfunc,
service_command_func_t *commandfunc);
service_command_func_t *commandfunc, uint64_t flags);
void service_free(struct service *service);
void service_message(struct service *service,
struct service_connection *sconn);
void service_start(struct service *service, int sock);
void service_start(struct service *service, int sock, int procfd);
const char *service_name(struct service *service);
/* Private service connection functions. */

View File

@ -73,7 +73,7 @@ service_find(const char *name)
struct casper_service *
service_register(const char *name, service_limit_func_t *limitfunc,
service_command_func_t *commandfunc)
service_command_func_t *commandfunc, uint64_t flags)
{
struct casper_service *casserv;
@ -88,7 +88,8 @@ service_register(const char *name, service_limit_func_t *limitfunc,
if (casserv == NULL)
return (NULL);
casserv->cs_service = service_alloc(name, limitfunc, commandfunc);
casserv->cs_service = service_alloc(name, limitfunc, commandfunc,
flags);
if (casserv->cs_service == NULL) {
free(casserv);
return (NULL);
@ -141,11 +142,10 @@ service_execute(int chanfd)
exit(1);
service = (struct service *)(uintptr_t)nvlist_take_number(nvl,
"service");
//XXX: We should remove this?
procfd = nvlist_take_descriptor(nvl, "procfd");
nvlist_destroy(nvl);
service_start(service, chanfd);
service_start(service, chanfd, procfd);
/* Not reached. */
exit(1);
}
@ -199,7 +199,7 @@ service_register_core(int fd)
struct service_connection *sconn;
casserv = service_register(CORE_CASPER_NAME, casper_limit,
casper_command);
casper_command, 0);
sconn = service_connection_add(casserv->cs_service, fd, NULL);
if (sconn == NULL) {
close(fd);

View File

@ -40,21 +40,25 @@ struct nvlist;
typedef struct nvlist nvlist_t;
#endif
#define CASPER_SERVICE_STDIO 0x00000001
#define CASPER_SERVICE_FD 0x00000002
typedef int service_limit_func_t(const nvlist_t *, const nvlist_t *);
typedef int service_command_func_t(const char *cmd, const nvlist_t *,
nvlist_t *, nvlist_t *);
struct casper_service *service_register(const char *name,
service_limit_func_t *limitfunc, service_command_func_t *commandfunc);
service_limit_func_t *limitfunc, service_command_func_t *commandfunc,
uint64_t flags);
#define __constructor __attribute__((constructor))
#define CREATE_SERVICE(name, limit_func, command_func) \
#define CREATE_SERVICE(name, limit_func, command_func, flags) \
static __constructor void \
init_casper_service(void) \
{ \
\
(void)service_register(name, limit_func, \
command_func); \
(void)service_register(name, limit_func, command_func, \
flags); \
}
#endif /* !_LIBCASPER_SERVICE_H_ */

View File

@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -78,6 +79,7 @@ struct service_connection {
struct service {
int s_magic;
char *s_name;
uint64_t s_flags;
service_limit_func_t *s_limit;
service_command_func_t *s_command;
TAILQ_HEAD(, service_connection) s_connections;
@ -85,7 +87,7 @@ struct service {
struct service *
service_alloc(const char *name, service_limit_func_t *limitfunc,
service_command_func_t *commandfunc)
service_command_func_t *commandfunc, uint64_t flags)
{
struct service *service;
@ -99,6 +101,7 @@ service_alloc(const char *name, service_limit_func_t *limitfunc,
}
service->s_limit = limitfunc;
service->s_command = commandfunc;
service->s_flags = flags;
TAILQ_INIT(&service->s_connections);
service->s_magic = SERVICE_MAGIC;
@ -338,8 +341,59 @@ service_name(struct service *service)
return (service->s_name);
}
static void
stdnull(void)
{
int fd;
fd = open(_PATH_DEVNULL, O_RDWR);
if (fd == -1)
errx(1, "Unable to open %s", _PATH_DEVNULL);
if (setsid() == -1)
errx(1, "Unable to detach from session");
if (dup2(fd, STDIN_FILENO) == -1)
errx(1, "Unable to cover stdin");
if (dup2(fd, STDOUT_FILENO) == -1)
errx(1, "Unable to cover stdout");
if (dup2(fd, STDERR_FILENO) == -1)
errx(1, "Unable to cover stderr");
close(fd);
}
static void
service_clean(int sock, int procfd, uint64_t flags)
{
int fd, maxfd, minfd;
assert(sock > STDERR_FILENO);
assert(procfd > STDERR_FILENO);
assert(sock != procfd);
if ((flags & CASPER_SERVICE_STDIO) == 0)
stdnull();
if ((flags & CASPER_SERVICE_FD) == 0) {
if (procfd > sock) {
maxfd = procfd;
minfd = sock;
} else {
maxfd = sock;
minfd = procfd;
}
for (fd = STDERR_FILENO + 1; fd < maxfd; fd++) {
if (fd != minfd)
close(fd);
}
closefrom(maxfd + 1);
}
}
void
service_start(struct service *service, int sock)
service_start(struct service *service, int sock, int procfd)
{
struct service_connection *sconn, *sconntmp;
fd_set fds;
@ -348,6 +402,8 @@ service_start(struct service *service, int sock)
assert(service != NULL);
assert(service->s_magic == SERVICE_MAGIC);
setproctitle("%s", service->s_name);
service_clean(sock, procfd, service->s_flags);
if (service_connection_add(service, sock, NULL) == NULL)
exit(1);

View File

@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$");
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <paths.h>
#include <stdbool.h>
#include <stdlib.h>
#include <strings.h>
@ -51,28 +50,6 @@ __FBSDID("$FreeBSD$");
/* Zygote info. */
static int zygote_sock = -1;
static void
stdnull(void)
{
int fd;
fd = open(_PATH_DEVNULL, O_RDWR);
if (fd == -1)
errx(1, "Unable to open %s", _PATH_DEVNULL);
if (setsid() == -1)
errx(1, "Unable to detach from session");
if (dup2(fd, STDIN_FILENO) == -1)
errx(1, "Unable to cover stdin");
if (dup2(fd, STDOUT_FILENO) == -1)
errx(1, "Unable to cover stdout");
if (dup2(fd, STDERR_FILENO) == -1)
errx(1, "Unable to cover stderr");
close(fd);
}
int
zygote_clone(zygote_func_t *func, int *chanfdp, int *procfdp)
{
@ -113,7 +90,7 @@ zygote_clone(zygote_func_t *func, int *chanfdp, int *procfdp)
static void
zygote_main(int sock)
{
int error, fd, procfd;
int error, procfd;
int chanfd[2];
nvlist_t *nvlin, *nvlout;
zygote_func_t *func;
@ -123,11 +100,6 @@ zygote_main(int sock)
setproctitle("zygote");
stdnull();
for (fd = STDERR_FILENO + 1; fd < sock; fd++)
close(fd);
closefrom(sock + 1);
for (;;) {
nvlin = nvlist_recv(sock, 0);
if (nvlin == NULL) {

View File

@ -759,4 +759,4 @@ dns_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
return (error);
}
CREATE_SERVICE("system.dns", dns_limit, dns_command);
CREATE_SERVICE("system.dns", dns_limit, dns_command, 0);

View File

@ -786,4 +786,4 @@ grp_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
return (error);
}
CREATE_SERVICE("system.grp", grp_limit, grp_command);
CREATE_SERVICE("system.grp", grp_limit, grp_command, 0);

View File

@ -780,4 +780,4 @@ pwd_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
return (error);
}
CREATE_SERVICE("system.pwd", pwd_limit, pwd_command);
CREATE_SERVICE("system.pwd", pwd_limit, pwd_command, 0);

View File

@ -114,4 +114,4 @@ random_command(const char *cmd, const nvlist_t *limits __unused,
return (0);
}
CREATE_SERVICE("system.random", NULL, random_command);
CREATE_SERVICE("system.random", NULL, random_command, 0);

View File

@ -290,4 +290,4 @@ sysctl_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
return (0);
}
CREATE_SERVICE("system.sysctl", sysctl_limit, sysctl_command);
CREATE_SERVICE("system.sysctl", sysctl_limit, sysctl_command, 0);