summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2018-11-11 21:34:40 -0600
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2018-11-11 21:34:40 -0600
commit1a18c43e6cc2402befd0e6c1153e9080ba65bf98 (patch)
tree7dc49ad4e4b491af2ae4c8ee392e3a859f6cf862
parent085c88296760818170d361542c15d7bcf8c9e3cf (diff)
downloadimage-1a18c43e6cc2402befd0e6c1153e9080ba65bf98.tar.gz
image-1a18c43e6cc2402befd0e6c1153e9080ba65bf98.tar.bz2
image-1a18c43e6cc2402befd0e6c1153e9080ba65bf98.tar.xz
image-1a18c43e6cc2402befd0e6c1153e9080ba65bf98.zip
cdinit: Parameterise squashfs path (and *almost* scan /proc/cmdline for it)
-rw-r--r--cdinit.c60
1 files changed, 53 insertions, 7 deletions
diff --git a/cdinit.c b/cdinit.c
index 1cc7ba8..aadae37 100644
--- a/cdinit.c
+++ b/cdinit.c
@@ -1,6 +1,6 @@
/*
* cdinit - start up udev, find the squashfs, and get the hell out of dodge
- * Copyright (c) 2016 Adélie Linux Team. All rights reserved.
+ * Copyright (c) 2016-2018 Adélie Linux Team. All rights reserved.
* Licensed under the NCSA open source license.
* See LICENSE file included with this source for more information.
*/
@@ -23,6 +23,36 @@
/*!
+ * @brief Grab a parameter out of /proc/cmdline, if it is set.
+ * @param param The parameter you wish to read.
+ * @param def The default value if no value is set (or NULL).
+ * @returns The value of the parameter as set in /proc/cmdline, or
+ * the value of `default` if no value is set.
+ * @note If a parameter is passed on the command line but has no value
+ * (ex: 'debug'), its value will not be returned.
+ */
+const char *get_param(const char *param, const char *def)
+{
+ int cmd_fd;
+
+ if(access("/proc/cmdline", R_OK) != 0)
+ {
+ fprintf(stderr, "can't access kernel command line\n");
+ return def;
+ }
+
+ cmd_fd = open("/proc/cmdline", O_RDONLY);
+ if(cmd_fd == -1)
+ {
+ fprintf(stderr, "can't open kernel command line\n");
+ return def;
+ }
+
+ close(cmd_fd);
+ return def;
+}
+
+/*!
* @brief Invoke a specified command. Return if it is run successfully.
* @param command User-readable description of what command is to run.
* @param path The full on-disk path to the executable to run.
@@ -77,11 +107,11 @@ bool cdi_invoke(const char *command, const char *path, char * const argv[])
* multiple drives that all have media present. We can narrow it down,
* however:
*
- * - We know that our device will have 'adelie.squashfs'.
+ * - We know that our device will have the specified squashfs.
* - We know it will be mountable without external helpers, as ISO9660,
* FAT, and HFS+ are built in to the kernel.
*/
-bool cdi_find_media(void)
+bool cdi_find_media(const char *squash_name)
{
struct udev *udev;
struct udev_enumerate *dev_list;
@@ -153,12 +183,20 @@ bool cdi_find_media(void)
}
free(fstype);
- if(access("/media/adelie.squashfs", F_OK) != 0)
+ if(chdir("/media") != 0)
+ {
+ fprintf(stderr, "cdi_find_media: error accessing %s:"
+ " %s\n", dev_node, strerror(errno));
+ umount("/media");
+ continue;
+ }
+ if(faccessat(AT_FDCWD, squash_name, F_OK, 0) != 0)
{
#ifdef DEBUG
fprintf(stderr, "cdi_find_media: %s: system not found:"
" %s\n", dev_node, strerror(errno));
#endif
+ chdir("/");
umount("/media");
continue;
}
@@ -168,9 +206,10 @@ bool cdi_find_media(void)
dev_node);
#endif
- int squash_fd = open("/media/adelie.squashfs", O_RDONLY);
+ int squash_fd = openat(AT_FDCWD, squash_name, O_RDONLY);
if(squash_fd == -1)
{
+ chdir("/");
umount("/media");
continue;
}
@@ -179,6 +218,7 @@ bool cdi_find_media(void)
if(dev_fd == -1)
{
close(squash_fd);
+ chdir("/");
umount("/media");
continue;
}
@@ -196,11 +236,13 @@ bool cdi_find_media(void)
#endif
ioctl(dev_fd, LOOP_CLR_FD, 0);
close(dev_fd);
+ chdir("/");
umount("/media");
continue;
}
close(dev_fd);
+ chdir("/");
udev_device_unref(device);
device = NULL;
break;
@@ -217,6 +259,7 @@ bool cdi_find_media(void)
int main(void)
{
pid_t our_pid;
+ const char *squash;
bool found = false;
unsigned char tries = 4;
@@ -289,15 +332,18 @@ int main(void)
}
}
+ /* Figure out what our squashfs is named. */
+ squash = get_param("squashroot", "adelie.squashfs");
+
/* Now we need to iterate over the available block devices, trying to
* find our CD media.
*/
- found = cdi_find_media();
+ found = cdi_find_media(squash);
while(!found && tries--)
{
+ found = cdi_find_media(squash);
fprintf(stderr, "Attempting to acquiesce...\n");
sleep(5);
- found = cdi_find_media();
}
if(!found)