1*6cf3cc9dSRobert Mustacchi /*
2*6cf3cc9dSRobert Mustacchi * This file and its contents are supplied under the terms of the
3*6cf3cc9dSRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
4*6cf3cc9dSRobert Mustacchi * You may only use this file in accordance with the terms of version
5*6cf3cc9dSRobert Mustacchi * 1.0 of the CDDL.
6*6cf3cc9dSRobert Mustacchi *
7*6cf3cc9dSRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this
8*6cf3cc9dSRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at
9*6cf3cc9dSRobert Mustacchi * http://www.illumos.org/license/CDDL.
10*6cf3cc9dSRobert Mustacchi */
11*6cf3cc9dSRobert Mustacchi
12*6cf3cc9dSRobert Mustacchi /*
13*6cf3cc9dSRobert Mustacchi * Copyright 2024 Oxide Computer Company
14*6cf3cc9dSRobert Mustacchi */
15*6cf3cc9dSRobert Mustacchi
16*6cf3cc9dSRobert Mustacchi /*
17*6cf3cc9dSRobert Mustacchi * This is a utility program for the various cp/mv/ln tests to create file
18*6cf3cc9dSRobert Mustacchi * system objects which are not as simple with basic utilities. In particular we
19*6cf3cc9dSRobert Mustacchi * support creating bound unix domain sockets, doors, and throw in a fifo for
20*6cf3cc9dSRobert Mustacchi * good measure (though that's a bit easier).
21*6cf3cc9dSRobert Mustacchi */
22*6cf3cc9dSRobert Mustacchi
23*6cf3cc9dSRobert Mustacchi #include <err.h>
24*6cf3cc9dSRobert Mustacchi #include <sys/types.h>
25*6cf3cc9dSRobert Mustacchi #include <sys/stat.h>
26*6cf3cc9dSRobert Mustacchi #include <fcntl.h>
27*6cf3cc9dSRobert Mustacchi #include <stdlib.h>
28*6cf3cc9dSRobert Mustacchi #include <unistd.h>
29*6cf3cc9dSRobert Mustacchi #include <door.h>
30*6cf3cc9dSRobert Mustacchi #include <stropts.h>
31*6cf3cc9dSRobert Mustacchi #include <string.h>
32*6cf3cc9dSRobert Mustacchi #include <sys/socket.h>
33*6cf3cc9dSRobert Mustacchi
34*6cf3cc9dSRobert Mustacchi static void
mkobj_server(void * cookie,char * argp,size_t size,door_desc_t * dp,uint_t ndesc)35*6cf3cc9dSRobert Mustacchi mkobj_server(void *cookie, char *argp, size_t size, door_desc_t *dp,
36*6cf3cc9dSRobert Mustacchi uint_t ndesc)
37*6cf3cc9dSRobert Mustacchi {
38*6cf3cc9dSRobert Mustacchi (void) door_return(NULL, 0, NULL, 0);
39*6cf3cc9dSRobert Mustacchi }
40*6cf3cc9dSRobert Mustacchi
41*6cf3cc9dSRobert Mustacchi int
main(int argc,char * argv[])42*6cf3cc9dSRobert Mustacchi main(int argc, char *argv[])
43*6cf3cc9dSRobert Mustacchi {
44*6cf3cc9dSRobert Mustacchi int c;
45*6cf3cc9dSRobert Mustacchi const char *door = NULL;
46*6cf3cc9dSRobert Mustacchi const char *fifo = NULL;
47*6cf3cc9dSRobert Mustacchi const char *uds = NULL;
48*6cf3cc9dSRobert Mustacchi
49*6cf3cc9dSRobert Mustacchi while ((c = getopt(argc, argv, ":d:f:s:")) != -1) {
50*6cf3cc9dSRobert Mustacchi switch (c) {
51*6cf3cc9dSRobert Mustacchi case 'd':
52*6cf3cc9dSRobert Mustacchi door = optarg;
53*6cf3cc9dSRobert Mustacchi break;
54*6cf3cc9dSRobert Mustacchi case 'f':
55*6cf3cc9dSRobert Mustacchi fifo = optarg;
56*6cf3cc9dSRobert Mustacchi break;
57*6cf3cc9dSRobert Mustacchi case 's':
58*6cf3cc9dSRobert Mustacchi uds = optarg;
59*6cf3cc9dSRobert Mustacchi break;
60*6cf3cc9dSRobert Mustacchi case ':':
61*6cf3cc9dSRobert Mustacchi errx(EXIT_FAILURE, "option -%c requires an operand", c);
62*6cf3cc9dSRobert Mustacchi case '?':
63*6cf3cc9dSRobert Mustacchi (void) fprintf(stderr, "unknown option: -%c\n", c);
64*6cf3cc9dSRobert Mustacchi (void) fprintf(stderr, "mkobj [-d door] [-f fifo] "
65*6cf3cc9dSRobert Mustacchi "[-s socket]\n");
66*6cf3cc9dSRobert Mustacchi exit(EXIT_FAILURE);
67*6cf3cc9dSRobert Mustacchi }
68*6cf3cc9dSRobert Mustacchi }
69*6cf3cc9dSRobert Mustacchi
70*6cf3cc9dSRobert Mustacchi argv += optind;
71*6cf3cc9dSRobert Mustacchi argc -= optind;
72*6cf3cc9dSRobert Mustacchi
73*6cf3cc9dSRobert Mustacchi if (argc != 0) {
74*6cf3cc9dSRobert Mustacchi errx(EXIT_FAILURE, "extraneous arguments starting with %s",
75*6cf3cc9dSRobert Mustacchi argv[0]);
76*6cf3cc9dSRobert Mustacchi }
77*6cf3cc9dSRobert Mustacchi
78*6cf3cc9dSRobert Mustacchi if (door == NULL && fifo == NULL && uds == NULL) {
79*6cf3cc9dSRobert Mustacchi errx(EXIT_FAILURE, "at least one of -d, -f and -s must be "
80*6cf3cc9dSRobert Mustacchi "specified");
81*6cf3cc9dSRobert Mustacchi }
82*6cf3cc9dSRobert Mustacchi
83*6cf3cc9dSRobert Mustacchi if (door != NULL) {
84*6cf3cc9dSRobert Mustacchi int fd;
85*6cf3cc9dSRobert Mustacchi
86*6cf3cc9dSRobert Mustacchi if ((fd = open(door, O_CREAT | O_EXCL | O_RDWR, 0666)) < 0) {
87*6cf3cc9dSRobert Mustacchi err(EXIT_FAILURE, "failed to create file %s for door "
88*6cf3cc9dSRobert Mustacchi "server attachment", door);
89*6cf3cc9dSRobert Mustacchi }
90*6cf3cc9dSRobert Mustacchi
91*6cf3cc9dSRobert Mustacchi (void) close(fd);
92*6cf3cc9dSRobert Mustacchi
93*6cf3cc9dSRobert Mustacchi if ((fd = door_create(mkobj_server, NULL, DOOR_REFUSE_DESC |
94*6cf3cc9dSRobert Mustacchi DOOR_NO_CANCEL)) < 0) {
95*6cf3cc9dSRobert Mustacchi err(EXIT_FAILURE, "failed to create door server");
96*6cf3cc9dSRobert Mustacchi }
97*6cf3cc9dSRobert Mustacchi
98*6cf3cc9dSRobert Mustacchi if (fattach(fd, door) != 0) {
99*6cf3cc9dSRobert Mustacchi err(EXIT_FAILURE, "failed to attach door to %s", door);
100*6cf3cc9dSRobert Mustacchi }
101*6cf3cc9dSRobert Mustacchi }
102*6cf3cc9dSRobert Mustacchi
103*6cf3cc9dSRobert Mustacchi if (fifo != NULL) {
104*6cf3cc9dSRobert Mustacchi if (mkfifo(fifo, 0666) != 0) {
105*6cf3cc9dSRobert Mustacchi err(EXIT_FAILURE, "failed to make fifo %s", fifo);
106*6cf3cc9dSRobert Mustacchi }
107*6cf3cc9dSRobert Mustacchi }
108*6cf3cc9dSRobert Mustacchi
109*6cf3cc9dSRobert Mustacchi if (uds != NULL) {
110*6cf3cc9dSRobert Mustacchi int fd;
111*6cf3cc9dSRobert Mustacchi struct sockaddr_un un;
112*6cf3cc9dSRobert Mustacchi
113*6cf3cc9dSRobert Mustacchi if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
114*6cf3cc9dSRobert Mustacchi err(EXIT_FAILURE, "failed to create a unix domain "
115*6cf3cc9dSRobert Mustacchi "socket");
116*6cf3cc9dSRobert Mustacchi }
117*6cf3cc9dSRobert Mustacchi
118*6cf3cc9dSRobert Mustacchi (void) memset(&un, 0, sizeof (un));
119*6cf3cc9dSRobert Mustacchi un.sun_family = AF_UNIX;
120*6cf3cc9dSRobert Mustacchi if (strlcpy(un.sun_path, uds, sizeof (un.sun_path)) >=
121*6cf3cc9dSRobert Mustacchi sizeof (un.sun_path)) {
122*6cf3cc9dSRobert Mustacchi errx(EXIT_FAILURE, "UDS path %s doesn't fit in "
123*6cf3cc9dSRobert Mustacchi "sockaddr sun_path", uds);
124*6cf3cc9dSRobert Mustacchi }
125*6cf3cc9dSRobert Mustacchi
126*6cf3cc9dSRobert Mustacchi if (bind(fd, (struct sockaddr *)&un, sizeof (un)) != 0) {
127*6cf3cc9dSRobert Mustacchi errx(EXIT_FAILURE, "failed to bind uds to %s", uds);
128*6cf3cc9dSRobert Mustacchi }
129*6cf3cc9dSRobert Mustacchi }
130*6cf3cc9dSRobert Mustacchi
131*6cf3cc9dSRobert Mustacchi /*
132*6cf3cc9dSRobert Mustacchi * Explicitly exit to ensure that we don't end up letting door threads
133*6cf3cc9dSRobert Mustacchi * stick around.
134*6cf3cc9dSRobert Mustacchi */
135*6cf3cc9dSRobert Mustacchi exit(EXIT_SUCCESS);
136*6cf3cc9dSRobert Mustacchi }
137