int main (int argc, char *argv[]) { Npcfsys *fs; Npcfid *afid, *root; uid_t uid = geteuid (); char *aname, *path; int fd = 0; /* stdin */ diod_log_init (argv[0]); if (argc != 3) usage (); aname = argv[1]; path = argv[2]; if (!(fs = npc_start (fd, fd, 65536+24, 0))) errn_exit (np_rerror (), "npc_start"); if (!(afid = npc_auth (fs, aname, uid, diod_auth)) && np_rerror () != 0) errn_exit (np_rerror (), "npc_auth"); if (!(root = npc_attach (fs, afid, aname, uid))) errn_exit (np_rerror (), "npc_attach"); if (afid && npc_clunk (afid) < 0) errn (np_rerror (), "npc_clunk afid"); if (_mkdir_p (root, path, 0755) < 0) errn_exit (np_rerror (), "mkdir"); if (npc_clunk (root) < 0) errn_exit (np_rerror (), "npc_clunk root"); npc_finish (fs); exit (0); }
int main (int argc, char *argv[]) { Npcfsys *fs; Npcfid *afid, *root; char *aname; int fd = 0; /* stdin */ uid_t uid = geteuid (); diod_log_init (argv[0]); if (argc != 2) usage (); aname = argv[1]; if (!(fs = npc_start (fd, 8192+24, 0))) errn_exit (np_rerror (), "npc_start"); if (!(afid = npc_auth (fs, aname, uid, diod_auth)) && np_rerror () != 0) errn_exit (np_rerror (), "npc_auth"); if (!(root = npc_attach (fs, afid, aname, uid))) errn_exit (np_rerror (), "npc_attach"); if (afid && npc_clunk (afid) < 0) errn_exit (np_rerror (), "npc_clunk afid"); _flush_series (fs, root); if (npc_clunk (root) < 0) errn_exit (np_rerror (), "npc_clunk root"); npc_finish (fs); diod_log_fini (); exit (0); }
int main (int argc, char *argv[]) { int fd; gid_t egid, gid; struct stat sb; diod_log_init (argv[0]); if (argc != 3) { msg ("Usage: tfsgid gid path"); exit (1); } egid = strtoul (argv[1], NULL, 10); gid = getgid (); if (setegid (egid) < 0) err_exit ("setegid"); if (access (argv[2], F_OK) == 0) msg_exit ("file exists"); if ((fd = open (argv[2], O_CREAT, 0644)) < 0) err_exit ("open"); (void)close (fd); if (stat (argv[2], &sb) < 0) err_exit ("stat"); #define SAME "same as" #define DIFF "different than" msg ("file gid is %s egid and %s gid", sb.st_gid == egid ? SAME : DIFF, sb.st_gid == gid ? SAME : DIFF); (void)unlink (argv[2]); exit(0); }
int main(int argc, char *argv[]) { #if HAVE_LIBCAP pthread_t t1, t2; assert (geteuid () == 0); diod_log_init (argv[0]); _prtcap ("task0", CAP_DAC_OVERRIDE); /* root, expect set */ _prtcap ("task0", CAP_CHOWN); msg ("task0: setfsuid 1"); setfsuid (1); _prtcap ("task0", CAP_DAC_OVERRIDE); /* non-root, expect clr */ _prtcap ("task0", CAP_CHOWN); msg ("task0: setfsuid 0"); /* root, expect set */ setfsuid (0); _prtcap ("task0", CAP_DAC_OVERRIDE); _prtcap ("task0", CAP_CHOWN); msg ("task0: setfsuid 1"); setfsuid (1); _prtcap ("task0", CAP_DAC_OVERRIDE); /* non-root, expect clr */ _prtcap ("task0", CAP_CHOWN); msg ("task0: set cap"); _setcap ("task0", CAP_DAC_OVERRIDE); _setcap ("task0", CAP_CHOWN); _prtcap ("task0", CAP_DAC_OVERRIDE); /* root with cap explicitly set, */ _prtcap ("task0", CAP_CHOWN); /* expect set */ msg ("task0: setfsuid 2"); setfsuid (2); _prtcap ("task0", CAP_DAC_OVERRIDE);/* non-root with cap explicitly set, */ _prtcap ("task0", CAP_CHOWN); /* (as root) expect set */ msg ("task0: clr cap"); _clrcap ("task0", CAP_DAC_OVERRIDE); _clrcap ("task0", CAP_CHOWN); _prtcap ("task0", CAP_DAC_OVERRIDE);/* non-root with cap explicitly clr, */ _prtcap ("task0", CAP_CHOWN); /* (as non-root) expect clr */ _create (&t1, proc1, NULL); _create (&t2, proc2, NULL); _join (t2, NULL); _join (t1, NULL); _prtcap ("task0", CAP_DAC_OVERRIDE); /* after threads, expect clr */ _prtcap ("task0", CAP_CHOWN); #else fprintf (stderr, "libcap unavailable\n"); exit (77); #endif exit (0); }
int main (int argc, char *argv[]) { Npcfsys *fs; Npcfid *afid, *root, *fid; char *aname; const int fd = 0; /* stdin */ uid_t uid; gid_t gid, ngid; diod_log_init (argv[0]); if (argc != 2) usage (); aname = argv[1]; if (geteuid () != 0) /* the server actually must be running as root */ msg_exit ("must run as root"); pick_user (&uid, &gid, &ngid); if (!(fs = npc_start (fd, 8192+24, 0))) errn_exit (np_rerror (), "npc_start"); if (!(afid = npc_auth (fs, aname, uid, diod_auth)) && np_rerror () != 0) errn_exit (np_rerror (), "npc_auth"); if (!(root = npc_attach (fs, afid, aname, uid))) errn_exit (np_rerror (), "npc_attach"); if (afid && npc_clunk (afid) < 0) errn_exit (np_rerror (), "npc_clunk afid"); /* should succeed */ if (!(fid = npc_create_bypath (root, "foo", 0644, O_RDONLY, gid))) errn_exit (np_rerror (), "npc_create_bypath as %d:%d with gid %d", uid, gid, gid); if (npc_clunk (fid) < 0) errn_exit (np_rerror (), "npc_clunk"); msg ("create foo with good gid succeeded"); /* should fail */ if ((fid = npc_create_bypath (root, "foo2", 0644, O_RDONLY, ngid))) msg_exit ("npc_create_bypath as %d:%d with gid %d succeeded: FAIL", uid, gid, ngid); msg ("create foo2 with bad gid failed"); if (npc_clunk (root) < 0) errn_exit (np_rerror (), "npc_clunk root"); npc_finish (fs); diod_log_fini (); exit (0); }
int main (int argc, char *argv[]) { Npsrv *srv; Npconn *conn; Nptrans *trans; int flags = SRV_FLAGS_DEBUG_9PTRACE | SRV_FLAGS_DEBUG_USER; diod_log_init (argv[0]); diod_conf_init (); if (!(srv = np_srv_create (16, flags))) errn_exit (np_rerror (), "out of memory"); srv->logmsg = diod_log_msg; srv->attach = myattach; srv->clunk = myclunk; /* create one connection */ if (!(trans = ttrans_create ())) err_exit ("ttrans_create"); if (!(conn = np_conn_create (srv, trans, "loopback"))) msg_exit ("np_conn_create failure"); _send_tversion (trans); _send_tauth (trans); _send_tattach (trans, 0, 0); _send_tattach (trans, 0, 1); _send_tattach (trans, 1, 2); _send_tattach (trans, 1, 3); _send_tattach (trans, 0, 4); _send_tclunk (trans, 4); _send_tclunk (trans, 3); _send_tclunk (trans, 2); _send_tclunk (trans, 1); _send_tclunk (trans, 0); ttrans_rpc (trans, NULL, NULL); /* signifies EOF to reader */ /* wait for exactly one connect/disconnect */ np_srv_wait_conncount (srv, 1); sleep(1); /* racy here - conn reader needs time to process EOF */ np_srv_destroy (srv); diod_conf_fini (); diod_log_fini (); exit (0); }
int main(int argc, char *argv[]) { char *path; gid_t gids[] = { TEST_SGID }; diod_log_init (argv[0]); assert (geteuid () == 0); /* clear supplemental groups */ _setgroups (0, NULL); msg ("supplemental groups cleared"); assert (geteuid () == 0); path = create_file (0, TEST_SGID, 0440); change_fsid (0, 0, TEST_UID, TEST_GID); assert (!read_file (path)); change_fsid (TEST_UID, TEST_GID, TEST_UID, TEST_SGID); assert (read_file (path)); change_fsid (TEST_UID, TEST_SGID, TEST_UID, TEST_GID); assert (!read_file (path)); /* set TEST_SGID in supplemental groups */ _setgroups (1, gids); msg ("%d added to supplemental groups", gids[0]); assert (read_file (path)); /* clear supplemental groups */ _setgroups (0, NULL); msg ("supplemental groups cleared"); assert (!read_file (path)); /* clean up */ change_fsid (TEST_UID, TEST_GID, 0, 0); _unlink (path); msg ("test complete"); exit (0); }
int main (int argc, char *argv[]) { diod_log_init (argv[0]); if (argc != 1) usage (); test_rlerror (); test_tstatfs (); test_rstatfs (); test_tlopen (); test_rlopen (); test_tlcreate (); test_rlcreate (); test_tsymlink (); test_rsymlink (); test_tmknod (); test_rmknod (); test_trename (); test_rrename (); test_treadlink(); test_rreadlink (); test_tgetattr (); test_rgetattr (); test_tsetattr (); test_rsetattr (); test_txattrwalk (); test_rxattrwalk (); test_txattrcreate (); test_rxattrcreate (); test_treaddir (); test_rreaddir (); test_tfsync (); test_rfsync (); test_tlock (); test_rlock (); test_tgetlock (); test_rgetlock (); test_tlink (); test_rlink (); test_tmkdir (); test_rmkdir (); test_trenameat (); test_rrenameat (); test_tunlinkat (); test_runlinkat (); test_tversion (); test_rversion (); test_tauth (); test_rauth (); test_tflush (); test_rflush (); test_tattach (); test_rattach (); test_twalk (); test_rwalk (); test_tread (); test_rread (); test_twrite (); test_rwrite (); test_tclunk (); test_rclunk (); test_tremove (); test_rremove (); exit (0); }
int main(int argc, char *argv[]) { pthread_t t1, t2; diod_log_init (argv[0]); assert (geteuid () == 0); msg ("task0: setgroups (NULL)"); _setgroups (0, NULL); show_groups ("task0"); _create (&t1, proc1, NULL); _create (&t2, proc2, NULL); _join (t2, NULL); _join (t1, NULL); show_groups ("task0"); exit (0); }
int main (int argc, char *argv[]) { Npcfsys *fs; Npcfid *afid, *root; uid_t uid = geteuid (); char *aname, *path, *attr, *value; int fd = 0; /* stdin */ diod_log_init (argv[0]); if (argc < 3) usage (); aname = argv[1]; path = argv[2]; attr = argv[3]; value = argv[4]; if (!(fs = npc_start (fd, fd, 65536+24, 0))) errn_exit (np_rerror (), "npc_start"); if (!(afid = npc_auth (fs, aname, uid, diod_auth)) && np_rerror () != 0) errn_exit (np_rerror (), "npc_auth"); if (!(root = npc_attach (fs, afid, aname, uid))) errn_exit (np_rerror (), "npc_attach"); if (afid && npc_clunk (afid) < 0) errn (np_rerror (), "npc_clunk afid"); if (npc_setxattr (root, path, attr, NULL, 0, 0) < 0) errn_exit (np_rerror (), "npc_setxattr"); if (npc_clunk (root) < 0) errn_exit (np_rerror (), "npc_clunk root"); npc_finish (fs); exit (0); }
int main (int argc, char *argv[]) { char *server = NULL; int msize = 65536; uid_t uid = geteuid (); int topt = 0; Npcfsys *fs = NULL; Npcfid *fid, *afid, *root; int c, fd; char buf[80], *host, *p; hostlist_t hl; hostlist_iterator_t itr; int lopt = 0; diod_log_init (argv[0]); opterr = 0; while ((c = GETOPT (argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 's': /* --server HOST[:PORT] or /path/to/socket */ server = optarg; break; case 'm': /* --msize SIZE */ msize = strtoul (optarg, NULL, 10); break; case 'u': /* --uid UID */ uid = strtoul (optarg, NULL, 10); break; case 't': /* --timeout SECS */ topt = strtoul (optarg, NULL, 10); break; case 'l': /* --long */ lopt = 1; break; default: usage (); } } if (signal (SIGPIPE, SIG_IGN) == SIG_ERR) err_exit ("signal"); if (signal (SIGALRM, sigalarm) == SIG_ERR) err_exit ("signal"); if (topt > 0) alarm (topt); if ((fd = diod_sock_connect (server, 0)) < 0) exit (1); if (!(fs = npc_start (fd, fd, msize, 0))) errn_exit (np_rerror (), "error negotiating protocol with server"); if (!(afid = npc_auth (fs, "ctl", uid, diod_auth)) && np_rerror () != 0) errn_exit (np_rerror (), "error authenticating to server"); if (!(root = npc_attach (fs, afid, "ctl", uid))) errn_exit (np_rerror (), "error attaching to aname=ctl"); if (!(fid = npc_open_bypath (root, "connections", O_RDONLY))) errn_exit (np_rerror (), "open connections"); if (!(hl = hostlist_create (NULL))) err_exit ("hostlist_create"); while (npc_gets (fid, buf, sizeof(buf))) { if ((p = strchr (buf, ' '))) *p = '\0'; if (!lopt && (p = strchr (buf, '.'))) *p = '\0'; if (!hostlist_push_host (hl, buf)) err_exit ("hostlist_push_host"); } hostlist_uniq (hl); if (lopt) { if (!(itr = hostlist_iterator_create (hl))) err_exit ("hostlist_iterator_create"); while ((host = hostlist_next (itr))) printf ("%s\n", host); hostlist_iterator_destroy (itr); } else { char s[1024]; if (hostlist_ranged_string (hl, sizeof (s), s) < 0) msg_exit ("hostlist output would be too long (use -l)"); printf ("%s\n", s); } hostlist_destroy (hl); if (npc_clunk (fid) < 0) errn_exit (np_rerror (), "clunk connections"); if (npc_clunk (root) < 0) errn_exit (np_rerror (), "error clunking ctl"); if (npc_clunk (afid) < 0) errn_exit (np_rerror (), "error clunking afid"); npc_finish (fs); exit(0); }
int main(int argc, char **argv) { int c; char *copt = NULL; srvmode_t mode = SRV_NORMAL; int rfdno = -1, wfdno = -1; diod_log_init (argv[0]); diod_conf_init (); /* config file overrides defaults */ opterr = 0; while ((c = GETOPT (argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'c': /* --config-file PATH */ copt = optarg; break; default: break; } } diod_conf_init_config_file (copt); /* Command line overrides config file. */ optind = 0; opterr = 0; while ((c = GETOPT (argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'f': /* --foreground */ diod_conf_set_foreground (1); break; case 'r': /* --rfdno */ mode = SRV_FILEDES; rfdno = strtoul (optarg, NULL, 10); break; case 'w': /* --wfdno */ mode = SRV_FILEDES; wfdno = strtoul (optarg, NULL, 10); break; case 'd': /* --debug MASK */ diod_conf_set_debuglevel (strtoul (optarg, NULL, 0)); break; case 'l': /* --listen HOST:PORT or /path/to/socket */ if (!diod_conf_opt_listen ()) diod_conf_clr_listen (); if (!strchr (optarg, ':') && optarg[0] != '/') usage (); diod_conf_add_listen (optarg); break; case 't': /* --nwthreads INT */ diod_conf_set_nwthreads (strtoul (optarg, NULL, 10)); break; case 'c': /* --config-file PATH */ break; case 'e': /* --export PATH */ if (!diod_conf_opt_exports ()) diod_conf_clr_exports (); diod_conf_add_exports (optarg); break; case 'E': /* --export-all */ diod_conf_set_exportall (1); break; case 'o': /* --export-ops opt,[opt,...] */ diod_conf_set_exportopts (optarg); break; case 'n': /* --no-auth */ diod_conf_set_auth_required (0); break; case 'p': /* --statfs-passthru */ diod_conf_set_statfs_passthru (0); break; case 'N': /* --no-userdb */ diod_conf_set_userdb (0); break; case 'S': /* --allsquash */ diod_conf_set_allsquash (1); break; case 'U': /* --squashuser USER */ diod_conf_set_squashuser (optarg); break; case 'u': { /* --runas-uid UID */ uid_t uid; char *end; errno = 0; uid = strtoul (optarg, &end, 10); if (errno != 0) err_exit ("error parsing --runas-uid argument"); if (*end != '\0') msg_exit ("error parsing --runas-uid argument"); diod_conf_set_runasuid (uid); break; } case 's': /* --socktest */ mode = SRV_SOCKTEST; break; case 'L': /* --logdest DEST */ diod_conf_set_logdest (optarg); diod_log_set_dest (optarg); break; default: usage(); } } if (optind < argc) usage(); if (diod_conf_opt_runasuid () && diod_conf_get_allsquash ()) msg_exit ("--runas-uid and allsquash cannot be used together"); if (mode == SRV_FILEDES && (rfdno == -1 || wfdno == -1)) msg_exit ("--rfdno,wfdno must be used together"); diod_conf_validate_exports (); if (geteuid () == 0) _setrlimit (); _service_run (mode, rfdno, wfdno); diod_conf_fini (); diod_log_fini (); exit (0); }
int main (int argc, char *argv[]) { char *aname = "ctl"; char *server = NULL; int msize = 65536; uid_t uid = geteuid (); int topt = 0; int Sopt = 0; int flags = 0; int fd, c; Npcfsys *fs = NULL; Npcfid *afid = NULL, *root = NULL; char *buf = NULL; struct timeval tv; struct timezone tz; diod_log_init (argv[0]); opterr = 0; while ((c = GETOPT (argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 's': /* --server HOST[:PORT] or /path/to/socket */ server = optarg; break; case 'm': /* --msize SIZE */ msize = strtoul (optarg, NULL, 10); break; case 'u': /* --uid UID */ uid = strtoul (optarg, NULL, 10); break; case 't': /* --timeout SECS */ topt = strtoul (optarg, NULL, 10); break; case 'S': /* --set-time */ Sopt = 1; break; default: usage (); } } if (signal (SIGPIPE, SIG_IGN) == SIG_ERR) err_exit ("signal"); if (signal (SIGALRM, sigalarm) == SIG_ERR) err_exit ("signal"); if (topt > 0) alarm (topt); if ((fd = diod_sock_connect (server, flags)) < 0) exit (1); if (!(fs = npc_start (fd, fd, msize, 0))) { errn (np_rerror (), "error negotiating protocol with server"); goto done; } if (!(afid = npc_auth (fs, aname, uid, diod_auth)) && np_rerror () != 0) { errn (np_rerror (), "error authenticating to server"); goto done; } if (!(root = npc_attach (fs, afid, aname, uid))) { errn (np_rerror (), "error attaching to aname='%s'", aname); goto done; } buf = npc_aget (root, "date"); if (!buf) { errn (np_rerror (), "error reading date"); goto done; } if (sscanf (buf, "%lu.%lu %d.%d", &tv.tv_sec, &tv.tv_usec, &tz.tz_minuteswest, &tz.tz_dsttime) != 4) { msg ("error scanning returned date: %s", buf); goto done; } if (Sopt) { if (settimeofday (&tv, &tz) < 0) err_exit ("settimeofday"); } else { time_t t = tv.tv_sec; printf ("%s", ctime (&t)); } done: if (buf) free (buf); if (root && npc_clunk (root) < 0) errn_exit (np_rerror (), "error clunking %s", aname); if (afid && npc_clunk (afid) < 0) errn_exit (np_rerror (), "error clunking afid"); if (fs) npc_finish (fs); close (fd); diod_log_fini (); exit (0); }
int main (int argc, char *argv[]) { char *aname = NULL; char *server = NULL; int msize = 65536; uid_t uid = geteuid (); int topt = 0; int lopt = 0; int fd, c; diod_log_init (argv[0]); opterr = 0; while ((c = GETOPT (argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'a': /* --aname NAME */ aname = optarg; break; case 's': /* --server HOST[:PORT] or /path/to/socket */ server = optarg; break; case 'm': /* --msize SIZE */ msize = strtoul (optarg, NULL, 10); break; case 'u': /* --uid UID */ uid = strtoul (optarg, NULL, 10); break; case 't': /* --timeout SECS */ topt = strtoul (optarg, NULL, 10); break; case 'l': /* --long */ lopt = 1; break; default: usage (); } } if (signal (SIGPIPE, SIG_IGN) == SIG_ERR) err_exit ("signal"); if (signal (SIGALRM, sigalarm) == SIG_ERR) err_exit ("signal"); if (topt > 0) alarm (topt); if ((fd = diod_sock_connect (server, 0)) < 0) exit (1); if (!aname) aname = "ctl"; if (lsfiles (fd, uid, msize, aname, lopt, argv + optind, argc - optind) < 0) exit (1); close (fd); diod_log_fini (); exit (0); }
int main (int argc, char *argv[]) { int fd = -1; int fd2 = -1; pid_t pid; int status; struct flock fl; diod_log_init (argv[0]); if (argc != 2) { msg ("Usage: tfcntl3 file"); exit (1); } msg ("1. Upgrade read lock to write lock (one fd)"); if ((fd = open (argv[1], O_RDWR)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_RDWR"); fl = sf_rdlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK rdlock failed"); msg ("fd: read-locked"); fl = sf_wrlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK wrlock failed"); msg ("fd: write-locked"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("2. Upgrade read lock to write lock (two fds)"); if ((fd = open (argv[1], O_RDWR)) < 0) err_exit ("open %s", argv[1]); msg ("fd: open O_RDWR"); fl = sf_rdlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK rdlock failed"); msg ("fd: read-locked"); if ((fd2 = open (argv[1], O_RDWR)) < 0) err_exit ("fd2: open %s", argv[1]); msg ("fd2: open O_RDWR"); fl = sf_wrlock; if (fcntl (fd2, F_SETLK, &fl) < 0) err_exit ("fd2: fcntl F_SETLK wrlock failed"); msg ("fd2: write-locked"); if (close (fd2) < 0) err_exit ("close fd2"); msg ("fd2: closed"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("3. Upgrade byte range of write lock (one fd)"); if ((fd = open (argv[1], O_RDWR)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_RDWR"); fl = sf_wrlock; fl.l_len = 1; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK wrlock (1 byte) failed"); msg ("fd: write-locked 1 byte"); fl = sf_wrlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK wrlock (entire file) failed"); msg ("fd: write-locked entire file"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("4. Downgrade byte range of write lock (one fd)"); if ((fd = open (argv[1], O_RDWR)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_RDWR"); fl = sf_wrlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK wrlock (entire file) failed"); msg ("fd: write-locked entire file"); fl = sf_wrlock; fl.l_len = 1; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK wrlock (one byte) failed"); msg ("fd: write-locked 1 byte"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("5. Downgrade write lock to read lock (one fd)"); if ((fd = open (argv[1], O_RDWR)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_RDWR"); fl = sf_wrlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK wrlock failed"); msg ("fd: write-locked"); fl = sf_rdlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK rdlock failed"); msg ("fd: read-locked"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("6. Read lock with O_RDONLY should succeed"); if ((fd = open (argv[1], O_RDONLY)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_RDONLY"); fl = sf_rdlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: fcntl F_SETLK rdlock failed"); msg ("fd: read-locked"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("7. Read lock with O_WRONLY should fail"); if ((fd = open (argv[1], O_WRONLY)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_WRONLY"); fl = sf_rdlock; if (fcntl (fd, F_SETLK, &fl) < 0) err ("fd: fcntl F_SETLK rdlock failed"); else msg ("fd: read-locked"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("8. Write lock with O_RDONLY should fail"); if ((fd = open (argv[1], O_RDONLY)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_RDONLY"); fl = sf_wrlock; if (fcntl (fd, F_SETLK, &fl) < 0) err ("fd: fcntl F_SETLK wrlock failed"); else msg ("fd: write-locked"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("9. Write lock with O_WRONLY should succeed"); if ((fd = open (argv[1], O_WRONLY)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_WRONLY"); fl = sf_wrlock; if (fcntl (fd, F_SETLK, &fl) < 0) err ("fd: fcntl F_SETLK wrlock failed"); else msg ("fd: write-locked"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("10. Write lock is not inherited across a fork"); if ((fd = open (argv[1], O_RDWR)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_RDWR"); fl = sf_wrlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: write-lock failed, aborting"); msg ("fd: write-locked"); switch (pid = fork ()) { case -1: err_exit ("fork"); case 0: /* child */ msg ("child forked"); fl = sf_rdlock; if (fcntl (fd, F_SETLK, &fl) < 0) { err ("fd: read-lock failed (child)"); exit (0); } msg_exit ("fd: read-locked (child)"); default: /* parent */ if (waitpid (pid, &status, 0) < 0) err_exit ("waitpid"); if (!WIFEXITED (status)) msg_exit ("child terminated without exit"); if (WEXITSTATUS (status) != 0) msg_exit ("child exited with %d, aborting", WEXITSTATUS (status)); msg ("child exited normally"); break; } if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed"); msg ("11. Write lock is dropped if another fd to same file is closed"); if ((fd = open (argv[1], O_RDWR)) < 0) err_exit ("fd: open %s", argv[1]); msg ("fd: open O_RDWR"); fl = sf_wrlock; if (fcntl (fd, F_SETLK, &fl) < 0) err_exit ("fd: write-lock failed, aborting"); msg ("fd: write-locked"); if ((fd2 = open (argv[1], O_RDWR)) < 0) err_exit ("fd2: open %s", argv[1]); msg ("fd2: open O_RDWR"); if (close (fd2) < 0) err_exit ("close fd2"); msg ("fd2: closed"); switch (pid = fork ()) { case -1: err_exit ("fork"); case 0: /* child */ msg ("child forked"); if (close (fd) < 0) err_exit ("close fd"); msg ("fd: closed (child)"); if ((fd2 = open (argv[1], O_RDWR)) < 0) err_exit ("fd2: open %s", argv[1]); msg ("fd2: open O_RDWR (child)"); fl = sf_rdlock; if (fcntl (fd2, F_SETLK, &fl) < 0) { err ("fd2: read-lock failed (child)"); exit (1); } msg ("fd2: read-locked (child)"); exit (0); default: /* parent */ if (waitpid (pid, &status, 0) < 0) err_exit ("waitpid"); if (!WIFEXITED (status)) msg_exit ("child terminated without exit"); if (WEXITSTATUS (status) != 0) msg_exit ("child exited with %d, aborting", WEXITSTATUS (status)); msg ("child exited normally"); break; } exit (0); }
int main (int argc, char *argv[]) { char *host = NULL; char *port = "564"; int msize = 65536; int numthreads = 16; int runtime = 10; int i, c, err; time_t now = time (NULL); thd_t *t; uint64_t readbytes = 0, writebytes = 0, opcount = 0; load_t loadtype = LOAD_IO; diod_log_init (argv[0]); opterr = 0; while ((c = GETOPT (argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'h': /* --hostname NAME */ host = optarg; break; case 'p': /* --port PORT */ port = optarg; break; case 'm': /* --msize SIZE */ msize = strtoul (optarg, NULL, 10); break; case 'n': /* --numthreads INT */ numthreads = strtoul (optarg, NULL, 10); break; case 'r': /* --runtime INT */ runtime = strtoul (optarg, NULL, 10); break; case 'g': /* --getattr */ loadtype = LOAD_GETATTR; break; default: usage (); } } if (signal (SIGPIPE, SIG_IGN) == SIG_ERR) err_exit ("signal"); if (!(t = malloc (sizeof (thd_t) * numthreads))) msg_exit ("out of memory"); for (i = 0; i < numthreads; i++) { t[i].host = host ? host : "localhost"; t[i].port = port; t[i].msize = msize; t[i].stoptime = now + runtime; t[i].fd = -1; t[i].fs = NULL; t[i].root = t[i].afid = t[i].infile = t[i].outfile = NULL; t[i].readbytes = t[i].writebytes = 0; t[i].loadtype = loadtype; if (!(t[i].buf = malloc (msize))) msg_exit ("out of memory"); if ((err = pthread_create (&t[i].t, NULL, loadgen, &t[i]))) errn_exit (err, "pthread_create"); } for (i = 0; i < numthreads; i++) { if ((err = pthread_join (t[i].t, NULL))) errn_exit (err, "pthread_join"); readbytes += t[i].readbytes; writebytes += t[i].writebytes; opcount += t[i].opcount; free (t[i].buf); } free (t); msg ("%"PRIu64" ops/s, %"PRIu64" rMB/s, %"PRIu64" wMB/s", opcount/runtime, readbytes/(1024*1024*runtime), writebytes/(1024*1024*runtime)); diod_log_fini (); exit (0); }
int main (int argc, char *argv[]) { char *dir = NULL; char *spec, *host; char *nspec = NULL; int c, i; int nopt = 0; int vopt = 0; int fopt = 0; int aopt = 0; int dopt = 0; int rfd = -1, wfd = -1; Opt o; diod_log_init (argv[0]); o = opt_create (); opterr = 0; while ((c = GETOPT (argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'f': /* --fake-mount */ fopt = 1; break; case 'n': /* --no-mtab */ nopt = 1; break; case 'v': /* --verbose */ vopt++; break; case 'o': /* --options OPT[,OPT]... */ opt_addf (o, "%s", optarg); break; case 'a': /* --9nbd-attach */ aopt++; break; case 'd': /* --9nbd-detach */ dopt++; break; default: usage (); } } /* Take care of 9nbd operations and exit. */ if (aopt) { _nbd_attach (o, argc - optind, argv + optind, nopt, vopt); exit (0); } if (dopt) { _nbd_detach (o, argc - optind, argv + optind, nopt, vopt); exit (0); } if (optind != argc - 2) usage (); if (geteuid () != 0) msg_exit ("you must be root"); spec = argv[optind++]; dir = argv[optind++]; host = _parse_spec (spec, o); _verify_mountpoint (dir); /* Remount - only pass mount flags into the VFS for an existing mount. * Take care of it here and exit. */ if (opt_find (o, "remount")) { if (opt_check_allowed_csv (o, "ro,rw,aname,remount")) msg_exit ("-oremount can only be used with ro,rw"); _diod_remount (o, spec, dir, vopt, fopt); goto done; } /* Ensure uname and access are set, and to diod-compatible values. * The uname user becomes the euid which will be used by munge auth. */ _parse_uname_access (o); if (seteuid (_uname2uid (opt_find (o, "uname"))) < 0) err_exit ("seteuid"); /* We require -otrans=fd because auth occurs in user space, then live fd * is passed to the kernel via -orfdno,wfdno. */ if (!opt_find (o, "trans")) opt_addf (o, "trans=%s", "fd"); else if (!opt_find (o, "trans=fd")) msg_exit ("only -otrans=fd transport is supported"); /* Set msize if not already set. Validate it later. */ if (!opt_find (o, "msize")) opt_addf (o, "msize=%d", DIOD_DEFAULT_MSIZE); /* Only .L version is supported. */ if (!opt_find (o, "version")) opt_addf (o, "version=%s", "9p2000.L"); else if (!opt_find (o, "version=9p2000.L")) msg_exit ("only -oversion=9p2000.L is supported (little p, big L)"); /* Set debug level. */ if (!opt_find (o, "debug")) opt_addf (o, "debug=%d", 0x1); /* send errors to dmesg */ /* Set rwdepth (number of concurrent reads with buffer > msize). * N.B. this option is not upstream yet but unknown options are ignored. */ if (!opt_find (o, "rwdepth")) opt_addf (o, "rwdepth=%d", 1); /* Server is on an inherited file descriptor. * For testing, we start server on a socketpair duped to fd 0. */ if (opt_find (o, "rfdno") || opt_find (o, "wfdno")) { if (!opt_scanf (o, "rfdno=%d", &rfd) || !opt_scanf (o, "wfdno=%d",&wfd)) msg_exit ("-orfdno,wfdno must be used together"); nopt = 1; /* force no mtab */ /* Connect to server on UNIX domain socket */ } else if (host[0] == '/') { if (opt_find (o, "port")) msg_exit ("-oport won't work with UNIX domain socket"); if ((rfd = diod_sock_connect_unix (host, 0)) < 0) exit (1); wfd = rfd; opt_addf (o, "rfdno=%d", rfd); opt_addf (o, "wfdno=%d", wfd); /* Connect to server on IANA port (or user-specified) and host. */ } else { char *port = opt_find (o, "port"); hostlist_iterator_t hi; hostlist_t hl; char *h; if (!port) port = "564"; if (!(hl = hostlist_create (host))) msg_exit ("error parsing host string: %s", host); if (!(hi = hostlist_iterator_create (hl))) msg_exit ("out of memory"); while ((h = hostlist_next (hi))) { if (vopt) msg ("trying to connect to %s:%s", h, port); if ((rfd = diod_sock_connect_inet (h, port, DIOD_SOCK_QUIET)) >= 0) break; } if (h) { /* create new 'spec' string identifying successful host */ char *p = strchr (spec , ':'); int len = strlen (h) + (p ? strlen (p) : 0) + 1; if (!(nspec = malloc (len))) msg_exit ("out of memory"); snprintf (nspec, len, "%s%s", h, p ? p : ""); } hostlist_destroy (hl); if (rfd < 0) msg_exit ("could not connect to server(s), giving up"); wfd = rfd; opt_delete (o, "port"); opt_addf (o, "rfdno=%d", rfd); opt_addf (o, "wfdno=%d", wfd); } NP_ASSERT (opt_find (o, "trans=fd")); NP_ASSERT (opt_scanf (o, "msize=%d", &i)); NP_ASSERT (opt_find (o, "version=9p2000.L")); NP_ASSERT (opt_scanf (o, "debug=%d", &i) || opt_scanf (o, "debug=%x", &i)); NP_ASSERT (opt_scanf (o, "wfdno=%d", &i) && opt_scanf (o, "rfdno=%d", &i)); NP_ASSERT ((opt_find (o, "access=user") && opt_find(o, "uname=root")) || (opt_scanf (o, "access=%d", &i) && opt_find(o, "uname"))); NP_ASSERT (!opt_find (o, "port")); _diod_mount (o, rfd, wfd, nspec ? nspec : spec, dir, vopt, fopt, nopt); done: opt_destroy (o); exit (0); }