int udev_node_mknod(struct udev_device *dev, const char *file, dev_t devnum, mode_t mode, uid_t uid, gid_t gid)
{
	struct udev *udev = udev_device_get_udev(dev);
	struct stat stats;
	int preserve = 0;
	int err = 0;

	if (major(devnum) == 0)
		devnum = udev_device_get_devnum(dev);

	if (strcmp(udev_device_get_subsystem(dev), "block") == 0)
		mode |= S_IFBLK;
	else
		mode |= S_IFCHR;

	if (file == NULL)
		file = udev_device_get_devnode(dev);

	if (lstat(file, &stats) == 0) {
		if (((stats.st_mode & S_IFMT) == (mode & S_IFMT)) && (stats.st_rdev == devnum)) {
			info(udev, "preserve file '%s', because it has correct dev_t\n", file);
			preserve = 1;
			udev_selinux_lsetfilecon(udev, file, mode);
			/* update time stamp when we re-use the node, like on media change events */
			utimes(file, NULL);
		} else {
			char file_tmp[UTIL_PATH_SIZE + sizeof(TMP_FILE_EXT)];

			info(udev, "atomically replace existing file '%s'\n", file);
			util_strscpyl(file_tmp, sizeof(file_tmp), file, TMP_FILE_EXT, NULL);
			unlink(file_tmp);
			udev_selinux_setfscreatecon(udev, file_tmp, mode);
			err = mknod(file_tmp, mode, devnum);
			udev_selinux_resetfscreatecon(udev);
			if (err != 0) {
				err(udev, "mknod(%s, %#o, %u, %u) failed: %m\n",
				    file_tmp, mode, major(devnum), minor(devnum));
				goto exit;
			}
			err = rename(file_tmp, file);
			if (err != 0) {
				err(udev, "rename(%s, %s) failed: %m\n", file_tmp, file);
				unlink(file_tmp);
			}
		}
	} else {
		info(udev, "mknod(%s, %#o, (%u,%u))\n", file, mode, major(devnum), minor(devnum));
		do {
			err = util_create_path(udev, file);
			if (err != 0 && err != -ENOENT)
				break;
			udev_selinux_setfscreatecon(udev, file, mode);
			err = mknod(file, mode, devnum);
			if (err != 0)
				err = -errno;
			udev_selinux_resetfscreatecon(udev);
		} while (err == -ENOENT);
		if (err != 0) {
			err(udev, "mknod(%s, %#o, (%u,%u) failed: %m\n", file, mode, major(devnum), minor(devnum));
			goto exit;
		}
	}

	if (!preserve || stats.st_mode != mode) {
		info(udev, "chmod(%s, %#o)\n", file, mode);
		err = chmod(file, mode);
		if (err != 0) {
			err(udev, "chmod(%s, %#o) failed: %m\n", file, mode);
			goto exit;
		}
	}

	if (!preserve || stats.st_uid != uid || stats.st_gid != gid) {
		info(udev, "chown(%s, %u, %u)\n", file, uid, gid);
		err = chown(file, uid, gid);
		if (err != 0) {
			err(udev, "chown(%s, %u, %u) failed: %m\n", file, uid, gid);
			goto exit;
		}
	}
exit:
	return err;
}
Beispiel #2
0
int
kbdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
	struct kbd_softc *k;
	struct kbd_state *ks;
	int error = 0;

	k = device_lookup_private(&kbd_cd, minor(dev));
	ks = &k->k_state;

	switch (cmd) {

	case KIOCTRANS: 	/* Set translation mode */
		/* We only support "raw" mode on /dev/kbd */
		if (*(int *)data != TR_UNTRANS_EVENT)
			error = EINVAL;
		break;

	case KIOCGTRANS:	/* Get translation mode */
		/* We only support "raw" mode on /dev/kbd */
		*(int *)data = TR_UNTRANS_EVENT;
		break;

#ifdef KIOCGETKEY
	case KIOCGETKEY:	/* Get keymap entry (old format) */
		error = kbd_oldkeymap(ks, cmd, (struct okiockey *)data);
		break;
#endif /* KIOCGETKEY */

	case KIOCSKEY:  	/* Set keymap entry */
		/* FALLTHROUGH */
	case KIOCGKEY:  	/* Get keymap entry */
		error = kbd_iockeymap(ks, cmd, (struct kiockeymap *)data);
		break;

	case KIOCCMD:		/* Send a command to the keyboard */
		/* pass it to the middle layer */
		if (k->k_ops != NULL && k->k_ops->docmd != NULL)
			error = (*k->k_ops->docmd)(k, *(int *)data, 1);
		break;

	case KIOCTYPE:		/* Get keyboard type */
		*(int *)data = ks->kbd_id;
		break;

	case KIOCSDIRECT:	/* Where to send input */
		k->k_evmode = *(int *)data;
		break;

	case KIOCLAYOUT:	/* Get keyboard layout */
		*(int *)data = ks->kbd_layout;
		break;

	case KIOCSLED:		/* Set keyboard LEDs */
		/* pass the request to the middle layer */
		if (k->k_ops != NULL && k->k_ops->setleds != NULL)
			error = (*k->k_ops->setleds)(k, *(char *)data, 1);
		break;

	case KIOCGLED:		/* Get keyboard LEDs */
		*(char *)data = ks->kbd_leds;
		break;

	case FIONBIO:		/* we will remove this someday (soon???) */
		break;

	case FIOASYNC:
		k->k_events.ev_async = (*(int *)data != 0);
		break;

	case FIOSETOWN:
		if (-*(int *)data != k->k_events.ev_io->p_pgid
		    && *(int *)data != k->k_events.ev_io->p_pid)
			error = EPERM;
		break;

	case TIOCSPGRP:
		if (*(int *)data != k->k_events.ev_io->p_pgid)
			error = EPERM;
		break;

	default:
		error = ENOTTY;
		break;
	}

	return error;
}
Beispiel #3
0
static int
iir_ioctl(dev_t dev, u_long cmd, caddr_t cmdarg, int flags, d_thread_t * p)
{
    GDT_DPRINTF(GDT_D_DEBUG, ("iir_ioctl() cmd 0x%lx\n",cmd));

#ifdef SDEV_PER_HBA
    int minor_no;
    struct gdt_softc *gdt;

    minor_no = minor(dev);
    gdt = gdt_minor2softc(minor_no);
    if (gdt == NULL)
        return (ENXIO);
#endif
    ++gdt_stat.io_count_act;
    if (gdt_stat.io_count_act > gdt_stat.io_count_max)
        gdt_stat.io_count_max = gdt_stat.io_count_act;

    switch (cmd) {
      case GDT_IOCTL_GENERAL:
        {
            gdt_ucmd_t *ucmd;
            struct gdt_softc *gdt;
            int lock;

            ucmd = (gdt_ucmd_t *)cmdarg;
            gdt = gdt_minor2softc(ucmd->io_node);
            if (gdt == NULL)
                return (ENXIO);
            lock = splcam();
            TAILQ_INSERT_TAIL(&gdt->sc_ucmd_queue, ucmd, links);
            ucmd->complete_flag = FALSE;
            splx(lock);
            gdt_next(gdt);
            if (!ucmd->complete_flag)
                (void) tsleep((void *)ucmd, PCATCH | PRIBIO, "iirucw", 0);
            break;
        }

      case GDT_IOCTL_DRVERS:
        *(int *)cmdarg = 
            (IIR_DRIVER_VERSION << 8) | IIR_DRIVER_SUBVERSION;
        break;

      case GDT_IOCTL_CTRTYPE:
        {
            gdt_ctrt_t *p;
            struct gdt_softc *gdt; 
            
            p = (gdt_ctrt_t *)cmdarg;
            gdt = gdt_minor2softc(p->io_node);
            if (gdt == NULL)
                return (ENXIO);
            p->oem_id = 0x8000;
            p->type = 0xfd;
            p->info = (gdt->sc_bus << 8) | (gdt->sc_slot << 3);
            p->ext_type = 0x6000 | gdt->sc_subdevice;
            p->device_id = gdt->sc_device;
            p->sub_device_id = gdt->sc_subdevice;
            break;
        }

      case GDT_IOCTL_OSVERS:
        {
            gdt_osv_t *p;

            p = (gdt_osv_t *)cmdarg;
            p->oscode = 10;
            p->version = osrelease[0] - '0';
            if (osrelease[1] == '.')
                p->subversion = osrelease[2] - '0';
            else
                p->subversion = 0;
            if (osrelease[3] == '.')
                p->revision = osrelease[4] - '0';
            else
                p->revision = 0;
            strcpy(p->name, ostype);
            break;
        }

      case GDT_IOCTL_CTRCNT:
        *(int *)cmdarg = gdt_cnt;
        break;

      case GDT_IOCTL_EVENT:
        {
            gdt_event_t *p;
            int lock;

            p = (gdt_event_t *)cmdarg;
            if (p->erase == 0xff) {
                if (p->dvr.event_source == GDT_ES_TEST)
                    p->dvr.event_data.size = sizeof(p->dvr.event_data.eu.test);
                else if (p->dvr.event_source == GDT_ES_DRIVER)
                    p->dvr.event_data.size= sizeof(p->dvr.event_data.eu.driver);
                else if (p->dvr.event_source == GDT_ES_SYNC)
                    p->dvr.event_data.size = sizeof(p->dvr.event_data.eu.sync);
                else
                    p->dvr.event_data.size = sizeof(p->dvr.event_data.eu.async);
                lock = splcam();
                gdt_store_event(p->dvr.event_source, p->dvr.event_idx,
                                &p->dvr.event_data);
                splx(lock);
            } else if (p->erase == 0xfe) {
                lock = splcam();
                gdt_clear_events();
                splx(lock);
            } else if (p->erase == 0) {
                p->handle = gdt_read_event(p->handle, &p->dvr);
            } else {
                gdt_readapp_event((u_int8_t)p->erase, &p->dvr);
            }
            break;
        }
        
      case GDT_IOCTL_STATIST:
        {
            gdt_statist_t *p;
            
            p = (gdt_statist_t *)cmdarg;
            bcopy(&gdt_stat, p, sizeof(gdt_statist_t));
            break;
        }

      default:
        break;
    }

    --gdt_stat.io_count_act;
    return (0);
}
Beispiel #4
0
/*
 * Arranges output according to a single parsed format substring.
 */
int
format1(const struct stat *st,
    const char *file,
    const char *fmt, int flen,
    char *buf, size_t blen,
    int flags, int size, int prec, int ofmt,
    int hilo, int what)
{
	u_int64_t data;
	char *stmp, lfmt[24], tmp[20];
	const char *sdata;
	char smode[12], sid[12], path[PATH_MAX + 4];
	struct passwd *pw;
	struct group *gr;
	const struct timespec *tsp;
	struct timespec ts;
	struct tm *tm;
	int l, small, formats;

	tsp = NULL;
	formats = 0;
	small = 0;

	/*
	 * First, pick out the data and tweak it based on hilo or
	 * specified output format (symlink output only).
	 */
	switch (what) {
	case SHOW_st_dev:
	case SHOW_st_rdev:
		small = (sizeof(st->st_dev) == 4);
		data = (what == SHOW_st_dev) ? st->st_dev : st->st_rdev;
#if HAVE_DEVNAME
		sdata = (what == SHOW_st_dev) ?
		    devname(st->st_dev, S_IFBLK) :
		    devname(st->st_rdev, 
		    S_ISCHR(st->st_mode) ? S_IFCHR :
		    S_ISBLK(st->st_mode) ? S_IFBLK :
		    0U);
		if (sdata == NULL)
			sdata = "???";
#endif /* HAVE_DEVNAME */
		if (hilo == HIGH_PIECE) {
			data = major(data);
			hilo = 0;
		}
		else if (hilo == LOW_PIECE) {
			data = minor((unsigned)data);
			hilo = 0;
		}
		formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX |
#if HAVE_DEVNAME
		    FMTF_STRING;
#else /* HAVE_DEVNAME */
		    0;
#endif /* HAVE_DEVNAME */
		if (ofmt == 0)
			ofmt = FMTF_UNSIGNED;
		break;
	case SHOW_st_ino:
		small = (sizeof(st->st_ino) == 4);
		data = st->st_ino;
		sdata = NULL;
		formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX;
		if (ofmt == 0)
			ofmt = FMTF_UNSIGNED;
		break;
	case SHOW_st_mode:
		small = (sizeof(st->st_mode) == 4);
		data = st->st_mode;
		strmode(st->st_mode, smode);
		stmp = smode;
		l = strlen(stmp);
		if (stmp[l - 1] == ' ')
			stmp[--l] = '\0';
		if (hilo == HIGH_PIECE) {
			data >>= 12;
			stmp += 1;
			stmp[3] = '\0';
			hilo = 0;
		}
		else if (hilo == MIDDLE_PIECE) {
Beispiel #5
0
void
dodumpsys(void)
{
	const struct bdevsw *bdev;
	int dumpend, psize;
	int error;

	if (dumpdev == NODEV)
		return;

	bdev = bdevsw_lookup(dumpdev);
	if (bdev == NULL || bdev->d_psize == NULL)
		return;

	/*
	 * For dumps during autoconfiguration,
	 * if dump device has already configured...
	 */
	if (dumpsize == 0)
		cpu_dumpconf();
	if (dumplo <= 0 || dumpsize == 0) {
		printf("\ndump to dev %u,%u not possible\n", major(dumpdev),
		    minor(dumpdev));
		return;
	}
	printf("\ndumping to dev %u,%u offset %ld\n", major(dumpdev),
	    minor(dumpdev), dumplo);

	psize = (*bdev->d_psize)(dumpdev);
	printf("dump ");
	if (psize == -1) {
		printf("area unavailable\n");
		return;
	}

#if 0	/* XXX this doesn't work.  grr. */
	/* toss any characters present prior to dump */
	while (sget() != NULL); /*syscons and pccons differ */
#endif

	dump_seg_prep();
	dumpend = dumplo + btodb(dump_header_size) + ctod(dump_npages);
	if (dumpend > psize) {
		printf("failed: insufficient space (%d < %d)\n",
		    psize, dumpend);
		goto failed;
	}

	dump_header_start();
	if ((error = cpu_dump()) != 0)
		goto err;
	if ((error = dump_header_finish()) != 0)
		goto err;

	if (dump_header_blkno != dumplo + btodb(dump_header_size)) {
		printf("BAD header size (%ld [written] != %ld [expected])\n",
		    (long)(dump_header_blkno - dumplo),
		    (long)btodb(dump_header_size));
		goto failed;
	}

	dump_totalbytesleft = roundup(ptoa(dump_npages), BYTES_PER_DUMP);
	error = dump_seg_iter(dumpsys_seg);

	if (error == 0 && dump_header_blkno != dumpend) {
		printf("BAD dump size (%ld [written] != %ld [expected])\n",
		    (long)(dumpend - dumplo),
		    (long)(dump_header_blkno - dumplo));
		goto failed;
	}

 err:
	switch (error) {

	case ENXIO:
		printf("device bad\n");
		break;

	case EFAULT:
		printf("device not ready\n");
		break;

	case EINVAL:
		printf("area improper\n");
		break;

	case EIO:
		printf("i/o error\n");
		break;

	case EINTR:
		printf("aborted from console\n");
		break;

	case 0:
		printf("succeeded\n");
		break;

	default:
		printf("error %d\n", error);
		break;
	}
failed:
	printf("\n\n");
	delay(5000000);		/* 5 seconds */
}
Beispiel #6
0
int
wsmouseioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
	return (wsmousedoioctl(wsmouse_cd.cd_devs[minor(dev)],
	    cmd, data, flag, p));
}
Beispiel #7
0
/* ALmost the same of entry_print_data in gfunc.c, but
 * not quite as we don't don't use FILE* structs here
 * for instance. TODO: integrate the two functions?
 * entry_print_data()
 */
gint rdup_write_header(struct rdup * e)
{
	char *out;
	char t;

	if (S_ISDIR(e->f_mode)) {
		t = 'd';
	} else if (S_ISCHR(e->f_mode)) {
		t = 'c';
	} else if (S_ISBLK(e->f_mode)) {
		t = 'b';
	} else if (S_ISFIFO(e->f_mode)) {
		t = 'p';
	} else if (S_ISSOCK(e->f_mode)) {
		t = 's';
	} else if (S_ISLNK(e->f_mode)) {
		t = 'l';
	} else {
		if (e->f_lnk == 1)
			t = 'h';
		else
			t = '-';
	}

	if (t == 'b' || t == 'c') {
		/* device */
		out =
		    g_strdup_printf("%c%c %.4o %ld %ld %s %ld %s %ld %d,%d\n%s",
				    e->plusmin == PLUS ? '+' : '-', t,
				    (int)e->f_mode & 07777,
				    (unsigned long)e->f_mtime,
				    (unsigned long)e->f_uid, e->f_user,
				    (unsigned long)e->f_gid, e->f_group,
				    (unsigned long)e->f_name_size,
				    (unsigned int)major(e->f_rdev),
				    (unsigned int)minor(e->f_rdev), e->f_name);
	} else if (t == 'l' || t == 'h') {
		/* link */
		gchar *n;
		n = g_strdup_printf("%s -> %s", e->f_name, e->f_target);
		e->f_name_size = strlen(n);
		out = g_strdup_printf("%c%c %.4o %ld %ld %s %ld %s %ld %zd\n%s",
				      e->plusmin == PLUS ? '+' : '-',
				      t,
				      (int)e->f_mode & 07777,
				      (unsigned long)e->f_mtime,
				      (unsigned long)e->f_uid,
				      e->f_user,
				      (unsigned long)e->f_gid,
				      e->f_group,
				      (unsigned long)e->f_name_size,
				      (size_t) e->f_size, n);
		g_free(n);
	} else {
		out = g_strdup_printf("%c%c %.4o %ld %ld %s %ld %s %ld %zd\n%s",
				      e->plusmin == PLUS ? '+' : '-',
				      t,
				      (int)e->f_mode & 07777,
				      (unsigned long)e->f_mtime,
				      (unsigned long)e->f_uid,
				      e->f_user,
				      (unsigned long)e->f_gid,
				      e->f_group,
				      (unsigned long)e->f_name_size,
				      (size_t) e->f_size, e->f_name);
	}

	if (sig != 0)
		signal_abort(sig);

	if (write(1, out, strlen(out)) == -1) {
		msg(_("Failed to write to stdout: %s"), strerror(errno));
		return -1;
	}
	g_free(out);
	return 0;
}
/*
 * find a mnttab entry that has the same dev as the supplied dev,
 *  returning it and a non-zero value if found, else returning 0
 *
 * this is just like getmntany(), except that it scans based on st_rdev,
 * and it even finds different slices on the same device/unit (thanx to
 * code copied from format.c)
 */
static int
vol_getmntdev(FILE *fp, struct mnttab *mp, dev_t dev, struct dk_cinfo *ip)
{
	int		fd;		/* dev-in-question fd */
	struct stat64	sb;		/* dev-in-question stat struct */
	int		ret_val = 0;	/* default value: no match found */
	char		*cn;		/* char pathname */
	struct dk_cinfo	dkinfo;		/* for testing for slices */


#ifdef	DEBUG
	denter(
	    "vol_getmntdev: entering for %d.%d, ctype/cnum/unit = %d/%d/%d\n",
	    (int)major(dev), (int)minor(dev), ip->dki_ctype, ip->dki_cnum,
	    ip->dki_unit);
#endif

	/* reset the mnttab -- just in case */
	rewind(fp);

	/* scan each entry in mnttab */
	while (getmntent(fp, mp) == 0) {

		/* don't even try unless it's a local pathname */
		if (mp->mnt_special[0] != '/') {
			continue;
		}

		/* get char pathname */
		if ((cn = volmgt_getfullrawname(mp->mnt_special)) == NULL) {
			continue;
		}
		if (cn[0] == NULLC) {
			free(cn);
			continue;	/* couldn't get raw name */
		}

		/* open the device */
		if ((fd = open(cn, O_RDONLY|O_NDELAY)) < 0) {
			/* if we can't open it *assume* it's not a match */
			free(cn);
			continue;
		}

		/* stat the device */
		if (fstat64(fd, &sb) < 0) {
			free(cn);
			(void) close(fd);
			continue;	/* ain't there: can't be a match */
		}

		/* ensure we have a spcl device (a double check) */
		if (!S_ISBLK(sb.st_mode) && !S_ISCHR(sb.st_mode)) {
			free(cn);
			(void) close(fd);
			continue;
		}

		/* (almost) finally -- check the dev_t for equality */
		if (sb.st_rdev == dev) {
			ret_val = 1;		/* match found! */
			free(cn);
			(void) close(fd);
			break;
		}

		/*
		 * check that the major numbers match, since if they
		 * don't then there's no reason to use the DKIOCINFO
		 * ioctl to see if we have to major/minor pairs that
		 * really point to the same device
		 */
		if (major(sb.st_rdev) != major(dev)) {
			/* no use continuing, since major devs are different */
			free(cn);
			(void) close(fd);
			continue;
		}

		/* one last check -- for diff. slices of the same dev/unit */
		if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) {
			free(cn);
			(void) close(fd);
			continue;
		}

		free(cn);		/* all done with raw pathname */
		(void) close(fd);	/* all done with file descriptor */

		/* if ctrler type/number and unit match, it's a match */
		if ((ip->dki_ctype == dkinfo.dki_ctype) &&
		    (ip->dki_cnum == dkinfo.dki_cnum) &&
		    (ip->dki_unit == dkinfo.dki_unit)) {
			/*
			 * even though minor numbers differ we have a
			 * match
			 */
			ret_val = 1;
			break;
		}

		/* go around again */
	}

	return (ret_val);
}
Beispiel #9
0
/* Store at most BUFLEN characters of the pathname of the slave pseudo
   terminal associated with the master FD is open on in BUF.
   Return 0 on success, otherwise an error number.  */
int
__ptsname_r (int fd, char *buf, size_t buflen)
{
  int save_errno = errno;
  int err;
  struct stat st;

  if (buf == NULL)
    {
      __set_errno (EINVAL);
      return EINVAL;
    }

#if defined __sun /* Solaris */
  if (fstat (fd, &st) < 0)
    return errno;
  if (!(S_ISCHR (st.st_mode) && major (st.st_rdev) == 0))
    {
      errno = ENOTTY;
      return errno;
    }
  {
    /* Master ptys can be recognized through a STREAMS ioctl.  See
       "STREAMS-based Pseudo-Terminal Subsystem"
       <http://docs.oracle.com/cd/E18752_01/html/816-4855/termsub15-44781.html>
       and "STREAMS ioctl commands"
       <http://docs.oracle.com/cd/E18752_01/html/816-5177/streamio-7i.html>
     */
    struct strioctl ioctl_arg;
    ioctl_arg.ic_cmd = ISPTM;
    ioctl_arg.ic_timout = 0;
    ioctl_arg.ic_len = 0;
    ioctl_arg.ic_dp = NULL;

    if (ioctl (fd, I_STR, &ioctl_arg) < 0)
      {
        errno = ENOTTY;
        return errno;
      }
  }
  {
    char tmpbuf[9 + 10 + 1];
    int n = sprintf (tmpbuf, "/dev/pts/%u", minor (st.st_rdev));
    if (n >= buflen)
      {
        errno = ERANGE;
        return errno;
      }
    memcpy (buf, tmpbuf, n + 1);
  }
#elif defined _AIX || defined __osf__ /* AIX, OSF/1 */
  /* This implementation returns /dev/pts/N, like ptsname() does.
     Whereas the generic implementation below returns /dev/ttypN.
     Both are correct, but let's be consistent with ptsname().  */
  if (fstat (fd, &st) < 0)
    return errno;
  if (!S_ISCHR (st.st_mode))
    {
      errno = ENOTTY;
      return errno;
    }
  {
    int ret;
    int dev;
    char tmpbuf[9 + 10 + 1];
    int n;
# ifdef _AIX
    ret = ioctl (fd, ISPTM, &dev);
# endif
# ifdef __osf__
    ret = ioctl (fd, ISPTM, NULL);
    dev = ret;
# endif
    if (ret < 0)
      {
        errno = ENOTTY;
        return errno;
      }
    n = sprintf (tmpbuf, "/dev/pts/%u", minor (dev));
    if (n >= buflen)
      {
        errno = ERANGE;
        return errno;
      }
    memcpy (buf, tmpbuf, n + 1);
  }
#else
  if (!__isatty (fd))
    {
#if ISATTY_FAILS_WITHOUT_SETTING_ERRNO && defined F_GETFL /* IRIX, Solaris */
      /* Set errno.  */
      if (fcntl (fd, F_GETFL) != -1)
        errno = ENOTTY;
#else
      /* We rely on isatty to set errno properly (i.e. EBADF or ENOTTY).  */
#endif
      return errno;
    }

  if (buflen < strlen (_PATH_TTY) + 3)
    {
      __set_errno (ERANGE);
      return ERANGE;
    }

  err = __ttyname_r (fd, buf, buflen);
  if (err != 0)
    {
      __set_errno (err);
      return errno;
    }

  if (strncmp(buf, "/dev/pts/", strlen("/dev/pts/")) != 0)
    buf[sizeof (_PATH_DEV) - 1] = 't';
#endif

  if (__stat (buf, &st) < 0)
    return errno;

  __set_errno (save_errno);
  return 0;
}
Beispiel #10
0
static int
read_initfile(const char *initfile)
{
	struct initline *p;
	FILE *f;
	char *buf = NULL;
	size_t buf_len = 0;
	int i,j,k;
	char *ptr, *getty;
#ifdef SPECIAL_CONSOLE_TERM
	char tty[50];
	struct stat stb;
#endif
	char *termenv, *getenv();
	
	termenv = getenv("TERM");	/* set by kernel */
	/* termenv = "vt100"; */
			
	i = numcmd;

	if (!(f = fopen(initfile, "r")))
		return 1;

	while(!feof(f)) {
		if (i+2 == inittab_size) {
			/* need to realloc inittab */
			inittab_size += NUMCMD;
			inittab = realloc(inittab, inittab_size * sizeof(struct initline));
			if (!inittab) {
				/* failure case - what do you do if init fails? */
				err("malloc failed");
				_exit(1);
			}
		}
		if (getline(&buf, &buf_len, f) == -1) break;

		for(k = 0; k < buf_len && buf[k]; k++) {
			if(buf[k] == '#') { 
				buf[k] = '\0'; break; 
			}
		}

		if(buf[0] == '\0' || buf[0] == '\n') continue;

		p = inittab + i;
		init_itab(p);
		p->line = strdup(buf);
		p->fullline = strdup(buf);
		if (!p->line || !p->fullline) {
			err("Not memory to allocate inittab entry");
			clear_itab(p);
			continue;
		}
		ptr = strtok(p->line, ":");
		if (!ptr) {
			err("Missing TTY/ID field in inittab");
			clear_itab(p);
			continue;
		}
		strncpy(p->tty, ptr, 9);
		//p->tty[9] = '\0';
		ptr = strtok(NULL, ":");
		if (!ptr) {
			err("Missing TERMTYPE field in inittab");
			clear_itab(p);
			continue;
		}
		strncpy(p->termcap, ptr, 29);
		//p->termcap[29] = '\0';

		getty = strtok(NULL, " \t\n");
		if (!getty) {
			err("Missing PROCESS field in inittab");
			clear_itab(p);
			continue;
		}
		add_tok(p, getty);
		j = 1;
		while((ptr = strtok(NULL, " \t\n")))
			add_tok(p, ptr);

#ifdef SPECIAL_CONSOLE_TERM
		/* special-case termcap for the console ttys */
		strcpy(tty, "/dev/");
		strcat(tty, p->tty);
		if(!termenv || stat(tty, &stb) < 0) {
			err("no TERM or cannot stat tty\n");
		} else {
			/* is it a console tty? */
			if(major(stb.st_rdev) == 4 && minor(stb.st_rdev) < 64) {
				strncpy(p->termcap, termenv, 30);
				p->termcap[29] = 0;
			}
		}
#endif

		i++;
	}

	if (buf)
		free(buf);
	
	fclose(f);

	numcmd = i;
	return 0;
}
Beispiel #11
0
bool VersionString::isNextVersion(const VersionString& nextVersionCandidate) const {
  VersionString variantOnThis(str());
  VersionString variantOnCandidate = nextVersionCandidate;

  if (variantOnCandidate <= variantOnThis) {
    return false;
  }
 
  // now know nextVersionCandidate > this

  if (build() && fidelityEqual(nextVersionCandidate)) {
    // true if versions except for build number are equal
    variantOnThis = VersionString(major(),minor(),patch().get());
    variantOnCandidate = VersionString(nextVersionCandidate.major(),
                                       nextVersionCandidate.minor(),
                                       nextVersionCandidate.patch().get());
    if (variantOnCandidate == variantOnThis) {
      return true;
    }
  }
  else {
    // strip out build numbers as needed, because that is not the level at which the 
    // versions differ
    if (build()) {
      variantOnThis = VersionString(major(),minor(),patch().get());
    }
    if (nextVersionCandidate.build()) {
      variantOnCandidate = VersionString(nextVersionCandidate.major(),
                                         nextVersionCandidate.minor(),
                                         nextVersionCandidate.patch().get());
    }
  }

  // now have major.minor or major.minor.patch for both

  if (variantOnThis.patch()) {
    if (variantOnCandidate.patch()) {
      VersionString thisIncremented(major(),minor(),patch().get() + 1);
      if (variantOnCandidate == thisIncremented) {
        return true;
      }
      // candidate has patch, but is not next patch version. to be next version,
      // must have patch == 0
      if (variantOnCandidate.patch().get() != 0) {
        return false;
      }
    }
  }

  // now major.minor.patch v. major.minor or major.minor.patch v. major.minor.0
  // strip out patch numbers

  if (variantOnThis.patch()) {
    variantOnThis = VersionString(variantOnThis.major(),variantOnThis.minor());
  }
  if (variantOnCandidate.patch()) {
    variantOnCandidate = VersionString(variantOnCandidate.major(),variantOnCandidate.minor());
  }

  // minor increment
  VersionString thisIncremented(variantOnThis.major(),variantOnThis.minor() + 1);
  if (variantOnCandidate == thisIncremented) {
    return true;
  }

  // major increment
  thisIncremented = VersionString(variantOnThis.major() + 1,0);
  if (variantOnCandidate == thisIncremented) {
    return true;
  }

  return false;
}
int
main(int argc, char *argv[])
{
	int	c, devfd;
	char	*protostore;
	long	protosize;
	struct stat disksb, bootsb;
	struct disklabel dl;
	daddr64_t partoffset;
#define BBPAD   0x1e0
	struct bb {
		char	bb_pad[BBPAD];	/* disklabel lives in here, actually */
		long	bb_secsize;	/* size of secondary boot block */
		long	bb_secstart;	/* start of secondary boot block */
		long	bb_flags;	/* unknown; always zero */
		long	bb_cksum;	/* checksum of the boot block, as longs. */
	} bb;
	long *lp, *ep;

	while ((c = getopt(argc, argv, "vns:e:")) != -1) {
		switch (c) {
		case 'n':
			/* Do not actually write the bootblock to disk */
			nowrite = 1;
			break;
		case 'v':
			/* Chat */
			verbose = 1;
			break;
		case 's':
			isofsblk = atoi(optarg);
			break;
		case 'e':
			isofseblk = atoi(optarg);
			break;
		default:
			usage();
		}
	}

	if (argc - optind < 3)
		usage();

	boot = argv[optind];
	proto = argv[optind + 1];
	dev = argv[optind + 2];

	if (verbose) {
		(void)printf("boot: %s\n", boot);
		(void)printf("proto: %s\n", proto);
		(void)printf("device: %s\n", dev);
	}

	/* Load proto blocks into core */
	if ((protostore = loadprotoblocks(proto, &protosize)) == NULL)
		exit(1);

	/* Open and check raw disk device */
	if ((devfd = opendev(dev, O_RDONLY, OPENDEV_PART, &dev)) < 0)
		err(1, "open: %s", dev);
	if (fstat(devfd, &disksb) == -1)
		err(1, "fstat: %s", dev);
	if (!S_ISCHR(disksb.st_mode))
		errx(1, "%s must be a character device node", dev);
	if ((minor(disksb.st_rdev) % getmaxpartitions()) != getrawpartition())
		errx(1, "%s must be the raw partition", dev);

	/* Extract and load block numbers */
	if (stat(boot, &bootsb) == -1)
		err(1, "stat: %s", boot);
	if (!S_ISREG(bootsb.st_mode))
		errx(1, "%s must be a regular file", boot);
	if ((minor(disksb.st_rdev) / getmaxpartitions()) !=
	    (minor(bootsb.st_dev) / getmaxpartitions()))
		errx(1, "%s must be somewhere on %s", boot, dev);

	/*
	 * Find the offset of the secondary boot block's partition
	 * into the disk.  If disklabels not supported, assume zero.
	 */
	if (ioctl(devfd, DIOCGDINFO, &dl) != -1) {
		partoffset = DL_GETPOFFSET(&dl.d_partitions[minor(bootsb.st_dev) %
		    getmaxpartitions()]);
	} else {
		if (errno != ENOTTY)
			err(1, "read disklabel: %s", dev);
		warnx("couldn't read label from %s, using part offset of 0",
		    dev);
		partoffset = 0;
	}
	if (verbose)
		(void)printf("%s partition offset = 0x%lx\n", boot, partoffset);

	/* Sync filesystems (make sure boot's block numbers are stable) */
	sync();
	sleep(2);
	sync();
	sleep(2);

	if (loadblocknums(boot, devfd, partoffset) != 0)
		exit(1);

	(void)close(devfd);

	if (nowrite)
		return 0;

#if 0
	/* Write patched proto bootblocks into the superblock */
	if (protosize > SBSIZE - DEV_BSIZE)
		errx(1, "proto bootblocks too big");
#endif

	if ((devfd = opendev(dev, O_RDWR, OPENDEV_PART, &dev)) < 0)
		err(1, "open: %s", dev);

	if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE)
		err(1, "lseek bootstrap");

	if (write(devfd, protostore, protosize) != protosize)
		err(1, "write bootstrap");

	if (lseek(devfd, 0, SEEK_SET) != 0)
		err(1, "lseek label");

	if (read(devfd, &bb, sizeof (bb)) != sizeof (bb))
		err(1, "read label");

	bb.bb_secsize = 15;
	bb.bb_secstart = 1;
	bb.bb_flags = 0;
	bb.bb_cksum = 0;

	for (lp = (long *)&bb, ep = &bb.bb_cksum; lp < ep; lp++)
		bb.bb_cksum += *lp;

	if (lseek(devfd, 0, SEEK_SET) != 0)
		err(1, "lseek label 2");

	if (write(devfd, &bb, sizeof bb) != sizeof bb)
		err(1, "write label ");

	(void)close(devfd);
	return 0;
}
Beispiel #13
0
/* Return value will become exit code.
 * It's ok to exit instead of return. */
static NOINLINE int cpio_o(void)
{
	static const char trailer[] ALIGN1 = "TRAILER!!!";
	struct name_s {
		struct name_s *next;
		char name[1];
	};
	struct inodes_s {
		struct inodes_s *next;
		struct name_s *names;
		struct stat st;
	};

	struct inodes_s *links = NULL;
	off_t bytes = 0; /* output bytes count */

	while (1) {
		const char *name;
		char *line;
		struct stat st;

		line = (option_mask32 & CPIO_OPT_NUL_TERMINATED)
				? bb_get_chunk_from_file(stdin, NULL)
				: xmalloc_fgetline(stdin);

		if (line) {
			/* Strip leading "./[./]..." from the filename */
			name = line;
			while (name[0] == '.' && name[1] == '/') {
				while (*++name == '/')
					continue;
			}
			if (!*name) { /* line is empty */
				free(line);
				continue;
			}
			if ((option_mask32 & CPIO_OPT_DEREF)
					? stat(name, &st)
					: lstat(name, &st)
			) {
 abort_cpio_o:
				bb_simple_perror_msg_and_die(name);
			}

			if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode)))
				st.st_size = 0; /* paranoia */

			/* Store hardlinks for later processing, dont output them */
			if (!S_ISDIR(st.st_mode) && st.st_nlink > 1) {
				struct name_s *n;
				struct inodes_s *l;

				/* Do we have this hardlink remembered? */
				l = links;
				while (1) {
					if (l == NULL) {
						/* Not found: add new item to "links" list */
						l = xzalloc(sizeof(*l));
						l->st = st;
						l->next = links;
						links = l;
						break;
					}
					if (l->st.st_ino == st.st_ino) {
						/* found */
						break;
					}
					l = l->next;
				}
				/* Add new name to "l->names" list */
				n = xmalloc(sizeof(*n) + strlen(name));
				strcpy(n->name, name);
				n->next = l->names;
				l->names = n;

				free(line);
				continue;
			}

		} else { /* line == NULL: EOF */
 next_link:
			if (links) {
				/* Output hardlink's data */
				st = links->st;
				name = links->names->name;
				links->names = links->names->next;
				/* GNU cpio is reported to emit file data
				 * only for the last instance. Mimic that. */
				if (links->names == NULL)
					links = links->next;
				else
					st.st_size = 0;
				/* NB: we leak links->names and/or links,
				 * this is intended (we exit soon anyway) */
			} else {
				/* If no (more) hardlinks to output,
				 * output "trailer" entry */
				name = trailer;
				/* st.st_size == 0 is a must, but for uniformity
				 * in the output, we zero out everything */
				memset(&st, 0, sizeof(st));
				/* st.st_nlink = 1; - GNU cpio does this */
			}
		}

		bytes += printf("070701"
		                "%08X%08X%08X%08X%08X%08X%08X"
		                "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */
				/* strlen+1: */ "%08X"
				/* chksum: */   "00000000" /* (only for "070702" files) */
				/* name,NUL: */ "%s%c",
		                (unsigned)(uint32_t) st.st_ino,
		                (unsigned)(uint32_t) st.st_mode,
		                (unsigned)(uint32_t) st.st_uid,
		                (unsigned)(uint32_t) st.st_gid,
		                (unsigned)(uint32_t) st.st_nlink,
		                (unsigned)(uint32_t) st.st_mtime,
		                (unsigned)(uint32_t) st.st_size,
		                (unsigned)(uint32_t) major(st.st_dev),
		                (unsigned)(uint32_t) minor(st.st_dev),
		                (unsigned)(uint32_t) major(st.st_rdev),
		                (unsigned)(uint32_t) minor(st.st_rdev),
		                (unsigned)(strlen(name) + 1),
		                name, '\0');
		bytes = cpio_pad4(bytes);

		if (st.st_size) {
			if (S_ISLNK(st.st_mode)) {
				char *lpath = xmalloc_readlink_or_warn(name);
				if (!lpath)
					goto abort_cpio_o;
				bytes += printf("%s", lpath);
				free(lpath);
			} else { /* S_ISREG */
				int fd = xopen(name, O_RDONLY);
				fflush_all();
				/* We must abort if file got shorter too! */
				bb_copyfd_exact_size(fd, STDOUT_FILENO, st.st_size);
				bytes += st.st_size;
				close(fd);
			}
			bytes = cpio_pad4(bytes);
		}

		if (!line) {
			if (name != trailer)
				goto next_link;
			/* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */
			return EXIT_SUCCESS;
		}

		free(line);
	} /* end of "while (1)" */
}
Beispiel #14
0
inline
bool DeviceInfo::supports(FeatureSet feature_set) const
{
    int version = major() * 10 + minor();
    return version >= feature_set;
}
Beispiel #15
0
static Eina_Bool 
_ecore_drm_logind_vt_setup(Ecore_Drm_Device *dev)
{
   struct stat st;
   char buff[64];
   struct vt_mode vtmode = { 0 };

   snprintf(buff, sizeof(buff), "/dev/tty%d", dev->vt);
   buff[sizeof(buff) - 1] = 0;

   dev->tty.fd = open(buff, (O_RDWR | O_CLOEXEC | O_NONBLOCK));
   if (dev->tty.fd < 0)
     {
        ERR("Could not open VT %s %m", buff);
        return EINA_FALSE;
     }

   if ((fstat(dev->tty.fd, &st) == -1) || 
       (major(st.st_rdev) != TTY_MAJOR) || 
       (minor(st.st_rdev) <= 0) || (minor(st.st_rdev) >= 64))
     {
        ERR("TTY %s is not a virtual terminal", buff);
        goto stat_err;
     }

   if (ioctl(dev->tty.fd, KDGKBMODE, &dev->tty.kbd_mode) < 0)
     {
        ERR("Could not read keyboard mode of %s: %m", buff);
        dev->tty.kbd_mode = K_UNICODE;
     }
   else if (dev->tty.kbd_mode == K_OFF)
     dev->tty.kbd_mode = K_UNICODE;

   if ((ioctl(dev->tty.fd, KDSKBMUTE, 1) < 0) && 
       (ioctl(dev->tty.fd, KDSKBMODE, K_OFF) < 0))
     {
        ERR("Could not set K_OFF keyboard mode on %s: %m", buff);
        goto stat_err;
     }

   if (ioctl(dev->tty.fd, KDSETMODE, KD_GRAPHICS) < 0)
     {
        ERR("Could not set KD_GRAPHICS mode on %s: %m", buff);
        goto kbdmode_err;
     }

   vtmode.mode = VT_PROCESS;
   vtmode.waitv = 0;
   vtmode.relsig = SIGUSR1;
   vtmode.acqsig = SIGUSR2;

   if (ioctl(dev->tty.fd, VT_SETMODE, &vtmode) < 0)
     {
        ERR("Could not take over virtual terminal: %m");
        goto mode_err;
     }

   return EINA_TRUE;

mode_err:
   ioctl(dev->tty.fd, KDSETMODE, KD_TEXT);
kbdmode_err:
   ioctl(dev->tty.fd, KDSKBMUTE, 0);
   ioctl(dev->tty.fd, KDSKBMODE, dev->tty.kbd_mode);
stat_err:
   close(dev->tty.fd);
   return EINA_FALSE;
}
Beispiel #16
0
int
wskbdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
	return (wskbd_do_ioctl(device_lookup(&wskbd_cd, minor(dev)),
	    cmd, data, flag,l));
}
Beispiel #17
0
void
xf86OpenConsole(void)
{
    int i, fd = -1, ret, current_vt = -1;
    struct vt_mode VT;
    struct vt_stat vts;
    struct stat st;
    MessageType from = X_PROBED;
    const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
    const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };

    if (serverGeneration == 1) {
        /*
         * setup the virtual terminal manager
         */
        if (xf86Info.vtno != -1) {
            from = X_CMDLINE;
        }
        else {

            i = 0;
            while (tty0[i] != NULL) {
                if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0)
                    break;
                i++;
            }

            if (fd < 0)
                FatalError("xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
                           strerror(errno));

            if (xf86Info.ShareVTs) {
                SYSCALL(ret = ioctl(fd, VT_GETSTATE, &vts));
                if (ret < 0)
                    FatalError("xf86OpenConsole: Cannot find the current"
                               " VT (%s)\n", strerror(errno));
                xf86Info.vtno = vts.v_active;
            }
            else {
                SYSCALL(ret = ioctl(fd, VT_OPENQRY, &xf86Info.vtno));
                if (ret < 0)
                    FatalError("xf86OpenConsole: Cannot find a free VT: "
                               "%s\n", strerror(errno));
                if (xf86Info.vtno == -1)
                    FatalError("xf86OpenConsole: Cannot find a free VT\n");
            }
            close(fd);
        }

        xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);

        /* Some of stdin / stdout / stderr maybe redirected to a file */
        for (i = STDIN_FILENO; i <= STDERR_FILENO; i++) {
            ret = fstat(i, &st);
            if (ret == 0 && S_ISCHR(st.st_mode) && major(st.st_rdev) == 4) {
                current_vt = minor(st.st_rdev);
                break;
            }
        }

        if (!KeepTty && current_vt == xf86Info.vtno) {
            xf86Msg(X_PROBED,
                    "controlling tty is VT number %d, auto-enabling KeepTty\n",
                    current_vt);
            KeepTty = TRUE;
        }

        if (!KeepTty) {
            pid_t ppid = getppid();
            pid_t ppgid;

            ppgid = getpgid(ppid);

            /*
             * change to parent process group that pgid != pid so
             * that setsid() doesn't fail and we become process
             * group leader
             */
            if (setpgid(0, ppgid) < 0)
                xf86Msg(X_WARNING, "xf86OpenConsole: setpgid failed: %s\n",
                        strerror(errno));

            /* become process group leader */
            if ((setsid() < 0))
                xf86Msg(X_WARNING, "xf86OpenConsole: setsid failed: %s\n",
                        strerror(errno));
        }

        i = 0;
        while (vcs[i] != NULL) {
            snprintf(vtname, sizeof(vtname), vcs[i], xf86Info.vtno);    /* /dev/tty1-64 */
            if ((xf86Info.consoleFd = open(vtname, O_RDWR | O_NDELAY, 0)) >= 0)
                break;
            i++;
        }

        if (xf86Info.consoleFd < 0)
            FatalError("xf86OpenConsole: Cannot open virtual console"
                       " %d (%s)\n", xf86Info.vtno, strerror(errno));

        /*
         * Linux doesn't switch to an active vt after the last close of a vt,
         * so we do this ourselves by remembering which is active now.
         */
        SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts));
        if (ret < 0)
            xf86Msg(X_WARNING, "xf86OpenConsole: VT_GETSTATE failed: %s\n",
                    strerror(errno));
        else
            activeVT = vts.v_active;

#if 0
        if (!KeepTty) {
            /*
             * Detach from the controlling tty to avoid char loss
             */
            if ((i = open("/dev/tty", O_RDWR)) >= 0) {
                SYSCALL(ioctl(i, TIOCNOTTY, 0));
                close(i);
            }
        }
#endif

        if (!xf86Info.ShareVTs) {
            struct termios nTty;

            /*
             * now get the VT.  This _must_ succeed, or else fail completely.
             */
            if (!switch_to(xf86Info.vtno, "xf86OpenConsole"))
                FatalError("xf86OpenConsole: Switching VT failed\n");

            SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_GETMODE, &VT));
            if (ret < 0)
                FatalError("xf86OpenConsole: VT_GETMODE failed %s\n",
                           strerror(errno));

            signal(SIGUSR1, xf86VTRequest);

            VT.mode = VT_PROCESS;
            VT.relsig = SIGUSR1;
            VT.acqsig = SIGUSR1;

            SYSCALL(ret = ioctl(xf86Info.consoleFd, VT_SETMODE, &VT));
            if (ret < 0)
                FatalError
                    ("xf86OpenConsole: VT_SETMODE VT_PROCESS failed: %s\n",
                     strerror(errno));

            SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS));
            if (ret < 0)
                FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed %s\n",
                           strerror(errno));

            tcgetattr(xf86Info.consoleFd, &tty_attr);
            SYSCALL(ioctl(xf86Info.consoleFd, KDGKBMODE, &tty_mode));

            /* disable kernel special keys and buffering, new style */
            SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMUTE, 1));
            if (ret < 0)
            {
                /* disable kernel special keys and buffering, old style */
                SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_OFF));
                if (ret < 0)
                {
                    /* fine, just disable special keys */
                    SYSCALL(ret = ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW));
                    if (ret < 0)
                        FatalError("xf86OpenConsole: KDSKBMODE K_RAW failed %s\n",
                                   strerror(errno));

                    /* ... and drain events, else the kernel gets angry */
                    xf86SetConsoleHandler(drain_console, NULL);
                }
            }

            nTty = tty_attr;
            nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
            nTty.c_oflag = 0;
            nTty.c_cflag = CREAD | CS8;
            nTty.c_lflag = 0;
            nTty.c_cc[VTIME] = 0;
            nTty.c_cc[VMIN] = 1;
            cfsetispeed(&nTty, 9600);
            cfsetospeed(&nTty, 9600);
            tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
        }
    }
    else {                      /* serverGeneration != 1 */
        if (!xf86Info.ShareVTs && xf86Info.autoVTSwitch) {
            /* now get the VT */
            if (!switch_to(xf86Info.vtno, "xf86OpenConsole"))
                FatalError("xf86OpenConsole: Switching VT failed\n");
        }
    }
}
Beispiel #18
0
static void
show_stat(struct stat64 *sp, const char *what)
{

	if (strcmp(what, "mode") == 0)
		printf("0%o", (unsigned int)(sp->st_mode & ALLPERMS));
	else if (strcmp(what, "inode") == 0)
		printf("%lld", (long long)sp->st_ino);
	else if (strcmp(what, "nlink") == 0)
		printf("%lld", (long long)sp->st_nlink);
	else if (strcmp(what, "uid") == 0)
		printf("%d", (int)sp->st_uid);
	else if (strcmp(what, "gid") == 0)
		printf("%d", (int)sp->st_gid);
	else if (strcmp(what, "size") == 0)
		printf("%lld", (long long)sp->st_size);
	else if (strcmp(what, "blocks") == 0)
		printf("%lld", (long long)sp->st_blocks);
	else if (strcmp(what, "atime") == 0)
		printf("%lld", (long long)sp->st_atime);
	else if (strcmp(what, "mtime") == 0)
		printf("%lld", (long long)sp->st_mtime);
	else if (strcmp(what, "ctime") == 0)
		printf("%lld", (long long)sp->st_ctime);
#ifdef HAS_CHFLAGS
	else if (strcmp(what, "flags") == 0)
		printf("%s", flags2str(chflags_flags, (long long)sp->st_flags));
#endif
	else if (strcmp(what, "major") == 0)
		printf("%u", (unsigned int)major(sp->st_rdev));
	else if (strcmp(what, "minor") == 0)
		printf("%u", (unsigned int)minor(sp->st_rdev));
	else if (strcmp(what, "type") == 0) {
		switch (sp->st_mode & S_IFMT) {
		case S_IFIFO:
			printf("fifo");
			break;
		case S_IFCHR:
			printf("char");
			break;
		case S_IFDIR:
			printf("dir");
			break;
		case S_IFBLK:
			printf("block");
			break;
		case S_IFREG:
			printf("regular");
			break;
		case S_IFLNK:
			printf("symlink");
			break;
		case S_IFSOCK:
			printf("socket");
			break;
		default:
			printf("unknown");
			break;
		}
	} else {
		printf("unknown");
	}
}
Beispiel #19
0
void
vinum_daemon(void)
{
    int s;
    struct daemonq *request;

    curproc->p_flag |= P_INMEM | P_SYSTEM;		    /* we're a system process */
    daemon_save_config();				    /* start by saving the configuration */
    daemonpid = curproc->p_pid;				    /* mark our territory */
    while (1) {
        tsleep(&vinum_daemon, PRIBIO, "vinum", 0);	    /* wait for something to happen */

        /*
         * It's conceivable that, as the result of an
         * I/O error, we'll be out of action long
         * enough that another daemon gets started.
         * That's OK, just give up gracefully.
         */
        if (curproc->p_pid != daemonpid) {		    /* we've been ousted in our sleep */
            if (daemon_options & daemon_verbose)
                log(LOG_INFO, "vinum: abdicating\n");
            return;
        }
        while (daemonq != NULL) {			    /* we have work to do, */
            s = splhigh();				    /* don't get interrupted here */
            request = daemonq;				    /* get the request */
            daemonq = daemonq->next;			    /* and detach it */
            if (daemonq == NULL)			    /* got to the end, */
                dqend = NULL;				    /* no end any more */
            splx(s);

            switch (request->type) {
            /*
             * We had an I/O error on a request.  Go through the
             * request and try to salvage it
             */
            case daemonrq_ioerror:
                if (daemon_options & daemon_verbose) {
                    struct request *rq = request->info.rq;

                    log(LOG_WARNING,
                        "vinum: recovering I/O request: %p\n%s dev %d.%d, offset 0x%x, length %ld\n",
                        rq,
                        rq->bp->b_flags & B_READ ? "Read" : "Write",
                        major(rq->bp->b_dev),
                        minor(rq->bp->b_dev),
                        rq->bp->b_blkno,
                        rq->bp->b_bcount);
                }
                recover_io(request->info.rq);		    /* the failed request */
                break;

            /*
             * Write the config to disk.  We could end up with
             * quite a few of these in a row.  Only honour the
             * last one
             */
            case daemonrq_saveconfig:
                if ((daemonq == NULL)			    /* no more requests */
                        ||(daemonq->type != daemonrq_saveconfig)) { /* or the next isn't the same */
                    if (((daemon_options & daemon_noupdate) == 0) /* we're allowed to do it */
                            &&((vinum_conf.flags & VF_READING_CONFIG) == 0)) { /* and we're not building the config now */
                        /*
                           * We obviously don't want to save a
                           * partial configuration.  Less obviously,
                           * we don't need to do anything if we're
                           * asked to write the config when we're
                           * building it up, because we save it at
                           * the end.
                         */
                        if (daemon_options & daemon_verbose)
                            log(LOG_INFO, "vinum: saving config\n");
                        daemon_save_config();		    /* save it */
                    }
                }
                break;

            case daemonrq_return:			    /* been told to stop */
                if (daemon_options & daemon_verbose)
                    log(LOG_INFO, "vinum: stopping\n");
                daemon_options |= daemon_stopped;	    /* note that we've stopped */
                Free(request);
                while (daemonq != NULL) {		    /* backed up requests, */
                    request = daemonq;			    /* get the request */
                    daemonq = daemonq->next;		    /* and detach it */
                    Free(request);			    /* then free it */
                }
                wakeup(&vinumclose);			    /* and wake any waiting vinum(8)s */
                return;

            case daemonrq_ping:				    /* tell the caller we're here */
                if (daemon_options & daemon_verbose)
                    log(LOG_INFO, "vinum: ping reply\n");
                wakeup(&vinum_finddaemon);		    /* wake up the caller */
                break;

            case daemonrq_closedrive:			    /* close a drive */
                close_drive(request->info.drive);	    /* do it */
                break;

            case daemonrq_init:				    /* initialize a plex */
            /* XXX */
            case daemonrq_revive:			    /* revive a subdisk */
            /* XXX */
            /* FALLTHROUGH */
            default:
                log(LOG_WARNING, "Invalid request\n");
                break;
            }
            if (request->privateinuse)			    /* one of ours, */
                request->privateinuse = 0;		    /* no longer in use */
            else
                Free(request);				    /* return it */
        }
    }
}
Beispiel #20
0
/* Implement dir_lookup as described in <hurd/fs.defs>. */
kern_return_t
diskfs_S_dir_lookup (struct protid *dircred,
		     char *path,
		     int flags,
		     mode_t mode,
		     enum retry_type *retry,
		     char *retryname,
		     file_t *returned_port,
		     mach_msg_type_name_t *returned_port_poly)
{
  struct node *dnp;
  struct node *np;
  int nsymlink = 0;
  char *nextname;
  char *relpath;
  int nextnamelen;
  error_t error = 0;
  char *pathbuf = 0;
  int pathbuflen = 0;
  int newnamelen;
  int create, excl;
  int lastcomp = 0;
  int newnode = 0;
  struct dirstat *ds = 0;
  int mustbedir = 0;
  size_t amt;
  int type;
  struct protid *newpi = 0;
  struct peropen *newpo = 0;

  if (!dircred)
    return EOPNOTSUPP;

  flags &= O_HURD;

  create = (flags & O_CREAT);
  excl = (flags & O_EXCL);

  /* Skip leading slashes */
  while (path[0] == '/')
    path++;

  /* Preserve the path relative to diruser->po->path.  */
  relpath = strdup (path);
  if (! relpath)
    return ENOMEM;

  /* Keep a pointer to the start of the path for length
     calculations.  */
  char *path_start = path;

  *returned_port_poly = MACH_MSG_TYPE_MAKE_SEND;
  *retry = FS_RETRY_NORMAL;
  retryname[0] = '\0';

  if (path[0] == '\0')
    {
      /* Set things up in the state expected by the code from gotit: on. */
      dnp = 0;
      np = dircred->po->np;
      pthread_mutex_lock (&np->lock);
      diskfs_nref (np);
      goto gotit;
    }

  dnp = dircred->po->np;

  pthread_mutex_lock (&dnp->lock);
  np = 0;

  diskfs_nref (dnp);		/* acquire a reference for later diskfs_nput */

  do
    {
      assert (!lastcomp);

      /* Find the name of the next pathname component */
      nextname = index (path, '/');

      if (nextname)
	{
	  *nextname++ = '\0';
	  while (*nextname == '/')
	    nextname++;
	  if (*nextname == '\0')
	    {
	      /* These are the rules for filenames ending in /. */
	      nextname = 0;
	      lastcomp = 1;
	      mustbedir = 1;
	      create = 0;
	    }
	  else
	    lastcomp = 0;
	}
      else
	lastcomp = 1;

      np = 0;

      /* diskfs_lookup the next pathname component */
      if (lastcomp && create)
	{
	  if (!ds)
	    ds = alloca (diskfs_dirstat_size);
	  error = diskfs_lookup (dnp, path, CREATE, &np, ds, dircred);
	}
      else
	error = diskfs_lookup (dnp, path, LOOKUP, &np, 0, dircred);

      if (lastcomp && create && excl && (!error || error == EAGAIN))
	error = EEXIST;

      /* If we get an error we're done */
      if (error == EAGAIN)
	{
	  if (dnp == dircred->po->shadow_root)
	    /* We're at the root of a shadow tree.  */
	    {
	      if (dircred->po->shadow_root_parent == MACH_PORT_NULL)
		{
		  /* This is a shadow root with no parent, meaning
		     we should treat it as a virtual root disconnected
		  from its real .. directory.  */
		  error = 0;
		  np = dnp;
		  diskfs_nref (np);
		}
	      else
		{
		  /* Punt the client up to the shadow root parent.  */
		  *retry = FS_RETRY_REAUTH;
		  *returned_port = dircred->po->shadow_root_parent;
		  *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
		  if (! lastcomp)
		    strcpy (retryname, nextname);
		  error = 0;
		  goto out;
		}
	    }
	  else if (dircred->po->root_parent != MACH_PORT_NULL)
	    /* We're at a real translator root; even if DIRCRED->po has a
	       shadow root, we can get here if its in a directory that was
	    renamed out from under it...  */
	    {
	      *retry = FS_RETRY_REAUTH;
	      *returned_port = dircred->po->root_parent;
	      *returned_port_poly = MACH_MSG_TYPE_COPY_SEND;
	      if (!lastcomp)
		strcpy (retryname, nextname);
	      error = 0;
	      goto out;
	    }
	  else
	    /* We're at a REAL root, as in there's no way up from here.  */
	    {
	      error = 0;
	      np = dnp;
	      diskfs_nref (np);
	    }
	}

      /* Create the new node if necessary */
      if (lastcomp && create)
	{
	  if (error == ENOENT)
	    {
	      mode &= ~(S_IFMT | S_ISPARE | S_ISVTX | S_ITRANS);
	      mode |= S_IFREG;
	      error = diskfs_create_node (dnp, path, mode, &np, dircred, ds);
	      if (diskfs_synchronous)
		{
		  diskfs_file_update (dnp, 1);
		  diskfs_file_update (np, 1);
		}
	      newnode = 1;
	    }
	  else
	    diskfs_drop_dirstat (dnp, ds);
	}

      if (error)
	goto out;

      /* If this is translated, start the translator (if necessary)
	 and return.  */
      if ((((flags & O_NOTRANS) == 0) || !lastcomp)
	  && ((np->dn_stat.st_mode & S_IPTRANS)
	      || S_ISFIFO (np->dn_stat.st_mode)
	      || S_ISCHR (np->dn_stat.st_mode)
	      || S_ISBLK (np->dn_stat.st_mode)
	      || fshelp_translated (&np->transbox)))
	{
	  mach_port_t dirport;
	  struct iouser *user;

	  /* A callback function for short-circuited translators.
	     Symlink & ifsock are handled elsewhere.  */
	  error_t short_circuited_callback1 (void *cookie1, void *cookie2,
					     uid_t *uid, gid_t *gid,
					     char **argz, size_t *argz_len)
	    {
	      struct node *node = cookie1;

	      switch (node->dn_stat.st_mode & S_IFMT)
		{
		case S_IFCHR:
		case S_IFBLK:
		  asprintf (argz, "%s%c%d%c%d",
			    (S_ISCHR (node->dn_stat.st_mode)
			     ? _HURD_CHRDEV : _HURD_BLKDEV),
			    0, major (node->dn_stat.st_rdev),
			    0, minor (node->dn_stat.st_rdev));
		  *argz_len = strlen (*argz) + 1;
		  *argz_len += strlen (*argz + *argz_len) + 1;
		  *argz_len += strlen (*argz + *argz_len) + 1;
		  break;
		case S_IFIFO:
		  asprintf (argz, "%s", _HURD_FIFO);
		  *argz_len = strlen (*argz) + 1;
		  break;
		default:
		  return ENOENT;
		}

	      *uid = node->dn_stat.st_uid;
	      *gid = node->dn_stat.st_gid;

	      return 0;
	    }

	  /* Create an unauthenticated port for DNP, and then
	     unlock it. */
	  error = iohelp_create_empty_iouser (&user);
	  if (! error)
	    {
	      error = diskfs_make_peropen (dnp, 0, dircred->po, &newpo);
	      if (! error)
		{
		  error = diskfs_create_protid (newpo, user, &newpi);
		  if (! error)
		    newpo = 0;
		}

	      iohelp_free_iouser (user);
	    }

	  if (error)
	    goto out;

	  dirport = ports_get_send_right (newpi);
	  if (np != dnp)
	    pthread_mutex_unlock (&dnp->lock);

	  /* Check if an active translator is currently running.  If
	     not, fshelp_fetch_root will start one.  In that case, we
	     need to register it in the list of active
	     translators.  */
	  boolean_t register_translator =
	    np->transbox.active == MACH_PORT_NULL;

	  error = fshelp_fetch_root (&np->transbox, dircred->po,
				     dirport, dircred->user,
				     lastcomp ? flags : 0,
				     ((np->dn_stat.st_mode & S_IPTRANS)
				      ? _diskfs_translator_callback1
				      : short_circuited_callback1),
				     _diskfs_translator_callback2,
				     retry, retryname, returned_port);

	  /* fetch_root copies DIRPORT for success, so we always should
	     deallocate our send right.  */
	  mach_port_deallocate (mach_task_self (), dirport);

	  if (error != ENOENT)
	    {
	      *returned_port_poly = MACH_MSG_TYPE_MOVE_SEND;
	      if (!lastcomp && !error)
		{
		  char *end = strchr (retryname, '\0');
		  *end++ = '/';
		  strcpy (end, nextname);
		}

	      if (register_translator)
		{
		  char *translator_path = strdupa (relpath);
		  char *complete_path;
		  if (nextname != NULL)
		    {
		      /* This was not the last path component.
			 NEXTNAME points to the next component, locate
			 the end of the current component and use it
			 to trim TRANSLATOR_PATH.  */
		      char *end = nextname;
		      while (*end != 0)
			end--;
		      translator_path[end - path_start] = '\0';
		    }

		  if (dircred->po->path == NULL || !strcmp (dircred->po->path,"."))
		      /* dircred is the root directory.  */
		      complete_path = translator_path;
		  else
		      asprintf (&complete_path, "%s/%s", dircred->po->path, translator_path);

		  error = fshelp_set_active_translator (&newpi->pi,
							complete_path,
							np->transbox.active);
		  if (complete_path != translator_path)
		    free(complete_path);
		  if (error)
		    goto out;
		}

	      goto out;
	    }

	  ports_port_deref (newpi);
	  newpi = NULL;

	  /* ENOENT means there was a hiccup, and the translator
	     vanished while NP was unlocked inside fshelp_fetch_root.
	     Reacquire the locks, and continue as normal. */
	  error = 0;
	  if (np != dnp)
	    {
	      if (!strcmp (path, ".."))
		pthread_mutex_lock (&dnp->lock);
	      else
		{
		  if (pthread_mutex_trylock (&dnp->lock))
		    {
		      pthread_mutex_unlock (&np->lock);
		      pthread_mutex_lock (&dnp->lock);
		      pthread_mutex_lock (&np->lock);
		    }
		}
	    }
	}

      if (S_ISLNK (np->dn_stat.st_mode)
	  && (!lastcomp
	      || mustbedir	/* "foo/" must see that foo points to a dir */
	      || !(flags & (O_NOLINK|O_NOTRANS))))
	{
	  /* Handle symlink interpretation */

	  if (nsymlink++ > diskfs_maxsymlinks)
	    {
	      error = ELOOP;
	      goto out;
	    }

	  nextnamelen = nextname ? strlen (nextname) + 1 : 0;
	  newnamelen = nextnamelen + np->dn_stat.st_size + 1 + 1;
	  if (pathbuflen < newnamelen)
	    {
	      pathbuf = alloca (newnamelen);
	      pathbuflen = newnamelen;
	    }

	  if (diskfs_read_symlink_hook)
	    error = (*diskfs_read_symlink_hook)(np, pathbuf);
	  if (!diskfs_read_symlink_hook || error == EINVAL)
	    {
	      error = diskfs_node_rdwr (np, pathbuf,
					0, np->dn_stat.st_size, 0,
					dircred, &amt);
	      if (!error)
		assert (amt == np->dn_stat.st_size);
	    }
	  if (error)
	    goto out;

	  if (np->dn_stat.st_size == 0)	/* symlink to "" */
	    path = nextname;
	  else
	    {
	      if (nextname)
		{
		  pathbuf[np->dn_stat.st_size] = '/';
		  memcpy (pathbuf + np->dn_stat.st_size + 1,
			  nextname, nextnamelen - 1);
		}
	      pathbuf[nextnamelen + np->dn_stat.st_size] = '\0';

	      if (pathbuf[0] == '/')
		{
		  /* Punt to the caller.  */
		  *retry = FS_RETRY_MAGICAL;
		  *returned_port = MACH_PORT_NULL;
		  memcpy (retryname, pathbuf,
			  nextnamelen + np->dn_stat.st_size + 1);
		  if (mustbedir)
		    {
		      retryname[nextnamelen + np->dn_stat.st_size] = '/';
		      retryname[nextnamelen + np->dn_stat.st_size + 1] = '\0';
		    }
		  goto out;
		}

	      path = pathbuf;
	    }

	  if (lastcomp)
	    lastcomp = 0;

	  diskfs_nput (np);
	  np = 0;

	  if (path == 0)	/* symlink to "" was the last component */
	    {
	      np = dnp;
	      dnp = 0;
	      break;
	    }
	}
      else
	{
	  /* Handle normal nodes */
	  path = nextname;
	  if (np == dnp)
	    diskfs_nrele (dnp);
	  else
	    diskfs_nput (dnp);
	  if (!lastcomp)
	    {
	      dnp = np;
	      np = 0;
	    }
	  else
	    dnp = 0;
	}
    } while (path && *path);
Beispiel #21
0
static int enumerate_partitions(dev_t devnum) {

        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
        _cleanup_udev_unref_ struct udev *udev = NULL;
        _cleanup_free_ char *boot = NULL, *home = NULL, *srv = NULL;
        struct udev_list_entry *first, *item;
        struct udev_device *parent = NULL;
        const char *name, *node, *pttype, *devtype;
        int boot_nr = -1, home_nr = -1, srv_nr = -1;
        bool home_rw = true, srv_rw = true;
        blkid_partlist pl;
        int r, k;
        dev_t pn;

        udev = udev_new();
        if (!udev)
                return log_oom();

        d = udev_device_new_from_devnum(udev, 'b', devnum);
        if (!d)
                return log_oom();

        name = udev_device_get_devnode(d);
        if (!name)
                name = udev_device_get_syspath(d);
        if (!name) {
                log_debug("Device %u:%u does not have a name, ignoring.",
                          major(devnum), minor(devnum));
                return 0;
        }

        parent = udev_device_get_parent(d);
        if (!parent) {
                log_debug("%s: not a partitioned device, ignoring.", name);
                return 0;
        }

        /* Does it have a devtype? */
        devtype = udev_device_get_devtype(parent);
        if (!devtype) {
                log_debug("%s: parent doesn't have a device type, ignoring.", name);
                return 0;
        }

        /* Is this a disk or a partition? We only care for disks... */
        if (!streq(devtype, "disk")) {
                log_debug("%s: parent isn't a raw disk, ignoring.", name);
                return 0;
        }

        /* Does it have a device node? */
        node = udev_device_get_devnode(parent);
        if (!node) {
                log_debug("%s: parent device does not have device node, ignoring.", name);
                return 0;
        }

        log_debug("%s: root device %s.", name, node);

        pn = udev_device_get_devnum(parent);
        if (major(pn) == 0)
                return 0;

        errno = 0;
        b = blkid_new_probe_from_filename(node);
        if (!b) {
                if (errno == 0)
                        return log_oom();

                return log_error_errno(errno, "%s: failed to allocate prober: %m", node);
        }

        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == 1)
                return 0; /* no results */
        else if (r == -2) {
                log_warning("%s: probe gave ambiguous results, ignoring", node);
                return 0;
        } else if (r != 0)
                return log_error_errno(errno ?: EIO, "%s: failed to probe: %m", node);

        errno = 0;
        r = blkid_probe_lookup_value(b, "PTTYPE", &pttype, NULL);
        if (r != 0)
                return log_error_errno(errno ?: EIO,
                                       "%s: failed to determine partition table type: %m", node);

        /* We only do this all for GPT... */
        if (!streq_ptr(pttype, "gpt")) {
                log_debug("%s: not a GPT partition table, ignoring.", node);
                return 0;
        }

        errno = 0;
        pl = blkid_probe_get_partitions(b);
        if (!pl) {
                if (errno == 0)
                        return log_oom();

                return log_error_errno(errno, "%s: failed to list partitions: %m", node);
        }

        e = udev_enumerate_new(udev);
        if (!e)
                return log_oom();

        r = udev_enumerate_add_match_parent(e, parent);
        if (r < 0)
                return log_oom();

        r = udev_enumerate_add_match_subsystem(e, "block");
        if (r < 0)
                return log_oom();

        r = udev_enumerate_scan_devices(e);
        if (r < 0)
                return log_error_errno(r, "%s: failed to enumerate partitions: %m", node);

        first = udev_enumerate_get_list_entry(e);
        udev_list_entry_foreach(item, first) {
                _cleanup_udev_device_unref_ struct udev_device *q;
                unsigned long long flags;
                const char *stype, *subnode;
                sd_id128_t type_id;
                blkid_partition pp;
                dev_t qn;
                int nr;

                q = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                if (!q)
                        continue;

                qn = udev_device_get_devnum(q);
                if (major(qn) == 0)
                        continue;

                if (qn == devnum)
                        continue;

                if (qn == pn)
                        continue;

                subnode = udev_device_get_devnode(q);
                if (!subnode)
                        continue;

                pp = blkid_partlist_devno_to_partition(pl, qn);
                if (!pp)
                        continue;

                nr = blkid_partition_get_partno(pp);
                if (nr < 0)
                        continue;

                stype = blkid_partition_get_type_string(pp);
                if (!stype)
                        continue;

                if (sd_id128_from_string(stype, &type_id) < 0)
                        continue;

                flags = blkid_partition_get_flags(pp);

                if (sd_id128_equal(type_id, GPT_SWAP)) {

                        if (flags & GPT_FLAG_NO_AUTO)
                                continue;

                        if (flags & GPT_FLAG_READ_ONLY) {
                                log_debug("%s marked as read-only swap partition, which is bogus. Ignoring.", subnode);
                                continue;
                        }

                        k = add_swap(subnode);
                        if (k < 0)
                                r = k;

                } else if (sd_id128_equal(type_id, GPT_ESP)) {

                        /* We only care for the first /boot partition */
                        if (boot && nr >= boot_nr)
                                continue;

                        /* Note that we do not honour the "no-auto"
                         * flag for the ESP, as it is often unset, to
                         * hide it from Windows. */

                        boot_nr = nr;

                        r = free_and_strdup(&boot, subnode);
                        if (r < 0)
                                return log_oom();

                } else if (sd_id128_equal(type_id, GPT_HOME)) {

                        if (flags & GPT_FLAG_NO_AUTO)
                                continue;

                        /* We only care for the first /home partition */
                        if (home && nr >= home_nr)
                                continue;

                        home_nr = nr;
                        home_rw = !(flags & GPT_FLAG_READ_ONLY),

                        r = free_and_strdup(&home, subnode);
                        if (r < 0)
                                return log_oom();

                } else if (sd_id128_equal(type_id, GPT_SRV)) {

                        if (flags & GPT_FLAG_NO_AUTO)
                                continue;

                        /* We only care for the first /srv partition */
                        if (srv && nr >= srv_nr)
                                continue;

                        srv_nr = nr;
                        srv_rw = !(flags & GPT_FLAG_READ_ONLY),

                        r = free_and_strdup(&srv, subnode);
                        if (r < 0)
                                return log_oom();
                }
        }
Beispiel #22
0
static int
setup_tty(struct launcher_direct *launcher, int tty)
{
	struct wl_event_loop *loop;
	struct vt_mode mode = { 0 };
	struct stat buf;
	char tty_device[32] ="<stdin>";
	int ret, kd_mode;

	if (tty == 0) {
		launcher->tty = dup(tty);
		if (launcher->tty == -1) {
			weston_log("couldn't dup stdin: %m\n");
			return -1;
		}
	} else {
		snprintf(tty_device, sizeof tty_device, "/dev/tty%d", tty);
		launcher->tty = open(tty_device, O_RDWR | O_CLOEXEC);
		if (launcher->tty == -1) {
			weston_log("couldn't open tty %s: %m\n", tty_device);
			return -1;
		}
	}

	if (fstat(launcher->tty, &buf) == -1 ||
	    major(buf.st_rdev) != TTY_MAJOR || minor(buf.st_rdev) == 0) {
		weston_log("%s not a vt\n", tty_device);
		weston_log("if running weston from ssh, "
			   "use --tty to specify a tty\n");
		goto err_close;
	}

	ret = ioctl(launcher->tty, KDGETMODE, &kd_mode);
	if (ret) {
		weston_log("failed to get VT mode: %m\n");
		return -1;
	}
	if (kd_mode != KD_TEXT) {
		weston_log("%s is already in graphics mode, "
			   "is another display server running?\n", tty_device);
		goto err_close;
	}

	ioctl(launcher->tty, VT_ACTIVATE, minor(buf.st_rdev));
	ioctl(launcher->tty, VT_WAITACTIVE, minor(buf.st_rdev));

	if (ioctl(launcher->tty, KDGKBMODE, &launcher->kb_mode)) {
		weston_log("failed to read keyboard mode: %m\n");
		goto err_close;
	}

	if (ioctl(launcher->tty, KDSKBMUTE, 1) &&
	    ioctl(launcher->tty, KDSKBMODE, K_OFF)) {
		weston_log("failed to set K_OFF keyboard mode: %m\n");
		goto err_close;
	}

	ret = ioctl(launcher->tty, KDSETMODE, KD_GRAPHICS);
	if (ret) {
		weston_log("failed to set KD_GRAPHICS mode on tty: %m\n");
		goto err_close;
	}

	/*
	 * SIGRTMIN is used as global VT-acquire+release signal. Note that
	 * SIGRT* must be tested on runtime, as their exact values are not
	 * known at compile-time. POSIX requires 32 of them to be available.
	 */
	if (SIGRTMIN > SIGRTMAX) {
		weston_log("not enough RT signals available: %u-%u\n",
			   SIGRTMIN, SIGRTMAX);
		ret = -EINVAL;
		goto err_close;
	}

	mode.mode = VT_PROCESS;
	mode.relsig = SIGRTMIN;
	mode.acqsig = SIGRTMIN;
	if (ioctl(launcher->tty, VT_SETMODE, &mode) < 0) {
		weston_log("failed to take control of vt handling\n");
		goto err_close;
	}

	loop = wl_display_get_event_loop(launcher->compositor->wl_display);
	launcher->vt_source =
		wl_event_loop_add_signal(loop, SIGRTMIN, vt_handler, launcher);
	if (!launcher->vt_source)
		goto err_close;

	return 0;

 err_close:
	close(launcher->tty);
	return -1;
}
Beispiel #23
0
static int verify_esp(const char *p, uint32_t *part, uint64_t *pstart, uint64_t *psize, sd_id128_t *uuid) {
        struct statfs sfs;
        struct stat st, st2;
        _cleanup_free_ char *t = NULL;
        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
        int r;
        const char *v, *t2;

        if (statfs(p, &sfs) < 0)
                return log_error_errno(errno, "Failed to check file system type of \"%s\": %m", p);

        if (sfs.f_type != 0x4d44) {
                log_error("File system \"%s\" is not a FAT EFI System Partition (ESP) file system.", p);
                return -ENODEV;
        }

        if (stat(p, &st) < 0)
                return log_error_errno(errno, "Failed to determine block device node of \"%s\": %m", p);

        if (major(st.st_dev) == 0) {
                log_error("Block device node of %p is invalid.", p);
                return -ENODEV;
        }

        t2 = strjoina(p, "/..");
        r = stat(t2, &st2);
        if (r < 0)
                return log_error_errno(errno, "Failed to determine block device node of parent of \"%s\": %m", p);

        if (st.st_dev == st2.st_dev) {
                log_error("Directory \"%s\" is not the root of the EFI System Partition (ESP) file system.", p);
                return -ENODEV;
        }

        r = asprintf(&t, "/dev/block/%u:%u", major(st.st_dev), minor(st.st_dev));
        if (r < 0)
                return log_oom();

        errno = 0;
        b = blkid_new_probe_from_filename(t);
        if (!b) {
                if (errno == 0)
                        return log_oom();

                return log_error_errno(errno, "Failed to open file system \"%s\": %m", p);
        }

        blkid_probe_enable_superblocks(b, 1);
        blkid_probe_set_superblocks_flags(b, BLKID_SUBLKS_TYPE);
        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == -2) {
                log_error("File system \"%s\" is ambiguous.", p);
                return -ENODEV;
        } else if (r == 1) {
                log_error("File system \"%s\" does not contain a label.", p);
                return -ENODEV;
        } else if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe file system \"%s\": %m", p);
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "TYPE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe file system type \"%s\": %m", p);
        }

        if (!streq(v, "vfat")) {
                log_error("File system \"%s\" is not FAT.", p);
                return -ENODEV;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_SCHEME", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition scheme \"%s\": %m", p);
        }

        if (!streq(v, "gpt")) {
                log_error("File system \"%s\" is not on a GPT partition table.", p);
                return -ENODEV;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_TYPE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition type UUID \"%s\": %m", p);
        }

        if (!streq(v, "c12a7328-f81f-11d2-ba4b-00a0c93ec93b")) {
                log_error("File system \"%s\" has wrong type for an EFI System Partition (ESP).", p);
                return -ENODEV;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition entry UUID \"%s\": %m", p);
        }

        r = sd_id128_from_string(v, uuid);
        if (r < 0) {
                log_error("Partition \"%s\" has invalid UUID \"%s\".", p, v);
                return -EIO;
        }

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_NUMBER", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition number \"%s\": m", p);
        }
        *part = strtoul(v, NULL, 10);

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_OFFSET", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition offset \"%s\": %m", p);
        }
        *pstart = strtoul(v, NULL, 10);

        errno = 0;
        r = blkid_probe_lookup_value(b, "PART_ENTRY_SIZE", &v, NULL);
        if (r != 0) {
                r = errno ? -errno : -EIO;
                return log_error_errno(r, "Failed to probe partition size \"%s\": %m", p);
        }
        *psize = strtoul(v, NULL, 10);

        return 0;
}
Beispiel #24
0
/*ARGSUSED*/
int
mmrw(dev_t dev, struct uio *uio, int flags)
{
	vaddr_t va;
	paddr_t pa;
	int o, c;
	struct iovec *iov;
	int error = 0;
	static int physlock;
	vm_prot_t prot;
	extern void *vmmap;

	if (minor(dev) == DEV_MEM) {
		/* lock against other uses of shared vmmap */
		while (physlock > 0) {
			physlock++;
			error = tsleep((void *)&physlock, PZERO | PCATCH,
			    "mmrw", 0);
			if (error)
				return (error);
		}
		physlock = 1;
	}
	while (uio->uio_resid > 0 && error == 0) {
		int n;
		iov = uio->uio_iov;
		if (iov->iov_len == 0) {
			uio->uio_iov++;
			uio->uio_iovcnt--;
			if (uio->uio_iovcnt < 0)
				panic("mmrw");
			continue;
		}

		/* Note how much is still to go */
		n = uio->uio_resid;

		switch (minor(dev)) {

		case DEV_MEM:
			pa = (paddr_t)uio->uio_offset;
			if (!pmap_pa_exists(pa)) {
				error = EFAULT;
				goto unlock;
			}
			prot = uio->uio_rw == UIO_READ ? VM_PROT_READ :
			    VM_PROT_WRITE;
			pmap_enter(pmap_kernel(), (vaddr_t)vmmap,
			    trunc_page(pa), prot, prot|PMAP_WIRED);
			pmap_update(pmap_kernel());
			o = uio->uio_offset & PGOFSET;
			c = min(uio->uio_resid, (int)(PAGE_SIZE - o));
			error = uiomove((char *)vmmap + o, c, uio);
			pmap_remove(pmap_kernel(),
			    (vaddr_t)vmmap, (vaddr_t)vmmap + PAGE_SIZE);
			pmap_update(pmap_kernel());
			break;

		case DEV_KMEM:
			va = (vaddr_t)uio->uio_offset;
			if (va >= MSGBUF_VA && va < MSGBUF_VA+PAGE_SIZE) {
				c = min(iov->iov_len, 4096);
			} else if (va >= prom_vstart && va < prom_vend &&
				   uio->uio_rw == UIO_READ) {
				/* Allow read-only access to the PROM */
				c = min(iov->iov_len, prom_vend - prom_vstart);
			} else {
				c = min(iov->iov_len, MAXPHYS);
				if (!uvm_kernacc((void *)va, c,
				    uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
					return (EFAULT);
			}
			error = uiomove((void *)va, c, uio);
			break;

		case DEV_NULL:
			if (uio->uio_rw == UIO_WRITE)
				uio->uio_resid = 0;
			return (0);

/* XXX should add sbus, etc */

#if defined(SUN4)
		case DEV_EEPROM:
			if (cputyp == CPU_SUN4)
				error = eeprom_uio(uio);
			else
				error = ENXIO;

			break;
#endif /* SUN4 */

		case DEV_ZERO:
			if (uio->uio_rw == UIO_WRITE) {
				uio->uio_resid = 0;
				return(0);
			}
			if (zeropage == NULL) {
				zeropage = (void *)
				    malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
				bzero(zeropage, PAGE_SIZE);
			}
			c = min(iov->iov_len, PAGE_SIZE);
			error = uiomove(zeropage, c, uio);
			break;

		default:
			return (ENXIO);
		}

		/* If we didn't make any progress (i.e. EOF), we're done here */
		if (n == uio->uio_resid)
			break;
	}
	if (minor(dev) == 0) {
unlock:
		if (physlock > 1)
			wakeup((void *)&physlock);
		physlock = 0;
	}
	return (error);
}
Beispiel #25
0
/* read UMOCKDEV_SCRIPT_* environment variables and set up dev_logfile_map
 * according to it */
static void
init_script_dev_logfile_map(void)
{
    int i, dev;
    char varname[100];
    const char *devname, *logname, *format;
    char *endptr;

    script_dev_logfile_map_inited = 1;

    for (i = 0; 1; ++i) {
	snprintf(varname, sizeof(varname), "UMOCKDEV_SCRIPT_RECORD_FILE_%i", i);
	logname = getenv(varname);
	if (logname == NULL)
	    break;
	snprintf(varname, sizeof(varname), "UMOCKDEV_SCRIPT_RECORD_DEV_%i", i);
	devname = getenv(varname);
	if (devname == NULL) {
	    fprintf(stderr, "umockdev: $%s not set\n", varname);
	    exit(1);
	}
	snprintf(varname, sizeof(varname), "UMOCKDEV_SCRIPT_RECORD_FORMAT_%i", i);
	format = getenv(varname);
	if (format == NULL) {
	    fprintf(stderr, "umockdev: $%s not set\n", varname);
	    exit(1);
	}
	dev = strtol(devname, &endptr, 10);
	if (dev != 0 && *endptr == '\0') {
	    /* if it's a number, then it is an rdev of a device */
	    /* ...and we should record its path */
	    const char *devpath;
	    snprintf(varname, sizeof(varname), "UMOCKDEV_SCRIPT_RECORD_DEVICE_PATH_%i", i);
	    devpath = getenv(varname);
	    if (devpath == NULL) {
		fprintf(stderr, "umockdev: $%s not set\n", varname);
		exit(1);
	    }
	    DBG(DBG_SCRIPT, "init_script_dev_logfile_map: will record script of device %i:%i into %s\n", major(dev), minor(dev),
	    logname);
	    fd_map_add(&script_dev_logfile_map, dev, logname);
	    fd_map_add(&script_dev_devpath_map, dev, devpath);

	    if (strcmp(format, "default") == 0)
		fd_map_add(&script_dev_format_map, dev, (void*) FMT_DEFAULT);
	    else if (strcmp(format, "evemu") == 0)
		fd_map_add(&script_dev_format_map, dev, (void*) FMT_EVEMU);
	    else {
		fprintf(stderr, "umockdev: unknown device script record format '%s'\n", format);
		exit(1);
	    }
	} else {
	    if (strcmp(format, "default") != 0) {
		fprintf(stderr, "umockdev: unknown socket script record format '%s'\n", format);
		exit(1);
	    }

	    /* if it's a path, then we record a socket */
	    if (script_socket_logfile_len < MAX_SCRIPT_SOCKET_LOGFILE) {
		DBG(DBG_SCRIPT, "init_script_dev_logfile_map: will record script of socket %s into %s\n", devname, logname);
		script_socket_logfile[2*script_socket_logfile_len] = devname;
		script_socket_logfile[2*script_socket_logfile_len+1] = logname;
		script_socket_logfile_len++;
	    } else {
		fprintf(stderr, "too many script sockets to record\n");
		abort();
	    }
	}
    }
}
Beispiel #26
0
/*
 * Call the low-level strategy routines to
 * perform the requests in a struct request
 */
int
launch_requests(struct request *rq, int reviveok)
{
    int s;
    struct rqgroup *rqg;
    int rqno;						    /* loop index */
    struct rqelement *rqe;				    /* current element */
    struct drive *drive;
    int rcount;						    /* request count */

    /*
     * First find out whether we're reviving, and the
     * request contains a conflict.  If so, we hang
     * the request off plex->waitlist of the first
     * plex we find which is reviving
     */
    if ((rq->flags & XFR_REVIVECONFLICT)		    /* possible revive conflict */
    &&(!reviveok)) {					    /* and we don't want to do it now, */
	struct sd *sd;
	struct request *waitlist;			    /* point to the waitlist */

	sd = &SD[rq->sdno];
	if (sd->waitlist != NULL) {			    /* something there already, */
	    waitlist = sd->waitlist;
	    while (waitlist->next != NULL)		    /* find the end */
		waitlist = waitlist->next;
	    waitlist->next = rq;			    /* hook our request there */
	} else
	    sd->waitlist = rq;				    /* hook our request at the front */

#if VINUMDEBUG
	if (debug & DEBUG_REVIVECONFLICT)
	    log(LOG_DEBUG,
		"Revive conflict sd %d: %p\n%s dev %d.%d, offset 0x%x, length %ld\n",
		rq->sdno,
		rq,
		rq->bp->b_flags & B_READ ? "Read" : "Write",
		major(rq->bp->b_dev),
		minor(rq->bp->b_dev),
		rq->bp->b_blkno,
		rq->bp->b_bcount);
#endif
	return 0;					    /* and get out of here */
    }
    rq->active = 0;					    /* nothing yet */
#if VINUMDEBUG
    if (debug & DEBUG_ADDRESSES)
	log(LOG_DEBUG,
	    "Request: %p\n%s dev %d.%d, offset 0x%x, length %ld\n",
	    rq,
	    rq->bp->b_flags & B_READ ? "Read" : "Write",
	    major(rq->bp->b_dev),
	    minor(rq->bp->b_dev),
	    rq->bp->b_blkno,
	    rq->bp->b_bcount);
    vinum_conf.lastrq = rq;
    vinum_conf.lastbuf = rq->bp;
    if (debug & DEBUG_LASTREQS)
	logrq(loginfo_user_bpl, (union rqinfou) rq->bp, rq->bp);
#endif

    /*
     * With the division of labour below (first count the requests, then
     * issue them), it's possible that we don't need this splbio()
     * protection.  But I'll try that some other time.
     */
    s = splbio();
    for (rqg = rq->rqg; rqg != NULL; rqg = rqg->next) {	    /* through the whole request chain */
	rqg->active = rqg->count;			    /* they're all active */
	for (rqno = 0; rqno < rqg->count; rqno++) {
	    rqe = &rqg->rqe[rqno];
	    if (rqe->flags & XFR_BAD_SUBDISK)		    /* this subdisk is bad, */
		rqg->active--;				    /* one less active request */
	}
	if (rqg->active)				    /* we have at least one active request, */
	    rq->active++;				    /* one more active request group */
    }

    /* Now fire off the requests */
    for (rqg = rq->rqg; rqg != NULL;) {			    /* through the whole request chain */
	if (rqg->lockbase >= 0)				    /* this rqg needs a lock first */
	    rqg->lock = lockrange(rqg->lockbase, rqg->rq->bp, &PLEX[rqg->plexno]);
	rcount = rqg->count;
	for (rqno = 0; rqno < rcount;) {
	    rqe = &rqg->rqe[rqno];

	    /*
	     * Point to next rqg before the bottom end
	     * changes the structures.
	     */
	    if (++rqno >= rcount)
		rqg = rqg->next;
	    if ((rqe->flags & XFR_BAD_SUBDISK) == 0) {	    /* this subdisk is good, */
		drive = &DRIVE[rqe->driveno];		    /* look at drive */
		drive->active++;
		if (drive->active >= drive->maxactive)
		    drive->maxactive = drive->active;
		vinum_conf.active++;
		if (vinum_conf.active >= vinum_conf.maxactive)
		    vinum_conf.maxactive = vinum_conf.active;

#if VINUMDEBUG
		if (debug & DEBUG_ADDRESSES)
		    log(LOG_DEBUG,
			"  %s dev %d.%d, sd %d, offset 0x%x, devoffset 0x%x, length %ld\n",
			rqe->b.b_flags & B_READ ? "Read" : "Write",
			major(rqe->b.b_dev),
			minor(rqe->b.b_dev),
			rqe->sdno,
			(u_int) (rqe->b.b_blkno - SD[rqe->sdno].driveoffset),
			rqe->b.b_blkno,
			rqe->b.b_bcount);
		if (debug & DEBUG_LASTREQS)
		    logrq(loginfo_rqe, (union rqinfou) rqe, rq->bp);
#endif


		/* fire off the request */
		BUF_STRATEGY(&rqe->b, 0);
	    }
	}
    }
    splx(s);
    return 0;
}
Beispiel #27
0
Errors Device_getDeviceInfo(DeviceInfo   *deviceInfo,
                            const String deviceName
                           )
{
  FileStat fileStat;
  int      handle;
  #if defined(HAVE_IOCTL) && defined(HAVE_BLKSSZGET)
    int      i;
  #endif
  #if defined(HAVE_IOCTL) && defined(HAVE_BLKGETSIZE)
    long     l;
  #endif
  FILE          *mtab;
  struct mntent mountEntry;
  char          buffer[4096];

  assert(deviceName != NULL);
  assert(deviceInfo != NULL);

  // initialize variables
  deviceInfo->type        = DEVICE_TYPE_UNKNOWN;
  deviceInfo->size        = -1LL;
  deviceInfo->blockSize   = 0L;
//  deviceInfo->freeBlocks  = 0LL;
//  deviceInfo->totalBlocks = 0LL;
  deviceInfo->mountedFlag = FALSE;

  // get device meta data
  if (LSTAT(String_cString(deviceName),&fileStat) == 0)
  {
    deviceInfo->timeLastAccess  = fileStat.st_atime;
    deviceInfo->timeModified    = fileStat.st_mtime;
    deviceInfo->timeLastChanged = fileStat.st_ctime;
    deviceInfo->userId          = fileStat.st_uid;
    deviceInfo->groupId         = fileStat.st_gid;
    deviceInfo->permission      = (DevicePermission)fileStat.st_mode;
    #ifdef HAVE_MAJOR
      deviceInfo->major         = major(fileStat.st_rdev);
    #else
      deviceInfo->major         = 0;
    #endif
    #ifdef HAVE_MINOR
      deviceInfo->minor         = minor(fileStat.st_rdev);
    #else
      deviceInfo->minor         = 0;
    #endif
    deviceInfo->id              = (uint64)fileStat.st_ino;

    if      (S_ISCHR(fileStat.st_mode)) deviceInfo->type = DEVICE_TYPE_CHARACTER;
    else if (S_ISBLK(fileStat.st_mode)) deviceInfo->type = DEVICE_TYPE_BLOCK;
  }

  if (deviceInfo->type == DEVICE_TYPE_BLOCK)
  {
    // try to get block size, total size
    handle = open(String_cString(deviceName),O_RDONLY);
    if (handle != -1)
    {
      #if defined(HAVE_IOCTL) && defined(HAVE_BLKSSZGET)
        if (ioctl(handle,BLKSSZGET, &i) == 0) deviceInfo->blockSize = (ulong)i;
      #endif
      #if defined(HAVE_IOCTL) && defined(HAVE_BLKGETSIZE)
        if (ioctl(handle,BLKGETSIZE,&l) == 0) deviceInfo->size      = (int64)l*512;
      #endif
      close(handle);
    }
  }

  // check if mounted
  mtab = setmntent("/etc/mtab","r");
  if (mtab != NULL)
  {
    while (getmntent_r(mtab,&mountEntry,buffer,sizeof(buffer)) != NULL)
    {
      if (String_equalsCString(deviceName,mountEntry.mnt_fsname))
      {
        deviceInfo->mountedFlag = TRUE;
        break;
      }
    }
    endmntent(mtab);
  }

  return ERROR_NONE;
}
Beispiel #28
0
/* Perform I/O on a subdisk */
void
sdio(struct buf *bp)
{
    int s;						    /* spl */
    struct sd *sd;
    struct sdbuf *sbp;
    daddr_t endoffset;
    struct drive *drive;

#if VINUMDEBUG
    if (debug & DEBUG_LASTREQS)
	logrq(loginfo_sdio, (union rqinfou) bp, bp);
#endif
    sd = &SD[Sdno(bp->b_dev)];				    /* point to the subdisk */
    drive = &DRIVE[sd->driveno];

    if (drive->state != drive_up) {
	if (sd->state >= sd_crashed) {
	    if (bp->b_flags & B_READ)			    /* reading, */
		set_sd_state(sd->sdno, sd_crashed, setstate_force);
	    else
		set_sd_state(sd->sdno, sd_stale, setstate_force);
	}
	bp->b_flags |= B_ERROR;
	bp->b_error = EIO;
	biodone(bp);
	return;
    }
    /*
     * We allow access to any kind of subdisk as long as we can expect
     * to get the I/O performed.
     */
    if (sd->state < sd_empty) {				    /* nothing to talk to, */
	bp->b_flags |= B_ERROR;
	bp->b_error = EIO;
	biodone(bp);
	return;
    }
    /* Get a buffer */
    sbp = (struct sdbuf *) Malloc(sizeof(struct sdbuf));
    if (sbp == NULL) {
	bp->b_flags |= B_ERROR;
	bp->b_error = ENOMEM;
	biodone(bp);
	return;
    }
    bzero(sbp, sizeof(struct sdbuf));			    /* start with nothing */
    sbp->b.b_flags = bp->b_flags | B_CALL;		    /* inform us when it's done */
    sbp->b.b_bufsize = bp->b_bufsize;			    /* buffer size */
    sbp->b.b_bcount = bp->b_bcount;			    /* number of bytes to transfer */
    sbp->b.b_resid = bp->b_resid;			    /* and amount waiting */
    sbp->b.b_dev = DRIVE[sd->driveno].dev;		    /* device */
    sbp->b.b_data = bp->b_data;				    /* data buffer */
    sbp->b.b_blkno = bp->b_blkno + sd->driveoffset;
    sbp->b.b_iodone = sdio_done;			    /* come here on completion */
    BUF_LOCKINIT(&sbp->b);				    /* get a lock for the buffer */
    BUF_LOCK(&sbp->b, LK_EXCLUSIVE);			    /* and lock it */
    sbp->bp = bp;					    /* note the address of the original header */
    sbp->sdno = sd->sdno;				    /* note for statistics */
    sbp->driveno = sd->driveno;
    endoffset = bp->b_blkno + sbp->b.b_bcount / DEV_BSIZE;  /* final sector offset */
    if (endoffset > sd->sectors) {			    /* beyond the end */
	sbp->b.b_bcount -= (endoffset - sd->sectors) * DEV_BSIZE; /* trim */
	if (sbp->b.b_bcount <= 0) {			    /* nothing to transfer */
	    bp->b_resid = bp->b_bcount;			    /* nothing transferred */
	    biodone(bp);
	    Free(sbp);
	    return;
	}
    }
#if VINUMDEBUG
    if (debug & DEBUG_ADDRESSES)
	log(LOG_DEBUG,
	    "  %s dev %d.%d, sd %d, offset 0x%x, devoffset 0x%x, length %ld\n",
	    sbp->b.b_flags & B_READ ? "Read" : "Write",
	    major(sbp->b.b_dev),
	    minor(sbp->b.b_dev),
	    sbp->sdno,
	    (u_int) (sbp->b.b_blkno - SD[sbp->sdno].driveoffset),
	    (int) sbp->b.b_blkno,
	    sbp->b.b_bcount);
#endif
    s = splbio();
#if VINUMDEBUG
    if (debug & DEBUG_LASTREQS)
	logrq(loginfo_sdiol, (union rqinfou) &sbp->b, &sbp->b);
#endif
    BUF_STRATEGY(&sbp->b, 0);
    splx(s);
}
Beispiel #29
0
int cdread(uint16_t dev, uint8_t flag)
{
	validchk(dev, PANIC_CDR);
	return ((*dev_tab[major(dev)].dev_read) (minor(dev), 1, flag));
}
Beispiel #30
0
int mmc_is_path_at_device_offset(const char *file_path, off_t block_offset)
{
    struct stat file_st;
    if (stat(file_path, &file_st) < 0)
        return -1;

    // Now check that the offset is in the right place by reading the sysfs file.
    char start_path[64];
    snprintf(start_path, sizeof(start_path), "/sys/dev/block/%d:%d/start", major(file_st.st_dev), minor(file_st.st_dev));

    char start[16];
    if (readsysfs(start_path, start, sizeof(start)) <= 0)
        return -1;

    off_t start_offset = strtoull(start, NULL, 0);

    return start_offset == block_offset ? 1 : 0;
}