int VerifyNotInFstab(char *name, Attributes a, Promise *pp) /* Ensure filesystem is NOT in fstab, and return no of changes */ { char regex[CF_BUFSIZE]; char *host, *mountpt, *opts; Item *ip; if (!FSTABLIST) { if (!LoadFileAsItemList(&FSTABLIST, VFSTAB[VSYSTEMHARDCLASS], a, pp)) { CfOut(cf_error, "", "Couldn't open %s!\n", VFSTAB[VSYSTEMHARDCLASS]); return false; } else { FSTAB_EDITS = 0; } } if (a.mount.mount_options) { opts = Rlist2String(a.mount.mount_options, ","); } else { opts = xstrdup(VMOUNTOPTS[VSYSTEMHARDCLASS]); } host = a.mount.mount_server; mountpt = name; if (MatchFSInFstab(mountpt)) { if (a.mount.editfstab) { #if defined(_AIX) FILE *pfp; char line[CF_BUFSIZE], aixcomm[CF_BUFSIZE]; snprintf(aixcomm, CF_BUFSIZE, "/usr/sbin/rmnfsmnt -f %s", mountpt); if ((pfp = cf_popen(aixcomm, "r")) == NULL) { cfPS(cf_error, CF_FAIL, "", pp, a, "Failed to invoke /usr/sbin/rmnfsmnt to edit fstab"); return 0; } while (!feof(pfp)) { if (CfReadLine(line, CF_BUFSIZE, pfp) == -1) { FatalError("Error in CfReadLine"); } if (line[0] == '#') { continue; } if (strstr(line, "busy")) { cfPS(cf_inform, CF_INTERPT, "", pp, a, "The device under %s cannot be removed from %s\n", mountpt, VFSTAB[VSYSTEMHARDCLASS]); return 0; } } cf_pclose(pfp); return 0; /* ignore internal editing for aix , always returns 0 changes */ #else snprintf(regex, CF_BUFSIZE, ".*[\\s]+%s[\\s]+.*", mountpt); for (ip = FSTABLIST; ip != NULL; ip = ip->next) { if (FullTextMatch(regex, ip->name)) { cfPS(cf_inform, CF_CHG, "", pp, a, "Deleting file system mounted on %s.\n", host); // Check host name matches too? DeleteThisItem(&FSTABLIST, ip); FSTAB_EDITS++; } } #endif } } if (a.mount.mount_options) { free(opts); } return 0; }
int VerifyNotInFstab(EvalContext *ctx, char *name, const Attributes *a, const Promise *pp, PromiseResult *result) /* Ensure filesystem is NOT in fstab, and return no of changes */ { char regex[CF_BUFSIZE]; char *host, *mountpt, *opts; Item *ip; if (!FSTABLIST) { if (!LoadFileAsItemList(&FSTABLIST, VFSTAB[VSYSTEMHARDCLASS], a->edits)) { Log(LOG_LEVEL_ERR, "Couldn't open '%s'", VFSTAB[VSYSTEMHARDCLASS]); return false; } else { FSTAB_EDITS = 0; } } if (a->mount.mount_options) { opts = Rlist2String(a->mount.mount_options, ","); } else { opts = xstrdup(VMOUNTOPTS[VSYSTEMHARDCLASS]); } host = a->mount.mount_server; mountpt = name; if (MatchFSInFstab(mountpt)) { if (a->mount.editfstab) { #if defined(_AIX) FILE *pfp; char aixcomm[CF_BUFSIZE]; snprintf(aixcomm, CF_BUFSIZE, "/usr/sbin/rmnfsmnt -f %s", mountpt); if ((pfp = cf_popen(aixcomm, "r", true)) == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Failed to invoke /usr/sbin/rmnfsmnt to edit fstab"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return 0; } size_t line_size = CF_BUFSIZE; char *line = xmalloc(line_size); for (;;) { ssize_t res = getline(&line, &line_size, pfp); if (res == -1) { if (!feof(pfp)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to read output of /bin/rmnfsmnt"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); cf_pclose(pfp); free(line); return 0; } else { break; } } if (line[0] == '#') { continue; } if (strstr(line, "busy")) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_INTERRUPTED, pp, a, "The device under '%s' cannot be removed from '%s'", mountpt, VFSTAB[VSYSTEMHARDCLASS]); *result = PromiseResultUpdate(*result, PROMISE_RESULT_INTERRUPTED); free(line); return 0; } } free(line); cf_pclose(pfp); return 0; /* ignore internal editing for aix , always returns 0 changes */ #else Item* next; snprintf(regex, CF_BUFSIZE, ".*[\\s]+%s[\\s]+.*", mountpt); for (ip = FSTABLIST; ip != NULL; ip = next) { next = ip->next; if (FullTextMatch(ctx, regex, ip->name)) { cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "Deleting file system mounted on '%s'", host); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); // Check host name matches too? DeleteThisItem(&FSTABLIST, ip); FSTAB_EDITS++; } } #endif } } if (a->mount.mount_options) { free(opts); } return 0; }