X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=libsysio%2Fsrc%2Finit.c;h=0708a96cfe06dbef4477a9f6e9c10b5264b46dee;hb=165400bbb8161b36764bd51056293375101329a6;hp=b50ce12c4aeb8eb76dd2a0ad7a03cad16052aaaf;hpb=58fa00472edb92e5cef936727774625b47e70ec3;p=fs%2Flustre-release.git diff --git a/libsysio/src/init.c b/libsysio/src/init.c index b50ce12..0708a96 100644 --- a/libsysio/src/init.c +++ b/libsysio/src/init.c @@ -9,7 +9,7 @@ * terms of the GNU Lesser General Public License * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) * - * Cplant(TM) Copyright 1998-2005 Sandia Corporation. + * Cplant(TM) Copyright 1998-2006 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the US Government. * Export of this program may require a license from the United States @@ -41,19 +41,21 @@ * lee@sandia.gov */ +#ifdef __linux__ #define _BSD_SOURCE +#endif -#if SYSIO_TRACING +#ifdef SYSIO_TRACING #include #endif #include -#if SYSIO_TRACING +#if defined(_BSD_SOURCE) || defined(SYSIO_TRACING) #include #endif #include #include #include -#if SYSIO_TRACING +#ifdef SYSIO_TRACING #include #endif #include @@ -66,7 +68,7 @@ #include "sysio.h" #include "xtio.h" -#if SYSIO_TRACING +#ifdef SYSIO_TRACING #include "native.h" #endif #include "inode.h" @@ -79,23 +81,30 @@ #include "stdfd.h" #endif -#if SYSIO_TRACING +#ifdef SYSIO_TRACING /* * Tracing callback record. */ struct trace_callback { - TAILQ_ENTRY(trace_callback) links; - void (*f)(const char *file, const char *func, int line); + TAILQ_ENTRY(trace_callback) links; /* trace list links */ + void (*f)(const char *file, /* callback function */ + const char *func, + int line, + void *data); + void *data; /* callback data */ + void (*destructor)(void *data); /* data destructor */ }; /* * Initialize a tracing callback record. */ -#define TCB_INIT(__tcb, __f) \ +#define TCB_INIT(__tcb, __f, __d, __destroy) \ do { \ (__tcb)->f = (__f); \ - } while (0); + (__tcb)->data = (__d); \ + (__tcb)->destructor = (__destroy); \ + } while (0) /* * Trace queue head record. @@ -128,6 +137,18 @@ void *_sysio_exit_trace_q = &_sysio_exit_trace_head; #endif /* + * In sysio_init we'll allow simple comments, strings outside {} + * delimited by COMMENT_INTRO, and '\n' or '\0' + */ +#define COMMENT_INTRO '#' + +/* + * In sysio_init we'll allow simple comments, strings outside {} + * delimited by COMMENT_INTRO, and '\n' or '\0' + */ +#define COMMENT_INTRO '#' + +/* * Sysio library initialization. Must be called before anything else in the * library. */ @@ -139,7 +160,7 @@ _sysio_init() extern int _sysio_sockets_init(void); #endif -#if SYSIO_TRACING +#ifdef SYSIO_TRACING /* * Initialize tracing callback queues. */ @@ -193,31 +214,28 @@ _sysio_shutdown() _sysio_unmount_all() == 0)) abort(); -#if ZERO_SUM_MEMORY +#ifdef ZERO_SUM_MEMORY _sysio_fd_shutdown(); _sysio_i_shutdown(); _sysio_fssw_shutdown(); -#if SYSIO_TRACING + _sysio_access_shutdown(); +#ifdef SYSIO_TRACING { struct trace_callback *tcb; /* * Empty the trace queues and free the entries. */ - while ((tcb = _sysio_entry_trace_head.tqh_first) != NULL) { - TAILQ_REMOVE(&_sysio_entry_trace_head, tcb, links); - free(tcb); - } - while ((tcb = _sysio_exit_trace_head.tqh_first) != NULL) { - TAILQ_REMOVE(&_sysio_exit_trace_head, tcb, links); - free(tcb); - } + while ((tcb = _sysio_entry_trace_head.tqh_first) != NULL) + _sysio_remove_trace(&_sysio_entry_trace_head, tcb); + while ((tcb = _sysio_exit_trace_head.tqh_first) != NULL) + _sysio_remove_trace(&_sysio_exit_trace_head, tcb); } #endif #endif } -#if SYSIO_TRACING +#ifdef SYSIO_TRACING #if !(defined(_HAVE_ASPRINTF) && _HAVE_ASPRINTF) /* @@ -310,14 +328,17 @@ void * _sysio_register_trace(void *q, void (*f)(const char *file, const char *func, - int line)) + int line, + void *data), + void *data, + void (*destructor)(void *data)) { struct trace_callback *tcb; tcb = malloc(sizeof(struct trace_callback)); if (!tcb) return NULL; - TCB_INIT(tcb, f); + TCB_INIT(tcb, f, data, destructor); TAILQ_INSERT_TAIL((struct trace_q *)q, tcb, links); return tcb; } @@ -328,9 +349,14 @@ _sysio_register_trace(void *q, void _sysio_remove_trace(void *q, void *p) { + struct trace_callback *tcb; + + tcb = (struct trace_callback *)p; - TAILQ_REMOVE((struct trace_q *)q, (struct trace_callback *)p, links); - free(p); + if (tcb->destructor) + (*tcb->destructor)(tcb->data); + TAILQ_REMOVE((struct trace_q *)q, tcb, links); + free(tcb); } void @@ -346,7 +372,7 @@ _sysio_run_trace_q(void *q, tcb = ((struct trace_q *)q)->tqh_first; while (tcb) { - (*tcb->f)(file, func, line); + (*tcb->f)(file, func, line, tcb->data); tcb = tcb->links.tqe_next; } } @@ -354,7 +380,8 @@ _sysio_run_trace_q(void *q, static void _sysio_trace_entry(const char *file __IS_UNUSED, const char *func, - int line __IS_UNUSED) + int line __IS_UNUSED, + void *data __IS_UNUSED) { _sysio_cprintf("+ENTER+ %s\n", func); @@ -363,7 +390,8 @@ _sysio_trace_entry(const char *file __IS_UNUSED, static void _sysio_trace_exit(const char *file __IS_UNUSED, const char *func, - int line __IS_UNUSED) + int line __IS_UNUSED, + void *data __IS_UNUSED) { _sysio_cprintf("+EXIT+ %s\n", func); @@ -520,6 +548,15 @@ do_creat(char *args) struct intent intent; dev_t dev; int err; + enum { + CREATE_DIR = 1, + CREATE_CHR = 2, + CREATE_BLK = 3, + CREATE_FILE = 4 + } op; + int intent_mode; + struct inode *ino; + int i; len = strlen(args); if (_sysio_get_args(args, v) - args != (ssize_t )len || @@ -552,69 +589,66 @@ do_creat(char *args) if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) return -ENOENT; + + /* + * Init, get the operation, setup the intent. + */ err = 0; mode = perms; + op = 0; if (strcmp(v[0].ovi_value, "dir") == 0) { - INTENT_INIT(&intent, INT_CREAT, &mode, 0); - err = - _sysio_namei(dir, v[1].ovi_value, ND_NEGOK, &intent, &pno); - if (err) - return err; - if (pno->p_base->pb_ino) - err = -EEXIST; - else if (IS_RDONLY(pno->p_parent, - pno->p_parent->p_base->pb_ino)) - err = -EROFS; - else { - struct inode *ino; - - ino = pno->p_parent->p_base->pb_ino; - err = (*ino->i_ops.inop_mkdir)(pno, mode); - } - P_RELE(pno); + op = CREATE_DIR; + INTENT_INIT(&intent, INT_CREAT, &mode, NULL); } else if (strcmp(v[0].ovi_value, "chr") == 0) { - if (!(v[5].ovi_value && parse_mm(v[5].ovi_value, &dev) == 0)) - return -EINVAL; + op = CREATE_CHR; mode |= S_IFCHR; - INTENT_INIT(&intent, INT_CREAT, &mode, 0); - err = - _sysio_namei(dir, v[1].ovi_value, ND_NEGOK, &intent, &pno); - if (err) - return err; - if (pno->p_base->pb_ino) - err = -EEXIST; - else if (IS_RDONLY(pno->p_parent, - pno->p_parent->p_base->pb_ino)) - err = -EROFS; - else { - struct inode *ino; - - ino = pno->p_parent->p_base->pb_ino; - err = (*ino->i_ops.inop_mknod)(pno, mode, dev); - } - P_RELE(pno); + INTENT_INIT(&intent, INT_CREAT, &mode, NULL); + if (!(v[5].ovi_value && parse_mm(v[5].ovi_value, &dev) == 0)) + err = -EINVAL; } else if (strcmp(v[0].ovi_value, "blk") == 0) { - /* - * We don't support block special files yet. - */ - return -EINVAL; + op = CREATE_BLK; + mode |= S_IFBLK; + INTENT_INIT(&intent, INT_CREAT, &mode, NULL); + if (!(v[5].ovi_value && parse_mm(v[5].ovi_value, &dev) == 0)) + err = -EINVAL; } else if (strcmp(v[0].ovi_value, "file") == 0) { - int i; - struct inode *ino; + op = CREATE_FILE; + intent_mode = O_CREAT|O_EXCL; + INTENT_INIT(&intent, INT_CREAT, &mode, &intent_mode); + } else + err = -EINVAL; + if (err) + return err; - i = O_CREAT|O_EXCL; - INTENT_INIT(&intent, INT_CREAT, &mode, &i); - err = - _sysio_namei(dir, v[1].ovi_value, ND_NEGOK, &intent, &pno); - if (err) - return err; + /* + * Lookup the given path. + */ + err = + _sysio_namei(dir, + v[1].ovi_value, + ND_NEGOK|ND_NOPERMCHECK, + &intent, + &pno); + if (err) + return err; + + /* + * Perform. + */ + switch (op) { + case CREATE_DIR: + err = _sysio_mkdir(pno, mode); + break; + case CREATE_CHR: + case CREATE_BLK: + err = _sysio_mknod(pno, mode, dev); + break; + case CREATE_FILE: err = _sysio_open(pno, O_CREAT|O_EXCL, mode); - if (err) { - P_RELE(pno); - return err; - } + if (err) + break; ino = pno->p_base->pb_ino; - if (!err && v[6].ovi_value) { + if (v[6].ovi_value) { struct iovec iovec; struct intnl_xtvec xtvec; struct ioctx io_context; @@ -650,10 +684,12 @@ do_creat(char *args) i = (*ino->i_ops.inop_close)(ino); if (!err) err = i; - P_RELE(pno); - } else - err = -EINVAL; + break; + default: + abort(); + } + P_RELE(pno); return err; } @@ -738,8 +774,13 @@ do_cd(char *args) if (_sysio_get_args(args, v) - args != (ssize_t )len || !v[0].ovi_value) return -EINVAL; - if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) + if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) { + /* + * We have no namespace yet. They really need to give us + * something to work with. + */ return -ENOENT; + } err = _sysio_namei(dir, v[0].ovi_value, 0, NULL, &pno); if (err) return err; @@ -785,7 +826,7 @@ do_chmd(char *args) if (!(dir = _sysio_cwd) && !(dir = _sysio_root)) return -ENOENT; - err = _sysio_namei(dir, v[0].ovi_value, 0, NULL, &pno); + err = _sysio_namei(dir, v[0].ovi_value, ND_NOPERMCHECK, NULL, &pno); if (err) return err; err = _sysio_setattr(pno, pno->p_base->pb_ino, SETATTR_MODE, &stbuf); @@ -832,7 +873,7 @@ do_open(char *args) return -ENOENT; INTENT_INIT(&intent, INT_OPEN, &m, NULL); pno = NULL; - err = _sysio_namei(dir, v[0].ovi_value, 0, &intent, &pno); + err = _sysio_namei(dir, v[0].ovi_value, ND_NOPERMCHECK, &intent, &pno); if (err) return err; fil = NULL; @@ -888,7 +929,7 @@ do_command(char *buf) return -EINVAL; } -#if SYSIO_TRACING +#ifdef SYSIO_TRACING /* * Set/Unset tracing. */ @@ -911,13 +952,17 @@ _sysio_boot_tracing(const char *arg) if (entcb == NULL) entcb = _sysio_register_trace(_sysio_entry_trace_q, - _sysio_trace_entry); + _sysio_trace_entry, + NULL, + NULL); if (entcb == NULL) return -errno; if (exitcb == NULL) exitcb = _sysio_register_trace(_sysio_exit_trace_q, - _sysio_trace_exit); + _sysio_trace_exit, + NULL, + NULL); if (exitcb == NULL) return -errno; } else { @@ -955,9 +1000,18 @@ _sysio_boot_namespace(const char *arg) /* * Discard leading white space. */ - while ((c = *arg) != '\0' && - !(c == '{' || strchr(IGNORE_WHITE, c) == NULL)) + while ((c = *arg) != '\0' && strchr(IGNORE_WHITE, c)) arg++; + if (COMMENT_INTRO == c) { + /* + * Discard comment. + */ + while (*arg && (*arg != '\n')) { + ++arg; + } + continue; + } + if (c == '\0') break; if (c != '{') { @@ -986,7 +1040,7 @@ _sysio_boot_namespace(const char *arg) if (err) break; } -#if SYSIO_TRACING +#ifdef SYSIO_TRACING if (err) _sysio_cprintf("+NS init+ failed at expr %u (last = %s): %s\n", count, @@ -997,7 +1051,7 @@ _sysio_boot_namespace(const char *arg) return err; } -#if DEFER_INIT_CWD +#ifdef DEFER_INIT_CWD /* * Set deferred initial working directory. */ @@ -1013,15 +1067,15 @@ _sysio_boot_cwd(const char *arg) /* * Given an identifier and it's arguments, perform optional initializations. */ -int +int _sysio_boot(const char *opt, const char *arg) { struct option_value_info vec[] = { -#if SYSIO_TRACING +#ifdef SYSIO_TRACING { "trace", NULL }, /* tracing? */ #endif { "namespace", NULL }, /* init namespace? */ -#if DEFER_INIT_CWD +#ifdef DEFER_INIT_CWD { "cwd", NULL }, /* init working dir */ #endif { NULL, NULL } @@ -1029,11 +1083,11 @@ _sysio_boot(const char *opt, const char *arg) struct option_value_info *v; unsigned u; static int (*f[])(const char *) = { -#if SYSIO_TRACING +#ifdef SYSIO_TRACING _sysio_boot_tracing, #endif _sysio_boot_namespace, -#if DEFER_INIT_CWD +#ifdef DEFER_INIT_CWD _sysio_boot_cwd, #endif NULL /* can't happen */