Пример #1
0
/* If a file PATHNAME exists, then open it.
   If is has a `compressed' extension, then open a pipe reading it */
static int
maybe_pipe_open(lkfile_t *fp)
{
	char *t;
	struct stat st;
	struct decompressor *dc;

	if (stat(fp->pathname, &st) == -1 || !S_ISREG(st.st_mode) ||
	    access(fp->pathname, R_OK) == -1)
		return -1;

	t = strrchr(fp->pathname, '.');
	if (t) {
		for (dc = &decompressors[0]; dc->cmd; dc++) {
			if (strcmp(t, dc->ext) == 0)
				return pipe_open(dc, fp);
		}
	}
	fp->fd = fopen(fp->pathname, "r");
	fp->pipe = 0;

	if (fp->fd == NULL)
		return -1;

	return 0;
}
Пример #2
0
int file_pipe(int fd[])
{
	int ret;
	struct file *file[2] = { NULL, NULL };
	if ((ret = filemap_alloc(NO_FD, &file[0])) != 0) {
		goto failed_cleanup;
	}
	if ((ret = filemap_alloc(NO_FD, &file[1])) != 0) {
		goto failed_cleanup;
	}

	if ((ret = pipe_open(&(file[0]->node), &(file[1]->node))) != 0) {
		goto failed_cleanup;
	}
	file[0]->pos = 0;
	file[0]->readable = 1, file[0]->writable = 0;
	filemap_open(file[0]);

	file[1]->pos = 0;
	file[1]->readable = 0, file[1]->writable = 1;
	filemap_open(file[1]);

	fd[0] = file[0]->fd, fd[1] = file[1]->fd;
	return 0;

failed_cleanup:
	if (file[0] != NULL) {
		filemap_free(file[0]);
	}
	if (file[1] != NULL) {
		filemap_free(file[1]);
	}
	return ret;
}
Пример #3
0
void
core_setup(admin_options_st *opt_admin,
        server_options_st *opt_server, worker_options_st *opt_worker,
        server_metrics_st *smetrics, worker_metrics_st *wmetrics)
{
    pipe_c = pipe_conn_create();
    if (pipe_c == NULL) {
        log_error("Could not create connection for pipe, abort");
        goto error;
    }

    if (!pipe_open(NULL, pipe_c)) {
        log_error("Could not open pipe connection: %s", strerror(pipe_c->err));
        goto error;
    }

    pipe_set_nonblocking(pipe_c);

    conn_arr = ring_array_create(sizeof(struct buf_sock *), RING_ARRAY_DEFAULT_CAP);
    if (conn_arr == NULL) {
        log_error("core setup failed: could not allocate conn array");
        goto error;
    }

    core_server_setup(opt_server, smetrics);
    core_worker_setup(opt_worker, wmetrics);
    core_admin_setup(opt_admin);

    core_init = true;

    return;

error:
    exit(EX_CONFIG);
}
Пример #4
0
int file_pipe(int fd[])
{
  int ret;
  struct file_desc_table *desc_table = fs_get_desc_table(current->fs_struct);
	struct file *file[2] = { NULL, NULL };
  file[0] = kernel_file_pool_allocate();
  file[1] = kernel_file_pool_allocate();
  if(file[0] == NULL || file[1] == NULL) {
    ret = -E_NFILE;
    goto failed_cleanup;
  }
  file_init(file[0]);
  file_init(file[1]);
  if ((ret = pipe_open(&(file[0]->node), &(file[1]->node))) != 0) {
    ret = -E_INVAL;
    goto failed_cleanup;
  }
  file[0]->pos = 0;
  file[0]->readable = 1;
  file[0]->writable = 0;

  file[1]->pos = 0;
  file[1]->readable = 0;
  file[1]->writable = 1;

  fd[0] = file_desc_table_get_unused(desc_table);
  if(fd[0] == -1) {
    ret = -E_MFILE;
    goto failed_cleanup;
  }
  file_desc_table_associate(desc_table, fd[0], file[0]);
  fd[1] = file_desc_table_get_unused(desc_table);
  if(fd[1] == -1) {
    file_desc_table_dissociate(desc_table, fd[0]);
    ret = -E_MFILE;
    goto failed_cleanup;
  }
  file_desc_table_associate(desc_table, fd[1], file[1]);
	return 0;

failed_cleanup:
	if (file[0] != NULL) {
		kernel_file_pool_free(file[0]);
	}
	if (file[1] != NULL) {
		kernel_file_pool_free(file[1]);
	}
	return ret;
}
Пример #5
0
int notice_init(event_base_t *base, notice_t *n, wake_up_hander handler, void *data)
{
    conn_t           *c = NULL;
    event_t          *rev = NULL;
    
    if (pipe_open(&n->channel) != FAST_OK) {
        return FAST_ERROR;
    }
    
    c = conn_get_from_mem(n->channel.pfd[0]);
    if (!c) {
        goto error;
    }
    conn_nonblocking(n->channel.pfd[0]);
    conn_nonblocking(n->channel.pfd[1]);
    n->call_back = handler;
    n->data = data;
    n->wake_up = notice_wake_up;
    
    c->ev_base = base;
    c->conn_data = n;
    c->log = base->log;
    
    rev = c->read;
    rev->handler = noice_read_event_handler;
    
    if (event_add(base,rev, EVENT_READ_EVENT, 0) == FAST_ERROR) {
        fast_log_error(base->log, FAST_LOG_FATAL, 0,"event adde failed");
        goto error;
    }
    
    n->log = base->log;
    return FAST_OK;
    
error:
    pipe_close(&n->channel);
    
    if (c) {
        conn_free_mem(c);
    }
    
    return FAST_ERROR;
}
Пример #6
0
static int
findfile_by_fullname(const char *fnam, const char *const *suffixes, lkfile_t *fp)
{
	int i;
	struct stat st;
	struct decompressor *dc;
	size_t fnam_len, sp_len;

	fp->pipe = 0;
	fnam_len = strlen(fnam);

	for (i = 0; suffixes[i]; i++) {
		if (suffixes[i] == 0)
			continue; /* we tried it already */

		sp_len = strlen(suffixes[i]);

		if (fnam_len + sp_len + 1 > sizeof(fp->pathname))
			continue;

		sprintf(fp->pathname, "%s%s", fnam, suffixes[i]);

		if(stat(fp->pathname, &st) == 0
		   && S_ISREG(st.st_mode)
		   && (fp->fd = fopen(fp->pathname, "r")) != NULL)
			return 0;

		for (dc = &decompressors[0]; dc->cmd; dc++) {
			if (fnam_len + sp_len + strlen(dc->ext) + 1 > sizeof(fp->pathname))
				continue;

			sprintf(fp->pathname, "%s%s%s", fnam, suffixes[i], dc->ext);

			if (stat(fp->pathname, &st) == 0
			    && S_ISREG(st.st_mode)
			    && access(fp->pathname, R_OK) == 0)
				return pipe_open(dc, fp);
		}
	}

	return -1;
}
Пример #7
0
void main()
{
	pipe_open();
	pthread_mutex_init(&AD_mutex,NULL);
	pthread_cond_init(&user_cond,NULL);
	
	pthread_t tid,tid2;
	
	int etid = pthread_create(&tid,NULL,user,NULL);
	if(etid<0)
	{
		printf("user pthread_create fail\n");
	}
	pthread_create(&tid2,NULL,AD_proc,NULL);
	if(etid<0)
	{
		printf("AD_proc pthread_create fail\n");
	}
	while(nend)	;
	pthread_mutex_destroy(&AD_mutex);
	pthread_cond_destroy(&user_cond);
}
Пример #8
0
/*===========================================================================*
 *				common_open				     *
 *===========================================================================*/
int common_open(char path[PATH_MAX], int oflags, mode_t omode)
{
/* Common code from do_creat and do_open. */
  int b, r, exist = TRUE, major_dev;
  dev_t dev;
  mode_t bits;
  struct filp *filp, *filp2;
  struct vnode *vp;
  struct vmnt *vmp;
  struct dmap *dp;
  struct lookup resolve;

  /* Remap the bottom two bits of oflags. */
  bits = (mode_t) mode_map[oflags & O_ACCMODE];
  if (!bits) return(EINVAL);

  /* See if file descriptor and filp slots are available. */
  if ((r = get_fd(0, bits, &(scratch(fp).file.fd_nr), &filp)) != OK) return(r);

  lookup_init(&resolve, path, PATH_NOFLAGS, &vmp, &vp);

  /* If O_CREATE is set, try to make the file. */
  if (oflags & O_CREAT) {
        omode = I_REGULAR | (omode & ALLPERMS & fp->fp_umask);
	vp = new_node(&resolve, oflags, omode);
	r = err_code;
	if (r == OK) exist = FALSE;	/* We just created the file */
	else if (r != EEXIST) {		/* other error */
		if (vp) unlock_vnode(vp);
		unlock_filp(filp);
		return(r);
	}
	else exist = !(oflags & O_EXCL);/* file exists, if the O_EXCL
					   flag is set this is an error */
  } else {
	/* Scan path name */
	resolve.l_vmnt_lock = VMNT_READ;
	resolve.l_vnode_lock = VNODE_OPCL;
	if ((vp = eat_path(&resolve, fp)) == NULL) {
		unlock_filp(filp);
		return(err_code);
	}

	if (vmp != NULL) unlock_vmnt(vmp);
  }

  /* Claim the file descriptor and filp slot and fill them in. */
  fp->fp_filp[scratch(fp).file.fd_nr] = filp;
  FD_SET(scratch(fp).file.fd_nr, &fp->fp_filp_inuse);
  filp->filp_count = 1;
  filp->filp_vno = vp;
  filp->filp_flags = oflags;

  /* Only do the normal open code if we didn't just create the file. */
  if (exist) {
	/* Check protections. */
	if ((r = forbidden(fp, vp, bits)) == OK) {
		/* Opening reg. files, directories, and special files differ */
		switch (vp->v_mode & S_IFMT) {
		   case S_IFREG:
			/* Truncate regular file if O_TRUNC. */
			if (oflags & O_TRUNC) {
				if ((r = forbidden(fp, vp, W_BIT)) != OK)
					break;
				truncate_vnode(vp, 0);
			}
			break;
		   case S_IFDIR:
			/* Directories may be read but not written. */
			r = (bits & W_BIT ? EISDIR : OK);
			break;
		   case S_IFCHR:
			/* Invoke the driver for special processing. */
			dev = (dev_t) vp->v_sdev;
			/* TTY needs to know about the O_NOCTTY flag. */
			r = dev_open(dev, who_e, bits | (oflags & O_NOCTTY));
			if (r == SUSPEND) suspend(FP_BLOCKED_ON_DOPEN);
			else vp = filp->filp_vno; /* Might be updated by
						   * dev_open/clone_opcl */
			break;
		   case S_IFBLK:

			lock_bsf();

			/* Invoke the driver for special processing. */
			dev = (dev_t) vp->v_sdev;
			r = bdev_open(dev, bits);
			if (r != OK) {
				unlock_bsf();
				break;
			}

			major_dev = major(vp->v_sdev);
			dp = &dmap[major_dev];
			if (dp->dmap_driver == NONE) {
				printf("VFS: block driver disappeared!\n");
				unlock_bsf();
				r = ENXIO;
				break;
			}

			/* Check whether the device is mounted or not. If so,
			 * then that FS is responsible for this device.
			 * Otherwise we default to ROOT_FS.
			 */
			vp->v_bfs_e = ROOT_FS_E; /* By default */
			for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp)
				if (vmp->m_dev == vp->v_sdev &&
				    !(vmp->m_flags & VMNT_FORCEROOTBSF)) {
					vp->v_bfs_e = vmp->m_fs_e;
				}

			/* Send the driver label to the file system that will
			 * handle the block I/O requests (even when its label
			 * and endpoint are known already), but only when it is
			 * the root file system. Other file systems will
			 * already have it anyway.
			 */
			if (vp->v_bfs_e != ROOT_FS_E) {
				unlock_bsf();
				break;
			}

			if (req_newdriver(vp->v_bfs_e, vp->v_sdev,
					dp->dmap_label) != OK) {
				printf("VFS: error sending driver label\n");
				bdev_close(dev);
				r = ENXIO;
			}
			unlock_bsf();
			break;

		   case S_IFIFO:
			/* Create a mapped inode on PFS which handles reads
			   and writes to this named pipe. */
			tll_upgrade(&vp->v_lock);
			r = map_vnode(vp, PFS_PROC_NR);
			if (r == OK) {
				if (vp->v_ref_count == 1) {
					vp->v_pipe_rd_pos = 0;
					vp->v_pipe_wr_pos = 0;
					if (vp->v_size != 0)
						r = truncate_vnode(vp, 0);
				}
				oflags |= O_APPEND;	/* force append mode */
				filp->filp_flags = oflags;
			}
			if (r == OK) {
				r = pipe_open(vp, bits, oflags);
			}
			if (r != ENXIO) {
				/* See if someone else is doing a rd or wt on
				 * the FIFO.  If so, use its filp entry so the
				 * file position will be automatically shared.
				 */
				b = (bits & R_BIT ? R_BIT : W_BIT);
				filp->filp_count = 0; /* don't find self */
				if ((filp2 = find_filp(vp, b)) != NULL) {
				    /* Co-reader or writer found. Use it.*/
				    fp->fp_filp[scratch(fp).file.fd_nr] = filp2;
				    filp2->filp_count++;
				    filp2->filp_vno = vp;
				    filp2->filp_flags = oflags;

				    /* v_count was incremented after the vnode
				     * has been found. i_count was incremented
				     * incorrectly in FS, not knowing that we
				     * were going to use an existing filp
				     * entry.  Correct this error.
				     */
				    unlock_vnode(vp);
				    put_vnode(vp);
				} else {
				    /* Nobody else found. Restore filp. */
				    filp->filp_count = 1;
				}
			}
			break;
		}
	}
  }

  unlock_filp(filp);

  /* If error, release inode. */
  if (r != OK) {
	if (r != SUSPEND) {
		fp->fp_filp[scratch(fp).file.fd_nr] = NULL;
		FD_CLR(scratch(fp).file.fd_nr, &fp->fp_filp_inuse);
		filp->filp_count = 0;
		filp->filp_vno = NULL;
		put_vnode(vp);
	}
  } else {
	r = scratch(fp).file.fd_nr;
  }

  return(r);
}
int main (int argc, char *argv[])
{
	errcode_t	retval = 0, retval2 = 0, orig_retval = 0;
	int		exit_value = FSCK_OK;
	ext2_filsys	fs = 0;
	io_manager	io_ptr;
	struct ext2_super_block *sb;
	const char	*lib_ver_date;
	int		my_ver, lib_ver;
	e2fsck_t	ctx;
	blk_t		orig_superblock;
	struct problem_context pctx;
	int flags, run_result;
	int journal_size;
	int sysval, sys_page_size = 4096;
	__u32 features[3];
	char *cp;
	klog_init();
	E2F_DBG_INFO("e2fsck start...");
#ifdef E2FSCK_PIPE_DEBUG_
	memset(pipe_msg_temp, 0, MSG_LEN);
	memcpy(pipe_msg_temp, argv[2], strlen(argv[2]));
  	pipe_open();
	pipe_write(C_IN_START);
#endif	

	clear_problem_context(&pctx);
#ifdef MTRACE
	mtrace();
#endif
#ifdef MCHECK
	mcheck(0);
#endif
#ifdef ENABLE_NLS
	setlocale(LC_MESSAGES, "");
	setlocale(LC_CTYPE, "");
	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
	textdomain(NLS_CAT_NAME);
#endif
	my_ver = ext2fs_parse_version_string(my_ver_string);
	lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
	if (my_ver > lib_ver) {
		fprintf( stderr, _("Error: ext2fs library version "
			"out of date!\n"));
		show_version_only++;
	}

	retval = PRS(argc, argv, &ctx);
	if (retval) {
		com_err("e2fsck", retval,
			_("while trying to initialize program"));
		exit(FSCK_ERROR);
	}
	reserve_stdio_fds();

	init_resource_track(&ctx->global_rtrack, NULL);
	if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
		fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
			 my_ver_date);

	if (show_version_only) {
		fprintf(stderr, _("\tUsing %s, %s\n"),
			error_message(EXT2_ET_BASE), lib_ver_date);
		exit(FSCK_OK);
	}

	check_mount(ctx);

	if (!(ctx->options & E2F_OPT_PREEN) &&
	    !(ctx->options & E2F_OPT_NO) &&
	    !(ctx->options & E2F_OPT_YES)) {
		if (!ctx->interactive)
			fatal_error(ctx,
				    _("need terminal for interactive repairs"));
	}
	ctx->superblock = ctx->use_superblock;
restart:
#ifdef CONFIG_TESTIO_DEBUG
	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
		io_ptr = test_io_manager;
		test_io_backing_manager = unix_io_manager;
	} else
#endif
		io_ptr = unix_io_manager;
	flags = EXT2_FLAG_NOFREE_ON_ERROR;
	if ((ctx->options & E2F_OPT_READONLY) == 0)
		flags |= EXT2_FLAG_RW;
	if ((ctx->mount_flags & EXT2_MF_MOUNTED) == 0)
		flags |= EXT2_FLAG_EXCLUSIVE;

	retval = try_open_fs(ctx, flags, io_ptr, &fs);

	if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
	    !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
	    ((retval == EXT2_ET_BAD_MAGIC) ||
	     (retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
	     ((retval == 0) && (retval2 = ext2fs_check_desc(fs))))) {
		if (retval2 == ENOMEM) {
			retval = retval2;
			goto failure;
		}
		if (fs->flags & EXT2_FLAG_NOFREE_ON_ERROR) {
			ext2fs_free(fs);
			fs = NULL;
		}
		if (!fs || (fs->group_desc_count > 1)) {
			printf(_("%s: %s trying backup blocks...\n"),
			       ctx->program_name,
			       retval ? _("Superblock invalid,") :
			       _("Group descriptors look bad..."));
			orig_superblock = ctx->superblock;
			get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
			if (fs)
				ext2fs_close(fs);
			orig_retval = retval;
			retval = try_open_fs(ctx, flags, io_ptr, &fs);
			if ((orig_retval == 0) && retval != 0) {
				if (fs)
					ext2fs_close(fs);
				com_err(ctx->program_name, retval,
					"when using the backup blocks");
				printf(_("%s: going back to original "
					 "superblock\n"), ctx->program_name);
				ctx->superblock = orig_superblock;
				retval = try_open_fs(ctx, flags, io_ptr, &fs);
			}
		}
	}
	if (((retval == EXT2_ET_UNSUPP_FEATURE) ||
	     (retval == EXT2_ET_RO_UNSUPP_FEATURE)) &&
	    fs && fs->super) {
		sb = fs->super;
		features[0] = (sb->s_feature_compat &
			       ~EXT2_LIB_FEATURE_COMPAT_SUPP);
		features[1] = (sb->s_feature_incompat &
			       ~EXT2_LIB_FEATURE_INCOMPAT_SUPP);
		features[2] = (sb->s_feature_ro_compat &
			       ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP);
		if (features[0] || features[1] || features[2])
			goto print_unsupp_features;
	}
failure:
	if (retval) {
		if (orig_retval)
			retval = orig_retval;
		com_err(ctx->program_name, retval, _("while trying to open %s"),
			ctx->filesystem_name);
		if (retval == EXT2_ET_REV_TOO_HIGH) {
			printf(_("The filesystem revision is apparently "
			       "too high for this version of e2fsck.\n"
			       "(Or the filesystem superblock "
			       "is corrupt)\n\n"));
			fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
		} else if (retval == EXT2_ET_SHORT_READ)
			printf(_("Could this be a zero-length partition?\n"));
		else if ((retval == EPERM) || (retval == EACCES))
			printf(_("You must have %s access to the "
			       "filesystem or be root\n"),
			       (ctx->options & E2F_OPT_READONLY) ?
			       "r/o" : "r/w");
		else if (retval == ENXIO)
			printf(_("Possibly non-existent or swap device?\n"));
		else if (retval == EBUSY)
			printf(_("Filesystem mounted or opened exclusively "
				 "by another program?\n"));
		else if (retval == ENOENT)
			printf(_("Possibly non-existent device?\n"));
#ifdef EROFS
		else if (retval == EROFS)
			printf(_("Disk write-protected; use the -n option "
			       "to do a read-only\n"
			       "check of the device.\n"));
#endif
		else
			fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
		fatal_error(ctx, 0);
	}
	/*
	 * We only update the master superblock because (a) paranoia;
	 * we don't want to corrupt the backup superblocks, and (b) we
	 * don't need to update the mount count and last checked
	 * fields in the backup superblock (the kernel doesn't update
	 * the backup superblocks anyway).  With newer versions of the
	 * library this flag is set by ext2fs_open2(), but we set this
	 * here just to be sure.  (No, we don't support e2fsck running
	 * with some other libext2fs than the one that it was shipped
	 * with, but just in case....)
	 */
	fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;

	if (!(ctx->flags & E2F_FLAG_GOT_DEVSIZE)) {
		__u32 blocksize = EXT2_BLOCK_SIZE(fs->super);
		int need_restart = 0;

		pctx.errcode = ext2fs_get_device_size2(ctx->filesystem_name,
						       blocksize,
						       &ctx->num_blocks);
		/*
		 * The floppy driver refuses to allow anyone else to
		 * open the device if has been opened with O_EXCL;
		 * this is unlike other block device drivers in Linux.
		 * To handle this, we close the filesystem and then
		 * reopen the filesystem after we get the device size.
		 */
		if (pctx.errcode == EBUSY) {
			ext2fs_close(fs);
			need_restart++;
			pctx.errcode =
				ext2fs_get_device_size2(ctx->filesystem_name,
							blocksize,
							&ctx->num_blocks);
		}
		if (pctx.errcode == EXT2_ET_UNIMPLEMENTED)
			ctx->num_blocks = 0;
		else if (pctx.errcode) {
			fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
			ctx->flags |= E2F_FLAG_ABORT;
			fatal_error(ctx, 0);
		}
		ctx->flags |= E2F_FLAG_GOT_DEVSIZE;
		if (need_restart)
			goto restart;
	}

	ctx->fs = fs;
	fs->priv_data = ctx;
	fs->now = ctx->now;
	sb = fs->super;
	if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
		com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
			_("while trying to open %s"),
			ctx->filesystem_name);
	get_newer:
		fatal_error(ctx, _("Get a newer version of e2fsck!"));
	}

	/*
	 * Set the device name, which is used whenever we print error
	 * or informational messages to the user.
	 */
	if (ctx->device_name == 0 &&
	    (sb->s_volume_name[0] != 0)) {
		ctx->device_name = string_copy(ctx, sb->s_volume_name,
					       sizeof(sb->s_volume_name));
	}
	if (ctx->device_name == 0)
		ctx->device_name = string_copy(ctx, ctx->filesystem_name, 0);
	for (cp = ctx->device_name; *cp; cp++)
		if (isspace(*cp) || *cp == ':')
			*cp = '_';

	ehandler_init(fs->io);

	if ((ctx->mount_flags & EXT2_MF_MOUNTED) &&
	    !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER))
		goto skip_journal;

	/*
	 * Make sure the ext3 superblock fields are consistent.
	 */
	retval = e2fsck_check_ext3_journal(ctx);
	if (retval) {
		com_err(ctx->program_name, retval,
			_("while checking ext3 journal for %s"),
			ctx->device_name);
		fatal_error(ctx, 0);
	}

	/*
	 * Check to see if we need to do ext3-style recovery.  If so,
	 * do it, and then restart the fsck.
	 */
	if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
		if (ctx->options & E2F_OPT_READONLY) {
			printf(_("Warning: skipping journal recovery "
				 "because doing a read-only filesystem "
				 "check.\n"));
			io_channel_flush(ctx->fs->io);
		} else {
			if (ctx->flags & E2F_FLAG_RESTARTED) {
				/*
				 * Whoops, we attempted to run the
				 * journal twice.  This should never
				 * happen, unless the hardware or
				 * device driver is being bogus.
				 */
				com_err(ctx->program_name, 0,
					_("unable to set superblock flags on %s\n"), ctx->device_name);
				fatal_error(ctx, 0);
			}
			retval = e2fsck_run_ext3_journal(ctx);
			if (retval) {
				com_err(ctx->program_name, retval,
				_("while recovering ext3 journal of %s"),
					ctx->device_name);
				fatal_error(ctx, 0);
			}
			ext2fs_close(ctx->fs);
			ctx->fs = 0;
			ctx->flags |= E2F_FLAG_RESTARTED;
			goto restart;
		}
	}

skip_journal:
	/*
	 * Check for compatibility with the feature sets.  We need to
	 * be more stringent than ext2fs_open().
	 */
	features[0] = sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP;
	features[1] = sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP;
	features[2] = (sb->s_feature_ro_compat &
		       ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP);
print_unsupp_features:
	if (features[0] || features[1] || features[2]) {
		int	i, j;
		__u32	*mask = features, m;

		fprintf(stderr, _("%s has unsupported feature(s):"),
			ctx->filesystem_name);

		for (i=0; i <3; i++,mask++) {
			for (j=0,m=1; j < 32; j++, m<<=1) {
				if (*mask & m)
					fprintf(stderr, " %s",
						e2p_feature2string(i, m));
			}
		}
		putc('\n', stderr);
		goto get_newer;
	}
#ifdef ENABLE_COMPRESSION
	if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
		com_err(ctx->program_name, 0,
			_("Warning: compression support is experimental.\n"));
#endif
#ifndef ENABLE_HTREE
	if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
		com_err(ctx->program_name, 0,
			_("E2fsck not compiled with HTREE support,\n\t"
			  "but filesystem %s has HTREE directories.\n"),
			ctx->device_name);
		goto get_newer;
	}
#endif

	/*
	 * If the user specified a specific superblock, presumably the
	 * master superblock has been trashed.  So we mark the
	 * superblock as dirty, so it can be written out.
	 */
	if (ctx->superblock &&
	    !(ctx->options & E2F_OPT_READONLY))
		ext2fs_mark_super_dirty(fs);

	/*
	 * Calculate the number of filesystem blocks per pagesize.  If
	 * fs->blocksize > page_size, set the number of blocks per
	 * pagesize to 1 to avoid division by zero errors.
	 */
#ifdef _SC_PAGESIZE
	sysval = sysconf(_SC_PAGESIZE);
	if (sysval > 0)
		sys_page_size = sysval;
#endif /* _SC_PAGESIZE */
	ctx->blocks_per_page = sys_page_size / fs->blocksize;
	if (ctx->blocks_per_page == 0)
		ctx->blocks_per_page = 1;

	if (ctx->superblock)
		set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
	ext2fs_mark_valid(fs);
	check_super_block(ctx);
	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
		fatal_error(ctx, 0);
	check_if_skip(ctx);
	check_resize_inode(ctx);
	if (bad_blocks_file)
		read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
	else if (cflag)
		read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
		fatal_error(ctx, 0);

	/*
	 * Mark the system as valid, 'til proven otherwise
	 */
	ext2fs_mark_valid(fs);

	retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
	if (retval) {
		com_err(ctx->program_name, retval,
			_("while reading bad blocks inode"));
		preenhalt(ctx);
		printf(_("This doesn't bode well,"
			 " but we'll try to go on...\n"));
	}

	/*
	 * Save the journal size in megabytes.
	 * Try and use the journal size from the backup else let e2fsck
	 * find the default journal size.
	 */
	if (sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS)
		journal_size = sb->s_jnl_blocks[16] >> 20;
	else
Пример #10
0
int pipe_input_command ( const char* command, const char* input_filename, pid_t* /*OUTPUT*/ child_pid )
{
	return pipe_open ( command, input_filename, 1, child_pid ) ;
}
Пример #11
0
int pipe_output_command ( const char* command, const char* output_filename, pid_t* /*OUTPUT*/ child_pid )
{
	return pipe_open ( command, output_filename, 0, child_pid ) ;
}
Пример #12
0
/*
 * Formats data LV for a use as a VDO pool LV.
 *
 * Calls tool 'vdoformat' on the already active volume.
 */
static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
				    const struct dm_vdo_target_params *vtp,
				    uint64_t *logical_size)
{
	char *dpath;
	const struct dm_config_node *cn;
	const struct dm_config_value *cv;
	struct pipe_data pdata;
	FILE *f;
	uint64_t lb;
	unsigned slabbits;
	int args = 1;
	char buf_args[5][128];
	char buf[256]; /* buffer for short disk header (64B) */
	const char *argv[19] = { /* Max supported args */
		find_config_tree_str_allow_empty(data_lv->vg->cmd, global_vdo_format_executable_CFG, NULL)
	};

	if (!(dpath = lv_path_dup(data_lv->vg->cmd->mem, data_lv))) {
		log_error("Failed to build device path for VDO formating of data volume %s.",
			  display_lvname(data_lv));
		return 0;
	}

	if (*logical_size) {
		if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--logical-size=" FMTu64 "K",
			       (*logical_size / 2)) < 0)
			return_0;

		argv[args] = buf_args[args];
		args++;
	}

	slabbits = 31 - clz(vtp->slab_size_mb / DM_VDO_BLOCK_SIZE * 512);
	log_debug("Slab size %s converted to %u bits.",
		  display_size(data_lv->vg->cmd, vtp->slab_size_mb * UINT64_C(2 * 1024)), slabbits);
	if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--slab-bits=%u", slabbits) < 0)
		return_0;

	argv[args] = buf_args[args];
	args++;

	if (vtp->check_point_frequency) {
		if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-checkpoint-frequency=%u",
				vtp->check_point_frequency) < 0)
			return_0;
		argv[args] = buf_args[args];
		args++;
	}

	/* Convert size to GiB units or one of these strings: 0.25, 0.50, 0.75 */
	if (vtp->index_memory_size_mb >= 1024) {
		if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-memory-size=%u",
				vtp->index_memory_size_mb / 1024) < 0)
			return_0;
	} else if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-memory-size=0.%u",
			       (vtp->index_memory_size_mb < 512) ? 25 :
			       (vtp->index_memory_size_mb < 768) ? 50 : 75) < 0)
		   return_0;

	argv[args] = buf_args[args];
	args++;

	if (vtp->use_sparse_index)  {
		if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-sparse") < 0)
			return_0;

		argv[args] = buf_args[args];
		args++;
	}

	/* Any other user opts add here */
	if (!(cn = find_config_tree_array(data_lv->vg->cmd, global_vdo_format_options_CFG, NULL))) {
		log_error(INTERNAL_ERROR "Unable to find configuration for vdoformat command options.");
		return 0;
	}

	for (cv = cn->v; cv && args < 16; cv = cv->next) {
		if (cv->type != DM_CFG_STRING) {
			log_error("Invalid string in config file: "
				  "global/vdoformat_options.");
			return 0;
		}
		if (cv->v.str[0])
			argv[++args] = cv->v.str;
	}

	/* Only unused VDO data LV could be activated and wiped */
	if (!dm_list_empty(&data_lv->segs_using_this_lv)) {
		log_error(INTERNAL_ERROR "Failed to wipe logical VDO data for volume %s.",
			  display_lvname(data_lv));
		return 0;
	}

	argv[args] = dpath;

	if (!(f = pipe_open(data_lv->vg->cmd, argv, 0, &pdata))) {
		log_error("WARNING: Cannot read output from %s.", argv[0]);
		return 0;
	}

	if (!*logical_size)
		while (fgets(buf, sizeof(buf), f)) {
			/* TODO: Watch out for locales */
			if (sscanf(buf, "Logical blocks defaulted to " FMTu64 " blocks", &lb) == 1) {
				*logical_size = lb * DM_VDO_BLOCK_SIZE;
				log_verbose("Available VDO logical blocks " FMTu64 " (%s).",
					    lb, display_size(data_lv->vg->cmd, *logical_size));
				break;
			} else
				log_warn("WARNING: Cannot parse output '%s' from %s.", buf, argv[0]);
		}

	if (!pipe_close(&pdata)) {
		log_error("Command %s failed.", argv[0]);
		return 0;
	}

	return 1;
}
Пример #13
0
/*===========================================================================*
 *				common_open				     *
 *===========================================================================*/
static int common_open(register int oflags, mode_t omode)
{
/* Common code from do_creat and do_open. */
  int b, r, exist = TRUE;
  dev_t dev;
  mode_t bits;
  struct filp *fil_ptr, *filp2;
  struct vnode *vp;
  struct vmnt *vmp;
  struct dmap *dp;

  /* Remap the bottom two bits of oflags. */
  bits = (mode_t) mode_map[oflags & O_ACCMODE];
  if (!bits) return(-EINVAL);

  /* See if file descriptor and filp slots are available. */
  if ((r = get_fd(0, bits, &m_in.fd, &fil_ptr)) != 0) return(r);

  /* If O_CREATE is set, try to make the file. */
  if (oflags & O_CREAT) {
        omode = I_REGULAR | (omode & ALL_MODES & fp->fp_umask);
	vp = new_node(omode);
	r = err_code;
	if (r == 0) exist = FALSE; /* We just created the file */
	else if (r != -EEXIST) return(r);  /* other error */ 
	else exist = !(oflags & O_EXCL);  /* file exists, if the O_EXCL
					     flag is set this is an error */
  } else {
	/* Scan path name */
	if ((vp = eat_path(PATH_NOFLAGS)) == NIL_VNODE) return(err_code);
  }

  /* Claim the file descriptor and filp slot and fill them in. */
  fp->fp_filp[m_in.fd] = fil_ptr;
  FD_SET(m_in.fd, &fp->fp_filp_inuse);
  fil_ptr->filp_count = 1;
  fil_ptr->filp_vno = vp;
  fil_ptr->filp_flags = oflags;
  
  /* Only do the normal open code if didn't just create the file. */
  if(exist) {
	/* Check protections. */
	if ((r = forbidden(vp, bits)) == 0) {
		/* Opening reg. files, directories, and special files differ */
  switch (vp->v_mode & I_TYPE) {
		   case I_REGULAR:
		   	/* Truncate regular file if O_TRUNC. */
		   	if (oflags & O_TRUNC) {
		   		if ((r = forbidden(vp, W_BIT)) != 0)
		   			break;
		   		truncate_vnode(vp, 0);
		   	}
		   	break;
		   case I_DIRECTORY:
		   	/* Directories may be read but not written. */
		   	r = (bits & W_BIT ? -EISDIR : 0);
		   	break;
      case I_CHAR_SPECIAL:
          /* Invoke the driver for special processing. */
			dev = (dev_t) vp->v_sdev;
			r = dev_open(dev, who_e, bits | (oflags & ~O_ACCMODE));
		   	if (r == SUSPEND) suspend(FP_BLOCKED_ON_DOPEN);
          break;
      case I_BLOCK_SPECIAL:
          /* Invoke the driver for special processing. */
			dev = (dev_t) vp->v_sdev;
			r = dev_open(dev, who_e, bits | (oflags & ~O_ACCMODE));
	 
			/* Check whether the device is mounted or not. If so,
			   then that FS is responsible for this device. Else
			   we default to ROOT_FS. */
			vp->v_bfs_e = ROOT_FS_E; /* By default */
			for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) 
				if (vmp->m_dev == vp->v_sdev) 
	      vp->v_bfs_e = vmp->m_fs_e;
	  
	  /* Get the driver endpoint of the block spec device */
	  dp = &dmap[(vp->v_sdev >> MAJOR) & BYTE];
	  if (dp->dmap_driver == ENDPT_NONE) {
				printk("VFS: driver not found for device %d\n",
		      vp->v_sdev);
				r = -ENXIO;
	      break;
	  }

			/* Send the driver endpoint (even when known already)*/
			if ((r = req_newdriver(vp->v_bfs_e, vp->v_sdev,
					       dp->dmap_driver)) != 0) {
				printk("VFS: error sending driver endpoint\n");
				r = -ENXIO;
	  }
          break;

      case I_NAMED_PIPE:
			/* Create a mapped inode on PFS which handles reads
			   and writes to this named pipe. */
			r = map_vnode(vp);
			if (r == 0) {
	  vp->v_pipe = I_PIPE;
				if (vp->v_ref_count == 1) {
					vp->v_pipe_rd_pos = 0;
					vp->v_pipe_wr_pos = 0;
					if (vp->v_size != 0)
						r = truncate_vnode(vp, 0);
				}
          oflags |= O_APPEND;	/* force append mode */
          fil_ptr->filp_flags = oflags;
			}
			if (r == 0) {
          r = pipe_open(vp, bits, oflags);
			}
          if (r != -ENXIO) {
              /* See if someone else is doing a rd or wt on
               * the FIFO.  If so, use its filp entry so the
               * file position will be automatically shared.
               */
              b = (bits & R_BIT ? R_BIT : W_BIT);
              fil_ptr->filp_count = 0; /* don't find self */
              if ((filp2 = find_filp(vp, b)) != NIL_FILP) {
                  /* Co-reader or writer found. Use it.*/
                  fp->fp_filp[m_in.fd] = filp2;
                  filp2->filp_count++;
		  filp2->filp_vno = vp;
                  filp2->filp_flags = oflags;

					/* v_count was incremented after the
					 * vnode has been found. i_count was
					 * incremented incorrectly in FS, not
					 * knowing that we were going to use an
					 * existing filp entry.  Correct this
					 * error.
                   */
                  put_vnode(vp);
	      } else {
					/* Nobody else found. Restore filp. */
                  fil_ptr->filp_count = 1;
              }
          }
          break;
  }
	}
  }

  /* If error, release inode. */
  if (r != 0) {
	if (r == SUSPEND) return(r);		/* Oops, just suspended */
	fp->fp_filp[m_in.fd] = NIL_FILP;
  	FD_CLR(m_in.fd, &fp->fp_filp_inuse);
	fil_ptr->filp_count= 0;
	put_vnode(vp);     
	fil_ptr->filp_vno = NIL_VNODE;
	return(r);
  }
  
  return(m_in.fd);
}
Пример #14
0
int stdio_init(void)
{
	bathos_stdout = pipe_open(CONFIG_STDOUT, BATHOS_MODE_OUTPUT, NULL);
	bathos_stdin = pipe_open(CONFIG_STDIN, BATHOS_MODE_INPUT, NULL);
	return 0;
}
Пример #15
0
static int
findfile_in_dir(const char *fnam, const char *dir, const int recdepth, const char *const *suf, lkfile_t *fp)
{
	DIR *d;
	struct dirent *de;
	char *ff, *fdir, *p;
	const char *q;
	struct decompressor *dc;
	int i, rc = -1, secondpass = 0;
	size_t dir_len;

	fp->fd = NULL;
	fp->pipe = 0;

	if ((d = opendir(dir)) == NULL)
		return -1;

	dir_len = strlen(dir);

	fdir = NULL;
	if ((ff = strchr(fnam, '/')) != NULL) {
		if ((fdir = strndup(fnam, ff - fnam)) == NULL) {
			closedir(d);
			return -1;
		}
	}

	/* Scan the directory twice: first for files, then
	   for subdirectories, so that we do never search
	   a subdirectory when the directory itself already
	   contains the file we are looking for. */
StartScan:
	while ((de = readdir(d)) != NULL) {
	    struct stat st;
	    int okdir;
	    size_t d_len;

	    d_len = strlen(de->d_name);
	    if (d_len < 3) {
		    if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
			continue;
	    }

	    if (dir_len + d_len + 2 > sizeof(fp->pathname))
		continue;

	    okdir = (ff && strcmp(de->d_name, fdir) == 0);

	    if ((secondpass && recdepth) || okdir) {
		char *a;

		if ((a = malloc(dir_len + d_len + 2)) == NULL)
			goto EndScan;

		sprintf(a, "%s/%s", dir, de->d_name);

		if (stat(a, &st) == 0 && S_ISDIR(st.st_mode)) {
			if (okdir)
				rc = findfile_in_dir(ff+1, a, 0, suf, fp);

			if (rc && recdepth)
				rc = findfile_in_dir(fnam, a, recdepth-1, suf, fp);

			if (!rc) {
				free(a);
				goto EndScan;
			}
		}
		free(a);
	    }

	    if (secondpass)
		    continue;

	    /* Should we be in a subdirectory? */
	    if (ff)
		    continue;

	    /* Does d_name start right? */
	    p = &de->d_name[0];
	    q = fnam;
	    while (*p && *p == *q) p++,q++;
	    if (*q)
		    continue;

	    sprintf(fp->pathname, "%s/%s", dir, de->d_name);
	    if (stat(fp->pathname, &st) != 0 || !S_ISREG(st.st_mode))
		    continue;

	    /* Does tail consist of a known suffix and possibly
	       a compression suffix? */
	    for(i = 0; suf[i]; i++) {
		    size_t l;

		    if (!strcmp(p, suf[i])) {
	    		rc = maybe_pipe_open(fp);
	    		goto EndScan;
		    }

		    l = strlen(suf[i]);
		    if (!strncmp(p, suf[i], l)) {
			for (dc = &decompressors[0]; dc->cmd; dc++)
			    if (strcmp(p+l, dc->ext) == 0) {
			    	rc = pipe_open(dc, fp);
			    	goto EndScan;
			    }
		    }
	    }
	}

	if (recdepth > 0 && !secondpass) {
		secondpass = 1;
		seekdir(d, 0);
		goto StartScan;
	}

EndScan:
	if (fdir != NULL)
		free(fdir);
	closedir(d);
	return rc;
}
Пример #16
-1
/* service_main */
static VOID WINAPI service_main(DWORD argc, LPTSTR *argv) {
    config_t        conf;
    void*           net;
    void*           threads;
    void*           pipe;

    h_service = RegisterServiceCtrlHandler(LDMSVC_SERVICE_NAME, handler);
    if(h_service == NULL) {
        return;
    }

    set_state1(SERVICE_START_PENDING);        // SERVICE_START_PENDING

    // open the heap
    if(!heap_start()) {
        dout("Failed to create the heap\n");
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    // parse configuration
    if(!config_parse_args(&conf, argc, argv)) {
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    if(0) {
        dout(va("PORT: %u\n", conf.port));
        dout(va("PIPE: %s\n", conf.pipe));
        dout(va("MAXC: %u\n", conf.maxconn));
    }

    // open network
    if((net = net_start()) == NULL) {
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    // open the pipe
    if((pipe = pipe_start(conf.pipe)) == NULL) {
        net_stop(net);
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    // connect the pipe
    if(!pipe_open(pipe)) {
        pipe_stop(pipe);
        net_stop(net);
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    // start threads
    if((threads = threads_start(net, pipe, conf.maxconn)) == NULL) {
        pipe_stop(pipe);
        net_stop(net);
        heap_stop();
        set_state2(SERVICE_STOPPED, 1);
        return;
    }

    set_state1(SERVICE_RUNNING);              // SERVICE_RUNNING

    while(svc_state == SERVICE_RUNNING) {
        if(!net_is_ready(net)) {
            net_bind(net, NULL, conf.port);
        }

        if(!threads_think(threads)) {
            break;
        }

        Sleep(1);
    }

    set_state1(SERVICE_STOP_PENDING);         // SERVICE_STOP_PENDING

    // close everything here
    threads_stop(threads);
    pipe_stop(pipe);
    net_stop(net);
    heap_stop();

    set_state2(SERVICE_STOPPED, 0);           // SERVICE_STOPPED
}