1*f6c47fdeSJoshua M. Clulow /*
2*f6c47fdeSJoshua M. Clulow  * This file and its contents are supplied under the terms of the
3*f6c47fdeSJoshua M. Clulow  * Common Development and Distribution License ("CDDL"), version 1.0.
4*f6c47fdeSJoshua M. Clulow  * You may only use this file in accordance with the terms of version
5*f6c47fdeSJoshua M. Clulow  * 1.0 of the CDDL.
6*f6c47fdeSJoshua M. Clulow  *
7*f6c47fdeSJoshua M. Clulow  * A full copy of the text of the CDDL should have accompanied this
8*f6c47fdeSJoshua M. Clulow  * source.  A copy of the CDDL is also available via the Internet at
9*f6c47fdeSJoshua M. Clulow  * http://www.illumos.org/license/CDDL.
10*f6c47fdeSJoshua M. Clulow  */
11*f6c47fdeSJoshua M. Clulow 
12*f6c47fdeSJoshua M. Clulow /*
13*f6c47fdeSJoshua M. Clulow  * Copyright 2021 Oxide Computer Company
14*f6c47fdeSJoshua M. Clulow  */
15*f6c47fdeSJoshua M. Clulow 
16*f6c47fdeSJoshua M. Clulow /*
17*f6c47fdeSJoshua M. Clulow  * rootisramdisk: a helper program for smf_root_is_ramdisk() in
18*f6c47fdeSJoshua M. Clulow  * "/lib/svc/share/smf_include.sh".  Exits zero if the root file system is
19*f6c47fdeSJoshua M. Clulow  * mounted from a ramdisk, or non-zero if not, or if we hit an error condition.
20*f6c47fdeSJoshua M. Clulow  */
21*f6c47fdeSJoshua M. Clulow 
22*f6c47fdeSJoshua M. Clulow #include <stdlib.h>
23*f6c47fdeSJoshua M. Clulow #include <stdio.h>
24*f6c47fdeSJoshua M. Clulow #include <stdbool.h>
25*f6c47fdeSJoshua M. Clulow #include <fcntl.h>
26*f6c47fdeSJoshua M. Clulow #include <err.h>
27*f6c47fdeSJoshua M. Clulow #include <limits.h>
28*f6c47fdeSJoshua M. Clulow #include <string.h>
29*f6c47fdeSJoshua M. Clulow #include <sys/modctl.h>
30*f6c47fdeSJoshua M. Clulow #include <sys/types.h>
31*f6c47fdeSJoshua M. Clulow #include <sys/mkdev.h>
32*f6c47fdeSJoshua M. Clulow #include <sys/stat.h>
33*f6c47fdeSJoshua M. Clulow 
34*f6c47fdeSJoshua M. Clulow #define	EXIT_USAGE			2
35*f6c47fdeSJoshua M. Clulow #define	EXIT_NOT_RAMDISK		3
36*f6c47fdeSJoshua M. Clulow 
37*f6c47fdeSJoshua M. Clulow bool g_verbose = false;
38*f6c47fdeSJoshua M. Clulow 
39*f6c47fdeSJoshua M. Clulow static bool
root_is_ramdisk(void)40*f6c47fdeSJoshua M. Clulow root_is_ramdisk(void)
41*f6c47fdeSJoshua M. Clulow {
42*f6c47fdeSJoshua M. Clulow 	struct stat st;
43*f6c47fdeSJoshua M. Clulow 	major_t maj;
44*f6c47fdeSJoshua M. Clulow 	char driver[PATH_MAX + 1];
45*f6c47fdeSJoshua M. Clulow 
46*f6c47fdeSJoshua M. Clulow 	if (stat("/", &st) != 0) {
47*f6c47fdeSJoshua M. Clulow 		err(EXIT_FAILURE, "stat");
48*f6c47fdeSJoshua M. Clulow 	}
49*f6c47fdeSJoshua M. Clulow 
50*f6c47fdeSJoshua M. Clulow 	maj = major(st.st_dev);
51*f6c47fdeSJoshua M. Clulow 	if (g_verbose) {
52*f6c47fdeSJoshua M. Clulow 		fprintf(stderr, "major = %lu\n", (long unsigned)maj);
53*f6c47fdeSJoshua M. Clulow 	}
54*f6c47fdeSJoshua M. Clulow 
55*f6c47fdeSJoshua M. Clulow 	if (modctl(MODGETNAME, driver, sizeof (driver), &maj) != 0) {
56*f6c47fdeSJoshua M. Clulow 		err(EXIT_FAILURE, "modctl");
57*f6c47fdeSJoshua M. Clulow 	}
58*f6c47fdeSJoshua M. Clulow 
59*f6c47fdeSJoshua M. Clulow 	if (g_verbose) {
60*f6c47fdeSJoshua M. Clulow 		fprintf(stderr, "driver = %s\n", driver);
61*f6c47fdeSJoshua M. Clulow 	}
62*f6c47fdeSJoshua M. Clulow 
63*f6c47fdeSJoshua M. Clulow 	return (strcmp(driver, "ramdisk") == 0);
64*f6c47fdeSJoshua M. Clulow }
65*f6c47fdeSJoshua M. Clulow 
66*f6c47fdeSJoshua M. Clulow int
main(int argc,char * argv[])67*f6c47fdeSJoshua M. Clulow main(int argc, char *argv[])
68*f6c47fdeSJoshua M. Clulow {
69*f6c47fdeSJoshua M. Clulow 	int c;
70*f6c47fdeSJoshua M. Clulow 
71*f6c47fdeSJoshua M. Clulow 	while ((c = getopt(argc, argv, ":v")) != -1) {
72*f6c47fdeSJoshua M. Clulow 		switch (c) {
73*f6c47fdeSJoshua M. Clulow 		case 'v':
74*f6c47fdeSJoshua M. Clulow 			g_verbose = true;
75*f6c47fdeSJoshua M. Clulow 			break;
76*f6c47fdeSJoshua M. Clulow 		case ':':
77*f6c47fdeSJoshua M. Clulow 			errx(EXIT_USAGE, "-%c requires an operand", optopt);
78*f6c47fdeSJoshua M. Clulow 			break;
79*f6c47fdeSJoshua M. Clulow 		case '?':
80*f6c47fdeSJoshua M. Clulow 			errx(EXIT_USAGE, "-%c unknown", optopt);
81*f6c47fdeSJoshua M. Clulow 			break;
82*f6c47fdeSJoshua M. Clulow 		}
83*f6c47fdeSJoshua M. Clulow 	}
84*f6c47fdeSJoshua M. Clulow 
85*f6c47fdeSJoshua M. Clulow 	return (root_is_ramdisk() ? EXIT_SUCCESS : EXIT_NOT_RAMDISK);
86*f6c47fdeSJoshua M. Clulow }
87