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 " -c compact the binlog (default)\n"
71 " -n do not compact the binlog\n"
72 " -v show version information\n"
73 " -h show this help\n",
74 progname
, JOB_DATA_SIZE_LIMIT_DEFAULT
, Filesizedef
);
79 parse_size_t(char *str
)
84 r
= sscanf(str
, "%zu%c", &size
, &x
);
85 if (1 != r
) usage("invalid size", str
);
90 require_arg(char *opt
, char *arg
)
92 if (!arg
) usage("option requires an argument", opt
);
97 warn_systemd_ignored_option(char *opt
, char *arg
)
99 if (sd_listen_fds(0) > 0) {
100 warnx("inherited listen fd; ignoring option: %s %s", opt
, arg
);
105 opts(int argc
, char **argv
, Wal
*w
)
110 for (i
= 1; i
< argc
; ++i
) {
111 if (argv
[i
][0] != '-') usage("unknown option", argv
[i
]);
112 if (argv
[i
][1] == 0 || argv
[i
][2] != 0) usage("unknown option",argv
[i
]);
113 switch (argv
[i
][1]) {
115 port
= require_arg("-p", argv
[++i
]);
116 warn_systemd_ignored_option("-p", argv
[i
]);
119 host_addr
= require_arg("-l", argv
[++i
]);
120 warn_systemd_ignored_option("-l", argv
[i
]);
123 job_data_size_limit
= parse_size_t(require_arg("-z",
127 w
->filesz
= parse_size_t(require_arg("-s", argv
[++i
]));
136 ms
= (int64
)parse_size_t(require_arg("-f", argv
[++i
]));
137 w
->syncrate
= ms
* 1000000;
144 user
= require_arg("-u", argv
[++i
]);
147 w
->dir
= require_arg("-b", argv
[++i
]);
153 printf("beanstalkd %s\n", version
);
156 usage("unknown option", argv
[i
]);
162 main(int argc
, char **argv
)
166 s
.wal
.filesz
= Filesizedef
;
167 struct job list
= {};
170 opts(argc
, argv
, &s
.wal
);
172 r
= make_server_socket(host_addr
, port
);
173 if (r
== -1) twarnx("make_server_socket()"), exit(111);
182 // We want to make sure that only one beanstalkd tries
183 // to use the wal directory at a time. So acquire a lock
184 // now and never release it.
185 if (!waldirlock(&s
.wal
)) {
186 twarnx("failed to lock wal dir %s", s
.wal
.dir
);
190 list
.prev
= list
.next
= &list
;
191 walinit(&s
.wal
, &list
);
192 prot_replay(&s
, &list
);