summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlejandro Sirgo Rica <asirgo@soleta.eu>2024-07-15 16:38:07 +0200
committerAlejandro Sirgo Rica <asirgo@soleta.eu>2024-07-16 13:44:40 +0200
commite62a55ae37bfdb2aba86696dde5bc27555dd5cf8 (patch)
tree17e00961938d32d433429e072383684ace7c4cc8 /src
parentdf52acba04e85191b0fc7f10b7853fe17fb25260 (diff)
src: port setclientmode code to C
Implement most of the code from the script setclientmode into ogServer to improve error handling and logs. Use a reduced version legacy script to replace the contents of the base PXE template. This file is now called updategrubprofile. Add updategrubprofile to the new extras/ folder. Create BIOS and UEFI files for PXE boot configuration. Each file is located in a different directory and requires a different name pattern. -BIOS- File format: /opt/opengnsys/tftpboot/menu.lst/01-XX-XX-XX-XX-XX-XX Template dir: /opt/opengnsys/tftpboot/menu.lst/templates/ -UEFI- File format: /opt/opengnsys/tftpboot/grub/01-xx:xx:xx:xx:xx:xx Template dir: /opt/opengnsys/tftpboot/grub/templates/
Diffstat (limited to 'src')
-rw-r--r--src/rest.c232
1 files changed, 196 insertions, 36 deletions
diff --git a/src/rest.c b/src/rest.c
index c0e158e..32cf757 100644
--- a/src/rest.c
+++ b/src/rest.c
@@ -1286,18 +1286,204 @@ static bool og_boot_mode_is_valid(const char *name)
return found;
}
+enum {
+ OG_TFTP_BOOT_BIOS,
+ OG_TFTP_BOOT_UEFI,
+ PXE_BOOT_TYPE_MAX,
+};
+
+const char *pxe_boot_type_to_dir[] = {
+ [OG_TFTP_BOOT_BIOS] = "/opt/opengnsys/tftpboot/menu.lst",
+ [OG_TFTP_BOOT_UEFI] = "/opt/opengnsys/tftpboot/grub"
+};
+
+static const char *pxe_boot_type(const int boot_type)
+{
+ if (boot_type < 0 || boot_type >= PXE_BOOT_TYPE_MAX)
+ return NULL;
+
+ return pxe_boot_type_to_dir[boot_type];
+}
+
+static int get_grub_filename(unsigned int boot_type, const char *mac,
+ char *pxe_filename, size_t pxe_filename_size)
+{
+ const char *fmt;
+
+ switch (boot_type) {
+ case OG_TFTP_BOOT_BIOS:
+ fmt = "01-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c";
+ break;
+ case OG_TFTP_BOOT_UEFI:
+ fmt = "01-%c%c:%c%c:%c%c:%c%c:%c%c:%c%c";
+ break;
+ default:
+ syslog(LOG_ERR, "unknown boot type %d", boot_type);
+ return -1;
+ }
+
+ snprintf(pxe_filename, pxe_filename_size, fmt,
+ mac[0], mac[1],
+ mac[2], mac[3],
+ mac[4], mac[5],
+ mac[6], mac[7],
+ mac[8], mac[9],
+ mac[10], mac[11]);
+
+ switch (boot_type) {
+ case OG_TFTP_BOOT_BIOS:
+ str_toupper(pxe_filename);
+ break;
+ case OG_TFTP_BOOT_UEFI:
+ str_tolower(pxe_filename);
+ break;
+ default:
+ syslog(LOG_ERR, "unknown boot type %d", boot_type);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int get_grub_file_path(unsigned int boot_type, const char *mac,
+ char *pxe_path, size_t pxe_path_size)
+{
+ char pxe_filename[PATH_MAX + 1];
+ const char *pxe_dir;
+ int ret;
+
+ pxe_dir = pxe_boot_type(boot_type);
+ if (!pxe_dir) {
+ syslog(LOG_ERR, "Invalid boot type parameter (%s:%d)\n",
+ __func__, __LINE__);
+ return -1;
+ }
+
+ ret = get_grub_filename(boot_type, mac, pxe_filename, sizeof(pxe_filename));
+
+ if (ret < 0)
+ return -1;
+
+ ret = snprintf(pxe_path, pxe_path_size,
+ "%s/%s", pxe_dir, pxe_filename);
+
+ if (ret >= pxe_path_size) {
+ syslog(LOG_ERR, "failed to generate pxe file path (%s:%d)\n",
+ __func__, __LINE__);
+ return -1;
+ }
+ return 0;
+}
+
+static int og_remove_tftpboot_file(unsigned int boot_type, const char *mac)
+{
+ char pxe_file_path[PATH_MAX + 1];
+ int ret;
+
+ ret = get_grub_file_path(boot_type, mac, pxe_file_path, sizeof(pxe_file_path));
+ if (ret < 0)
+ return -1;
+
+ if (unlink(pxe_file_path) < 0) {
+ syslog(LOG_ERR, "failed to delete file (%s:%d) %s\n",
+ __func__, __LINE__, pxe_file_path);
+ return -1;
+ }
+ return 0;
+}
+
+static int og_create_boot_file(unsigned int boot_type, const char *mac,
+ const char *mode, char *params)
+{
+ char tmp_filename[] = "/tmp/mode_params_XXXXXX";
+ char pxe_template_path[PATH_MAX + 1];
+ char pxe_file_path[PATH_MAX + 1];
+ char cmd_params[16384] = {};
+ const char *pxe_dir;
+ int status;
+ pid_t pid;
+ int ret;
+ int fd;
+
+ pxe_dir = pxe_boot_type(boot_type);
+ if (!pxe_dir) {
+ syslog(LOG_ERR, "Invalid boot type parameter (%s:%d)\n",
+ __func__, __LINE__);
+ return -1;
+ }
+
+ snprintf(pxe_template_path, sizeof(pxe_template_path),
+ "%s/templates/%s", pxe_dir, mode);
+
+ ret = get_grub_file_path(boot_type, mac, pxe_file_path, sizeof(pxe_file_path));
+ if (ret < 0)
+ return -1;
+
+ if (unlink(pxe_file_path) < 0)
+ syslog(LOG_INFO, "failed to delete file %s (%s:%d)\n",
+ pxe_file_path, __func__, __LINE__);
+
+ snprintf(cmd_params, sizeof(cmd_params),
+ "DATA='%s'\nTEMPLATE_PATH='%s'\nPXEFILE_PATH='%s'",
+ params, pxe_template_path, pxe_file_path);
+
+ fd = mkstemp(tmp_filename);
+ if (fd < 0) {
+ syslog(LOG_ERR, "cannot generate temp file %s: %s (%s:%d)\n",
+ tmp_filename, strerror(errno), __func__, __LINE__);
+ return -1;
+ }
+
+ ret = write(fd, cmd_params, strlen(cmd_params) + 1);
+ close(fd);
+
+ if (ret < 0) {
+ syslog(LOG_ERR, "cannot write file %s: %s (%s:%d)\n",
+ tmp_filename, strerror(errno), __func__, __LINE__);
+ unlink(tmp_filename);
+ return -1;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ syslog(LOG_ERR, "fork failed (%s:%d) %s\n",
+ __func__, __LINE__, strerror(errno));
+ unlink(tmp_filename);
+ return -1;
+ }
+
+ if (pid == 0) {
+ execlp("/bin/bash", "/bin/bash",
+ "/opt/opengnsys/bin/updategrubprofile", tmp_filename, NULL);
+ syslog(LOG_ERR, "failed script execution (%s:%d) %s\n",
+ __func__, __LINE__, strerror(errno));
+ _exit(-1);
+ } else if (waitpid(pid, &status, 0) < 0) {
+ syslog(LOG_ERR, "waitpid failed (%s:%d) %s\n",
+ __func__, __LINE__, strerror(errno));
+ unlink(tmp_filename);
+ return -1;
+ }
+
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+ syslog(LOG_ERR, "failed script execution %s (%s:%d)\n",
+ strerror(errno), __func__, __LINE__);
+ unlink(tmp_filename);
+ return -1;
+ }
+
+ unlink(tmp_filename);
+
+ return 0;
+}
+
static int og_set_client_mode(struct og_dbi *dbi, const char *mac,
const char *mode)
{
- char filename[PATH_MAX + 1] = "/tmp/mode_params_XXXXXX";
- char cmd_params[16384] = {};
char params[4096] = "\0";
const char *msglog;
dbi_result result;
unsigned int i;
- int numbytes;
- int status;
- int fd;
if (!og_boot_mode_is_valid(mode)) {
syslog(LOG_ERR, "invalid boot mode in client (%s:%d)\n",
@@ -1360,40 +1546,14 @@ static int og_set_client_mode(struct og_dbi *dbi, const char *mac,
dbi_result_free(result);
- snprintf(cmd_params, sizeof(cmd_params),
- "MODE_FILE='%s'\nMAC='%s'\nDATA='%s'\nMODE='PERM'",
- mode, mac, params);
-
- fd = mkstemp(filename);
- if (fd < 0) {
- syslog(LOG_ERR, "cannot generate temp file (%s:%d)\n",
- __func__, __LINE__);
- return -1;
- }
-
- numbytes = write(fd, cmd_params, strlen(cmd_params) + 1);
- close(fd);
-
- if (numbytes < 0) {
- syslog(LOG_ERR, "cannot write file\n");
- unlink(filename);
- return -1;
- }
-
- if (fork() == 0) {
- execlp("/bin/bash", "/bin/bash",
- "/opt/opengnsys/bin/setclientmode", filename, NULL);
- syslog(LOG_ERR, "failed script execution (%s:%d)\n",
- __func__, __LINE__);
+ if (og_create_boot_file(OG_TFTP_BOOT_BIOS, mac, mode, params) < 0) {
+ syslog(LOG_ERR, "failed to create BIOS boot file (%s:%d)\n", __FILE__, __LINE__);
return -1;
- } else {
- wait(&status);
}
- unlink(filename);
- if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
- syslog(LOG_ERR, "failed script execution (%s:%d)\n",
- __func__, __LINE__);
+ if (og_create_boot_file(OG_TFTP_BOOT_UEFI, mac, mode, params) < 0) {
+ og_remove_tftpboot_file(OG_TFTP_BOOT_BIOS, mac);
+ syslog(LOG_ERR, "failed to create UEFI boot file (%s:%d)\n", __FILE__, __LINE__);
return -1;
}