/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2002 Cluster File Systems, Inc. * Author: Peter J. Braam * Author: Phil Schwan * Author: Robert Read * * This file is part of Lustre, http://www.lustre.org. * * Lustre is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * Lustre is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Lustre; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include #include #include #include #include #include "obdctl.h" #include "parser.h" static int jt_quit(int argc, char **argv) { Parser_quit(argc, argv); return 0; } static int jt_noop(int argc, char **argv) { return 0; } static int jt_opt_ignore_errors(int argc, char **argv) { Parser_ignore_errors(1); return 0; } #include static int parse_audit_ops(char * str, __u64 * mask) { char * op = strtok(str, ","); int rc = 0; while (op) { if (!strcmp(op, "all")) { *mask |= AUDIT_ALL_OPS; break; } else if (!strcmp(op,"none")) { *mask &= ~AUDIT_ALL_OPS; } else if (!strcmp(op,"create")) SET_AUDIT_OP((*mask), AUDIT_CREATE); else if (!strcmp(op,"link")) SET_AUDIT_OP((*mask), AUDIT_LINK); else if (!strcmp(op,"delete")) SET_AUDIT_OP((*mask), AUDIT_UNLINK); else if (!strcmp(op,"rename")) SET_AUDIT_OP((*mask), AUDIT_RENAME); else if (!strcmp(op,"read")) { SET_AUDIT_OP((*mask), AUDIT_READ); SET_AUDIT_OP((*mask), AUDIT_MMAP); } else if (!strcmp(op,"write")) SET_AUDIT_OP((*mask), AUDIT_WRITE); else if (!strcmp(op,"open")) SET_AUDIT_OP((*mask), AUDIT_OPEN); else if (!strcmp(op,"stat")) SET_AUDIT_OP((*mask), AUDIT_STAT); else if (!strcmp(op,"readdir")) SET_AUDIT_OP((*mask), AUDIT_READDIR); else if (!strcmp(op,"readlink")) SET_AUDIT_OP((*mask), AUDIT_READLINK); else if (!strcmp(op,"setattr")) SET_AUDIT_OP((*mask), AUDIT_SETATTR); else { fprintf(stderr, "invalid audit operation '%s'\n", op); } op = strtok(NULL, ","); } return rc; } #include #include #include static int set_dir_audit(char * dir, __u64 mask) { int rc = 0; char * buf; DIR * sdr; struct dirent * ent = (void*)buf; buf = malloc(strlen(dir) + NAME_MAX + 1); sdr = opendir(dir); if (!sdr) { fprintf(stderr, "cannot open dir %s\n", dir); free(buf); return -1; } while ((ent = readdir(sdr)) != NULL) { int fd; if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue; sprintf(buf, "%s/%s", dir, ent->d_name); fd = open(buf, O_RDONLY); if (fd < 0) { fprintf(stderr, "can't open: %s: %s\n", buf, strerror(rc = errno)); continue; } rc = ioctl(fd, LL_IOC_AUDIT, mask); close(fd); } closedir(sdr); free(buf); return rc; } static int set_audit(int argc, char **argv, int fs) { __u64 mask = 0; struct stat st; int rc, fd; if (argc != 4) return CMD_HELP; /* audit can be for all operations or for failed only */ if (!strcmp(argv[1], "fail")) SET_AUDIT_OP(mask, AUDIT_FAIL); else if (strcmp(argv[1], "all")) { fprintf(stderr, "%s: invalid audit type %s\n", jt_cmdname(argv[0]), argv[1]); return -EINVAL; } rc = parse_audit_ops(argv[2], &mask); if (rc < 0) return -EINVAL; //open file/dir fd = open(argv[3], O_RDONLY); if (fd < 0) { fprintf(stderr, "can't open: %s: %s\n", argv[3], strerror(rc = errno)); return -1; } rc = fstat(fd, &st); if (rc) { close(fd); return rc; } //audit for fs? if (fs) SET_AUDIT_OP(mask, AUDIT_FS); else { //if dir then set audit for childs also if (S_ISDIR(st.st_mode)) { //rc = set_dir_audit(argv[3], mask | AUD_BIT(AUDIT_DIR)); } } //set audit for file/dir itself rc = ioctl(fd, LL_IOC_AUDIT, mask); close(fd); return rc; } static int jt_set_audit(int argc, char **argv) { return set_audit(argc, argv, 0); } static int jt_set_fsaudit(int argc, char **argv) { return set_audit(argc, argv, 1); } /* * XXX Should not belong to here */ static int flush_cred_ioctl(char *mp) { int fd, rc; fd = open(mp, O_RDONLY); if (fd == -1) { fprintf(stderr, "flush_cred_ioctl: error open %s: %s\n", mp, strerror(errno)); return -1; } rc = ioctl(fd, LL_IOC_FLUSH_CRED); if (rc == -1) { fprintf(stderr, "flush_cred_ioctl: error ioctl %s: %s\n", mp, strerror(errno)); } close(fd); return rc; } static int jt_flush_cred(int argc, char **argv) { FILE *proc; char procline[PATH_MAX], *line; int i, rc = 0; /* no args means search all lustre mountpoints */ if (argc < 2) { proc = fopen("/proc/mounts", "r"); if (!proc) { fprintf(stderr, "%s: can't open /proc/mounts\n", jt_cmdname(argv[0])); return -1; } while ((line = fgets(procline, PATH_MAX, proc)) != NULL) { char dev[PATH_MAX]; char mp[PATH_MAX]; char fs[PATH_MAX]; if (sscanf(line, "%s %s %s", dev, mp, fs) != 3) { fprintf(stderr, "%s: unexpected format in " "/proc/mounts\n", jt_cmdname(argv[0])); return -1; } if (strcmp(fs, "lustre") && strcmp(fs, "lustre_lite")) continue; if (flush_cred_ioctl(mp)) rc = -1; } } else { /* follow the exact flush sequence as supplied */ for (i = 1; i < argc; i++) { if (flush_cred_ioctl(argv[i])) rc = -1; } } return rc; } command_t cmdlist[] = { /* Metacommands */ {"--device", jt_opt_device, 0, "run after connecting to device \n" "--device "}, {"--threads", jt_opt_threads, 0, "run separate instances of on device \n" "--threads "}, {"--ignore_errors", jt_opt_ignore_errors, 0, "ignore errors that occur during script processing\n" "--ignore_errors"}, {"ignore_errors", jt_opt_ignore_errors, 0, "ignore errors that occur during script processing\n" "ignore_errors"}, {"dump", jt_ioc_dump, 0, "usage: dump file, save ioctl buffer to file"}, /* Network configuration commands */ {"==== network config ====", jt_noop, 0, "network config"}, {"--net", jt_opt_net, 0, "run after setting network to \n" "usage: --net "}, {"network", jt_ptl_network, 0, "commands that follow apply to net\n" "usage: network "}, {"interface_list", jt_ptl_print_interfaces, 0, "print interface entries\n" "usage: interface_list"}, {"add_interface", jt_ptl_add_interface, 0, "add interface entry\n" "usage: add_interface ip [netmask]"}, {"del_interface", jt_ptl_del_interface, 0, "del interface entry\n" "usage: del_interface [ip]"}, {"peer_list", jt_ptl_print_peers, 0, "print peer entries\n" "usage: peer_list"}, {"add_peer", jt_ptl_add_peer, 0, "add an peer entry\n" "usage: add_peer "}, {"del_peer", jt_ptl_del_peer, 0, "remove an peer entry\n" "usage: del_peer [] [] [ks]"}, {"conn_list", jt_ptl_print_connections, 0, "print all the connected remote nid\n" "usage: conn_list"}, {"connect", jt_ptl_connect, 0, "connect to a remote nid\n" "usage: connect [iIOC]"}, {"disconnect", jt_ptl_disconnect, 0, "disconnect from a remote nid\n" "usage: disconnect []"}, {"active_tx", jt_ptl_print_active_txs, 0, "print active transmits\n" "usage: active_tx"}, {"mynid", jt_ptl_mynid, 0, "inform the socknal of the local nid. " "The nid defaults to hostname for tcp networks and is automatically " "setup for elan/myrinet networks.\n" "usage: mynid []"}, {"shownid", jt_ptl_shownid, 0, "print the local NID\n" "usage: shownid"}, {"add_uuid", jt_lcfg_add_uuid, 0, "associate a UUID with a nid\n" "usage: add_uuid "}, {"close_uuid", jt_obd_close_uuid, 0, "disconnect a UUID\n" "usage: close_uuid "}, {"del_uuid", jt_lcfg_del_uuid, 0, "delete a UUID association\n" "usage: del_uuid "}, {"add_route", jt_ptl_add_route, 0, "add an entry to the portals routing table\n" "usage: add_route []"}, {"del_route", jt_ptl_del_route, 0, "delete route via gateway to targets from the portals routing table\n" "usage: del_route [] []"}, {"set_route", jt_ptl_notify_router, 0, "enable/disable routes via gateway in the portals routing table\n" "usage: set_route [