12 static char *user
= NULL
;
13 static char *port
= "11300";
14 static char *host_addr
;
17 su(const char *user
) {
22 pwent
= getpwnam(user
);
23 if (errno
) twarn("getpwnam(\"%s\")", user
), exit(32);
24 if (!pwent
) twarnx("getpwnam(\"%s\"): no such user", user
), exit(33);
26 r
= setgid(pwent
->pw_gid
);
27 if (r
== -1) twarn("setgid(%d \"%s\")", pwent
->pw_gid
, user
), exit(34);
29 r
= setuid(pwent
->pw_uid
);
30 if (r
== -1) twarn("setuid(%d \"%s\")", pwent
->pw_uid
, user
), exit(34);
40 sa
.sa_handler
= SIG_IGN
;
42 r
= sigemptyset(&sa
.sa_mask
);
43 if (r
== -1) twarn("sigemptyset()"), exit(111);
45 r
= sigaction(SIGPIPE
, &sa
, 0);
46 if (r
== -1) twarn("sigaction(SIGPIPE)"), exit(111);
48 sa
.sa_handler
= enter_drain_mode
;
49 r
= sigaction(SIGUSR1
, &sa
, 0);
50 if (r
== -1) twarn("sigaction(SIGUSR1)"), exit(111);
54 usage(char *msg
, char *arg
)
56 if (arg
) warnx("%s: %s", msg
, arg
);
57 fprintf(stderr
, "Use: %s [OPTIONS]\n"
60 " -b DIR wal directory (must be absolute path if used with -d)\n"
61 " -f MS fsync at most once every MS milliseconds"
62 " (use -f 0 for \"always fsync\")\n"
63 " -F never fsync (default)\n"
64 " -l ADDR listen on address (default is 0.0.0.0)\n"
65 " -p PORT listen on port (default is 11300)\n"
66 " -u USER become user and group\n"
67 " -z BYTES set the maximum job size in bytes (default is %d)\n"
68 " -s BYTES set the size of each wal file (default is %d)\n"
69 " (will be rounded up to a multiple of 512 bytes)\n"
70 " -v show version information\n"
71 " -h show this help\n",
72 progname
, JOB_DATA_SIZE_LIMIT_DEFAULT
, Filesizedef
);
77 parse_size_t(char *str
)
82 r
= sscanf(str
, "%zu%c", &size
, &x
);
83 if (1 != r
) usage("invalid size", str
);
88 require_arg(char *opt
, char *arg
)
90 if (!arg
) usage("option requires an argument", opt
);
95 warn_systemd_ignored_option(char *opt
, char *arg
)
97 if (sd_listen_fds(0) > 0) {
98 warnx("inherited listen fd; ignoring option: %s %s", opt
, arg
);
103 opts(int argc
, char **argv
, Wal
*w
)
108 for (i
= 1; i
< argc
; ++i
) {
109 if (argv
[i
][0] != '-') usage("unknown option", argv
[i
]);
110 if (argv
[i
][1] == 0 || argv
[i
][2] != 0) usage("unknown option",argv
[i
]);
111 switch (argv
[i
][1]) {
113 port
= require_arg("-p", argv
[++i
]);
114 warn_systemd_ignored_option("-p", argv
[i
]);
117 host_addr
= require_arg("-l", argv
[++i
]);
118 warn_systemd_ignored_option("-l", argv
[i
]);
121 job_data_size_limit
= parse_size_t(require_arg("-z",
125 w
->filesz
= parse_size_t(require_arg("-s", argv
[++i
]));
128 ms
= (int64
)parse_size_t(require_arg("-f", argv
[++i
]));
129 w
->syncrate
= ms
* 1000000;
136 user
= require_arg("-u", argv
[++i
]);
139 w
->dir
= require_arg("-b", argv
[++i
]);
145 printf("beanstalkd %s\n", version
);
148 usage("unknown option", argv
[i
]);
154 main(int argc
, char **argv
)
158 s
.wal
.filesz
= Filesizedef
;
159 struct job list
= {};
162 opts(argc
, argv
, &s
.wal
);
164 r
= make_server_socket(host_addr
, port
);
165 if (r
== -1) twarnx("make_server_socket()"), exit(111);
174 // We want to make sure that only one beanstalkd tries
175 // to use the wal directory at a time. So acquire a lock
176 // now and never release it.
177 if (!waldirlock(&s
.wal
)) {
178 twarnx("failed to lock wal dir %s", s
.wal
.dir
);
182 list
.prev
= list
.next
= &list
;
183 walinit(&s
.wal
, &list
);
184 prot_replay(&s
, &list
);