From 582c6c28ba0691169790a9b1b0509cee9917b5a3 Mon Sep 17 00:00:00 2001 From: Nick Anderson Date: Wed, 20 Aug 2025 16:48:26 -0500 Subject: [PATCH 1/2] Fixed invalid colon separating host and path from cifs and panfs in fstab This commit introduces a conditional check to format the device string for CIFS and PanFS without a colon (:), as required by their specific syntax. It also updates the logging to show the full fstab entry that is being added. Additionally, the log message has been updated to be more descriptive, now displaying the full fstab entry that is being added. Ticket: CFE-4494 --- cf-agent/nfs.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/cf-agent/nfs.c b/cf-agent/nfs.c index fd5c5aafa7..fe103df790 100644 --- a/cf-agent/nfs.c +++ b/cf-agent/nfs.c @@ -468,29 +468,49 @@ int VerifyInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promi mountpt = name; fstype = a->mount.mount_type; + char device[CF_BUFSIZE]; + if (StringEqual(fstype, "cifs") || StringEqual(fstype, "panfs")) + { + NDEBUG_UNUSED int ret = snprintf(device, sizeof(device), "%s%s", host, rmountpt); + assert(ret >= 0 && ret < CF_BUFSIZE); + } + else + { + NDEBUG_UNUSED int ret = snprintf(device, sizeof(device), "%s:%s", host, rmountpt); + assert(ret >= 0 && ret < CF_BUFSIZE); + } + #if defined(__QNX__) || defined(__QNXNTO__) - snprintf(fstab, CF_BUFSIZE, "%s:%s \t %s %s\t%s 0 0", host, rmountpt, mountpt, fstype, opts); + NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s \t %s %s\t%s 0 0", device, mountpt, fstype, opts); + assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(_CRAY) char fstype_upper[CF_BUFSIZE]; strlcpy(fstype_upper, fstype, CF_BUFSIZE); ToUpperStrInplace(fstype_upper); - snprintf(fstab, CF_BUFSIZE, "%s:%s \t %s %s\t%s", host, rmountpt, mountpt, fstype_upper, opts); + NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s \t %s %s\t%s", device, mountpt, fstype_upper, opts); + assert(ret >= 0 && ret < CF_BUFSIZE); break; #elif defined(__hpux) - snprintf(fstab, CF_BUFSIZE, "%s:%s %s \t %s \t %s 0 0", host, rmountpt, mountpt, fstype, opts); + NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s %s \t %s \t %s 0 0", device, mountpt, fstype, opts); + assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(_AIX) - snprintf(fstab, CF_BUFSIZE, - "%s:\n\tdev\t= %s\n\ttype\t= %s\n\tvfs\t= %s\n\tnodename\t= %s\n\tmount\t= true\n\toptions\t= %s\n\taccount\t= false\n", - mountpt, rmountpt, fstype, fstype, host, opts); + NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, + "%s:\n\tdev\t= %s\n\ttype\t= %s\n\tvfs\t= %s\n\tnodename\t= %s\n\tmount\t= true\n\toptions\t= %s\n\taccount\t= false\n", + mountpt, rmountpt, fstype, fstype, host, opts); + assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(__linux__) - snprintf(fstab, CF_BUFSIZE, "%s:%s \t %s \t %s \t %s", host, rmountpt, mountpt, fstype, opts); + NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s \t %s \t %s \t %s", device, mountpt, fstype, opts); + assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__APPLE__) - snprintf(fstab, CF_BUFSIZE, "%s:%s \t %s \t %s \t %s 0 0", host, rmountpt, mountpt, fstype, opts); + NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s \t %s \t %s \t %s 0 0", device, mountpt, fstype, opts); + assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(__sun) || defined(sco) || defined(__SCO_DS) - snprintf(fstab, CF_BUFSIZE, "%s:%s - %s %s - yes %s", host, rmountpt, mountpt, fstype, opts); + NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s - %s %s - yes %s", device, mountpt, fstype, opts); + assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(__CYGWIN__) - snprintf(fstab, CF_BUFSIZE, "/bin/mount %s:%s %s", host, rmountpt, mountpt); + NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "/bin/mount %s %s", device, mountpt); + assert(ret >= 0 && ret < CF_BUFSIZE); #else #error "Could not determine format of fstab entry on this platform." #endif @@ -503,7 +523,7 @@ int VerifyInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promi { AppendItem(&FSTABLIST, fstab, NULL); FSTAB_EDITS++; - cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Adding file system '%s:%s' to '%s'", host, rmountpt, + cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Adding file system entry '%s' to '%s'", fstab, VFSTAB[VSYSTEMHARDCLASS]); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); changes += 1; From 4cc65278c490ebfc9948f480d223c751a6201da2 Mon Sep 17 00:00:00 2001 From: Nick Anderson Date: Fri, 22 Aug 2025 17:18:39 -0500 Subject: [PATCH 2/2] Added documentation references for file system table configuration --- cf-agent/nfs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cf-agent/nfs.c b/cf-agent/nfs.c index fe103df790..4ba7d095c7 100644 --- a/cf-agent/nfs.c +++ b/cf-agent/nfs.c @@ -481,6 +481,9 @@ int VerifyInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promi } #if defined(__QNX__) || defined(__QNXNTO__) + // QNX documents 4 fstab fields : https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.utilities/topic/f/fstab.html + // specialdevice mountpoint type mountoptions + // TODO Remove DUMP and PASS options used here (unsupported)? NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s \t %s %s\t%s 0 0", device, mountpt, fstype, opts); assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(_CRAY) @@ -492,9 +495,13 @@ int VerifyInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promi assert(ret >= 0 && ret < CF_BUFSIZE); break; #elif defined(__hpux) + // HP-UX documents 7 fstab fields: https://nixdoc.net/man-pages/HP-UX/man4/fstab.4.html + // deviceSpecialFile directory type options backupFrequency passNumber comment + // TODO Bring promise comment in as the 7th comment field # promise comment (stripped of newlines) NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s %s \t %s \t %s 0 0", device, mountpt, fstype, opts); assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(_AIX) + // AIX uses /etc/filesystems: https://www.ibm.com/docs/en/aix/7.2.0?topic=files-filesystems-file NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s:\n\tdev\t= %s\n\ttype\t= %s\n\tvfs\t= %s\n\tnodename\t= %s\n\tmount\t= true\n\toptions\t= %s\n\taccount\t= false\n", mountpt, rmountpt, fstype, fstype, host, opts); @@ -503,12 +510,18 @@ int VerifyInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promi NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s \t %s \t %s \t %s", device, mountpt, fstype, opts); assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__APPLE__) + // BSDs document 6 fstab fields https://man.freebsd.org/cgi/man.cgi?fstab(5) + // Device Mountpoint FStype Options Dump Pass NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s \t %s \t %s \t %s 0 0", device, mountpt, fstype, opts); assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(__sun) || defined(sco) || defined(__SCO_DS) + // SunOS uses /etc/fstab and documents 7 fields: https://docs.oracle.com/cd/E19455-01/805-6331/fsadm-59727/index.html + // deviceToMount deviceToFsck mountPoint FStype fsckPass automount? mountOptions + // - is used for deviceToFsck for read-only and network based file systems NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "%s - %s %s - yes %s", device, mountpt, fstype, opts); assert(ret >= 0 && ret < CF_BUFSIZE); #elif defined(__CYGWIN__) + // https://cygwin.com/cygwin-ug-net/using.html#mount-table NDEBUG_UNUSED int ret = snprintf(fstab, CF_BUFSIZE, "/bin/mount %s %s", device, mountpt); assert(ret >= 0 && ret < CF_BUFSIZE); #else