Example #1
0
/* Open a temporary file in an executable and writable mount point
   listed in the mounts file.  Subsequent calls with the same mounts
   keep searching for mount points in the same file.  Providing NULL
   as the mounts file closes the file.  */
static int
open_temp_exec_file_mnt (const char *mounts)
{
  static const char *last_mounts;
  static FILE *last_mntent;

  if (mounts != last_mounts)
    {
      if (last_mntent)
	endmntent (last_mntent);

      last_mounts = mounts;

      if (mounts)
	last_mntent = setmntent (mounts, "r");
      else
	last_mntent = NULL;
    }

  if (!last_mntent)
    return -1;

  for (;;)
    {
      int fd;
      struct mntent mnt;
      char buf[MAXPATHLEN * 3];

      if (getmntent_r (last_mntent, &mnt, buf, sizeof (buf)) == NULL)
	return -1;

      if (hasmntopt (&mnt, "ro")
	  || hasmntopt (&mnt, "noexec")
	  || access (mnt.mnt_dir, W_OK))
	continue;

      fd = open_temp_exec_file_dir (mnt.mnt_dir);

      if (fd != -1)
	return fd;
    }
}
Example #2
0
/*!
 * \brief Unmount filesystem
 *
 * This function takes the same arguments as umount(2), but returns true on
 * success and false on failure.
 *
 * This function will /proc/mounts for the mountpoint (using an exact string
 * compare). If the source path of the mountpoint is a block device and the
 * block device is a loop device, then it will be disassociated from the
 * previously attached file. Note that the return value of
 * loopdev_remove_device() is ignored and this function will always return true
 * if umount(2) is successful.
 *
 * \param target See man umount(2)
 *
 * \return True if umount(2) is successful. False if umount(2) is unsuccessful.
 */
bool umount(const char *target)
{
    struct mntent ent;
    std::string source;
    std::string mnt_dir;

    autoclose::file fp(setmntent("/proc/mounts", "r"), endmntent);
    if (fp) {
        char buf[1024];
        while (getmntent_r(fp.get(), &ent, buf, sizeof(buf))) {
            mnt_dir = get_deleted_mount_path(ent.mnt_dir);
            if (mnt_dir == target) {
                source = ent.mnt_fsname;
            }
        }
    } else {
        LOGW("Failed to read /proc/mounts: %s", strerror(errno));
    }

    int ret = ::umount(target);

    int saved_errno = errno;

    if (!source.empty()) {
        struct stat sb;

        if (stat(source.c_str(), &sb) == 0
                && S_ISBLK(sb.st_mode) && major(sb.st_rdev) == 7) {
            // If the source path is a loop block device, then disassociate it
            // from the image
            LOGD("Clearing loop device %s", source.c_str());
            if (!loopdev_remove_device(source)) {
                LOGW("Failed to clear loop device: %s", strerror(errno));
            }
        }
    }

    errno = saved_errno;

    return ret == 0;
}
Example #3
0
int
_sol_getmntent(FILE *fp, struct mnttab *mgetp)
{
	struct mntent mntbuf;
	struct mntent *ret;

	ret = getmntent_r(fp, &mntbuf, buf, BUFSIZE);

	if (ret != NULL) {
		mgetp->mnt_special = mntbuf.mnt_fsname;
		mgetp->mnt_mountp = mntbuf.mnt_dir;
		mgetp->mnt_fstype = mntbuf.mnt_type;
		mgetp->mnt_mntopts = mntbuf.mnt_opts;
		return (0);
	}

	if (feof(fp))
		return (-1);

	return (MNT_TOOLONG);
}
Example #4
0
struct mntent *getmntent(FILE * filep)
{
    struct mntent *tmp;
    static char *buff = NULL;
    static struct mntent mnt;
    __UCLIBC_MUTEX_LOCK(mylock);

    if (!buff) {
#ifdef __cplusplus
            buff = (char *) malloc(BUFSIZ);
#else
            buff = malloc(BUFSIZ);
#endif
		if (!buff)
		    abort();
    }

    tmp = getmntent_r(filep, &mnt, buff, BUFSIZ);
    __UCLIBC_MUTEX_UNLOCK(mylock);
    return(tmp);
}
Example #5
0
bool is_mounted(const std::string &mountpoint)
{
    autoclose::file fp(setmntent("/proc/mounts", "r"), endmntent);
    if (!fp) {
        LOGE("Failed to read /proc/mounts: %s", strerror(errno));
        return false;
    }

    bool found = false;
    struct mntent ent;
    char buf[1024];

    while (getmntent_r(fp.get(), &ent, buf, sizeof(buf))) {
        if (mountpoint == ent.mnt_dir) {
            found = true;
            break;
        }
    }

    return found;
}
Example #6
0
/*
 * File system functions
 */
JNIEXPORT void JNICALL
Java_net_rubygrapefruit_platform_internal_jni_PosixFileSystemFunctions_listFileSystems(JNIEnv *env, jclass target, jobject info, jobject result) {
    FILE *fp = setmntent(MOUNTED, "r");
    if (fp == NULL) {
        mark_failed_with_errno(env, "could not open mount file", result);
        return;
    }
    char buf[1024];
    struct mntent mount_info;

    jclass info_class = env->GetObjectClass(info);
    jmethodID method = env->GetMethodID(info_class, "add", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V");

    while (getmntent_r(fp, &mount_info, buf, sizeof(buf)) != NULL) {
        jstring mount_point = char_to_java(env, mount_info.mnt_dir, result);
        jstring file_system_type = char_to_java(env, mount_info.mnt_type, result);
        jstring device_name = char_to_java(env, mount_info.mnt_fsname, result);
        env->CallVoidMethod(info, method, mount_point, file_system_type, device_name, JNI_FALSE);
    }

    endmntent(fp);
}
Example #7
0
/**
 * @conn connection to report errors against
 * @pool storage pool to check for status
 *
 * Determine if a storage pool is already mounted
 *
 * Return 0 if not mounted, 1 if mounted, -1 on error
 */
static int
virStorageBackendFileSystemIsMounted(virStoragePoolObjPtr pool) {
    FILE *mtab;
    struct mntent ent;
    char buf[1024];

    if ((mtab = fopen(_PATH_MOUNTED, "r")) == NULL) {
        virReportSystemError(errno,
                             _("cannot read mount list '%s'"),
                             _PATH_MOUNTED);
        return -1;
    }

    while ((getmntent_r(mtab, &ent, buf, sizeof(buf))) != NULL) {
        if (STREQ(ent.mnt_dir, pool->def->target.path)) {
            VIR_FORCE_FCLOSE(mtab);
            return 1;
        }
    }

    VIR_FORCE_FCLOSE(mtab);
    return 0;
}
Example #8
0
static bool is_mounted(const char device_file[])
{
	FILE *f;
	bool rc;
	struct mntent mnt;
	struct mntent *mnte;
	char buf[512];

	rc = false;

	if ((f = setmntent("/etc/mtab", "r")) == NULL)
		return rc;

	while ((mnte = getmntent_r(f, &mnt, buf, sizeof(buf))) != NULL) {
		if (strcmp(device_file, mnt.mnt_fsname) == 0) {
			rc = true;
			break;
		}
	}

	endmntent(f);
	return rc;
}
Example #9
0
bool unmount_all(const std::string &dir)
{
    int failed;
    struct mntent ent;
    char buf[1024];

    for (int tries = 0; tries < MAX_UNMOUNT_TRIES; ++tries) {
        failed = 0;

        autoclose::file fp(setmntent("/proc/mounts", "r"), endmntent);
        if (!fp) {
            LOGE("Failed to read /proc/mounts: %s", strerror(errno));
            return false;
        }

        while (getmntent_r(fp.get(), &ent, buf, sizeof(buf))) {
            if (starts_with(ent.mnt_dir, dir)) {
                //LOGD("Attempting to unmount %s", ent.mnt_dir);

                if (!util::umount(ent.mnt_dir)) {
                    LOGE("Failed to unmount %s: %s",
                         ent.mnt_dir, strerror(errno));
                    ++failed;
                }
            }
        }

        if (failed == 0) {
            return true;
        }

        // Retry
    }

    LOGE("Failed to unmount %d partitions", failed);
    return false;
}
Example #10
0
/* Check mount point and FS type.
 * Also return the associated device number.
 * (for STAY_IN_FS security option).
 */
int CheckFSInfo( char *path, char *expected_type, dev_t * p_fs_dev, int check_mounted,
                 int save_fs )
{
    FILE          *fp;
    struct mntent *p_mnt;
    struct mntent  mnt_ent;
    char           mnt_buff[4096];

    char           rpath[RBH_PATH_MAX];
    char           mntdir[RBH_PATH_MAX];
    char           tmp_buff[RBH_PATH_MAX];
    char          *parentmntdir;
    char           fs_spec[RBH_PATH_MAX];
#ifdef _HAVE_FID
    char          *ptr;
#endif

    char           type[256];

    struct stat    pathstat;
    struct stat    parentmntstat;

    size_t         pathlen, outlen;

    if ( ( expected_type == NULL ) || ( expected_type[0] == '\0' ) )
    {
        DisplayLog( LVL_CRIT, "CheckFS", "/!\\ ERROR /!\\ No filesystem type specified" );
        return EINVAL;
    }

    /* convert to canonic path */
    if ( !realpath( path, rpath ) )
    {
        DisplayLog( LVL_CRIT, "CheckFS", "Error %d in realpath(%s): %s",
                    errno, ( path ? path : "<null>" ), strerror( errno ) );
        return errno;
    }


    /* open mount tab and look for the given path */
    outlen = 0;

    fp = setmntent( MOUNTED, "r" );

    if ( fp == NULL )
    {
        DisplayLog( LVL_CRIT, "CheckFS", "Error %d in setmntent(%s): %s",
                    errno, MOUNTED, strerror( errno ) );
        return errno;
    }

    while ( ( p_mnt = getmntent_r( fp, &mnt_ent, mnt_buff, 4096 ) ) != NULL )
    {
        /* get the longest matching path */

        if ( p_mnt->mnt_dir != NULL )
        {

            pathlen = strlen( p_mnt->mnt_dir );

            /* if check_mounted is FALSE, root filesystem is allowed */
            if ( !check_mounted && ( pathlen > outlen )
                 && !strcmp( p_mnt->mnt_dir, "/" ) )
            {
                DisplayLog( LVL_DEBUG, "CheckFS",
                            "Root mountpoint is allowed for matching %s, type=%s, fs=%s",
                            rpath, p_mnt->mnt_type, p_mnt->mnt_fsname );
                outlen = pathlen;
                strncpy( mntdir, p_mnt->mnt_dir, RBH_PATH_MAX );
                strncpy( type, p_mnt->mnt_type, 256 );
                strncpy( fs_spec, p_mnt->mnt_fsname, RBH_PATH_MAX );
            }
            /* in other cases, the filesystem must be <mountpoint>/<smthg> or <mountpoint>\0 */
            else if ( ( pathlen > outlen ) &&
                      !strncmp( rpath, p_mnt->mnt_dir, pathlen ) &&
                      ( ( rpath[pathlen] == '/' ) || ( rpath[pathlen] == '\0' ) ) )
            {
                DisplayLog( LVL_FULL, "CheckFS",
                            "%s is under mountpoint %s, type=%s, fs=%s",
                            rpath, p_mnt->mnt_dir, p_mnt->mnt_type, p_mnt->mnt_fsname );

                outlen = pathlen;
                strncpy( mntdir, p_mnt->mnt_dir, RBH_PATH_MAX );
                strncpy( type, p_mnt->mnt_type, 256 );
                strncpy( fs_spec, p_mnt->mnt_fsname, RBH_PATH_MAX );
            }
        }
    }

    if ( outlen <= 0 )
    {
        DisplayLog( LVL_CRIT, "CheckFS", "No mount entry matches '%s' in %s", rpath, MOUNTED );
        DisplayLog( LVL_CRIT, "CheckFS",
                    "Set 'check_mounted = FALSE' in configuration to force using root filesystem" );
        endmntent( fp );
        return ENOENT;
    }


    /* display the matching entry */
    DisplayLog( LVL_EVENT, "CheckFS",
                "'%s' matches mount point '%s', type=%s, fs=%s", rpath, mntdir, type, fs_spec );

    /* check filesystem type */
    if ( strcasecmp( type, expected_type ) )
    {
        if (check_mounted)
        {
            DisplayLog( LVL_CRIT, "CheckFS",
                        "/!\\ ERROR /!\\ The specified type for '%s' (%s) does not match actual filesystem type (%s)",
                        rpath, expected_type, type );
            endmntent( fp );
            return EINVAL;
        }
        else
        {
            DisplayLog( LVL_MAJOR, "CheckFS",
                        "/!\\ WARNING /!\\ The specified type for '%s' (%s) "
                        "does not match actual filesystem type (%s).",
                        rpath, expected_type, type );
            DisplayLog( LVL_MAJOR, "CheckFS", "check_mounted is disabled: continuing." );
        }
    }

    /* stat the given fs_path */
    if ( stat( rpath, &pathstat ) != 0 )
    {
        DisplayLog( LVL_CRIT, "CheckFS",
                    "/!\\ ERROR /!\\ Couldn't stat '%s': %s", rpath, strerror( errno ) );
        endmntent( fp );
        return errno;
    }

    /* Stat upper level of mount point, to check if
     * the filesystem is mounted (device  must be different).
     * (dirname modifies string content, so we work on a copy
     * in tmp_buff).
     */
    strcpy( tmp_buff, mntdir );
    parentmntdir = dirname( tmp_buff );

    if ( lstat( parentmntdir, &parentmntstat ) != 0 )
    {
        DisplayLog( LVL_CRIT, "CheckFS",
                    "/!\\ ERROR /!\\ Couldn't stat %s: %s", parentmntdir, strerror( errno ) );
        endmntent( fp );
        return errno;
    }

    /* check that filesystem device is different from root (except if check_mounted is disabled) */
    if ( ( pathstat.st_dev == parentmntstat.st_dev ) && check_mounted )
    {
        DisplayLog( LVL_CRIT, "CheckFS",
                    "/!\\ ERROR /!\\ Filesystem '%s' is not mounted ! dev(%s)=dev(%s)=%#"
                    PRIx64, mntdir, parentmntdir, rpath, (uint64_t)parentmntstat.st_dev );
        endmntent( fp );
        return ENOENT;
    }

#ifdef _HAVE_FID
    if ( save_fs )
    {
        set_mount_point( mntdir );

        ptr = strstr( fs_spec, ":/" );
        if ( ptr != NULL )
        {
            set_fsname( ptr + 2 );
        }
    }
#endif

    /* all checks are OK */

    if ( p_fs_dev != NULL )
        *p_fs_dev = pathstat.st_dev;

    endmntent( fp );
    return 0;

}                               /* CheckFSInfo */
Example #11
0
/* override definition in bionic/stubs.c */
struct mntent *getmntent(FILE *fp)
{
    static struct mntent mnt;
    static char buf[256];
    return getmntent_r(fp, &mnt, buf, 256);
}
Example #12
0
int ow_read_mounts(struct ow_fs *dst, int cap, char *buf, size_t len) {
    int n = 0, r = 0;

    /* keep a pointer to the beginning of the buffer */
    char *head = buf;

    /* find all physical filesystems mounted on the system, and store
     * their type names as a string array embedded in `buf` */
    r = ow__read_physfs(&buf, &len);
    if (r != 0) return -1;

    /* mark the end of our embedded string array */
    char *tail = buf;

    /* now we work our way through `/proc/mounts`, cross-referencing each
     * entry's filesystem type with the embedded array we just compiled */
    FILE *f = setmntent("/proc/mounts", "r");
    if (f == NULL) {
        return -errno;
    }

    struct mntent mnt;

    while (n < cap && getmntent_r(f, &mnt, buf, len) != NULL) {
        /* ignore entries for filesystem types which aren't associated
         * with any physical device */
        const char *type = ow__strarr_find(head, tail, mnt.mnt_type);
        if (type == NULL) {
            continue;
        }

        /* move `mnt.mnt_dir` to the start of the buffer */
        size_t num = strlen(mnt.mnt_dir) + 1;
        memcpy(buf, mnt.mnt_dir, num);

        /* use `stat(2)` to detect the device's major and minor numbers */
        struct stat st;
        if (stat(buf, &st) != 0) {
            r = errno;
            break;
        }

        /* append this filesystem to the list */
        struct ow_fs *fs = &dst[n++];

        fs->device = st.st_dev;
        fs->root   = buf;
        fs->type   = type;

        /* advance our buffer pointer so that subsequent calls to `getmntent_r`
         * won't overwrite the last entry's `root` property, which we keep in
         * the user-provided buffer */
        buf += num;
        len -= num;

        /* update filesystem utilization and I/O stats */
        r = ow__read_fsutil(fs) || ow__read_fsio(fs, buf, len);
        if (r != 0) break;
    }

    if (ferror(f)) {
        r = r || errno;
    }

    endmntent(f);
    return r != 0 ? -r : n;
}
Example #13
0
psi_mountlist_t *
psi_arch_mountlist(const int remote)
{
    FILE *mntent;
    struct mntent mnt;
    char buf[PATH_MAX * 3];     /* size used in autofs so I hope it's okay */
    psi_mountlist_t *ml = NULL;
    psi_mountinfo_t *mounti, **mounts;

    /* Open /etc/mtab */
    mntent = setmntent(_PATH_MOUNTED, "r");
    if (mntent == NULL)
        return (psi_mountlist_t *) PyErr_SetFromErrnoWithFilename(
            PyExc_OSError, _PATH_MOUNTED);

    /* Create our (empty) mountlist */
    ml = (psi_mountlist_t *)psi_calloc(sizeof(psi_mountlist_t));
    if (ml == NULL) {
        fclose(mntent);
        return NULL;
    }

    /* Step through each line in the mount file */
    while (getmntent_r(mntent, &mnt, buf, sizeof(buf)) != NULL) {

        /* Skip remote filesystems if not asked for them */
        if (!remote &&
            (strchr(mnt.mnt_fsname, ':') != NULL ||
             strncmp(mnt.mnt_fsname, "//", 2) == 0))
            continue;

        /* Allocate space for the mount information */
        if ((mounti = psi_calloc(sizeof(psi_mountinfo_t))) == NULL) {
            fclose(mntent);
            psi_free_mountlist(ml);
            return NULL;
        }
        
        /* And then allocate more space for the mount list */
        mounts = (psi_mountinfo_t **)psi_realloc(
            ml->mounts,
            (ml->count + 1) * sizeof(psi_mountinfo_t *));
        if (mounts == NULL) {
            fclose(mntent);
            psi_free_mountinfo(mounti);
            psi_free_mountlist(ml);
            return NULL;
        }
        ml->mounts = mounts;
        ml->mounts[ml->count] = mounti;
        ml->count += 1;

        /* Finally add the information to mounti */
        if (set_mntent(mounti, &mnt) < 0) {
            fclose(mntent);
            psi_free_mountlist(ml);
            return NULL;
        }
        if (posix_set_vfs(mounti) < 0) {
            fclose(mntent);
            psi_free_mountlist(ml);
            return NULL;
        }
    }
    if (!feof(mntent)) {        /* Uh oh, we had a read error */
        endmntent(mntent);
        psi_free_mountlist(ml);
        PyErr_Format(PyExc_OSError, "Read error in %s", _PATH_MOUNTED);
        return NULL;
    }
    endmntent(mntent);
    return ml;
}
Example #14
0
mntent* getmntent(FILE* fp) {
  return getmntent_r(fp, g_getmntent_mntent_tls_buffer.get(),
                     g_getmntent_strings_tls_buffer.get(),
                     g_getmntent_strings_tls_buffer.size());
}
Example #15
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;
}
Example #16
0
static int nilfs_cleaner_find_fs(struct nilfs_cleaner *cleaner,
				 const char *device, const char *mntdir)
{
	struct mntent *mntent, mntbuf;
	char buf[LINE_MAX];
	char canonical[PATH_MAX + 2];
	char *cdev = NULL, *cdir = NULL;
	char *mdir, *mdev;
	char *last_match_dev = NULL, *last_match_dir = NULL;
	pid_t last_match_pid = 0;
	FILE *fp = NULL;
	int ret = -1, nfound = 0;

	if (device && myrealpath(device, canonical, sizeof(canonical))) {
		cdev = strdup(canonical);
		if (!cdev)
			goto error;
		cleaner->device = cdev;
	}

	if (mntdir && myrealpath(mntdir, canonical, sizeof(canonical))) {
		cdir = strdup(canonical);
		if (!cdir)
			goto error;
		cleaner->mountdir = cdir;
	}

	fp = fopen(MTAB, "r");
	if (fp == NULL) {
		nilfs_cleaner_logger(LOG_ERR, _("Error: cannot open " MTAB
						"."));
		goto abort;
	}

	while ((mntent = getmntent_r(fp, &mntbuf, buf, sizeof(buf))) != NULL) {
		if (strcmp(mntent->mnt_type, MNTTYPE_NILFS) != 0)
			continue;

		if (cleaner->mountdir != NULL) {
			mdir = mntent->mnt_dir;
			if (myrealpath(mdir, canonical, sizeof(canonical)))
				mdir = canonical;
			if (strcmp(mdir, cleaner->mountdir) != 0)
				continue;
		}
			
		if (cleaner->device != NULL) {
			mdev = mntent->mnt_fsname;
			if (myrealpath(mdev, canonical, sizeof(canonical)))
				mdev = canonical;
			if (strcmp(mdev, cleaner->device) != 0)
				continue;
		}

		if (hasmntopt(mntent, MNTOPT_RW)) {
			/* we found a candidate */
			nfound++;

			if (cleaner->device == NULL) {
				mdev = mntent->mnt_fsname;
				if (myrealpath(mdev, canonical,
					       sizeof(canonical))) {
					mdev = canonical;
				}
				if (last_match_dev)
					free(last_match_dev);
				last_match_dev = strdup(mdev);
				if (!last_match_dev)
					goto error;
			}
			if (cleaner->mountdir == NULL) {
				mdir = mntent->mnt_dir;
				if (myrealpath(mdir, canonical,
					       sizeof(canonical))) {
					mdir = canonical;
				}
				if (last_match_dir)
					free(last_match_dir);
				last_match_dir = strdup(mdir);
				if (!last_match_dir)
					goto error;
			}
			last_match_pid = 0;
			ret = nilfs_find_gcpid_opt(mntent->mnt_opts,
						   &last_match_pid);
			if (ret < 0)
				goto error;
		}
	}
	if (nfound == 0) {
		nilfs_cleaner_logger(LOG_ERR,
				     _("Error: no valid nilfs mountpoint "
				       "found."));
		goto abort;
	}
	if (last_match_dir)
		cleaner->mountdir = last_match_dir;
	if (last_match_dev)
		cleaner->device = last_match_dev;
	if (last_match_pid)
		cleaner->cleanerd_pid = last_match_pid;

	endmntent(fp);
	return 0;
error:
	nilfs_cleaner_logger(LOG_ERR,  _("Error: failed to find fs: %s."),
			     strerror(errno));
abort:
	free(last_match_dir); /* free(NULL) is just ignored */
	free(last_match_dev);
	if (fp)
		endmntent(fp);
	return -1;
}
Example #17
0
int partition_probe_main(probe_ctx *ctx, void *probe_arg)
{
        int probe_ret = 0;
        SEXP_t *mnt_entity, *mnt_opval, *mnt_entval, *probe_in;
        char    mnt_path[PATH_MAX];
        oval_operation_t mnt_op;
        FILE *mnt_fp;
        oval_schema_version_t obj_over;
#if defined(PROC_CHECK) && defined(__linux__)
        int   mnt_fd;
        struct statfs stfs;

        mnt_fd = open(MTAB_PATH, O_RDONLY);

        if (mnt_fd < 0)
                return (PROBE_ESYSTEM);

        if (fstatfs(mnt_fd, &stfs) != 0) {
                close(mnt_fd);
                return (PROBE_ESYSTEM);
        }

        if (stfs.f_type != PROC_SUPER_MAGIC) {
                close(mnt_fd);
                return (PROBE_EFATAL);
        }

        mnt_fp = fdopen(mnt_fd, "r");

        if (mnt_fp == NULL) {
                close(mnt_fd);
                return (PROBE_ESYSTEM);
        }
#else
        mnt_fp = fopen(MTAB_PATH, "r");

        if (mnt_fp == NULL)
                return (PROBE_ESYSTEM);
#endif
        probe_in   = probe_ctx_getobject(ctx);
        obj_over   = probe_obj_get_platform_schema_version(probe_in);
        mnt_entity = probe_obj_getent(probe_in, "mount_point", 1);

        if (mnt_entity == NULL) {
                fclose(mnt_fp);
                return (PROBE_ENOENT);
        }

        mnt_opval = probe_ent_getattrval(mnt_entity, "operation");

        if (mnt_opval != NULL) {
                mnt_op = (oval_operation_t)SEXP_number_geti(mnt_opval);
                SEXP_free(mnt_opval);
        } else
                mnt_op = OVAL_OPERATION_EQUALS;

        mnt_entval = probe_ent_getval(mnt_entity);

        if (!SEXP_stringp(mnt_entval)) {
                SEXP_free(mnt_entval);
                SEXP_free(mnt_entity);
		fclose(mnt_fp);
                return (PROBE_EINVAL);
        }

        SEXP_string_cstr_r(mnt_entval, mnt_path, sizeof mnt_path);
        SEXP_free(mnt_entval);
        SEXP_free(mnt_entity);

        if (mnt_fp != NULL) {
                char buffer[MTAB_LINE_MAX];
                struct mntent mnt_ent, *mnt_entp;

                pcre *re = NULL;
                const char *estr = NULL;
                int eoff = -1;
#if defined(HAVE_BLKID_GET_TAG_VALUE)
                blkid_cache blkcache;

                if (blkid_get_cache(&blkcache, NULL) != 0) {
                        endmntent(mnt_fp);
                        return (PROBE_EUNKNOWN);
                }
#endif
                if (mnt_op == OVAL_OPERATION_PATTERN_MATCH) {
                        re = pcre_compile(mnt_path, PCRE_UTF8, &estr, &eoff, NULL);

                        if (re == NULL) {
                                endmntent(mnt_fp);
                                return (PROBE_EINVAL);
                        }
                }

                while ((mnt_entp = getmntent_r(mnt_fp, &mnt_ent,
                                               buffer, sizeof buffer)) != NULL)
                {
			if (strcmp(mnt_entp->mnt_type, "rootfs") == 0)
			    continue;

                        if (mnt_op == OVAL_OPERATION_EQUALS) {
                                if (strcmp(mnt_entp->mnt_dir, mnt_path) == 0) {
#if defined(HAVE_BLKID_GET_TAG_VALUE)
	                                collect_item(ctx, obj_over, mnt_entp, blkcache);
#else
	                                collect_item(ctx, obj_over, mnt_entp);
#endif
                                        break;
                                }
			} else if (mnt_op == OVAL_OPERATION_NOT_EQUAL) {
				if (strcmp(mnt_entp->mnt_dir, mnt_path) != 0) {
					if (
#if defined(HAVE_BLKID_GET_TAG_VALUE)
						collect_item(ctx, obj_over, mnt_entp, blkcache)
#else
						collect_item(ctx, obj_over, mnt_entp)
#endif
					!= 0)
						break;
                                }
                        } else if (mnt_op == OVAL_OPERATION_PATTERN_MATCH) {
                                int rc;

                                rc = pcre_exec(re, NULL, mnt_entp->mnt_dir,
                                               strlen(mnt_entp->mnt_dir), 0, 0, NULL, 0);

                                if (rc == 0) {
	                                if (
#if defined(HAVE_BLKID_GET_TAG_VALUE)
		                                collect_item(ctx, obj_over, mnt_entp, blkcache)
#else
		                                collect_item(ctx, obj_over, mnt_entp)
#endif
                                        != 0)
		                                break;
                                }
                                /* XXX: check for pcre_exec error */
                        }
                }

                endmntent(mnt_fp);

                if (mnt_op == OVAL_OPERATION_PATTERN_MATCH)
                        pcre_free(re);
        }

        return (probe_ret);
}
Example #18
0
extern int umount_main(int argc, char **argv)
{
	int doForce;
	char path[2*PATH_MAX];
	struct mntent me;
	FILE *fp;
	int status=EXIT_SUCCESS;
	unsigned long opt;
	struct mtab_list {
		char *dir;
		char *device;
		struct mtab_list *next;
	} *mtl, *m;

	/* Parse any options */

	opt = bb_getopt_ulflags (argc, argv, OPTION_STRING);

	argc -= optind;
	argv += optind;

	doForce = MAX((opt & OPT_FORCE), (opt & OPT_LAZY));

	/* Get a list of mount points from mtab.  We read them all in now mostly
	 * for umount -a (so we don't have to worry about the list changing while
	 * we iterate over it, or about getting stuck in a loop on the same failing
	 * entry.  Notice that this also naturally reverses the list so that -a
	 * umounts the most recent entries first. */

	m=mtl=0;
	if(!(fp = setmntent(bb_path_mtab_file, "r")))
		bb_error_msg_and_die("Cannot open %s", bb_path_mtab_file);
	while (getmntent_r(fp,&me,path,sizeof(path))) {
		m=xmalloc(sizeof(struct mtab_list));
		m->next=mtl;
		m->device=bb_xstrdup(me.mnt_fsname);
		m->dir=bb_xstrdup(me.mnt_dir);
		mtl=m;
	}
	endmntent(fp);

	/* If we're umounting all, then m points to the start of the list and
	 * the argument list should be empty (which will match all). */
	if(!(opt & OPT_ALL)) {
		m=0;
		if(argc <= 0) bb_show_usage();
	}

	// Loop through everything we're supposed to umount, and do so.
	for(;;) {
		int curstat;

		// Do we already know what to umount this time through the loop?
		if(m) safe_strncpy(path,m->dir,PATH_MAX);
		// For umount -a, end of mtab means time to exit.
		else if(opt & OPT_ALL) break;
		// Get next command line argument (and look it up in mtab list)
		else if(!argc--) break;
		else {
			// Get next command line argument (and look it up in mtab list)
			realpath(*argv++, path);
			for(m = mtl; m; m = m->next)
				if(!strcmp(path, m->dir) || !strcmp(path, m->device))
					break;
		}

		// Let's ask the thing nicely to unmount.
		curstat = umount(path);

		// Force the unmount, if necessary.
		if(curstat && doForce) {
			curstat = umount2(path, doForce);
			if(curstat)
				bb_error_msg_and_die("forced umount of %s failed!", path);
		}

		// If still can't umount, maybe remount read-only?
		if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) {
			curstat = mount(m->device, path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
			bb_error_msg(curstat ? "Cannot remount %s read-only" :
						 "%s busy - remounted read-only", m->device);
		}

		/* De-allocate the loop device.  This ioctl should be ignored on any
		 * non-loop block devices. */
		if(ENABLE_FEATURE_MOUNT_LOOP && !(opt & OPT_DONTFREELOOP) && m)
			del_loop(m->device);

		if(curstat) {
			/* Yes, the ENABLE is redundant here, but the optimizer for ARM
			 * can't do simple constant propagation in local variables... */
			if(ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m)
				erase_mtab(m->dir);
			status = EXIT_FAILURE;
			bb_perror_msg("Couldn't umount %s", path);
		}
		// Find next matching mtab entry for -a or umount /dev
		while(m && (m = m->next))
			if((opt & OPT_ALL) || !strcmp(path,m->device))
				break;
	}

	// Free mtab list if necessary

	if(ENABLE_FEATURE_CLEAN_UP) {
		while(mtl) {
			m=mtl->next;
			free(mtl->device);
			free(mtl->dir);
			free(mtl);
			mtl=m;
		}
	}

	return status;
}
Example #19
0
int
main (int argc, char *argv[])
{
	get_options (argc, argv);

	struct statfs fsbuf;
	float disktotal, diskfree, diskused;
	int diskpercent;

	if (statfs (mountpath, &fsbuf) < 0) exit (2);

	float mbratio = ((float)fsbuf.f_bsize) / 1048576.0;

	disktotal	= (fsbuf.f_blocks * mbratio) / 1024.0;
	diskfree	= (fsbuf.f_bfree * mbratio) / 1024.0;
	diskused	= disktotal - diskfree;

	diskpercent = (100 * (fsbuf.f_blocks - fsbuf.f_bfree)) / fsbuf.f_blocks;

	/* For hddtemp, the mount path needs to be looked up in a mount table to find
	 * the corresponding device. To speed things up when the monitor is run again, the
	 * device path is available from the cache. Repeated mount table scans avoided.
	 */
	struct stat mountstat;

	if (stat (mountpath, &mountstat) < 0) exit (3);

	char cachepath[256], cachedisk[256], buffer[256], mntbuffer[256];
	float maxdisktemp = 0.0, disktemp = 0.0;
	int cacheupdate = 0, ret;
	struct mntent mountent;
	char *diskpath = NULL;
	FILE *file;

	sprintf (cachepath, "/dev/shm/diskinfo.%d.%d.%d",
		major (mountstat.st_dev), minor (mountstat.st_dev), getuid ());

	/* If the cache exists, read it instead of scanning the mount table. The device
	 * path is added to the cache the first time the monitor is run. If the cache does
	 * not yet exist, then need to scan a mount table to find the device path.
	 */
	if ((file = fopen (cachepath, "r")))
	{
		char cachemount[256];

		fgets (buffer, 256, file);
		ret = sscanf (buffer, "%s %s %f", cachemount, cachedisk, &maxdisktemp);
		assert (ret == 3);
		fclose (file);

		assert (strcmp (mountpath, cachemount) == 0);
		diskpath = cachedisk;
	}
	else	/* Scan a mount table to get the device path */
	{
		struct stat mntstat;

		file = setmntent ("/proc/mounts", "r");
		assert (file != NULL);

		while (getmntent_r (file, &mountent, mntbuffer, 256))
		{
			if (stat (mountent.mnt_dir, &mntstat)) continue;
			
			/* NB: Will looking for an entry beginning with slash always work? */
			if (mountstat.st_dev == mntstat.st_dev && mountent.mnt_fsname[0] == '/')
			{
				diskpath = mountent.mnt_fsname;
				break;
			}
		}

		endmntent (file);
		cacheupdate = 1;
	}
	assert (diskpath != NULL);

	/* Get the current temperature of the disk. Use hddtemp for this because is has a
	 * reference database for most HDDs.  Might be quicker to consult the daemonized version
	 * of hddtemp, will debate that idea for a future modification to this program. However,
	 * because this program is intended to be run only infrequently say every 30 seconds there
	 * is not all that much overhead in piping input from hddtemp. And there are minimal
	 * processes that need to be left running all the time when using a pipe.
	 */
	char hddtemp[256], *ID = NULL;
	sprintf (hddtemp, "/usr/sbin/hddtemp %s", diskpath);
	
	if ((file = popen (hddtemp, "r")))
	{
		char *temp;

		fgets (buffer, 256, file);
		pclose (file);

		temp = strstr((ID = strstr(buffer, ": ") + 2), ": ") + 2;
		*(temp - 2) = temp[strlen (temp) - 1] = '\0';
		disktemp = atof (temp);

		if (disktemp > maxdisktemp)
		{
			maxdisktemp = disktemp;
			cacheupdate = 1;
		}
	}
	assert (ID != NULL);

	/* Create a new cache or update the cache if there is new maximum disk
	 * temperature. Avoid unnecessary cache writes.
	 */
	if (cacheupdate)
		if ((file = fopen (cachepath, "w")))
		{
			fprintf (file, "%s %s %f\n", mountpath, diskpath, maxdisktemp);
			fclose (file);
		}

	/* Recalculate temperatures as farenheit */
	char CF = 'C';
	if (showfarenheit)
	{
		CF = 'F';
		disktemp = (disktemp * 1.8) + 32.0;
		maxdisktemp = (maxdisktemp * 1.8) + 32.0;
	}

	/** XFCE GENMON XML **/

	/* Icon */
	printf ("<img>%s</img>\n", iconfile);

	/* Text */
	printf ("<txt>%sG\n%d°%c</txt>\n", du(diskused), (int)disktemp, CF);

	/* Tool tip */
	printf ("<tool>ID: %s\n", ID);
	printf ("Mount: %s  Device: %s\n", mountpath, diskpath);

	printf ("Total: %.2fG  Available: %.2fG  Used: %.2fG (%d%%)\n",
		disktotal, diskfree, diskused, diskpercent);

	printf ("Maximum temperature observed: %d°%c</tool>\n", (int)maxdisktemp, CF);

	/* Percent bar */
	if (showbar) printf ("<bar>%d</bar>\n", diskpercent);

	return 0;
}
Example #20
0
struct mntent *getmntent(FILE * fp)
{
	static struct mntent me;
	return getmntent_r(fp, &me, mntbuf, _MAX_MNTLEN);
}
Example #21
0
static int pgfuse_statfs( const char *path, struct statvfs *buf )
{
	PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
	PGconn *conn;
	int64_t blocks_total, blocks_used, blocks_free, blocks_avail;
	int64_t files_total, files_used, files_free, files_avail;
	int res;
	int i;
	size_t nof_locations = MAX_TABLESPACE_OIDS;
	char *location[MAX_TABLESPACE_OIDS];
	FILE *mtab;
	struct mntent *m;
	struct mntent mnt;
	char strings[MTAB_BUFFER_SIZE];
	char *prefix;
	int prefix_len;

	if( data->verbose ) {
		syslog( LOG_INFO, "Statfs called on '%s', thread #%u",
			data->mountpoint, THREAD_ID );
	}
		
	memset( buf, 0, sizeof( struct statvfs ) );
	
	ACQUIRE( conn );
        PSQL_BEGIN( conn );

	/* blocks */

	res = psql_get_tablespace_locations( conn, location, &nof_locations, data->verbose );
	if( res < 0 ) {
		PSQL_ROLLBACK( conn ); RELEASE( conn );
		return res;
	}

	/* transform them and especially resolve symlinks */
	for( i = 0; i < nof_locations; i++ ) {
		char *old_path = location[i];
		char *new_path = realpath( old_path, NULL );
		if( new_path == NULL ) {
			/* do nothing, most likely a permission problem */
			syslog( LOG_ERR, "realpath for '%s' failed: %s,  pgfuse mount point '%s', thread #%u",
				old_path, strerror( errno ), data->mountpoint, THREAD_ID );
		} else {
			location[i] = new_path;
			free( old_path );
		}
	}
	
	blocks_free = INT64_MAX;
	blocks_avail = INT64_MAX;
	
	/* iterate over mount entries and try to match to the tablespace locations */
	mtab = setmntent( MTAB_FILE, "r" );
	while( ( m = getmntent_r( mtab, &mnt, strings, sizeof( strings ) ) ) != NULL ) {
		struct statfs fs;
		
		/* skip filesystems without mount point */
		if( mnt.mnt_dir == NULL ) continue;
		
		/* skip filesystems which are not a prefix of one of the tablespace locations */
		prefix = NULL;
		prefix_len = 0;
		for( i = 0; i < nof_locations; i++ ) {
			if( strncmp( mnt.mnt_dir, location[i], strlen( mnt.mnt_dir ) ) == 0 ) {
				if( strlen( mnt.mnt_dir ) > prefix_len ) {
					prefix_len = strlen( mnt.mnt_dir );
					prefix = strdup( mnt.mnt_dir );
					blocks_free = INT64_MAX;
					blocks_avail = INT64_MAX;
				}
			}
		}
		if( prefix == NULL ) continue;
		
		/* get data of file system */
		res = statfs( prefix, &fs );
		if( res < 0 ) {
			syslog( LOG_ERR, "statfs on '%s' failed: %s,  pgfuse mount point '%s', thread #%u",
				prefix,	strerror( errno ), data->mountpoint, THREAD_ID );
			return res;
		}

		if( data->verbose ) {
			syslog( LOG_DEBUG, "Checking mount point '%s' for free disk space, now %jd, was %jd, pgfuse mount point '%s', thread #%u",
				prefix,	fs.f_bfree, blocks_free, data->mountpoint, THREAD_ID );
		}

		/* take the smallest available disk space free (worst case the first one
		 * to overflow one of the tablespaces)
		 */
		if( fs.f_bfree * fs.f_frsize < blocks_free * data->block_size ) {
			blocks_free = fs.f_bfree * fs.f_frsize / data->block_size;
		}
		if( fs.f_bavail * fs.f_frsize < blocks_avail * data->block_size ) {
			blocks_avail = fs.f_bavail * fs.f_frsize / data->block_size;
		}
				
		if( prefix ) free( prefix );
	}
	endmntent( mtab );
	
	for( i = 0; i < nof_locations; i++ ) {
		if( location[i] ) free( location[i] );
	}
			
	blocks_used = psql_get_fs_blocks_used( conn );	
	if( blocks_used < 0 ) {
                PSQL_ROLLBACK( conn ); RELEASE( conn );
		return blocks_used;
	}
            
	blocks_total = blocks_avail + blocks_used;
	blocks_free = blocks_avail;
	
	/* inodes */

	/* no restriction on the number of files storable, we could
	   add some limits later */
	files_total = INT64_MAX;
	
	files_used = psql_get_fs_files_used( conn );
	if( files_used < 0 ) {
                PSQL_ROLLBACK( conn ); RELEASE( conn );
		return files_used;
	}
	
	files_free = files_total - files_used;
	files_avail = files_free;

	if( data->verbose ) {
		syslog( LOG_DEBUG, "Stats for '%s' are (%jd blocks total, %jd used, %jd free, "
			"%"PRId64" inodes total, %"PRId64" inodes used, %"PRId64" inodes free, thread #%u",
			data->mountpoint, 
			blocks_total, blocks_used, blocks_free,
			files_total, files_used, files_free,
			THREAD_ID );
	}
	
	/* fill statfs structure */
	
	/* Note: blocks have to be retrning as units of f_frsize
	 * f_favail, f_fsid and f_flag are currently ignored by FUSE ? */
	buf->f_bsize = data->block_size;
	buf->f_frsize = data->block_size;
	buf->f_blocks = blocks_total;
	buf->f_bfree = blocks_free;
	buf->f_bavail = blocks_avail;
	buf->f_files = files_total;
	buf->f_ffree = files_free;
	buf->f_favail = files_avail;
	buf->f_fsid =  0x4FE3A364;
	if( data->read_only ) {
		buf->f_flag |= ST_RDONLY;
	}
	buf->f_namemax = MAX_FILENAME_LENGTH;

	PSQL_COMMIT( conn ); RELEASE( conn );
	
	return 0;
}
struct mntent *getmntent(FILE *f)
{
	static char linebuf[256];
	static struct mntent mnt;
	return getmntent_r(f, &mnt, linebuf, sizeof linebuf);
}
Example #23
0
RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType)
{
    *penmType = RTFSTYPE_UNKNOWN;

    /*
     * Validate input.
     */
    AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
    AssertReturn(*pszFsPath, VERR_INVALID_PARAMETER);

    /*
     * Convert the path and query the stats.
     * We're simply return the device id.
     */
    char const *pszNativeFsPath;
    int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL);
    if (RT_SUCCESS(rc))
    {
        struct stat Stat;
        if (!stat(pszNativeFsPath, &Stat))
        {
#if defined(RT_OS_LINUX)
            FILE *mounted = setmntent("/proc/mounts", "r");
            if (!mounted)
                mounted = setmntent("/etc/mtab", "r");
            if (mounted)
            {
                char            szBuf[1024];
                struct stat     mntStat;
                struct mntent   mntEnt;
                while (getmntent_r(mounted, &mntEnt, szBuf, sizeof(szBuf)))
                {
                    if (!stat(mntEnt.mnt_dir, &mntStat))
                    {
                        if (mntStat.st_dev == Stat.st_dev)
                        {
                            if (!strcmp("ext4", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT4;
                            else if (!strcmp("ext3", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT3;
                            else if (!strcmp("ext2", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT2;
                            else if (!strcmp("jfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_JFS;
                            else if (!strcmp("xfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_XFS;
                            else if (   !strcmp("vfat", mntEnt.mnt_type)
                                     || !strcmp("msdos", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_FAT;
                            else if (!strcmp("ntfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NTFS;
                            else if (!strcmp("hpfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_HPFS;
                            else if (!strcmp("ufs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_UFS;
                            else if (!strcmp("tmpfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_TMPFS;
                            else if (!strcmp("hfsplus", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_HFS;
                            else if (!strcmp("udf", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_UDF;
                            else if (!strcmp("iso9660", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_ISO9660;
                            else if (!strcmp("smbfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_SMBFS;
                            else if (!strcmp("cifs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_CIFS;
                            else if (!strcmp("nfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NFS;
                            else if (!strcmp("nfs4", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NFS;
                            else if (!strcmp("sysfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_SYSFS;
                            else if (!strcmp("proc", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_PROC;
                            else if (   !strcmp("fuse", mntEnt.mnt_type)
                                     || !strncmp("fuse.", mntEnt.mnt_type, 5)
                                     || !strcmp("fuseblk", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_FUSE;
                            else
                            {
                                /* sometimes there are more than one entry for the same partition */
                                continue;
                            }
                            break;
                        }
                    }
                }
                endmntent(mounted);
            }

#elif defined(RT_OS_SOLARIS)
            if (!strcmp("zfs", Stat.st_fstype))
                *penmType = RTFSTYPE_ZFS;
            else if (!strcmp("ufs", Stat.st_fstype))
                *penmType = RTFSTYPE_UFS;
            else if (!strcmp("nfs", Stat.st_fstype))
                *penmType = RTFSTYPE_NFS;

#elif defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
            struct statfs statfsBuf;
            if (!statfs(pszNativeFsPath, &statfsBuf))
            {
                if (!strcmp("hfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_HFS;
                else if (   !strcmp("fat", statfsBuf.f_fstypename)
                         || !strcmp("msdos", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_FAT;
                else if (!strcmp("ntfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_NTFS;
                else if (!strcmp("autofs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_AUTOFS;
                else if (!strcmp("devfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_DEVFS;
                else if (!strcmp("nfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_NFS;
                else if (!strcmp("ufs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_UFS;
                else if (!strcmp("zfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_ZFS;
            }
            else
                rc = RTErrConvertFromErrno(errno);
#endif
        }
        else
            rc = RTErrConvertFromErrno(errno);
        rtPathFreeNative(pszNativeFsPath, pszFsPath);
    }

    return rc;
}
Example #24
0
static int
statfs_mock(const char *mtab,
            const char *path,
            struct statfs *buf)
{
    FILE *f;
    struct mntent mb;
    char mntbuf[1024];
    char *canonPath = NULL;
    int ret = -1;

    if (!(f = real_setmntent(mtab, "r"))) {
        fprintf(stderr, "Unable to open %s", mtab);
        return -1;
    }

    /* We don't need to do this in callers because real statfs(2)
     * does that for us. However, in mocked implementation we
     * need to do this. */
    if (!(canonPath = canonicalize_file_name(path)))
        return -1;

    while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
        int ftype;

        if (STRNEQ(mb.mnt_dir, canonPath))
            continue;

        if (STREQ(mb.mnt_type, "nfs") ||
            STREQ(mb.mnt_type, "nfs4")) {
            ftype = NFS_SUPER_MAGIC;
        } else if (STREQ(mb.mnt_type, "gfs2")||
                   STREQ(mb.mnt_type, "gfs2meta")) {
            ftype = GFS2_MAGIC;
        } else if (STREQ(mb.mnt_type, "ocfs2")) {
            ftype = OCFS2_SUPER_MAGIC;
        } else if (STREQ(mb.mnt_type, "afs")) {
            ftype = AFS_FS_MAGIC;
        } else if (STREQ(mb.mnt_type, "smb3")) {
            ftype = SMB_SUPER_MAGIC;
        } else if (STREQ(mb.mnt_type, "cifs")) {
            ftype = CIFS_SUPER_MAGIC;
        } else if (STRPREFIX(mb.mnt_type, "fuse")) {
            ftype = FUSE_SUPER_MAGIC;
        } else if (STRPREFIX(mb.mnt_type, "ceph")) {
            ftype = CEPH_SUPER_MAGIC;
        } else if (STRPREFIX(mb.mnt_type, "gpfs")) {
            ftype = GPFS_SUPER_MAGIC;
        } else {
            /* Everything else is EXT4. We don't care really for other paths. */
            ftype = EXT4_SUPER_MAGIC;
        }

        memset(buf, 0, sizeof(*buf));
        /* We only care about f_type so far. */
        buf->f_type = ftype;
        ret = 0;
        break;
    }

    endmntent(f);
    VIR_FREE(canonPath);
    return ret;
}