[PATCH v3 0/7] add support to resize MBR logical partitions
by Hu Tao
Hi Rich,
This is v3 series to add support for resizing MBR logical partitions.
changes to v2:
1. remove p_part_num
2. remove filter_parts
3. name the function calculate_target_partitions
4. remove the code to restart guest introduced in v2
changes to v1:
1. spit the patches so it's easier to review
2. fix the parted error caused by unaligned logical partitions
3. extend the content of logical partitions
4. refactor to make logical partitions a seperate list
Hu Tao (7):
resize: introduce partition_type
resize: simplify the code to filter parts
resize: add function find_partitions
resize: add function calculate_target_partitions
resize: add function mbr_part_type
resize: add partition type LogicalPartition
resize: add support to resize logical partitions
resize/resize.ml | 145 +++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 110 insertions(+), 35 deletions(-)
--
1.9.3
10 years, 2 months
[PATCH] inspect: basic Minix support
by Pino Toscano
Add a basic support for identifying Minix, extracting its version and
hostname.
Related to RHBZ#1144137.
---
src/guestfs-internal.h | 2 ++
src/inspect-apps.c | 1 +
src/inspect-fs-unix.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++
src/inspect-fs.c | 11 ++++++++++
src/inspect-icon.c | 1 +
src/inspect.c | 1 +
6 files changed, 73 insertions(+)
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 69ea2dc..fd0c4a1 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -513,6 +513,7 @@ enum inspect_os_type {
OS_TYPE_HURD,
OS_TYPE_DOS,
OS_TYPE_OPENBSD,
+ OS_TYPE_MINIX,
};
enum inspect_os_distro {
@@ -758,6 +759,7 @@ extern int guestfs___check_linux_root (guestfs_h *g, struct inspect_fs *fs);
extern int guestfs___check_freebsd_root (guestfs_h *g, struct inspect_fs *fs);
extern int guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs);
extern int guestfs___check_hurd_root (guestfs_h *g, struct inspect_fs *fs);
+extern int guestfs___check_minix_root (guestfs_h *g, struct inspect_fs *fs);
/* inspect-fs-windows.c */
extern char *guestfs___case_sensitive_path_silently (guestfs_h *g, const char *);
diff --git a/src/inspect-apps.c b/src/inspect-apps.c
index c199238..a77e9ce 100644
--- a/src/inspect-apps.c
+++ b/src/inspect-apps.c
@@ -157,6 +157,7 @@ guestfs__inspect_list_applications2 (guestfs_h *g, const char *root)
break;
case OS_TYPE_FREEBSD:
+ case OS_TYPE_MINIX:
case OS_TYPE_NETBSD:
case OS_TYPE_DOS:
case OS_TYPE_OPENBSD:
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
index 89236ab..3f57cd5 100644
--- a/src/inspect-fs-unix.c
+++ b/src/inspect-fs-unix.c
@@ -77,6 +77,7 @@ static pcre *re_nld;
static pcre *re_opensuse_version;
static pcre *re_sles_version;
static pcre *re_sles_patchlevel;
+static pcre *re_minix;
static void compile_regexps (void) __attribute__((constructor));
static void free_regexps (void) __attribute__((destructor));
@@ -135,6 +136,7 @@ compile_regexps (void)
COMPILE (re_opensuse_version, "^VERSION = (\\d+)\\.(\\d+)", 0);
COMPILE (re_sles_version, "^VERSION = (\\d+)", 0);
COMPILE (re_sles_patchlevel, "^PATCHLEVEL = (\\d+)", 0);
+ COMPILE (re_minix, "^(\\d+)\\.(\\d+)(\\.(\\d+))?", 0);
}
static void
@@ -167,6 +169,7 @@ free_regexps (void)
pcre_free (re_opensuse_version);
pcre_free (re_sles_version);
pcre_free (re_sles_patchlevel);
+ pcre_free (re_minix);
}
static void check_architecture (guestfs_h *g, struct inspect_fs *fs);
@@ -782,6 +785,48 @@ guestfs___check_hurd_root (guestfs_h *g, struct inspect_fs *fs)
return 0;
}
+/* The currently mounted device is maybe to be a Minix root. */
+int
+guestfs___check_minix_root (guestfs_h *g, struct inspect_fs *fs)
+{
+ fs->type = OS_TYPE_MINIX;
+
+ if (guestfs_is_file_opts (g, "/etc/version",
+ GUESTFS_IS_FILE_OPTS_FOLLOWSYMLINKS, 1, -1) > 0) {
+ char *major, *minor;
+ if (parse_release_file (g, fs, "/etc/version") == -1)
+ return -1;
+
+ if (match2 (g, fs->product_name, re_minix, &major, &minor)) {
+ fs->major_version = guestfs___parse_unsigned_int (g, major);
+ free (major);
+ if (fs->major_version == -1) {
+ free (minor);
+ return -1;
+ }
+ fs->minor_version = guestfs___parse_unsigned_int (g, minor);
+ free (minor);
+ if (fs->minor_version == -1)
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+
+ /* Determine the architecture. */
+ check_architecture (g, fs);
+
+ /* TODO: enable fstab inspection once resolve_fstab_device implements
+ * the proper mapping from the Minix device names to the appliance names
+ */
+
+ /* Determine hostname. */
+ if (check_hostname_unix (g, fs) == -1)
+ return -1;
+
+ return 0;
+}
+
static void
check_architecture (guestfs_h *g, struct inspect_fs *fs)
{
@@ -863,6 +908,18 @@ check_hostname_unix (guestfs_h *g, struct inspect_fs *fs)
}
break;
+ case OS_TYPE_MINIX:
+ if (guestfs_is_file (g, "/etc/hostname.file")) {
+ fs->hostname = guestfs___first_line_of_file (g, "/etc/hostname.file");
+ if (fs->hostname == NULL)
+ return -1;
+ if (STREQ (fs->hostname, "")) {
+ free (fs->hostname);
+ fs->hostname = NULL;
+ }
+ }
+ break;
+
case OS_TYPE_WINDOWS: /* not here, see check_windows_system_registry */
case OS_TYPE_DOS:
case OS_TYPE_OPENBSD:
diff --git a/src/inspect-fs.c b/src/inspect-fs.c
index 21d2a23..539d814 100644
--- a/src/inspect-fs.c
+++ b/src/inspect-fs.c
@@ -247,6 +247,17 @@ check_filesystem (guestfs_h *g, const char *mountable,
if (guestfs___check_hurd_root (g, fs) == -1)
return -1;
}
+ /* Minix root? */
+ else if (is_dir_etc &&
+ is_dir_bin &&
+ guestfs_is_file (g, "/service/vm") > 0 &&
+ guestfs_is_file (g, "/etc/fstab") > 0 &&
+ guestfs_is_file (g, "/etc/version") > 0) {
+ fs->is_root = 1;
+ fs->format = OS_FORMAT_INSTALLED;
+ if (guestfs___check_minix_root (g, fs) == -1)
+ return -1;
+ }
/* Linux root? */
else if (is_dir_etc &&
(is_dir_bin ||
diff --git a/src/inspect-icon.c b/src/inspect-icon.c
index 94b63a2..0ffca72 100644
--- a/src/inspect-icon.c
+++ b/src/inspect-icon.c
@@ -197,6 +197,7 @@ guestfs__inspect_get_icon (guestfs_h *g, const char *root, size_t *size_r,
case OS_TYPE_NETBSD:
case OS_TYPE_DOS:
case OS_TYPE_OPENBSD:
+ case OS_TYPE_MINIX:
case OS_TYPE_UNKNOWN:
; /* nothing */
}
diff --git a/src/inspect.c b/src/inspect.c
index 1a9554e..9248b06 100644
--- a/src/inspect.c
+++ b/src/inspect.c
@@ -118,6 +118,7 @@ guestfs__inspect_get_type (guestfs_h *g, const char *root)
case OS_TYPE_FREEBSD: ret = safe_strdup (g, "freebsd"); break;
case OS_TYPE_HURD: ret = safe_strdup (g, "hurd"); break;
case OS_TYPE_LINUX: ret = safe_strdup (g, "linux"); break;
+ case OS_TYPE_MINIX: ret = safe_strdup (g, "minix"); break;
case OS_TYPE_NETBSD: ret = safe_strdup (g, "netbsd"); break;
case OS_TYPE_OPENBSD: ret = safe_strdup (g, "openbsd"); break;
case OS_TYPE_WINDOWS: ret = safe_strdup (g, "windows"); break;
--
1.9.3
10 years, 2 months
Possible bug in preview version of virt-v2v
by Jeff Forbes
Hi,
I have been testing:
virt-v2v preview packages for RHEL and CentOS 7.1<http://rwmj.wordpress.com/2014/09/17/virt-v2v-preview-packages-for-rhel-a...>
and have been able to almost get it to work. There seems to be a bug where the software tries to mount a disk partition as /sysroot. An attempt is made to make /dev/sda2 as sysroot; however, the root partition is an LVM partition (/dev/mapper/centos-root). An error is given when an attempt is made to cop the virtio drivers to the VM: (a snippet of the verbose debug log)
cp /sysroot/usr/share/virtio-win/drivers/amd64/Win2012R2/viostor.sys /sysroot/Wi
ndows/System32/drivers/viostor.sys
cp: cannot stat '/sysroot/usr/share/virtio-win/drivers/amd64/Win2012R2/viostor.s
ys': No such file or directory
guestfsd: error: cp: cannot stat '/sysroot/usr/share/virtio-win/drivers/amd64/Wi
n2012R2/viostor.sys': No such file or directory
guestfsd: main_loop: proc 87 (cp) took 0.06 seconds
libguestfs: trace: cp = -1 (error)
libguestfs: trace: hivex_close
guestfsd: main_loop: new request, len 0x28
hivex: hivex_close: hivex_close
libguestfs: trace: hivex_close = 0
virt-v2v: error: libguestfs error: cp: cp: cannot stat
'/sysroot/usr/share/virtio-win/drivers/amd64/Win2012R2/viostor.sys': No
such file or directory
I have attached the entire output of the verbose debugging log.
Jeff
10 years, 2 months
[PATCH] New APIs: Implement stat calls that return nanosecond timestamps (RHBZ#1144891).
by Richard W.M. Jones
The existing APIs guestfs_stat, guestfs_lstat and guestfs_lstatlist
return a stat structure that contains atime, mtime and ctime fields
that store only the timestamp in seconds.
Modern filesystems can store timestamps down to nanosecond
granularity, and the ordinary glibc stat(2) wrapper will return these
in "hidden" stat fields:
struct timespec st_atim; /* Time of last access. */
struct timespec st_mtim; /* Time of last modification. */
struct timespec st_ctim; /* Time of last status change. */
with the following macros defined for backwards compatibility:
#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec
It is not possible to redefine guestfs_stat to return a longer struct
guestfs_stat with room for the extra nanosecond fields, because that
would break the ABI of guestfs_lstatlist as it returns an array
containing consecutive stat structs (not pointers). Changing the
return type of guestfs_stat would break API. Changing the generator
to support symbol versioning is judged to be too intrusive.
Therefore this adds a new struct (guestfs_statns) and new APIs:
guestfs_statns
guestfs_lstatns
guestfs_lstatnslist
which return the new struct (or array of structs in the last case).
The old APIs may of course still be used, forever, but are deprecated
and shouldn't be used in new programs.
Because virt tools are compiled with -DGUESTFS_WARN_DEPRECATED=1, I
have updated all the places calling the deprecated functions. This
has revealed some areas for improvement: in particular virt-diff and
virt-ls could be changed to print the nanosecond fields.
FUSE now returns nanoseconds in stat calls where available, fixing
https://bugzilla.redhat.com/show_bug.cgi?id=1144891
Notes about the implementation:
- guestfs_internal_lstatlist has been removed and replaced by
guestfs_internal_lstatnslist. As the former was an internal API no
one should have been calling it, or indeed can call it unless they
start defining their own header files.
- guestfs_stat and guestfs_lstat have been changed into library-side
functions. They, along with guestfs_lstatlist, are now implemented
as wrappers around the new functions which just throw away the
nanosecond fields.
---
TODO | 6 ++
cat/ls.c | 58 +++++------
cat/visit.c | 10 +-
cat/visit.h | 2 +-
configure.ac | 6 ++
daemon/stat.c | 168 +++++++++++++------------------
diff/diff.c | 119 +++++++++++-----------
fuse/test-fuse.c | 4 +-
generator/actions.ml | 151 ++++++++++++++++-----------
generator/structs.ml | 30 ++++++
gobject/Makefile.inc | 2 +
java/Makefile.inc | 1 +
java/com/redhat/et/libguestfs/.gitignore | 1 +
po/POTFILES | 1 +
src/MAX_PROC_NR | 2 +-
src/file.c | 90 +++++++++++++++--
src/fuse.c | 82 +++++++++------
v2v/convert_linux.ml | 8 +-
18 files changed, 443 insertions(+), 298 deletions(-)
diff --git a/TODO b/TODO
index ea19795..e6af186 100644
--- a/TODO
+++ b/TODO
@@ -598,3 +598,9 @@ Improvements in virt-log
- Support Windows guests, see
http://rwmj.wordpress.com/2011/04/17/decoding-the-windows-event-log-using...
+
+Subsecond handling in virt-diff, virt-ls
+----------------------------------------
+
+Handle nanoseconds properly. You should be able to specify them on
+the command line and display them.
diff --git a/cat/ls.c b/cat/ls.c
index 43705c2..de8248e 100644
--- a/cat/ls.c
+++ b/cat/ls.c
@@ -71,7 +71,7 @@ static void output_int64 (int64_t);
static void output_int64_dev (int64_t);
static void output_int64_perms (int64_t);
static void output_int64_size (int64_t);
-static void output_int64_time (int64_t);
+static void output_int64_time (int64_t secs, int64_t nsecs);
static void output_int64_uid (int64_t);
static void output_string (const char *);
static void output_string_link (const char *);
@@ -449,7 +449,7 @@ do_ls_R (const char *dir)
return 0;
}
-static int show_file (const char *dir, const char *name, const struct guestfs_stat *stat, const struct guestfs_xattr_list *xattrs, void *unused);
+static int show_file (const char *dir, const char *name, const struct guestfs_statns *stat, const struct guestfs_xattr_list *xattrs, void *unused);
static int
do_ls_lR (const char *dir)
@@ -466,7 +466,7 @@ do_ls_lR (const char *dir)
*/
static int
show_file (const char *dir, const char *name,
- const struct guestfs_stat *stat,
+ const struct guestfs_statns *stat,
const struct guestfs_xattr_list *xattrs,
void *unused)
{
@@ -476,45 +476,45 @@ show_file (const char *dir, const char *name,
/* Display the basic fields. */
output_start_line ();
- if (is_reg (stat->mode))
+ if (is_reg (stat->st_mode))
filetype = "-";
- else if (is_dir (stat->mode))
+ else if (is_dir (stat->st_mode))
filetype = "d";
- else if (is_chr (stat->mode))
+ else if (is_chr (stat->st_mode))
filetype = "c";
- else if (is_blk (stat->mode))
+ else if (is_blk (stat->st_mode))
filetype = "b";
- else if (is_fifo (stat->mode))
+ else if (is_fifo (stat->st_mode))
filetype = "p";
- else if (is_lnk (stat->mode))
+ else if (is_lnk (stat->st_mode))
filetype = "l";
- else if (is_sock (stat->mode))
+ else if (is_sock (stat->st_mode))
filetype = "s";
else
filetype = "u";
output_string (filetype);
- output_int64_perms (stat->mode & 07777);
+ output_int64_perms (stat->st_mode & 07777);
- output_int64_size (stat->size);
+ output_int64_size (stat->st_size);
/* Display extra fields when enabled. */
if (enable_uids) {
- output_int64_uid (stat->uid);
- output_int64_uid (stat->gid);
+ output_int64_uid (stat->st_uid);
+ output_int64_uid (stat->st_gid);
}
if (enable_times) {
- output_int64_time (stat->atime);
- output_int64_time (stat->mtime);
- output_int64_time (stat->ctime);
+ output_int64_time (stat->st_atime_sec, stat->st_atime_nsec);
+ output_int64_time (stat->st_mtime_sec, stat->st_mtime_nsec);
+ output_int64_time (stat->st_ctime_sec, stat->st_ctime_nsec);
}
if (enable_extra_stats) {
- output_int64_dev (stat->dev);
- output_int64 (stat->ino);
- output_int64 (stat->nlink);
- output_int64_dev (stat->rdev);
- output_int64 (stat->blocks);
+ output_int64_dev (stat->st_dev);
+ output_int64 (stat->st_ino);
+ output_int64 (stat->st_nlink);
+ output_int64_dev (stat->st_rdev);
+ output_int64 (stat->st_blocks);
}
/* Disabled for now -- user would definitely want these to be interpreted.
@@ -524,7 +524,7 @@ show_file (const char *dir, const char *name,
path = full_path (dir, name);
- if (checksum && is_reg (stat->mode)) {
+ if (checksum && is_reg (stat->st_mode)) {
csum = guestfs_checksum (g, checksum, path);
if (!csum)
exit (EXIT_FAILURE);
@@ -534,7 +534,7 @@ show_file (const char *dir, const char *name,
output_string (path);
- if (is_lnk (stat->mode))
+ if (is_lnk (stat->st_mode))
/* XXX Fix this for NTFS. */
link = guestfs_readlink (g, path);
if (link)
@@ -703,7 +703,7 @@ output_int64_perms (int64_t i)
}
static void
-output_int64_time (int64_t i)
+output_int64_time (int64_t secs, int64_t nsecs)
{
int r;
@@ -713,19 +713,19 @@ output_int64_time (int64_t i)
if (time_t_output) {
switch (time_relative) {
case 0: /* --time-t */
- r = printf ("%10" PRIi64, i);
+ r = printf ("%10" PRIi64, secs);
break;
case 1: /* --time-relative */
- r = printf ("%8" PRIi64, now - i);
+ r = printf ("%8" PRIi64, now - secs);
break;
case 2: /* --time-days */
default:
- r = printf ("%3" PRIi64, (now - i) / 86400);
+ r = printf ("%3" PRIi64, (now - secs) / 86400);
break;
}
}
else {
- time_t t = (time_t) i;
+ time_t t = (time_t) secs;
char buf[64];
struct tm *tm;
diff --git a/cat/visit.c b/cat/visit.c
index 2347b56..963beb8 100644
--- a/cat/visit.c
+++ b/cat/visit.c
@@ -51,11 +51,11 @@ _visit (guestfs_h *g, int depth, const char *dir,
* case.
*/
if (depth == 0) {
- CLEANUP_FREE_STAT struct guestfs_stat *stat = NULL;
+ CLEANUP_FREE_STATNS struct guestfs_statns *stat = NULL;
CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
int r;
- stat = guestfs_lstat (g, dir);
+ stat = guestfs_lstatns (g, dir);
if (stat == NULL)
return -1;
@@ -71,14 +71,14 @@ _visit (guestfs_h *g, int depth, const char *dir,
size_t i, xattrp;
CLEANUP_FREE_STRING_LIST char **names = NULL;
- CLEANUP_FREE_STAT_LIST struct guestfs_stat_list *stats = NULL;
+ CLEANUP_FREE_STAT_LIST struct guestfs_statns_list *stats = NULL;
CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
names = guestfs_ls (g, dir);
if (names == NULL)
return -1;
- stats = guestfs_lstatlist (g, dir, names);
+ stats = guestfs_lstatnslist (g, dir, names);
if (stats == NULL)
return -1;
@@ -123,7 +123,7 @@ _visit (guestfs_h *g, int depth, const char *dir,
return -1;
/* Recursively call visit, but only on directories. */
- if (is_dir (stats->val[i].mode)) {
+ if (is_dir (stats->val[i].st_mode)) {
path = full_path (dir, names[i]);
if (_visit (g, depth + 1, path, f, opaque) == -1)
return -1;
diff --git a/cat/visit.h b/cat/visit.h
index f6b538b..a64b42e 100644
--- a/cat/visit.h
+++ b/cat/visit.h
@@ -19,7 +19,7 @@
#ifndef VISIT_H
#define VISIT_H
-typedef int (*visitor_function) (const char *dir, const char *name, const struct guestfs_stat *stat, const struct guestfs_xattr_list *xattrs, void *opaque);
+typedef int (*visitor_function) (const char *dir, const char *name, const struct guestfs_statns *stat, const struct guestfs_xattr_list *xattrs, void *opaque);
extern int visit (guestfs_h *g, const char *dir, visitor_function f, void *opaque);
diff --git a/configure.ac b/configure.ac
index 0b2c0e0..01f1b3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -270,6 +270,12 @@ dnl Check if stat has the required fields.
AC_STRUCT_ST_BLOCKS
AC_CHECK_MEMBER([struct stat.st_blksize],[
AC_DEFINE([HAVE_STRUCT_STAT_ST_BLKSIZE],[1],[Define to 1 if 'st_blksize' is a member of 'struct stat'.])])
+AC_CHECK_MEMBER([struct stat.st_atim.tv_nsec],[
+ AC_DEFINE([HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])])
+AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],[
+ AC_DEFINE([HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])])
+AC_CHECK_MEMBER([struct stat.st_ctim.tv_nsec],[
+ AC_DEFINE([HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC],[1],[Define to 1 if 'st_mtim.tv_nsec' is a member of 'struct stat'.])])
dnl Define a C symbol for the host CPU architecture.
AC_DEFINE_UNQUOTED([host_cpu],["$host_cpu"],[Host architecture.])
diff --git a/daemon/stat.c b/daemon/stat.c
index 939fe08..a784914 100644
--- a/daemon/stat.c
+++ b/daemon/stat.c
@@ -30,11 +30,64 @@
#include "daemon.h"
#include "actions.h"
-guestfs_int_stat *
-do_stat (const char *path)
+static guestfs_int_statns *
+stat_to_statns (guestfs_int_statns *ret, const struct stat *statbuf)
+{
+ if (ret == NULL) {
+ ret = malloc (sizeof *ret);
+ if (ret == NULL) {
+ reply_with_perror ("malloc");
+ return NULL;
+ }
+ }
+
+ ret->st_dev = statbuf->st_dev;
+ ret->st_ino = statbuf->st_ino;
+ ret->st_mode = statbuf->st_mode;
+ ret->st_nlink = statbuf->st_nlink;
+ ret->st_uid = statbuf->st_uid;
+ ret->st_gid = statbuf->st_gid;
+ ret->st_rdev = statbuf->st_rdev;
+ ret->st_size = statbuf->st_size;
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+ ret->st_blksize = statbuf->st_blksize;
+#else
+ ret->st_blksize = -1;
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+ ret->st_blocks = statbuf->st_blocks;
+#else
+ ret->st_blocks = -1;
+#endif
+ ret->st_atime_sec = statbuf->st_atime;
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ ret->st_atime_nsec = statbuf->st_atim.tv_nsec;
+#else
+ ret->st_atime_nsec = 0;
+#endif
+ ret->st_mtime_sec = statbuf->st_mtime;
+#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+ ret->st_mtime_nsec = statbuf->st_mtim.tv_nsec;
+#else
+ ret->st_mtime_nsec = 0;
+#endif
+ ret->st_ctime_sec = statbuf->st_ctime;
+#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
+ ret->st_ctime_nsec = statbuf->st_ctim.tv_nsec;
+#else
+ ret->st_ctime_nsec = 0;
+#endif
+
+ ret->st_spare1 = ret->st_spare2 = ret->st_spare3 =
+ ret->st_spare4 = ret->st_spare5 = ret->st_spare6 = 0;
+
+ return ret;
+}
+
+guestfs_int_statns *
+do_statns (const char *path)
{
int r;
- guestfs_int_stat *ret;
struct stat statbuf;
CHROOT_IN;
@@ -46,42 +99,13 @@ do_stat (const char *path)
return NULL;
}
- ret = malloc (sizeof *ret);
- if (ret == NULL) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- ret->dev = statbuf.st_dev;
- ret->ino = statbuf.st_ino;
- ret->mode = statbuf.st_mode;
- ret->nlink = statbuf.st_nlink;
- ret->uid = statbuf.st_uid;
- ret->gid = statbuf.st_gid;
- ret->rdev = statbuf.st_rdev;
- ret->size = statbuf.st_size;
-#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
- ret->blksize = statbuf.st_blksize;
-#else
- ret->blksize = -1;
-#endif
-#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
- ret->blocks = statbuf.st_blocks;
-#else
- ret->blocks = -1;
-#endif
- ret->atime = statbuf.st_atime;
- ret->mtime = statbuf.st_mtime;
- ret->ctime = statbuf.st_ctime;
-
- return ret;
+ return stat_to_statns (NULL, &statbuf);
}
-guestfs_int_stat *
-do_lstat (const char *path)
+guestfs_int_statns *
+do_lstatns (const char *path)
{
int r;
- guestfs_int_stat *ret;
struct stat statbuf;
CHROOT_IN;
@@ -93,42 +117,14 @@ do_lstat (const char *path)
return NULL;
}
- ret = malloc (sizeof *ret);
- if (ret == NULL) {
- reply_with_perror ("malloc");
- return NULL;
- }
-
- ret->dev = statbuf.st_dev;
- ret->ino = statbuf.st_ino;
- ret->mode = statbuf.st_mode;
- ret->nlink = statbuf.st_nlink;
- ret->uid = statbuf.st_uid;
- ret->gid = statbuf.st_gid;
- ret->rdev = statbuf.st_rdev;
- ret->size = statbuf.st_size;
-#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
- ret->blksize = statbuf.st_blksize;
-#else
- ret->blksize = -1;
-#endif
-#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
- ret->blocks = statbuf.st_blocks;
-#else
- ret->blocks = -1;
-#endif
- ret->atime = statbuf.st_atime;
- ret->mtime = statbuf.st_mtime;
- ret->ctime = statbuf.st_ctime;
-
- return ret;
+ return stat_to_statns (NULL, &statbuf);
}
-guestfs_int_stat_list *
-do_internal_lstatlist (const char *path, char *const *names)
+guestfs_int_statns_list *
+do_internal_lstatnslist (const char *path, char *const *names)
{
int path_fd;
- guestfs_int_stat_list *ret;
+ guestfs_int_statns_list *ret;
size_t i, nr_names;
nr_names = count_strings (names);
@@ -138,9 +134,10 @@ do_internal_lstatlist (const char *path, char *const *names)
reply_with_perror ("malloc");
return NULL;
}
- ret->guestfs_int_stat_list_len = nr_names;
- ret->guestfs_int_stat_list_val = calloc (nr_names, sizeof (guestfs_int_stat));
- if (ret->guestfs_int_stat_list_val == NULL) {
+ ret->guestfs_int_statns_list_len = nr_names;
+ ret->guestfs_int_statns_list_val =
+ calloc (nr_names, sizeof (guestfs_int_statns));
+ if (ret->guestfs_int_statns_list_val == NULL) {
reply_with_perror ("malloc");
free (ret);
return NULL;
@@ -152,7 +149,7 @@ do_internal_lstatlist (const char *path, char *const *names)
if (path_fd == -1) {
reply_with_perror ("%s", path);
- free (ret->guestfs_int_stat_list_val);
+ free (ret->guestfs_int_statns_list_val);
free (ret);
return NULL;
}
@@ -163,35 +160,14 @@ do_internal_lstatlist (const char *path, char *const *names)
r = fstatat (path_fd, names[i], &statbuf, AT_SYMLINK_NOFOLLOW);
if (r == -1)
- ret->guestfs_int_stat_list_val[i].ino = -1;
- else {
- ret->guestfs_int_stat_list_val[i].dev = statbuf.st_dev;
- ret->guestfs_int_stat_list_val[i].ino = statbuf.st_ino;
- ret->guestfs_int_stat_list_val[i].mode = statbuf.st_mode;
- ret->guestfs_int_stat_list_val[i].nlink = statbuf.st_nlink;
- ret->guestfs_int_stat_list_val[i].uid = statbuf.st_uid;
- ret->guestfs_int_stat_list_val[i].gid = statbuf.st_gid;
- ret->guestfs_int_stat_list_val[i].rdev = statbuf.st_rdev;
- ret->guestfs_int_stat_list_val[i].size = statbuf.st_size;
-#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
- ret->guestfs_int_stat_list_val[i].blksize = statbuf.st_blksize;
-#else
- ret->guestfs_int_stat_list_val[i].blksize = -1;
-#endif
-#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
- ret->guestfs_int_stat_list_val[i].blocks = statbuf.st_blocks;
-#else
- ret->guestfs_int_stat_list_val[i].blocks = -1;
-#endif
- ret->guestfs_int_stat_list_val[i].atime = statbuf.st_atime;
- ret->guestfs_int_stat_list_val[i].mtime = statbuf.st_mtime;
- ret->guestfs_int_stat_list_val[i].ctime = statbuf.st_ctime;
- }
+ ret->guestfs_int_statns_list_val[i].st_ino = -1;
+ else
+ stat_to_statns (&ret->guestfs_int_statns_list_val[i], &statbuf);
}
if (close (path_fd) == -1) {
reply_with_perror ("close: %s", path);
- free (ret->guestfs_int_stat_list_val);
+ free (ret->guestfs_int_statns_list_val);
free (ret);
return NULL;
}
diff --git a/diff/diff.c b/diff/diff.c
index 16c970b..af4e179 100644
--- a/diff/diff.c
+++ b/diff/diff.c
@@ -78,7 +78,7 @@ static void output_int64 (int64_t);
static void output_int64_dev (int64_t);
static void output_int64_perms (int64_t);
static void output_int64_size (int64_t);
-static void output_int64_time (int64_t);
+static void output_int64_time (int64_t secs, int64_t nsecs);
static void output_int64_uid (int64_t);
static void output_string (const char *);
static void output_string_link (const char *);
@@ -398,7 +398,7 @@ struct tree {
struct file {
char *path;
- struct guestfs_stat *stat;
+ struct guestfs_statns *stat;
struct guestfs_xattr_list *xattrs;
char *csum; /* Checksum. If NULL, use file times and size. */
};
@@ -410,7 +410,7 @@ free_tree (struct tree *t)
for (i = 0; i < t->nr_files; ++i) {
free (t->files[i].path);
- guestfs_free_stat (t->files[i].stat);
+ guestfs_free_statns (t->files[i].stat);
guestfs_free_xattr_list (t->files[i].xattrs);
free (t->files[i].csum);
}
@@ -420,7 +420,7 @@ free_tree (struct tree *t)
free (t);
}
-static int visit_entry (const char *dir, const char *name, const struct guestfs_stat *stat, const struct guestfs_xattr_list *xattrs, void *vt);
+static int visit_entry (const char *dir, const char *name, const struct guestfs_statns *stat, const struct guestfs_xattr_list *xattrs, void *vt);
static struct tree *
visit_guest (guestfs_h *g)
@@ -454,13 +454,13 @@ visit_guest (guestfs_h *g)
*/
static int
visit_entry (const char *dir, const char *name,
- const struct guestfs_stat *stat_orig,
+ const struct guestfs_statns *stat_orig,
const struct guestfs_xattr_list *xattrs_orig,
void *vt)
{
struct tree *t = vt;
char *path = NULL, *csum = NULL;
- struct guestfs_stat *stat = NULL;
+ struct guestfs_statns *stat = NULL;
struct guestfs_xattr_list *xattrs = NULL;
size_t i;
@@ -469,7 +469,7 @@ visit_entry (const char *dir, const char *name,
/* Copy the stats and xattrs because the visit function will
* free them after we return.
*/
- stat = guestfs_copy_stat (stat_orig);
+ stat = guestfs_copy_statns (stat_orig);
if (stat == NULL) {
perror ("guestfs_copy_stat");
goto error;
@@ -480,7 +480,7 @@ visit_entry (const char *dir, const char *name,
goto error;
}
- if (checksum && is_reg (stat->mode)) {
+ if (checksum && is_reg (stat->st_mode)) {
csum = guestfs_checksum (t->g, checksum, path);
if (!csum)
goto error;
@@ -488,19 +488,20 @@ visit_entry (const char *dir, const char *name,
/* If --atime option was NOT passed, flatten the atime field. */
if (!atime)
- stat->atime = 0;
+ stat->st_atime_sec = 0;
/* If --dir-links option was NOT passed, flatten nlink field in
* directories.
*/
- if (!dir_links && is_dir (stat->mode))
- stat->nlink = 0;
+ if (!dir_links && is_dir (stat->st_mode))
+ stat->st_nlink = 0;
/* If --dir-times option was NOT passed, flatten time fields in
* directories.
*/
- if (!dir_times && is_dir (stat->mode))
- stat->atime = stat->mtime = stat->ctime = 0;
+ if (!dir_times && is_dir (stat->st_mode))
+ stat->st_atime_sec = stat->st_mtime_sec = stat->st_ctime_sec =
+ stat->st_atime_nsec = stat->st_mtime_nsec = stat->st_ctime_nsec = 0;
/* Add the pathname and stats to the list. */
i = t->nr_files++;
@@ -535,7 +536,7 @@ visit_entry (const char *dir, const char *name,
error:
free (path);
free (csum);
- guestfs_free_stat (stat);
+ guestfs_free_statns (stat);
guestfs_free_xattr_list (xattrs);
return -1;
}
@@ -622,7 +623,7 @@ compare_stats (struct file *file1, struct file *file2)
{
int r;
- r = guestfs_compare_stat (file1->stat, file2->stat);
+ r = guestfs_compare_statns (file1->stat, file2->stat);
if (r != 0)
return r;
@@ -640,10 +641,10 @@ changed (guestfs_h *g1, struct file *file1,
{
/* Did file content change? */
if (cst != 0 ||
- (is_reg (file1->stat->mode) && is_reg (file2->stat->mode) &&
- (file1->stat->mtime != file2->stat->mtime ||
- file1->stat->ctime != file2->stat->ctime ||
- file1->stat->size != file2->stat->size))) {
+ (is_reg (file1->stat->st_mode) && is_reg (file2->stat->st_mode) &&
+ (file1->stat->st_mtime_sec != file2->stat->st_mtime_sec ||
+ file1->stat->st_ctime_sec != file2->stat->st_ctime_sec ||
+ file1->stat->st_size != file2->stat->st_size))) {
output_start_line ();
output_string ("=");
output_file (g1, file1);
@@ -673,19 +674,19 @@ changed (guestfs_h *g1, struct file *file1,
output_string ("changed:");
#define COMPARE_STAT(n) \
if (file1->stat->n != file2->stat->n) output_string (#n)
- COMPARE_STAT (dev);
- COMPARE_STAT (ino);
- COMPARE_STAT (mode);
- COMPARE_STAT (nlink);
- COMPARE_STAT (uid);
- COMPARE_STAT (gid);
- COMPARE_STAT (rdev);
- COMPARE_STAT (size);
- COMPARE_STAT (blksize);
- COMPARE_STAT (blocks);
- COMPARE_STAT (atime);
- COMPARE_STAT (mtime);
- COMPARE_STAT (ctime);
+ COMPARE_STAT (st_dev);
+ COMPARE_STAT (st_ino);
+ COMPARE_STAT (st_mode);
+ COMPARE_STAT (st_nlink);
+ COMPARE_STAT (st_uid);
+ COMPARE_STAT (st_gid);
+ COMPARE_STAT (st_rdev);
+ COMPARE_STAT (st_size);
+ COMPARE_STAT (st_blksize);
+ COMPARE_STAT (st_blocks);
+ COMPARE_STAT (st_atime_sec);
+ COMPARE_STAT (st_mtime_sec);
+ COMPARE_STAT (st_ctime_sec);
#undef COMPARE_STAT
if (guestfs_compare_xattr_list (file1->xattrs, file2->xattrs))
output_string ("xattrs");
@@ -701,8 +702,8 @@ diff (struct file *file1, guestfs_h *g1, struct file *file2, guestfs_h *g2)
CLEANUP_FREE char *tmpd, *tmpda = NULL, *tmpdb = NULL, *cmd = NULL;
int r;
- assert (is_reg (file1->stat->mode));
- assert (is_reg (file2->stat->mode));
+ assert (is_reg (file1->stat->st_mode));
+ assert (is_reg (file2->stat->st_mode));
if (asprintf (&tmpd, "%s/virtdiffXXXXXX", tmpdir) < 0) {
perror ("asprintf");
@@ -755,47 +756,47 @@ output_file (guestfs_h *g, struct file *file)
size_t i;
CLEANUP_FREE char *link = NULL;
- if (is_reg (file->stat->mode))
+ if (is_reg (file->stat->st_mode))
filetype = "-";
- else if (is_dir (file->stat->mode))
+ else if (is_dir (file->stat->st_mode))
filetype = "d";
- else if (is_chr (file->stat->mode))
+ else if (is_chr (file->stat->st_mode))
filetype = "c";
- else if (is_blk (file->stat->mode))
+ else if (is_blk (file->stat->st_mode))
filetype = "b";
- else if (is_fifo (file->stat->mode))
+ else if (is_fifo (file->stat->st_mode))
filetype = "p";
- else if (is_lnk (file->stat->mode))
+ else if (is_lnk (file->stat->st_mode))
filetype = "l";
- else if (is_sock (file->stat->mode))
+ else if (is_sock (file->stat->st_mode))
filetype = "s";
else
filetype = "u";
output_string (filetype);
- output_int64_perms (file->stat->mode & 07777);
+ output_int64_perms (file->stat->st_mode & 07777);
- output_int64_size (file->stat->size);
+ output_int64_size (file->stat->st_size);
/* Display extra fields when enabled. */
if (enable_uids) {
- output_int64_uid (file->stat->uid);
- output_int64_uid (file->stat->gid);
+ output_int64_uid (file->stat->st_uid);
+ output_int64_uid (file->stat->st_gid);
}
if (enable_times) {
if (atime)
- output_int64_time (file->stat->atime);
- output_int64_time (file->stat->mtime);
- output_int64_time (file->stat->ctime);
+ output_int64_time (file->stat->st_atime_sec, file->stat->st_atime_nsec);
+ output_int64_time (file->stat->st_mtime_sec, file->stat->st_mtime_nsec);
+ output_int64_time (file->stat->st_ctime_sec, file->stat->st_ctime_nsec);
}
if (enable_extra_stats) {
- output_int64_dev (file->stat->dev);
- output_int64 (file->stat->ino);
- output_int64 (file->stat->nlink);
- output_int64_dev (file->stat->rdev);
- output_int64 (file->stat->blocks);
+ output_int64_dev (file->stat->st_dev);
+ output_int64 (file->stat->st_ino);
+ output_int64 (file->stat->st_nlink);
+ output_int64_dev (file->stat->st_rdev);
+ output_int64 (file->stat->st_blocks);
}
if (file->csum)
@@ -803,7 +804,7 @@ output_file (guestfs_h *g, struct file *file)
output_string (file->path);
- if (is_lnk (file->stat->mode)) {
+ if (is_lnk (file->stat->st_mode)) {
/* XXX Fix this for NTFS. */
link = guestfs_readlink (g, file->path);
if (link)
@@ -1056,7 +1057,7 @@ output_int64_perms (int64_t i)
}
static void
-output_int64_time (int64_t i)
+output_int64_time (int64_t secs, int64_t nsecs)
{
int r;
@@ -1066,19 +1067,19 @@ output_int64_time (int64_t i)
if (time_t_output) {
switch (time_relative) {
case 0: /* --time-t */
- r = printf ("%10" PRIi64, i);
+ r = printf ("%10" PRIi64, secs);
break;
case 1: /* --time-relative */
- r = printf ("%8" PRIi64, now - i);
+ r = printf ("%8" PRIi64, now - secs);
break;
case 2: /* --time-days */
default:
- r = printf ("%3" PRIi64, (now - i) / 86400);
+ r = printf ("%3" PRIi64, (now - secs) / 86400);
break;
}
}
else {
- time_t t = (time_t) i;
+ time_t t = (time_t) secs;
char buf[64];
struct tm *tm;
diff --git a/fuse/test-fuse.c b/fuse/test-fuse.c
index dda6fde..2876dc4 100644
--- a/fuse/test-fuse.c
+++ b/fuse/test-fuse.c
@@ -247,9 +247,9 @@ test_fuse (void)
char buf[128];
ssize_t r;
unsigned u, u1;
-#if 0
int fd;
struct timeval tv[2];
+#if 0
struct timespec ts[2];
#endif
acl_t acl;
@@ -544,7 +544,6 @@ test_fuse (void)
return -1;
}
-#if 0
STAGE ("checking utimes");
fd = open ("timestamp", O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0644);
@@ -574,7 +573,6 @@ test_fuse (void)
(int) statbuf.st_mtime, (int) statbuf.st_mtim.tv_nsec);
return -1;
}
-#endif
#if 0
/* Does not work! See https://bugzilla.redhat.com/show_bug.cgi?id=1144766 */
diff --git a/generator/actions.ml b/generator/actions.ml
index 73dcd33..7782198 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -2605,6 +2605,7 @@ See also C<guestfs_write>." };
{ defaults with
name = "lstatlist";
style = RStructList ("statbufs", "stat"), [Pathname "path"; StringList "names"], [];
+ deprecated_by = Some "lstatnslist";
shortdesc = "lstat on multiple files";
longdesc = "\
This call allows you to perform the C<guestfs_lstat> operation
@@ -2613,7 +2614,26 @@ C<names> is the list of files from this directory.
On return you get a list of stat structs, with a one-to-one
correspondence to the C<names> list. If any name did not exist
-or could not be lstat'd, then the C<ino> field of that structure
+or could not be lstat'd, then the C<st_ino> field of that structure
+is set to C<-1>.
+
+This call is intended for programs that want to efficiently
+list a directory contents without making many round-trips.
+See also C<guestfs_lxattrlist> for a similarly efficient call
+for getting extended attributes." };
+
+ { defaults with
+ name = "lstatnslist";
+ style = RStructList ("statbufs", "statns"), [Pathname "path"; StringList "names"], [];
+ shortdesc = "lstat on multiple files";
+ longdesc = "\
+This call allows you to perform the C<guestfs_lstatns> operation
+on multiple files, where all files are in the directory C<path>.
+C<names> is the list of files from this directory.
+
+On return you get a list of stat structs, with a one-to-one
+correspondence to the C<names> list. If any name did not exist
+or could not be lstat'd, then the C<st_ino> field of that structure
is set to C<-1>.
This call is intended for programs that want to efficiently
@@ -3223,6 +3243,38 @@ This call returns the number of strings which were removed
See L<guestfs(3)/BACKEND>, L<guestfs(3)/BACKEND SETTINGS>." };
+ { defaults with
+ name = "stat";
+ style = RStruct ("statbuf", "stat"), [Pathname "path"], [];
+ deprecated_by = Some "statns";
+ tests = [
+ InitISOFS, Always, TestResult (
+ [["stat"; "/empty"]], "ret->size == 0"), []
+ ];
+ shortdesc = "get file information";
+ longdesc = "\
+Returns file information for the given C<path>.
+
+This is the same as the C<stat(2)> system call." };
+
+ { defaults with
+ name = "lstat";
+ style = RStruct ("statbuf", "stat"), [Pathname "path"], [];
+ deprecated_by = Some "lstatns";
+ tests = [
+ InitISOFS, Always, TestResult (
+ [["lstat"; "/empty"]], "ret->size == 0"), []
+ ];
+ shortdesc = "get file information for a symbolic link";
+ longdesc = "\
+Returns file information for the given C<path>.
+
+This is the same as C<guestfs_stat> except that if C<path>
+is a symbolic link, then the link is stat-ed, not the file it
+refers to.
+
+This is the same as the C<lstat(2)> system call." };
+
]
(* daemon_functions are any functions which cause some action
@@ -4347,38 +4399,6 @@ result into a list of lines.
See also: C<guestfs_sh_lines>" };
{ defaults with
- name = "stat";
- style = RStruct ("statbuf", "stat"), [Pathname "path"], [];
- proc_nr = Some 52;
- tests = [
- InitISOFS, Always, TestResult (
- [["stat"; "/empty"]], "ret->size == 0"), []
- ];
- shortdesc = "get file information";
- longdesc = "\
-Returns file information for the given C<path>.
-
-This is the same as the C<stat(2)> system call." };
-
- { defaults with
- name = "lstat";
- style = RStruct ("statbuf", "stat"), [Pathname "path"], [];
- proc_nr = Some 53;
- tests = [
- InitISOFS, Always, TestResult (
- [["lstat"; "/empty"]], "ret->size == 0"), []
- ];
- shortdesc = "get file information for a symbolic link";
- longdesc = "\
-Returns file information for the given C<path>.
-
-This is the same as C<guestfs_stat> except that if C<path>
-is a symbolic link, then the link is stat-ed, not the file it
-refers to.
-
-This is the same as the C<lstat(2)> system call." };
-
- { defaults with
name = "statvfs";
style = RStruct ("statbuf", "statvfs"), [Pathname "path"], [];
proc_nr = Some 54;
@@ -7493,30 +7513,6 @@ names, you will need to locate and parse the password file
yourself (Augeas support makes this relatively easy)." };
{ defaults with
- name = "internal_lstatlist";
- style = RStructList ("statbufs", "stat"), [Pathname "path"; StringList "names"], [];
- proc_nr = Some 204;
- visibility = VInternal;
- shortdesc = "lstat on multiple files";
- longdesc = "\
-This call allows you to perform the C<guestfs_lstat> operation
-on multiple files, where all files are in the directory C<path>.
-C<names> is the list of files from this directory.
-
-On return you get a list of stat structs, with a one-to-one
-correspondence to the C<names> list. If any name did not exist
-or could not be lstat'd, then the C<ino> field of that structure
-is set to C<-1>.
-
-This call is intended for programs that want to efficiently
-list a directory contents without making many round-trips.
-See also C<guestfs_lxattrlist> for a similarly efficient call
-for getting extended attributes. Very long directory listings
-might cause the protocol message size to be exceeded, causing
-this call to fail. The caller must split up such requests
-into smaller groups of names." };
-
- { defaults with
name = "internal_lxattrlist";
style = RStructList ("xattrs", "xattr"), [Pathname "path"; StringList "names"], [];
proc_nr = Some 205;
@@ -11942,6 +11938,47 @@ New (SVR4) portable format with a checksum.
longdesc = "\
Get the realtime (wallclock) timestamp of the current journal entry." };
+ { defaults with
+ name = "statns";
+ style = RStruct ("statbuf", "statns"), [Pathname "path"], [];
+ proc_nr = Some 421;
+ tests = [
+ InitISOFS, Always, TestResult (
+ [["statns"; "/empty"]], "ret->st_size == 0"), []
+ ];
+ shortdesc = "get file information";
+ longdesc = "\
+Returns file information for the given C<path>.
+
+This is the same as the C<stat(2)> system call." };
+
+ { defaults with
+ name = "lstatns";
+ style = RStruct ("statbuf", "statns"), [Pathname "path"], [];
+ proc_nr = Some 422;
+ tests = [
+ InitISOFS, Always, TestResult (
+ [["lstatns"; "/empty"]], "ret->st_size == 0"), []
+ ];
+ shortdesc = "get file information for a symbolic link";
+ longdesc = "\
+Returns file information for the given C<path>.
+
+This is the same as C<guestfs_statns> except that if C<path>
+is a symbolic link, then the link is stat-ed, not the file it
+refers to.
+
+This is the same as the C<lstat(2)> system call." };
+
+ { defaults with
+ name = "internal_lstatnslist";
+ style = RStructList ("statbufs", "statns"), [Pathname "path"; StringList "names"], [];
+ proc_nr = Some 423;
+ visibility = VInternal;
+ shortdesc = "lstat on multiple files";
+ longdesc = "\
+This is the internal call which implements C<guestfs_lstatnslist>." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/generator/structs.ml b/generator/structs.ml
index 65c78b2..578ebb7 100644
--- a/generator/structs.ml
+++ b/generator/structs.ml
@@ -143,6 +143,36 @@ let structs = [
"ctime", FInt64;
];
s_camel_name = "Stat" };
+ (* Because we omitted the nanosecond fields from the above struct,
+ * we also have this:
+ *)
+ { defaults with
+ s_name = "statns";
+ s_cols = [
+ "st_dev", FInt64;
+ "st_ino", FInt64;
+ "st_mode", FInt64;
+ "st_nlink", FInt64;
+ "st_uid", FInt64;
+ "st_gid", FInt64;
+ "st_rdev", FInt64;
+ "st_size", FInt64;
+ "st_blksize", FInt64;
+ "st_blocks", FInt64;
+ "st_atime_sec", FInt64;
+ "st_atime_nsec", FInt64;
+ "st_mtime_sec", FInt64;
+ "st_mtime_nsec", FInt64;
+ "st_ctime_sec", FInt64;
+ "st_ctime_nsec", FInt64;
+ "st_spare1", FInt64;
+ "st_spare2", FInt64;
+ "st_spare3", FInt64;
+ "st_spare4", FInt64;
+ "st_spare5", FInt64;
+ "st_spare6", FInt64;
+ ];
+ s_camel_name = "StatNS" };
{ defaults with
s_name = "statvfs";
s_cols = [
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index ed1ff3b..c93dace 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -38,6 +38,7 @@ guestfs_gobject_headers= \
include/guestfs-gobject/struct-mdstat.h \
include/guestfs-gobject/struct-partition.h \
include/guestfs-gobject/struct-stat.h \
+ include/guestfs-gobject/struct-statns.h \
include/guestfs-gobject/struct-statvfs.h \
include/guestfs-gobject/struct-utsname.h \
include/guestfs-gobject/struct-version.h \
@@ -115,6 +116,7 @@ guestfs_gobject_sources= \
src/struct-mdstat.c \
src/struct-partition.c \
src/struct-stat.c \
+ src/struct-statns.c \
src/struct-statvfs.c \
src/struct-utsname.c \
src/struct-version.c \
diff --git a/java/Makefile.inc b/java/Makefile.inc
index 731e782..614caaa 100644
--- a/java/Makefile.inc
+++ b/java/Makefile.inc
@@ -34,6 +34,7 @@ java_built_sources = \
com/redhat/et/libguestfs/PV.java \
com/redhat/et/libguestfs/Partition.java \
com/redhat/et/libguestfs/Stat.java \
+ com/redhat/et/libguestfs/StatNS.java \
com/redhat/et/libguestfs/StatVFS.java \
com/redhat/et/libguestfs/UTSName.java \
com/redhat/et/libguestfs/VG.java \
diff --git a/java/com/redhat/et/libguestfs/.gitignore b/java/com/redhat/et/libguestfs/.gitignore
index 00bcec9..4882c96 100644
--- a/java/com/redhat/et/libguestfs/.gitignore
+++ b/java/com/redhat/et/libguestfs/.gitignore
@@ -12,6 +12,7 @@ MDStat.java
PV.java
Partition.java
Stat.java
+StatNS.java
StatVFS.java
UTSName.java
VG.java
diff --git a/po/POTFILES b/po/POTFILES
index add74b6..aec8c62 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -238,6 +238,7 @@ gobject/src/struct-lvm_vg.c
gobject/src/struct-mdstat.c
gobject/src/struct-partition.c
gobject/src/struct-stat.c
+gobject/src/struct-statns.c
gobject/src/struct-statvfs.c
gobject/src/struct-utsname.c
gobject/src/struct-version.c
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 816d01b..5721413 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-420
+423
diff --git a/src/file.c b/src/file.c
index d21a61d..378a9c0 100644
--- a/src/file.c
+++ b/src/file.c
@@ -377,33 +377,33 @@ guestfs__write_append (guestfs_h *g, const char *path,
return write_or_append (g, path, content, size, 1);
}
-#define LSTATLIST_MAX 1000
+#define LSTATNSLIST_MAX 1000
-struct guestfs_stat_list *
-guestfs__lstatlist (guestfs_h *g, const char *dir, char * const*names)
+struct guestfs_statns_list *
+guestfs__lstatnslist (guestfs_h *g, const char *dir, char * const*names)
{
size_t len = guestfs___count_strings (names);
size_t old_len;
- struct guestfs_stat_list *ret;
+ struct guestfs_statns_list *ret;
ret = safe_malloc (g, sizeof *ret);
ret->len = 0;
ret->val = NULL;
while (len > 0) {
- CLEANUP_FREE_STAT_LIST struct guestfs_stat_list *stats = NULL;
+ CLEANUP_FREE_STATNS_LIST struct guestfs_statns_list *stats = NULL;
/* Note we don't need to free up the strings because take_strings
* does not do a deep copy.
*/
- CLEANUP_FREE char **first = take_strings (g, names, LSTATLIST_MAX, &names);
+ CLEANUP_FREE char **first = take_strings (g, names, LSTATNSLIST_MAX, &names);
- len = len <= LSTATLIST_MAX ? 0 : len - LSTATLIST_MAX;
+ len = len <= LSTATNSLIST_MAX ? 0 : len - LSTATNSLIST_MAX;
- stats = guestfs_internal_lstatlist (g, dir, first);
+ stats = guestfs_internal_lstatnslist (g, dir, first);
if (stats == NULL) {
- guestfs_free_stat_list (ret);
+ guestfs_free_statns_list (ret);
return NULL;
}
@@ -411,9 +411,9 @@ guestfs__lstatlist (guestfs_h *g, const char *dir, char * const*names)
old_len = ret->len;
ret->len += stats->len;
ret->val = safe_realloc (g, ret->val,
- ret->len * sizeof (struct guestfs_stat));
+ ret->len * sizeof (struct guestfs_statns));
memcpy (&ret->val[old_len], stats->val,
- stats->len * sizeof (struct guestfs_stat));
+ stats->len * sizeof (struct guestfs_statns));
}
return ret;
@@ -602,3 +602,71 @@ guestfs__ls (guestfs_h *g, const char *directory)
close (fd);
return NULL;
}
+
+static void
+statns_to_old_stat (struct guestfs_statns *a, struct guestfs_stat *r)
+{
+ r->ino = a->st_ino;
+ r->mode = a->st_mode;
+ r->nlink = a->st_nlink;
+ r->uid = a->st_uid;
+ r->gid = a->st_gid;
+ r->rdev = a->st_rdev;
+ r->size = a->st_size;
+ r->blksize = a->st_blksize;
+ r->blocks = a->st_blocks;
+ r->atime = a->st_atime_sec;
+ r->mtime = a->st_mtime_sec;
+ r->ctime = a->st_ctime_sec;
+}
+
+struct guestfs_stat *
+guestfs__stat (guestfs_h *g, const char *path)
+{
+ CLEANUP_FREE_STATNS struct guestfs_statns *r;
+ struct guestfs_stat *ret;
+
+ r = guestfs_statns (g, path);
+ if (r == NULL)
+ return NULL;
+
+ ret = safe_malloc (g, sizeof *ret);
+ statns_to_old_stat (r, ret);
+ return ret; /* caller frees */
+}
+
+struct guestfs_stat *
+guestfs__lstat (guestfs_h *g, const char *path)
+{
+ CLEANUP_FREE_STATNS struct guestfs_statns *r;
+ struct guestfs_stat *ret;
+
+ r = guestfs_lstatns (g, path);
+ if (r == NULL)
+ return NULL;
+
+ ret = safe_malloc (g, sizeof *ret);
+ statns_to_old_stat (r, ret);
+ return ret; /* caller frees */
+}
+
+struct guestfs_stat_list *
+guestfs__lstatlist (guestfs_h *g, const char *dir, char * const*names)
+{
+ CLEANUP_FREE_STATNS_LIST struct guestfs_statns_list *r;
+ struct guestfs_stat_list *ret;
+ size_t i;
+
+ r = guestfs_lstatnslist (g, dir, names);
+ if (r == NULL)
+ return NULL;
+
+ ret = safe_malloc (g, sizeof *ret);
+ ret->len = r->len;
+ ret->val = safe_calloc (g, r->len, sizeof (struct guestfs_stat));
+
+ for (i = 0; i < r->len; ++i)
+ statns_to_old_stat (&r->val[i], &ret->val[i]);
+
+ return ret;
+}
diff --git a/src/fuse.c b/src/fuse.c
index 00f9092..08a8784 100644
--- a/src/fuse.c
+++ b/src/fuse.c
@@ -165,7 +165,7 @@ mount_local_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
*/
names = malloc ((ents->len + 1) * sizeof (char *));
if (names) {
- CLEANUP_FREE_STAT_LIST struct guestfs_stat_list *ss = NULL;
+ CLEANUP_FREE_STATNS_LIST struct guestfs_statns_list *ss = NULL;
CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL;
char **links;
@@ -173,26 +173,35 @@ mount_local_readdir (const char *path, void *buf, fuse_fill_dir_t filler,
names[i] = ents->val[i].name;
names[i] = NULL;
- ss = guestfs_lstatlist (g, path, names);
+ ss = guestfs_lstatnslist (g, path, names);
if (ss) {
for (i = 0; i < ss->len; ++i) {
- if (ss->val[i].ino >= 0) {
+ if (ss->val[i].st_ino >= 0) {
struct stat statbuf;
memset (&statbuf, 0, sizeof statbuf);
- statbuf.st_dev = ss->val[i].dev;
- statbuf.st_ino = ss->val[i].ino;
- statbuf.st_mode = ss->val[i].mode;
- statbuf.st_nlink = ss->val[i].nlink;
- statbuf.st_uid = ss->val[i].uid;
- statbuf.st_gid = ss->val[i].gid;
- statbuf.st_rdev = ss->val[i].rdev;
- statbuf.st_size = ss->val[i].size;
- statbuf.st_blksize = ss->val[i].blksize;
- statbuf.st_blocks = ss->val[i].blocks;
- statbuf.st_atime = ss->val[i].atime;
- statbuf.st_mtime = ss->val[i].mtime;
- statbuf.st_ctime = ss->val[i].ctime;
+ statbuf.st_dev = ss->val[i].st_dev;
+ statbuf.st_ino = ss->val[i].st_ino;
+ statbuf.st_mode = ss->val[i].st_mode;
+ statbuf.st_nlink = ss->val[i].st_nlink;
+ statbuf.st_uid = ss->val[i].st_uid;
+ statbuf.st_gid = ss->val[i].st_gid;
+ statbuf.st_rdev = ss->val[i].st_rdev;
+ statbuf.st_size = ss->val[i].st_size;
+ statbuf.st_blksize = ss->val[i].st_blksize;
+ statbuf.st_blocks = ss->val[i].st_blocks;
+ statbuf.st_atime = ss->val[i].st_atime_sec;
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ statbuf.st_atim.tv_nsec = ss->val[i].st_atime_nsec;
+#endif
+ statbuf.st_mtime = ss->val[i].st_mtime_sec;
+#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+ statbuf.st_mtim.tv_nsec = ss->val[i].st_mtime_nsec;
+#endif
+ statbuf.st_ctime = ss->val[i].st_ctime_sec;
+#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
+ statbuf.st_ctim.tv_nsec = ss->val[i].st_ctime_nsec;
+#endif
lsc_insert (g, path, names[i], now, &statbuf);
}
@@ -246,7 +255,7 @@ static int
mount_local_getattr (const char *path, struct stat *statbuf)
{
const struct stat *buf;
- CLEANUP_FREE_STAT struct guestfs_stat *r = NULL;
+ CLEANUP_FREE_STAT struct guestfs_statns *r = NULL;
DECL_G ();
DEBUG_CALL ("%s, %p", path, statbuf);
@@ -256,24 +265,33 @@ mount_local_getattr (const char *path, struct stat *statbuf)
return 0;
}
- r = guestfs_lstat (g, path);
+ r = guestfs_lstatns (g, path);
if (r == NULL)
RETURN_ERRNO;
memset (statbuf, 0, sizeof *statbuf);
- statbuf->st_dev = r->dev;
- statbuf->st_ino = r->ino;
- statbuf->st_mode = r->mode;
- statbuf->st_nlink = r->nlink;
- statbuf->st_uid = r->uid;
- statbuf->st_gid = r->gid;
- statbuf->st_rdev = r->rdev;
- statbuf->st_size = r->size;
- statbuf->st_blksize = r->blksize;
- statbuf->st_blocks = r->blocks;
- statbuf->st_atime = r->atime;
- statbuf->st_mtime = r->mtime;
- statbuf->st_ctime = r->ctime;
+ statbuf->st_dev = r->st_dev;
+ statbuf->st_ino = r->st_ino;
+ statbuf->st_mode = r->st_mode;
+ statbuf->st_nlink = r->st_nlink;
+ statbuf->st_uid = r->st_uid;
+ statbuf->st_gid = r->st_gid;
+ statbuf->st_rdev = r->st_rdev;
+ statbuf->st_size = r->st_size;
+ statbuf->st_blksize = r->st_blksize;
+ statbuf->st_blocks = r->st_blocks;
+ statbuf->st_atime = r->st_atime_sec;
+#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
+ statbuf->st_atim.tv_nsec = r->st_atime_nsec;
+#endif
+ statbuf->st_mtime = r->st_mtime_sec;
+#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+ statbuf->st_mtim.tv_nsec = r->st_mtime_nsec;
+#endif
+ statbuf->st_ctime = r->st_ctime_sec;
+#ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
+ statbuf->st_ctim.tv_nsec = r->st_ctime_nsec;
+#endif
return 0;
}
@@ -1133,7 +1151,7 @@ guestfs__umount_local (guestfs_h *g,
* Note on attribute caching: FUSE can cache filesystem attributes for
* short periods of time (configurable via -o attr_timeout). It
* doesn't cache xattrs, and in any case FUSE caching doesn't solve
- * the problem that we have to make a series of guestfs_lstat and
+ * the problem that we have to make a series of guestfs_lstatns and
* guestfs_lgetxattr calls when we first list a directory (thus, many
* round trips).
*
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml
index fb254b1..d932bcc 100644
--- a/v2v/convert_linux.ml
+++ b/v2v/convert_linux.ml
@@ -43,7 +43,7 @@ type kernel_info = {
ki_version : string; (* version-release *)
ki_arch : string; (* Kernel architecture. *)
ki_vmlinuz : string; (* The path of the vmlinuz file. *)
- ki_vmlinuz_stat : G.stat; (* stat(2) of vmlinuz *)
+ ki_vmlinuz_stat : G.statns; (* stat(2) of vmlinuz *)
ki_initrd : string option; (* Path of initramfs, if found. *)
ki_modpath : string; (* The module path. *)
ki_modules : string list; (* The list of module names. *)
@@ -165,7 +165,7 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source =
if not (g#is_dir ~followsymlinks:true modpath) then
raise Not_found;
let vmlinuz_stat =
- try g#stat vmlinuz with G.Error _ -> raise Not_found in
+ try g#statns vmlinuz with G.Error _ -> raise Not_found in
(* Get/construct the version. XXX Read this from kernel file. *)
let version =
@@ -357,11 +357,11 @@ let rec convert ~verbose ~keep_serial_console (g : G.guestfs) inspect source =
filter_map (
fun vmlinuz ->
try
- let statbuf = g#stat vmlinuz in
+ let statbuf = g#statns vmlinuz in
let kernel =
List.find (
fun { ki_vmlinuz_stat = s } ->
- statbuf.G.dev = s.G.dev && statbuf.G.ino = s.G.ino
+ statbuf.G.st_dev = s.G.st_dev && statbuf.G.st_ino = s.G.st_ino
) installed_kernels in
Some kernel
with Not_found -> None
--
2.0.4
10 years, 2 months
[PATCH] daemon: augeas: filter out AUG_NO_STDINC from aug-init (RHBZ#1144927)
by Pino Toscano
The lenses in our custom path need the system lens for base
definitions. Disabling the system path was worthless anyway, since our
API does not allow user-specified custom paths.
The only possible use for AUG_NO_STDINC to aug-init could have been to
not load the lenses right at init time loading them later; however, this
is what the AUG_NO_LOAD flag (= 32) does already.
---
daemon/augeas.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/daemon/augeas.c b/daemon/augeas.c
index ce49726..4f1d9a8 100644
--- a/daemon/augeas.c
+++ b/daemon/augeas.c
@@ -133,6 +133,11 @@ do_aug_init (const char *root, int flags)
return -1;
}
+ /* Filter out AUG_NO_STDINC, since the lenses in our custom path
+ * need the lenses from the system path.
+ */
+ flags &= ~AUG_NO_STDINC;
+
/* Pass AUG_NO_ERR_CLOSE so we can display detailed errors. */
aug = aug_init (buf, "/usr/share/guestfs/", flags | AUG_NO_ERR_CLOSE);
--
1.9.3
10 years, 2 months
[PATCH] fuse: Enable futimens test (RHBZ#1144766).
by Richard W.M. Jones
---
fuse/test-fuse.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/fuse/test-fuse.c b/fuse/test-fuse.c
index 2876dc4..1e18a75 100644
--- a/fuse/test-fuse.c
+++ b/fuse/test-fuse.c
@@ -249,9 +249,7 @@ test_fuse (void)
unsigned u, u1;
int fd;
struct timeval tv[2];
-#if 0
struct timespec ts[2];
-#endif
acl_t acl;
char *acl_text;
@@ -574,8 +572,6 @@ test_fuse (void)
return -1;
}
-#if 0
- /* Does not work! See https://bugzilla.redhat.com/show_bug.cgi?id=1144766 */
STAGE ("checking utimens");
fd = open ("timestamp", O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_CLOEXEC, 0644);
@@ -605,7 +601,6 @@ test_fuse (void)
return -1;
}
close (fd);
-#endif
STAGE ("checking writes");
--
2.0.4
10 years, 2 months
[PATCH v2 00/13] virt-resize: add support for resizing MBR logical partitions
by Hu Tao
Hi Rich,
This is v2 series to add support for resizing MBR logical partitions.
I found the reason of problem in v1 that parted reports error when
adding logical partitions, is that logical partitions are not aligned
to 2 sectors. This problem doesn't appear in v2.
This is for early review, because of:
1. I'm not sure the splitting of patches is appropriate or not, but
it's much easier to review than v1.
2. The test script is not included, I'm not sure where to add the test
script. But I'll send the test script I used.
Thanks!
changes to v1:
1. spit the patches so it's easier to review
2. fix the parted error caused by unaligned logical partitions
3. extend the content of logical partitions
4. refactor to make logical partitions a seperate list
Hu Tao (13):
resize: convert sectsize to int64
add function div_roundup64
resize: introduce partition type
resize: introduce filter_part
resize: add function find_partition
resize: add function print_summmary
resize: expose loop to calculate new partitions' positions
resize: add function mbr_part_type
resize: add function copy_partition
resize: add function set_partition_bootable_and_id
resize: add function expand_partition_content
resize: add partition type LogicalPartition
resize: add support to resize logical partitions
mllib/common_utils.ml | 1 +
mllib/common_utils.mli | 1 +
resize/resize.ml | 217 ++++++++++++++++++++++++++++++++++++-------------
3 files changed, 161 insertions(+), 58 deletions(-)
--
1.9.3
10 years, 2 months
[PATCH] appliance: Add libsystemd0 (and systemd as an alternative for sysvinit) on Debian-based systems
by Hilko Bengen
---
appliance/packagelist.in | 2 ++
1 file changed, 2 insertions(+)
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index 3e028e3..418c574 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -80,6 +80,7 @@ dnl iproute has been renamed to iproute2
libcap2
libhivex0
libpcre3
+ libsystemd0
libsystemd-id128-0
libsystemd-journal0
libyajl2
@@ -91,6 +92,7 @@ dnl iproute has been renamed to iproute2
openssh-client
reiserfsprogs
sysvinit dnl for /sbin/reboot
+ systemd dnl alternative for /sbin/reboot
ufsutils
vim-tiny
xz-utils
--
2.1.0
10 years, 2 months