From 30f58eb78a7561d95398009c402fee5a2c7d029b 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 (cherry picked from commit 582c6c28ba0691169790a9b1b0509cee9917b5a3) --- 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 73c8005243..997cae4967 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 1b499ae6316ba735ad115a5f01a0c4f8a6ab635e 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 (cherry picked from commit 4cc65278c490ebfc9948f480d223c751a6201da2) --- cf-agent/nfs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cf-agent/nfs.c b/cf-agent/nfs.c index 997cae4967..c7602fa4b6 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