summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdevinfo/devinfo_devlink.c
diff options
context:
space:
mode:
authorvikram <none@none>2007-10-29 12:57:18 -0700
committervikram <none@none>2007-10-29 12:57:18 -0700
commit225f002560140ca3f36af7251c3ea773acaf8da4 (patch)
treee97794b652a32ebb4474f9b6b72009879a282a68 /usr/src/lib/libdevinfo/devinfo_devlink.c
parentddbf0f5b4139c525b411dded33321debf1f3c923 (diff)
downloadillumos-gate-225f002560140ca3f36af7251c3ea773acaf8da4.tar.gz
6601022 svm mirror creation failed on all machines in snv_72 and onward
Diffstat (limited to 'usr/src/lib/libdevinfo/devinfo_devlink.c')
-rw-r--r--usr/src/lib/libdevinfo/devinfo_devlink.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/usr/src/lib/libdevinfo/devinfo_devlink.c b/usr/src/lib/libdevinfo/devinfo_devlink.c
index 6f53830b0c..2feae724c5 100644
--- a/usr/src/lib/libdevinfo/devinfo_devlink.c
+++ b/usr/src/lib/libdevinfo/devinfo_devlink.c
@@ -3387,17 +3387,36 @@ daemon_call(const char *root, struct dca_off *dcp)
struct stat sb;
char *prefix;
int rofd;
+ int rdonly;
/*
- * If /etc/dev missing and readonly root, assume we are in install.
- * Don't use statvfs() since it doesn't always report the truth.
+ * If root is readonly, there are two possibilities:
+ * - we are in some sort of install scenario
+ * - we are early in boot
+ * If the latter we don't want daemon_call() to succeed.
+ * else we want to use /tmp/etc/dev
+ *
+ * Both of these requrements are fulfilled if we check for
+ * for a root owned door file in /tmp/etc/dev. If we are
+ * early in boot, the door file won't exist, so this call
+ * will fail.
+ *
+ * If we are in install, the door file will be present.
+ *
+ * If root is read-only, try only once, since libdevinfo
+ * isn't capable of starting devfsadmd correctly in that
+ * situation.
+ *
+ * Don't use statvfs() to check for readonly roots since it
+ * doesn't always report the truth.
*/
rofd = -1;
- if (stat("/etc/dev", &sb) == -1 &&
- (rofd = open(DEVNAME_CHECK_FILE,
- O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1 && errno == EROFS)
+ rdonly = 0;
+ if ((rofd = open(DEVNAME_CHECK_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644))
+ == -1 && errno == EROFS) {
+ rdonly = 1;
prefix = "/tmp";
- else {
+ } else {
if (rofd != -1) {
(void) close(rofd);
(void) unlink(DEVNAME_CHECK_FILE);
@@ -3408,6 +3427,19 @@ daemon_call(const char *root, struct dca_off *dcp)
(void) snprintf(synch_door, sizeof (synch_door),
"%s/etc/dev/%s", prefix, DEVFSADM_SYNCH_DOOR);
+ /*
+ * Return ENOTSUP to prevent retries if root is readonly
+ */
+ if (stat(synch_door, &sb) == -1 || sb.st_uid != 0) {
+ if (rdonly)
+ dcp->dca_error = ENOTSUP;
+ else
+ dcp->dca_error = ENOENT;
+ dprintf(DBG_ERR, "stat failed: %s: no file or not root owned\n",
+ synch_door);
+ return;
+ }
+
if ((fd = open(synch_door, O_RDONLY)) == -1) {
dcp->dca_error = errno;
dprintf(DBG_ERR, "open of %s failed: %s\n",